diff options
Diffstat (limited to 'drivers/usb/net')
-rw-r--r-- | drivers/usb/net/usbnet.c | 30 | ||||
-rw-r--r-- | drivers/usb/net/usbnet.h | 1 |
2 files changed, 28 insertions, 3 deletions
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 54183e173a6d..17fc6ae5c075 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c | |||
@@ -61,8 +61,11 @@ | |||
61 | * let the USB host controller be busy for 5msec or more before an irq | 61 | * let the USB host controller be busy for 5msec or more before an irq |
62 | * is required, under load. Jumbograms change the equation. | 62 | * is required, under load. Jumbograms change the equation. |
63 | */ | 63 | */ |
64 | #define RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4) | 64 | #define RX_MAX_QUEUE_MEMORY (60 * 1518) |
65 | #define TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4) | 65 | #define RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? \ |
66 | (RX_MAX_QUEUE_MEMORY/(dev)->rx_urb_size) : 4) | ||
67 | #define TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? \ | ||
68 | (RX_MAX_QUEUE_MEMORY/(dev)->hard_mtu) : 4) | ||
66 | 69 | ||
67 | // reawaken network queue this soon after stopping; else watchdog barks | 70 | // reawaken network queue this soon after stopping; else watchdog barks |
68 | #define TX_TIMEOUT_JIFFIES (5*HZ) | 71 | #define TX_TIMEOUT_JIFFIES (5*HZ) |
@@ -227,13 +230,23 @@ static int usbnet_change_mtu (struct net_device *net, int new_mtu) | |||
227 | { | 230 | { |
228 | struct usbnet *dev = netdev_priv(net); | 231 | struct usbnet *dev = netdev_priv(net); |
229 | int ll_mtu = new_mtu + net->hard_header_len; | 232 | int ll_mtu = new_mtu + net->hard_header_len; |
233 | int old_hard_mtu = dev->hard_mtu; | ||
234 | int old_rx_urb_size = dev->rx_urb_size; | ||
230 | 235 | ||
231 | if (new_mtu <= 0 || ll_mtu > dev->hard_mtu) | 236 | if (new_mtu <= 0) |
232 | return -EINVAL; | 237 | return -EINVAL; |
233 | // no second zero-length packet read wanted after mtu-sized packets | 238 | // no second zero-length packet read wanted after mtu-sized packets |
234 | if ((ll_mtu % dev->maxpacket) == 0) | 239 | if ((ll_mtu % dev->maxpacket) == 0) |
235 | return -EDOM; | 240 | return -EDOM; |
236 | net->mtu = new_mtu; | 241 | net->mtu = new_mtu; |
242 | |||
243 | dev->hard_mtu = net->mtu + net->hard_header_len; | ||
244 | if (dev->rx_urb_size == old_hard_mtu) { | ||
245 | dev->rx_urb_size = dev->hard_mtu; | ||
246 | if (dev->rx_urb_size > old_rx_urb_size) | ||
247 | usbnet_unlink_rx_urbs(dev); | ||
248 | } | ||
249 | |||
237 | return 0; | 250 | return 0; |
238 | } | 251 | } |
239 | 252 | ||
@@ -521,6 +534,17 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) | |||
521 | return count; | 534 | return count; |
522 | } | 535 | } |
523 | 536 | ||
537 | // Flush all pending rx urbs | ||
538 | // minidrivers may need to do this when the MTU changes | ||
539 | |||
540 | void usbnet_unlink_rx_urbs(struct usbnet *dev) | ||
541 | { | ||
542 | if (netif_running(dev->net)) { | ||
543 | (void) unlink_urbs (dev, &dev->rxq); | ||
544 | tasklet_schedule(&dev->bh); | ||
545 | } | ||
546 | } | ||
547 | EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs); | ||
524 | 548 | ||
525 | /*-------------------------------------------------------------------------*/ | 549 | /*-------------------------------------------------------------------------*/ |
526 | 550 | ||
diff --git a/drivers/usb/net/usbnet.h b/drivers/usb/net/usbnet.h index 89fc4958eecf..c0746f0454af 100644 --- a/drivers/usb/net/usbnet.h +++ b/drivers/usb/net/usbnet.h | |||
@@ -166,6 +166,7 @@ struct skb_data { /* skb->cb is one of these */ | |||
166 | extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *); | 166 | extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *); |
167 | extern void usbnet_defer_kevent (struct usbnet *, int); | 167 | extern void usbnet_defer_kevent (struct usbnet *, int); |
168 | extern void usbnet_skb_return (struct usbnet *, struct sk_buff *); | 168 | extern void usbnet_skb_return (struct usbnet *, struct sk_buff *); |
169 | extern void usbnet_unlink_rx_urbs(struct usbnet *); | ||
169 | 170 | ||
170 | extern u32 usbnet_get_msglevel (struct net_device *); | 171 | extern u32 usbnet_get_msglevel (struct net_device *); |
171 | extern void usbnet_set_msglevel (struct net_device *, u32); | 172 | extern void usbnet_set_msglevel (struct net_device *, u32); |