[PATCH 1/1] UBUNTU: SAUCE: brcmsmac: fix tx status processing
Seth Forshee
seth.forshee at canonical.com
Thu Jan 24 16:02:41 UTC 2013
From: Arend van Spriel <arend at broadcom.com>
The tx status feedback is processed in a loop limiting the number
of frames processed in one run. Bisecting by Seth Forshee showed
following commit as culprit:
commit 57fe504817ccec9b6ac23e973d2925343bf1e3b6
Author: Piotr Haber <phaber at broadcom.com>
Date: Wed Nov 28 21:44:07 2012 +0100
brcmsmac: fix bounds checking in tx/rx
The code terminate processing when the limit is reached regardless
the txstatus value read from the device register. When that status
is flagged as being valid it must be processed.
Cc: Seth Forshee <seth.forshee at canonical.com>
Reported-by: Linus Torvalds <torvalds at linux-foundation.org>
Signed-off-by: Arend van Spriel <arend at broadcom.com>
Signed-off-by: Seth Forshee <seth.forshee at canonical.com>
---
drivers/net/wireless/brcm80211/brcmsmac/main.c | 25 +++++++++---------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 17594de..9f3d7e9 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -1027,7 +1027,6 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
static bool
brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
{
- bool morepending = false;
struct bcma_device *core;
struct tx_status txstatus, *txs;
u32 s1, s2;
@@ -1041,23 +1040,20 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
txs = &txstatus;
core = wlc_hw->d11core;
*fatal = false;
- s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
- while (!(*fatal)
- && (s1 & TXS_V)) {
- /* !give others some time to run! */
- if (n >= max_tx_num) {
- morepending = true;
- break;
- }
+ while (n < max_tx_num) {
+ s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
if (s1 == 0xffffffff) {
brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
__func__);
*fatal = true;
return false;
}
- s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
+ /* only process when valid */
+ if (!(s1 & TXS_V))
+ break;
+ s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
txs->status = s1 & TXS_STATUS_MASK;
txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
txs->sequence = s2 & TXS_SEQ_MASK;
@@ -1065,15 +1061,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
txs->lasttxtime = 0;
*fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
-
- s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
+ if (*fatal == true)
+ return false;
n++;
}
- if (*fatal)
- return false;
-
- return morepending;
+ return n >= max_tx_num;
}
static void brcms_c_tbtt(struct brcms_c_info *wlc)
--
1.7.9.5
More information about the kernel-team
mailing list