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.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 01aed7ad6bec..322cadc51ded 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -82,6 +82,7 @@ struct brcmf_usbdev_info {
82 int tx_high_watermark; 82 int tx_high_watermark;
83 int tx_freecount; 83 int tx_freecount;
84 bool tx_flowblock; 84 bool tx_flowblock;
85 spinlock_t tx_flowblock_lock;
85 86
86 struct brcmf_usbreq *tx_reqs; 87 struct brcmf_usbreq *tx_reqs;
87 struct brcmf_usbreq *rx_reqs; 88 struct brcmf_usbreq *rx_reqs;
@@ -411,6 +412,7 @@ static void brcmf_usb_tx_complete(struct urb *urb)
411{ 412{
412 struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; 413 struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context;
413 struct brcmf_usbdev_info *devinfo = req->devinfo; 414 struct brcmf_usbdev_info *devinfo = req->devinfo;
415 unsigned long flags;
414 416
415 brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status, 417 brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status,
416 req->skb); 418 req->skb);
@@ -419,11 +421,13 @@ static void brcmf_usb_tx_complete(struct urb *urb)
419 brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0); 421 brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
420 req->skb = NULL; 422 req->skb = NULL;
421 brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount); 423 brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
424 spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
422 if (devinfo->tx_freecount > devinfo->tx_high_watermark && 425 if (devinfo->tx_freecount > devinfo->tx_high_watermark &&
423 devinfo->tx_flowblock) { 426 devinfo->tx_flowblock) {
424 brcmf_txflowblock(devinfo->dev, false); 427 brcmf_txflowblock(devinfo->dev, false);
425 devinfo->tx_flowblock = false; 428 devinfo->tx_flowblock = false;
426 } 429 }
430 spin_unlock_irqrestore(&devinfo->tx_flowblock_lock, flags);
427} 431}
428 432
429static void brcmf_usb_rx_complete(struct urb *urb) 433static void brcmf_usb_rx_complete(struct urb *urb)
@@ -568,6 +572,7 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
568 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); 572 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
569 struct brcmf_usbreq *req; 573 struct brcmf_usbreq *req;
570 int ret; 574 int ret;
575 unsigned long flags;
571 576
572 brcmf_dbg(USB, "Enter, skb=%p\n", skb); 577 brcmf_dbg(USB, "Enter, skb=%p\n", skb);
573 if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) { 578 if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) {
@@ -599,11 +604,13 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
599 goto fail; 604 goto fail;
600 } 605 }
601 606
607 spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
602 if (devinfo->tx_freecount < devinfo->tx_low_watermark && 608 if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
603 !devinfo->tx_flowblock) { 609 !devinfo->tx_flowblock) {
604 brcmf_txflowblock(dev, true); 610 brcmf_txflowblock(dev, true);
605 devinfo->tx_flowblock = true; 611 devinfo->tx_flowblock = true;
606 } 612 }
613 spin_unlock_irqrestore(&devinfo->tx_flowblock_lock, flags);
607 return 0; 614 return 0;
608 615
609fail: 616fail:
@@ -1164,6 +1171,7 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
1164 1171
1165 /* Initialize the spinlocks */ 1172 /* Initialize the spinlocks */
1166 spin_lock_init(&devinfo->qlock); 1173 spin_lock_init(&devinfo->qlock);
1174 spin_lock_init(&devinfo->tx_flowblock_lock);
1167 1175
1168 INIT_LIST_HEAD(&devinfo->rx_freeq); 1176 INIT_LIST_HEAD(&devinfo->rx_freeq);
1169 INIT_LIST_HEAD(&devinfo->rx_postq); 1177 INIT_LIST_HEAD(&devinfo->rx_postq);