diff options
author | Piotr Haber <phaber@broadcom.com> | 2012-11-29 00:44:07 +0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-11-30 22:38:17 +0400 |
commit | 57fe504817ccec9b6ac23e973d2925343bf1e3b6 (patch) | |
tree | e2d352683f674a21e7bfcde05d619aa4d4ef4f4b | |
parent | 94d9902dc06a28a1b25cf56a7cdc057608bdf48b (diff) | |
download | linux-57fe504817ccec9b6ac23e973d2925343bf1e3b6.tar.xz |
brcmsmac: fix bounds checking in tx/rx
brcms_b_txstatus and brcms_b_recv are off by one when
doing bounds checking on number of packets to process
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Piotr Haber <phaber@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmsmac/main.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 054e1da47806..8fce68751e47 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -1044,11 +1044,17 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) 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; + } if (s1 == 0xffffffff) { brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - return morepending; + *fatal = true; + return false; } s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); @@ -1060,17 +1066,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs); - /* !give others some time to run! */ - if (++n >= max_tx_num) - break; s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); + n++; } if (*fatal) - return 0; - - if (n >= max_tx_num) - morepending = true; + return false; return morepending; } @@ -7631,16 +7632,19 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) uint n = 0; uint bound_limit = bound ? RXBND : -1; + bool morepending; skb_queue_head_init(&recv_frames); /* gather received frames */ - while (dma_rx(wlc_hw->di[fifo], &recv_frames)) { - + do { /* !give others some time to run! */ - if (++n >= bound_limit) + if (n >= bound_limit) break; - } + + morepending = dma_rx(wlc_hw->di[fifo], &recv_frames); + n++; + } while (morepending); /* post more rbufs */ dma_rxfill(wlc_hw->di[fifo]); @@ -7670,7 +7674,7 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) brcms_c_recv(wlc_hw->wlc, p); } - return n >= bound_limit; + return morepending; } /* second-level interrupt processing |