diff options
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/cdc_ncm.c | 3 | ||||
-rw-r--r-- | drivers/net/usb/qmi_wwan.c | 13 | ||||
-rw-r--r-- | drivers/net/usb/usbnet.c | 35 |
3 files changed, 45 insertions, 6 deletions
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 9197b2c72ca3..00d3b2d37828 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -1215,6 +1215,9 @@ static const struct usb_device_id cdc_devs[] = { | |||
1215 | { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46), | 1215 | { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46), |
1216 | .driver_info = (unsigned long)&wwan_info, | 1216 | .driver_info = (unsigned long)&wwan_info, |
1217 | }, | 1217 | }, |
1218 | { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x76), | ||
1219 | .driver_info = (unsigned long)&wwan_info, | ||
1220 | }, | ||
1218 | 1221 | ||
1219 | /* Infineon(now Intel) HSPA Modem platform */ | 1222 | /* Infineon(now Intel) HSPA Modem platform */ |
1220 | { USB_DEVICE_AND_INTERFACE_INFO(0x1519, 0x0443, | 1223 | { USB_DEVICE_AND_INTERFACE_INFO(0x1519, 0x0443, |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 575a5839ee34..c8e05e27f38c 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -351,6 +351,10 @@ static const struct usb_device_id products[] = { | |||
351 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57), | 351 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57), |
352 | .driver_info = (unsigned long)&qmi_wwan_info, | 352 | .driver_info = (unsigned long)&qmi_wwan_info, |
353 | }, | 353 | }, |
354 | { /* HUAWEI_INTERFACE_NDIS_CONTROL_QUALCOMM */ | ||
355 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x69), | ||
356 | .driver_info = (unsigned long)&qmi_wwan_info, | ||
357 | }, | ||
354 | 358 | ||
355 | /* 2. Combined interface devices matching on class+protocol */ | 359 | /* 2. Combined interface devices matching on class+protocol */ |
356 | { /* Huawei E367 and possibly others in "Windows mode" */ | 360 | { /* Huawei E367 and possibly others in "Windows mode" */ |
@@ -361,6 +365,14 @@ static const struct usb_device_id products[] = { | |||
361 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17), | 365 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17), |
362 | .driver_info = (unsigned long)&qmi_wwan_info, | 366 | .driver_info = (unsigned long)&qmi_wwan_info, |
363 | }, | 367 | }, |
368 | { /* HUAWEI_NDIS_SINGLE_INTERFACE_VDF */ | ||
369 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x37), | ||
370 | .driver_info = (unsigned long)&qmi_wwan_info, | ||
371 | }, | ||
372 | { /* HUAWEI_INTERFACE_NDIS_HW_QUALCOMM */ | ||
373 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x67), | ||
374 | .driver_info = (unsigned long)&qmi_wwan_info, | ||
375 | }, | ||
364 | { /* Pantech UML290, P4200 and more */ | 376 | { /* Pantech UML290, P4200 and more */ |
365 | USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff), | 377 | USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff), |
366 | .driver_info = (unsigned long)&qmi_wwan_info, | 378 | .driver_info = (unsigned long)&qmi_wwan_info, |
@@ -461,6 +473,7 @@ static const struct usb_device_id products[] = { | |||
461 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | 473 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ |
462 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 474 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
463 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | 475 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
476 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ | ||
464 | 477 | ||
465 | /* 4. Gobi 1000 devices */ | 478 | /* 4. Gobi 1000 devices */ |
466 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 479 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index f34b2ebee815..5e33606c1366 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -380,6 +380,12 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) | |||
380 | unsigned long lockflags; | 380 | unsigned long lockflags; |
381 | size_t size = dev->rx_urb_size; | 381 | size_t size = dev->rx_urb_size; |
382 | 382 | ||
383 | /* prevent rx skb allocation when error ratio is high */ | ||
384 | if (test_bit(EVENT_RX_KILL, &dev->flags)) { | ||
385 | usb_free_urb(urb); | ||
386 | return -ENOLINK; | ||
387 | } | ||
388 | |||
383 | skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); | 389 | skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); |
384 | if (!skb) { | 390 | if (!skb) { |
385 | netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); | 391 | netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); |
@@ -539,6 +545,17 @@ block: | |||
539 | break; | 545 | break; |
540 | } | 546 | } |
541 | 547 | ||
548 | /* stop rx if packet error rate is high */ | ||
549 | if (++dev->pkt_cnt > 30) { | ||
550 | dev->pkt_cnt = 0; | ||
551 | dev->pkt_err = 0; | ||
552 | } else { | ||
553 | if (state == rx_cleanup) | ||
554 | dev->pkt_err++; | ||
555 | if (dev->pkt_err > 20) | ||
556 | set_bit(EVENT_RX_KILL, &dev->flags); | ||
557 | } | ||
558 | |||
542 | state = defer_bh(dev, skb, &dev->rxq, state); | 559 | state = defer_bh(dev, skb, &dev->rxq, state); |
543 | 560 | ||
544 | if (urb) { | 561 | if (urb) { |
@@ -791,6 +808,11 @@ int usbnet_open (struct net_device *net) | |||
791 | (dev->driver_info->flags & FLAG_FRAMING_AX) ? "ASIX" : | 808 | (dev->driver_info->flags & FLAG_FRAMING_AX) ? "ASIX" : |
792 | "simple"); | 809 | "simple"); |
793 | 810 | ||
811 | /* reset rx error state */ | ||
812 | dev->pkt_cnt = 0; | ||
813 | dev->pkt_err = 0; | ||
814 | clear_bit(EVENT_RX_KILL, &dev->flags); | ||
815 | |||
794 | // delay posting reads until we're fully open | 816 | // delay posting reads until we're fully open |
795 | tasklet_schedule (&dev->bh); | 817 | tasklet_schedule (&dev->bh); |
796 | if (info->manage_power) { | 818 | if (info->manage_power) { |
@@ -1103,13 +1125,11 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, | |||
1103 | if (info->tx_fixup) { | 1125 | if (info->tx_fixup) { |
1104 | skb = info->tx_fixup (dev, skb, GFP_ATOMIC); | 1126 | skb = info->tx_fixup (dev, skb, GFP_ATOMIC); |
1105 | if (!skb) { | 1127 | if (!skb) { |
1106 | if (netif_msg_tx_err(dev)) { | 1128 | /* packet collected; minidriver waiting for more */ |
1107 | netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); | 1129 | if (info->flags & FLAG_MULTI_PACKET) |
1108 | goto drop; | ||
1109 | } else { | ||
1110 | /* cdc_ncm collected packet; waits for more */ | ||
1111 | goto not_drop; | 1130 | goto not_drop; |
1112 | } | 1131 | netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); |
1132 | goto drop; | ||
1113 | } | 1133 | } |
1114 | } | 1134 | } |
1115 | length = skb->len; | 1135 | length = skb->len; |
@@ -1254,6 +1274,9 @@ static void usbnet_bh (unsigned long param) | |||
1254 | } | 1274 | } |
1255 | } | 1275 | } |
1256 | 1276 | ||
1277 | /* restart RX again after disabling due to high error rate */ | ||
1278 | clear_bit(EVENT_RX_KILL, &dev->flags); | ||
1279 | |||
1257 | // waiting for all pending urbs to complete? | 1280 | // waiting for all pending urbs to complete? |
1258 | if (dev->wait) { | 1281 | if (dev->wait) { |
1259 | if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) { | 1282 | if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) { |