]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
smsc95xx: fix transmission where ZLP is expected
authorSteve Glendinning <steve.glendinning@smsc.com>
Tue, 22 Sep 2009 04:00:27 +0000 (04:00 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 12 Oct 2009 19:40:28 +0000 (12:40 -0700)
[ Upstream commit ec4756238239f1a331d9fb95bad8b281dad56855 ]

Usbnet framework assumes USB hardware doesn't handle zero length
packets, but SMSC LAN95xx requires these to be sent for correct
operation.

This patch fixes an easily reproducible tx lockup when sending a frame
that results in exactly 512 bytes in a USB transmission (e.g. a UDP
frame with 458 data bytes, due to IP headers and our USB headers).  It
adds an extra flag to usbnet for the hardware driver to indicate that
it can handle and requires the zero length packets.

This patch should not affect other usbnet users, please also consider
for -stable.

Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/net/usb/smsc95xx.c
drivers/net/usb/usbnet.c
include/linux/usb/usbnet.h

index fe045896406bdbf3bffa7525621b31b535a265d5..df49d0daaa16c1ac29905d30212a6a4bf540bea8 100644 (file)
@@ -1232,7 +1232,7 @@ static const struct driver_info smsc95xx_info = {
        .rx_fixup       = smsc95xx_rx_fixup,
        .tx_fixup       = smsc95xx_tx_fixup,
        .status         = smsc95xx_status,
-       .flags          = FLAG_ETHER,
+       .flags          = FLAG_ETHER | FLAG_SEND_ZLP,
 };
 
 static const struct usb_device_id products[] = {
index edfd9e10ceba28fcdc6454dd9c7f386a6ac9f6ac..d49df73520177134d02931b4f2cdc4b67654f426 100644 (file)
@@ -988,7 +988,7 @@ int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
         * NOTE:  strictly conforming cdc-ether devices should expect
         * the ZLP here, but ignore the one-byte packet.
         */
-       if ((length % dev->maxpacket) == 0) {
+       if (!(info->flags & FLAG_SEND_ZLP) && (length % dev->maxpacket) == 0) {
                urb->transfer_buffer_length++;
                if (skb_tailroom(skb)) {
                        skb->data[skb->len] = 0;
index 310e18a880fff5da371f000225a871008afbb84e..c42eeb32058a98bc67698167f2ec17faed5cbed0 100644 (file)
@@ -86,6 +86,7 @@ struct driver_info {
 
 #define FLAG_FRAMING_AX 0x0040         /* AX88772/178 packets */
 #define FLAG_WLAN      0x0080          /* use "wlan%d" names */
+#define FLAG_SEND_ZLP  0x0200          /* hw requires ZLPs are sent */
 
 
        /* init device ... can sleep, or cause probe() failure */