diff options
Diffstat (limited to 'drivers/net/usb/usbnet.c')
-rw-r--r-- | drivers/net/usb/usbnet.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 06ee82f557d4..d74de074a438 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -59,15 +59,13 @@ | |||
59 | * For high speed, each frame comfortably fits almost 36 max size | 59 | * For high speed, each frame comfortably fits almost 36 max size |
60 | * Ethernet packets (so queues should be bigger). | 60 | * Ethernet packets (so queues should be bigger). |
61 | * | 61 | * |
62 | * REVISIT qlens should be members of 'struct usbnet'; the goal is to | 62 | * The goal is to let the USB host controller be busy for 5msec or |
63 | * let the USB host controller be busy for 5msec or more before an irq | 63 | * more before an irq is required, under load. Jumbograms change |
64 | * is required, under load. Jumbograms change the equation. | 64 | * the equation. |
65 | */ | 65 | */ |
66 | #define RX_MAX_QUEUE_MEMORY (60 * 1518) | 66 | #define MAX_QUEUE_MEMORY (60 * 1518) |
67 | #define RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? \ | 67 | #define RX_QLEN(dev) ((dev)->rx_qlen) |
68 | (RX_MAX_QUEUE_MEMORY/(dev)->rx_urb_size) : 4) | 68 | #define TX_QLEN(dev) ((dev)->tx_qlen) |
69 | #define TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? \ | ||
70 | (RX_MAX_QUEUE_MEMORY/(dev)->hard_mtu) : 4) | ||
71 | 69 | ||
72 | // reawaken network queue this soon after stopping; else watchdog barks | 70 | // reawaken network queue this soon after stopping; else watchdog barks |
73 | #define TX_TIMEOUT_JIFFIES (5*HZ) | 71 | #define TX_TIMEOUT_JIFFIES (5*HZ) |
@@ -347,6 +345,22 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb) | |||
347 | } | 345 | } |
348 | EXPORT_SYMBOL_GPL(usbnet_skb_return); | 346 | EXPORT_SYMBOL_GPL(usbnet_skb_return); |
349 | 347 | ||
348 | /* must be called if hard_mtu or rx_urb_size changed */ | ||
349 | void usbnet_update_max_qlen(struct usbnet *dev) | ||
350 | { | ||
351 | enum usb_device_speed speed = dev->udev->speed; | ||
352 | |||
353 | switch (speed) { | ||
354 | case USB_SPEED_HIGH: | ||
355 | dev->rx_qlen = MAX_QUEUE_MEMORY / dev->rx_urb_size; | ||
356 | dev->tx_qlen = MAX_QUEUE_MEMORY / dev->hard_mtu; | ||
357 | break; | ||
358 | default: | ||
359 | dev->rx_qlen = dev->tx_qlen = 4; | ||
360 | } | ||
361 | } | ||
362 | EXPORT_SYMBOL_GPL(usbnet_update_max_qlen); | ||
363 | |||
350 | 364 | ||
351 | /*------------------------------------------------------------------------- | 365 | /*------------------------------------------------------------------------- |
352 | * | 366 | * |
@@ -375,6 +389,9 @@ int usbnet_change_mtu (struct net_device *net, int new_mtu) | |||
375 | usbnet_unlink_rx_urbs(dev); | 389 | usbnet_unlink_rx_urbs(dev); |
376 | } | 390 | } |
377 | 391 | ||
392 | /* max qlen depend on hard_mtu and rx_urb_size */ | ||
393 | usbnet_update_max_qlen(dev); | ||
394 | |||
378 | return 0; | 395 | return 0; |
379 | } | 396 | } |
380 | EXPORT_SYMBOL_GPL(usbnet_change_mtu); | 397 | EXPORT_SYMBOL_GPL(usbnet_change_mtu); |
@@ -843,6 +860,9 @@ int usbnet_open (struct net_device *net) | |||
843 | goto done; | 860 | goto done; |
844 | } | 861 | } |
845 | 862 | ||
863 | /* hard_mtu or rx_urb_size may change in reset() */ | ||
864 | usbnet_update_max_qlen(dev); | ||
865 | |||
846 | // insist peer be connected | 866 | // insist peer be connected |
847 | if (info->check_connect && (retval = info->check_connect (dev)) < 0) { | 867 | if (info->check_connect && (retval = info->check_connect (dev)) < 0) { |
848 | netif_dbg(dev, ifup, dev->net, "can't open; %d\n", retval); | 868 | netif_dbg(dev, ifup, dev->net, "can't open; %d\n", retval); |
@@ -927,6 +947,9 @@ int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd) | |||
927 | if (dev->driver_info->link_reset) | 947 | if (dev->driver_info->link_reset) |
928 | dev->driver_info->link_reset(dev); | 948 | dev->driver_info->link_reset(dev); |
929 | 949 | ||
950 | /* hard_mtu or rx_urb_size may change in link_reset() */ | ||
951 | usbnet_update_max_qlen(dev); | ||
952 | |||
930 | return retval; | 953 | return retval; |
931 | 954 | ||
932 | } | 955 | } |
@@ -1020,6 +1043,9 @@ static void __handle_link_change(struct usbnet *dev) | |||
1020 | tasklet_schedule(&dev->bh); | 1043 | tasklet_schedule(&dev->bh); |
1021 | } | 1044 | } |
1022 | 1045 | ||
1046 | /* hard_mtu or rx_urb_size may change during link change */ | ||
1047 | usbnet_update_max_qlen(dev); | ||
1048 | |||
1023 | clear_bit(EVENT_LINK_CHANGE, &dev->flags); | 1049 | clear_bit(EVENT_LINK_CHANGE, &dev->flags); |
1024 | } | 1050 | } |
1025 | 1051 | ||
@@ -1599,6 +1625,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1599 | if ((dev->driver_info->flags & FLAG_WWAN) != 0) | 1625 | if ((dev->driver_info->flags & FLAG_WWAN) != 0) |
1600 | SET_NETDEV_DEVTYPE(net, &wwan_type); | 1626 | SET_NETDEV_DEVTYPE(net, &wwan_type); |
1601 | 1627 | ||
1628 | /* initialize max rx_qlen and tx_qlen */ | ||
1629 | usbnet_update_max_qlen(dev); | ||
1630 | |||
1602 | status = register_netdev (net); | 1631 | status = register_netdev (net); |
1603 | if (status) | 1632 | if (status) |
1604 | goto out4; | 1633 | goto out4; |