--- zzzz-none-000/linux-2.6.32.61/drivers/net/usb/usbnet.c 2013-06-10 09:43:48.000000000 +0000 +++ virian-300e-630/linux-2.6.32.61/drivers/net/usb/usbnet.c 2014-03-13 17:35:54.000000000 +0000 @@ -962,7 +962,8 @@ struct usbnet *dev = entry->dev; if (urb->status == 0) { - dev->net->stats.tx_packets++; + if (!(dev->driver_info->flags & FLAG_MULTI_PACKET)) + dev->net->stats.tx_packets++; dev->net->stats.tx_bytes += entry->length; } else { dev->net->stats.tx_errors++; @@ -1033,9 +1034,13 @@ if (info->tx_fixup) { skb = info->tx_fixup (dev, skb, GFP_ATOMIC); if (!skb) { - if (netif_msg_tx_err (dev)) + if (netif_msg_tx_err (dev)) { devdbg (dev, "can't tx_fixup skb"); - goto drop; + goto drop; + } else { + /* cdc_ncm collected packet; waits for more */ + goto not_drop; + } } } length = skb->len; @@ -1058,13 +1063,21 @@ /* 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. + * NOTE2: CDC NCM specification is different from CDC ECM when + * handling ZLP/short packets, so cdc_ncm driver will make short + * packet itself if needed. */ - if (!(info->flags & FLAG_SEND_ZLP) && (length % dev->maxpacket) == 0) { - urb->transfer_buffer_length++; - if (skb_tailroom(skb)) { - skb->data[skb->len] = 0; - __skb_put(skb, 1); - } + if (length % dev->maxpacket == 0) { + if (!(info->flags & FLAG_SEND_ZLP)) { + if (!(info->flags & FLAG_MULTI_PACKET)) { + urb->transfer_buffer_length++; + if (skb_tailroom(skb)) { + skb->data[skb->len] = 0; + __skb_put(skb, 1); + } + } + } else + urb->transfer_flags |= URB_ZERO_PACKET; } spin_lock_irqsave (&dev->txq.lock, flags); @@ -1091,6 +1104,7 @@ devdbg (dev, "drop, code %d", retval); drop: dev->net->stats.tx_dropped++; +not_drop: if (skb) dev_kfree_skb_any (skb); usb_free_urb (urb); @@ -1296,12 +1310,16 @@ if (status < 0) goto out1; +/* --- 20140313 AVM/WK: FIX: we always want usb0, not eth4 ---*/ +#if 0 // heuristic: "usb%d" for links we know are two-host, // else "eth%d" when there's reasonable doubt. userspace // can rename the link if it knows better. if ((dev->driver_info->flags & FLAG_ETHER) != 0 && (net->dev_addr [0] & 0x02) == 0) strcpy (net->name, "eth%d"); +#endif + /* WLAN devices should always be named "wlan%d" */ if ((dev->driver_info->flags & FLAG_WLAN) != 0) strcpy(net->name, "wlan%d");