aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Glendinning <steve.glendinning@smsc.com>2009-09-22 00:00:27 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-22 17:28:26 -0400
commitec4756238239f1a331d9fb95bad8b281dad56855 (patch)
tree774936e88cb6c8527473e8e4d30b6a9dc914c1f2
parent36989b90879c785f95b877bdcf65a2527dadd893 (diff)
smsc95xx: fix transmission where ZLP is expected
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>
-rw-r--r--drivers/net/usb/smsc95xx.c2
-rw-r--r--drivers/net/usb/usbnet.c2
-rw-r--r--include/linux/usb/usbnet.h1
3 files changed, 3 insertions, 2 deletions
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 3aafebdbe7b5..c6c922247d05 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1227,7 +1227,7 @@ static const struct driver_info smsc95xx_info = {
1227 .rx_fixup = smsc95xx_rx_fixup, 1227 .rx_fixup = smsc95xx_rx_fixup,
1228 .tx_fixup = smsc95xx_tx_fixup, 1228 .tx_fixup = smsc95xx_tx_fixup,
1229 .status = smsc95xx_status, 1229 .status = smsc95xx_status,
1230 .flags = FLAG_ETHER, 1230 .flags = FLAG_ETHER | FLAG_SEND_ZLP,
1231}; 1231};
1232 1232
1233static const struct usb_device_id products[] = { 1233static const struct usb_device_id products[] = {
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 24b36f795151..ca5ca5ae061d 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1049,7 +1049,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
1049 * NOTE: strictly conforming cdc-ether devices should expect 1049 * NOTE: strictly conforming cdc-ether devices should expect
1050 * the ZLP here, but ignore the one-byte packet. 1050 * the ZLP here, but ignore the one-byte packet.
1051 */ 1051 */
1052 if ((length % dev->maxpacket) == 0) { 1052 if (!(info->flags & FLAG_SEND_ZLP) && (length % dev->maxpacket) == 0) {
1053 urb->transfer_buffer_length++; 1053 urb->transfer_buffer_length++;
1054 if (skb_tailroom(skb)) { 1054 if (skb_tailroom(skb)) {
1055 skb->data[skb->len] = 0; 1055 skb->data[skb->len] = 0;
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index bb69e256cd16..f81473052059 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -89,6 +89,7 @@ struct driver_info {
89#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */ 89#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
90#define FLAG_WLAN 0x0080 /* use "wlan%d" names */ 90#define FLAG_WLAN 0x0080 /* use "wlan%d" names */
91#define FLAG_AVOID_UNLINK_URBS 0x0100 /* don't unlink urbs at usbnet_stop() */ 91#define FLAG_AVOID_UNLINK_URBS 0x0100 /* don't unlink urbs at usbnet_stop() */
92#define FLAG_SEND_ZLP 0x0200 /* hw requires ZLPs are sent */
92 93
93 94
94 /* init device ... can sleep, or cause probe() failure */ 95 /* init device ... can sleep, or cause probe() failure */