diff options
author | Arend van Spriel <arend@broadcom.com> | 2013-08-10 06:27:19 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-08-15 16:07:51 -0400 |
commit | 4061f895088a2825b15312947aedb8574e2d8de5 (patch) | |
tree | b92def4417eb28dc36df9ef6e38534eb42428a40 /drivers/net/wireless/brcm80211/brcmfmac | |
parent | 74ea1f45243ecfbed30e3ef51d9ec5df2042be03 (diff) |
brcmfmac: use irq safe spinlock in brcmf_sdbrcm_txdata()
Firmware-signalling needs transmit to firmware to be atomic and
uses a spinlock with irq disabled. Therefor, brcmf_sdbrcm_txdata()
should not use spin_unlock_bh() as it would enable the interrupts.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 5 |
2 files changed, 8 insertions, 3 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 080395f49fa5..9249b6d42066 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | |||
@@ -36,7 +36,11 @@ struct brcmf_bus_dcmd { | |||
36 | * | 36 | * |
37 | * @init: prepare for communication with dongle. | 37 | * @init: prepare for communication with dongle. |
38 | * @stop: clear pending frames, disable data flow. | 38 | * @stop: clear pending frames, disable data flow. |
39 | * @txdata: send a data frame to the dongle (callee disposes skb). | 39 | * @txdata: send a data frame to the dongle. When the data |
40 | * has been transferred, the common driver must be | ||
41 | * notified using brcmf_txcomplete(). The common | ||
42 | * driver calls this function with interrupts | ||
43 | * disabled. | ||
40 | * @txctl: transmit a control request message to dongle. | 44 | * @txctl: transmit a control request message to dongle. |
41 | * @rxctl: receive a control response message from dongle. | 45 | * @rxctl: receive a control response message from dongle. |
42 | * @gettxq: obtain a reference of bus transmit queue (optional). | 46 | * @gettxq: obtain a reference of bus transmit queue (optional). |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 264111968320..5cbce1dff093 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -2276,6 +2276,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) | |||
2276 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 2276 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
2277 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | 2277 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
2278 | struct brcmf_sdio *bus = sdiodev->bus; | 2278 | struct brcmf_sdio *bus = sdiodev->bus; |
2279 | ulong flags; | ||
2279 | 2280 | ||
2280 | brcmf_dbg(TRACE, "Enter\n"); | 2281 | brcmf_dbg(TRACE, "Enter\n"); |
2281 | 2282 | ||
@@ -2293,7 +2294,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) | |||
2293 | bus->sdcnt.fcqueued++; | 2294 | bus->sdcnt.fcqueued++; |
2294 | 2295 | ||
2295 | /* Priority based enq */ | 2296 | /* Priority based enq */ |
2296 | spin_lock_bh(&bus->txqlock); | 2297 | spin_lock_irqsave(&bus->txqlock, flags); |
2297 | if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) { | 2298 | if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) { |
2298 | skb_pull(pkt, SDPCM_HDRLEN); | 2299 | skb_pull(pkt, SDPCM_HDRLEN); |
2299 | brcmf_txcomplete(bus->sdiodev->dev, pkt, false); | 2300 | brcmf_txcomplete(bus->sdiodev->dev, pkt, false); |
@@ -2307,7 +2308,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) | |||
2307 | bus->txoff = true; | 2308 | bus->txoff = true; |
2308 | brcmf_txflowblock(bus->sdiodev->dev, true); | 2309 | brcmf_txflowblock(bus->sdiodev->dev, true); |
2309 | } | 2310 | } |
2310 | spin_unlock_bh(&bus->txqlock); | 2311 | spin_unlock_irqrestore(&bus->txqlock, flags); |
2311 | 2312 | ||
2312 | #ifdef DEBUG | 2313 | #ifdef DEBUG |
2313 | if (pktq_plen(&bus->txq, prec) > qcount[prec]) | 2314 | if (pktq_plen(&bus->txq, prec) > qcount[prec]) |