Merge branch 'cdc-next'
authorDavid S. Miller <davem@davemloft.net>
Thu, 20 Mar 2014 20:58:01 +0000 (16:58 -0400)
committerDavid S. Miller <davem@davemloft.net>
Thu, 20 Mar 2014 20:58:01 +0000 (16:58 -0400)
Ben Chan says:

====================
Adjust MTU as indicated by MBIM extended functional descriptor.

The MBIM extended functional descriptor, defined in "Universal Serial Bus
Communications Class Subclass Specification for Mobile Broadband Interface
Model, Revision 1.0, Errata-1" by USB-IF, indicates the operator preferred MTU
value via a wMTU field.

This patch set ensures that the initial MTU value set by cdc_ncm on a MBIM net
device does not exceed the wMTU value, provided the MBIM device exposes a MBIM
extended functional descriptor.

* Changelog
v2: Fixed a le16_to_cpu conversion issue in patch 2/2 pointed out by
    Bjørn Mork <bjorn@mork.no>
v3: No code changes. Resubmitted to include patch 1/2 as suggested by
    David Miller <davem@davemloft.net>
v4: No code changes. Resubmitted as suggested by David Miller:
    - Added a summary of the patch set
    - Carried the ACK from Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    - Added a specified the tree (net-next) to apply the patch set to
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/usb/cdc_ncm.c
include/linux/usb/cdc_ncm.h
include/uapi/linux/usb/cdc.h

index dbff290ed0e4f5ac4752efbe56eeea0fda0c419f..e8711a8cfa0187a6866436779743d7293ebc924e 100644 (file)
@@ -74,6 +74,7 @@ static int cdc_ncm_setup(struct usbnet *dev)
        u8 iface_no;
        int err;
        int eth_hlen;
+       u16 mbim_mtu;
        u16 ntb_fmt_supported;
        __le16 max_datagram_size;
 
@@ -261,6 +262,14 @@ out:
        /* set MTU to max supported by the device if necessary */
        if (dev->net->mtu > ctx->max_datagram_size - eth_hlen)
                dev->net->mtu = ctx->max_datagram_size - eth_hlen;
+
+       /* do not exceed operater preferred MTU */
+       if (ctx->mbim_extended_desc) {
+               mbim_mtu = le16_to_cpu(ctx->mbim_extended_desc->wMTU);
+               if (mbim_mtu != 0 && mbim_mtu < dev->net->mtu)
+                       dev->net->mtu = mbim_mtu;
+       }
+
        return 0;
 }
 
@@ -399,6 +408,14 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
                        ctx->mbim_desc = (const struct usb_cdc_mbim_desc *)buf;
                        break;
 
+               case USB_CDC_MBIM_EXTENDED_TYPE:
+                       if (buf[0] < sizeof(*(ctx->mbim_extended_desc)))
+                               break;
+
+                       ctx->mbim_extended_desc =
+                               (const struct usb_cdc_mbim_extended_desc *)buf;
+                       break;
+
                default:
                        break;
                }
index c3fa807459967286c0407c18da294ca6d95ced42..bdf05fb3672944d322f3ccbf35d122162ffeb55d 100644 (file)
@@ -93,6 +93,7 @@ struct cdc_ncm_ctx {
 
        const struct usb_cdc_ncm_desc *func_desc;
        const struct usb_cdc_mbim_desc *mbim_desc;
+       const struct usb_cdc_mbim_extended_desc *mbim_extended_desc;
        const struct usb_cdc_ether_desc *ether_desc;
 
        struct usb_interface *control;
index f35aa0a338c7610d89aa7f9e92e47d7e3a0de0a2..b6a9cdd6e096a26831bcb5c1cc69e6d41c8afe05 100644 (file)
@@ -56,6 +56,7 @@
 #define USB_CDC_OBEX_TYPE              0x15
 #define USB_CDC_NCM_TYPE               0x1a
 #define USB_CDC_MBIM_TYPE              0x1b
+#define USB_CDC_MBIM_EXTENDED_TYPE     0x1c
 
 /* "Header Functional Descriptor" from CDC spec  5.2.3.1 */
 struct usb_cdc_header_desc {
@@ -205,6 +206,17 @@ struct usb_cdc_mbim_desc {
        __u8    bmNetworkCapabilities;
 } __attribute__ ((packed));
 
+/* "MBIM Extended Functional Descriptor" from CDC MBIM spec 1.0 errata-1 */
+struct usb_cdc_mbim_extended_desc {
+       __u8    bLength;
+       __u8    bDescriptorType;
+       __u8    bDescriptorSubType;
+
+       __le16  bcdMBIMExtendedVersion;
+       __u8    bMaxOutstandingCommandMessages;
+       __le16  wMTU;
+} __attribute__ ((packed));
+
 /*-------------------------------------------------------------------------*/
 
 /*