aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/net/usbnet.c30
-rw-r--r--drivers/usb/net/usbnet.h1
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
540void 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}
547EXPORT_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 */
166extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *); 166extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *);
167extern void usbnet_defer_kevent (struct usbnet *, int); 167extern void usbnet_defer_kevent (struct usbnet *, int);
168extern void usbnet_skb_return (struct usbnet *, struct sk_buff *); 168extern void usbnet_skb_return (struct usbnet *, struct sk_buff *);
169extern void usbnet_unlink_rx_urbs(struct usbnet *);
169 170
170extern u32 usbnet_get_msglevel (struct net_device *); 171extern u32 usbnet_get_msglevel (struct net_device *);
171extern void usbnet_set_msglevel (struct net_device *, u32); 172extern void usbnet_set_msglevel (struct net_device *, u32);