Commit fe13bc44 authored by Steve Glendinning's avatar Steve Glendinning Committed by Greg Kroah-Hartman

smsc95xx: fix transmission where ZLP is expected

[ Upstream commit ec475623 ]

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: default avatarSteve Glendinning <steve.glendinning@smsc.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 65745342
...@@ -1232,7 +1232,7 @@ static const struct driver_info smsc95xx_info = { ...@@ -1232,7 +1232,7 @@ static const struct driver_info smsc95xx_info = {
.rx_fixup = smsc95xx_rx_fixup, .rx_fixup = smsc95xx_rx_fixup,
.tx_fixup = smsc95xx_tx_fixup, .tx_fixup = smsc95xx_tx_fixup,
.status = smsc95xx_status, .status = smsc95xx_status,
.flags = FLAG_ETHER, .flags = FLAG_ETHER | FLAG_SEND_ZLP,
}; };
static const struct usb_device_id products[] = { static const struct usb_device_id products[] = {
......
...@@ -988,7 +988,7 @@ int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) ...@@ -988,7 +988,7 @@ int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
* NOTE: strictly conforming cdc-ether devices should expect * NOTE: strictly conforming cdc-ether devices should expect
* the ZLP here, but ignore the one-byte packet. * 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++; urb->transfer_buffer_length++;
if (skb_tailroom(skb)) { if (skb_tailroom(skb)) {
skb->data[skb->len] = 0; skb->data[skb->len] = 0;
......
...@@ -86,6 +86,7 @@ struct driver_info { ...@@ -86,6 +86,7 @@ struct driver_info {
#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */ #define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
#define FLAG_WLAN 0x0080 /* use "wlan%d" names */ #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 */ /* init device ... can sleep, or cause probe() failure */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment