From: Yauheni Kaliuta <yauheni.kaliuta@xxxxxxxxx> cdc_ether: parse NCM class specific descriptor usbnet: store NCM descriptor, handle ZLP according to NCM spec Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@xxxxxxxxx> --- drivers/net/usb/cdc_ether.c | 12 ++++++++++++ drivers/net/usb/usbnet.c | 5 ++++- include/linux/usb/usbnet.h | 5 ++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index c8cdb7f..a18988d 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -229,6 +229,18 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) * side link address we were given. */ break; + case USB_CDC_NCM_TYPE: + if (info->ncm) { + dev_dbg(&intf->dev, "extra CDC NCM\n"); + goto bad_desc; + } + info->ncm = (void *) buf; + if (info->ncm->bLength != sizeof *info->ncm) { + dev_dbg(&intf->dev, "CDC NCM len %u\n", + info->ncm->bLength); + goto bad_desc; + } + break; } next_desc: len -= buf [0]; /* bLength */ diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index bba5b6e..5b30ed2 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1067,8 +1067,11 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, /* don't assume the hardware handles USB_ZERO_PACKET * NOTE: strictly conforming cdc-ether devices should expect * the ZLP here, but ignore the one-byte packet. + * NCM does not expect ZLP if transfer is dwNtbOutMaxSize */ - if (!(info->flags & FLAG_SEND_ZLP) && (length % dev->maxpacket) == 0) { + if (!(info->flags & FLAG_SEND_ZLP) && + !(info->flags & FLAG_NO_SHORT) && + (length % dev->maxpacket) == 0) { urb->transfer_buffer_length++; if (skb_tailroom(skb)) { skb->data[skb->len] = 0; diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 96bad3b..089ca9c 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -43,7 +43,7 @@ struct usbnet { /* protocol/interface state */ struct net_device *net; int msg_enable; - unsigned long data [5]; + unsigned long data[6]; u32 xid; u32 hard_mtu; /* count any extra framing */ size_t rx_urb_size; /* size for rx urbs */ @@ -96,6 +96,8 @@ struct driver_info { #define FLAG_WWAN 0x0400 /* use "wwan%d" names */ #define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */ +#define FLAG_NO_SHORT 0x1000 /* do not force short transfer */ + /* init device ... can sleep, or cause probe() failure */ int (*bind)(struct usbnet *, struct usb_interface *); @@ -165,6 +167,7 @@ struct cdc_state { struct usb_cdc_ether_desc *ether; struct usb_interface *control; struct usb_interface *data; + struct usb_cdc_ncm_desc *ncm; }; extern int usbnet_generic_cdc_bind (struct usbnet *, struct usb_interface *); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html