diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/usb.c')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/usb.c | 8 |
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 | ||
429 | static void brcmf_usb_rx_complete(struct urb *urb) | 433 | static 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 | ||
609 | fail: | 616 | fail: |
@@ -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); |