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 {
int tx_high_watermark;
int tx_freecount;
bool tx_flowblock;
+ spinlock_t tx_flowblock_lock;
struct brcmf_usbreq *tx_reqs;
struct brcmf_usbreq *rx_reqs;
@@ -411,6 +412,7 @@ static void brcmf_usb_tx_complete(struct urb *urb)
{
struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context;
struct brcmf_usbdev_info *devinfo = req->devinfo;
+ unsigned long flags;
brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status,
req->skb);
@@ -419,11 +421,13 @@ static void brcmf_usb_tx_complete(struct urb *urb)
brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
req->skb = NULL;
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
+ spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
if (devinfo->tx_freecount > devinfo->tx_high_watermark &&
devinfo->tx_flowblock) {
brcmf_txflowblock(devinfo->dev, false);
devinfo->tx_flowblock = false;
}
+ spin_unlock_irqrestore(&devinfo->tx_flowblock_lock, flags);
}
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)
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
struct brcmf_usbreq *req;
int ret;
+ unsigned long flags;
brcmf_dbg(USB, "Enter, skb=%p\n", skb);
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)
goto fail;
}
+ spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
!devinfo->tx_flowblock) {
brcmf_txflowblock(dev, true);
devinfo->tx_flowblock = true;
}
+ spin_unlock_irqrestore(&devinfo->tx_flowblock_lock, flags);
return 0;
fail:
@@ -1164,6 +1171,7 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
/* Initialize the spinlocks */
spin_lock_init(&devinfo->qlock);
+ spin_lock_init(&devinfo->tx_flowblock_lock);
INIT_LIST_HEAD(&devinfo->rx_freeq);
INIT_LIST_HEAD(&devinfo->rx_postq);