aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/usb.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 914c56fe6c5f..e15630cc3889 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -443,14 +443,15 @@ static void brcmf_usb_rx_complete(struct urb *urb)
443 struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; 443 struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context;
444 struct brcmf_usbdev_info *devinfo = req->devinfo; 444 struct brcmf_usbdev_info *devinfo = req->devinfo;
445 struct sk_buff *skb; 445 struct sk_buff *skb;
446 int ifidx = 0; 446 struct sk_buff_head skbq;
447 447
448 brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status); 448 brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status);
449 brcmf_usb_del_fromq(devinfo, req); 449 brcmf_usb_del_fromq(devinfo, req);
450 skb = req->skb; 450 skb = req->skb;
451 req->skb = NULL; 451 req->skb = NULL;
452 452
453 if (urb->status == 0) { 453 /* zero lenght packets indicate usb "failure". Do not refill */
454 if (urb->status == 0 && urb->actual_length) {
454 devinfo->bus_pub.bus->dstats.rx_packets++; 455 devinfo->bus_pub.bus->dstats.rx_packets++;
455 } else { 456 } else {
456 devinfo->bus_pub.bus->dstats.rx_errors++; 457 devinfo->bus_pub.bus->dstats.rx_errors++;
@@ -460,13 +461,10 @@ static void brcmf_usb_rx_complete(struct urb *urb)
460 } 461 }
461 462
462 if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { 463 if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) {
464 skb_queue_head_init(&skbq);
465 skb_queue_tail(&skbq, skb);
463 skb_put(skb, urb->actual_length); 466 skb_put(skb, urb->actual_length);
464 if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { 467 brcmf_rx_frames(devinfo->dev, &skbq);
465 brcmf_err("rx protocol error\n");
466 brcmu_pkt_buf_free_skb(skb);
467 devinfo->bus_pub.bus->dstats.rx_errors++;
468 } else
469 brcmf_rx_packet(devinfo->dev, ifidx, skb);
470 brcmf_usb_rx_refill(devinfo, req); 468 brcmf_usb_rx_refill(devinfo, req);
471 } else { 469 } else {
472 brcmu_pkt_buf_free_skb(skb); 470 brcmu_pkt_buf_free_skb(skb);
@@ -1520,10 +1518,23 @@ static void brcmf_release_fw(struct list_head *q)
1520 } 1518 }
1521} 1519}
1522 1520
1521static int brcmf_usb_reset_device(struct device *dev, void *notused)
1522{
1523 /* device past is the usb interface so we
1524 * need to use parent here.
1525 */
1526 brcmf_dev_reset(dev->parent);
1527 return 0;
1528}
1523 1529
1524void brcmf_usb_exit(void) 1530void brcmf_usb_exit(void)
1525{ 1531{
1532 struct device_driver *drv = &brcmf_usbdrvr.drvwrap.driver;
1533 int ret;
1534
1526 brcmf_dbg(USB, "Enter\n"); 1535 brcmf_dbg(USB, "Enter\n");
1536 ret = driver_for_each_device(drv, NULL, NULL,
1537 brcmf_usb_reset_device);
1527 usb_deregister(&brcmf_usbdrvr); 1538 usb_deregister(&brcmf_usbdrvr);
1528 brcmf_release_fw(&fw_image_list); 1539 brcmf_release_fw(&fw_image_list);
1529} 1540}