aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Haber <phaber@broadcom.com>2012-11-28 15:44:07 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-11-30 13:38:17 -0500
commit57fe504817ccec9b6ac23e973d2925343bf1e3b6 (patch)
treee2d352683f674a21e7bfcde05d619aa4d4ef4f4b
parent94d9902dc06a28a1b25cf56a7cdc057608bdf48b (diff)
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.c30
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)
1044 s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); 1044 s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
1045 while (!(*fatal) 1045 while (!(*fatal)
1046 && (s1 & TXS_V)) { 1046 && (s1 & TXS_V)) {
1047 /* !give others some time to run! */
1048 if (n >= max_tx_num) {
1049 morepending = true;
1050 break;
1051 }
1047 1052
1048 if (s1 == 0xffffffff) { 1053 if (s1 == 0xffffffff) {
1049 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, 1054 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
1050 __func__); 1055 __func__);
1051 return morepending; 1056 *fatal = true;
1057 return false;
1052 } 1058 }
1053 s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); 1059 s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
1054 1060
@@ -1060,17 +1066,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
1060 1066
1061 *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs); 1067 *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
1062 1068
1063 /* !give others some time to run! */
1064 if (++n >= max_tx_num)
1065 break;
1066 s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); 1069 s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
1070 n++;
1067 } 1071 }
1068 1072
1069 if (*fatal) 1073 if (*fatal)
1070 return 0; 1074 return false;
1071
1072 if (n >= max_tx_num)
1073 morepending = true;
1074 1075
1075 return morepending; 1076 return morepending;
1076} 1077}
@@ -7631,16 +7632,19 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
7631 7632
7632 uint n = 0; 7633 uint n = 0;
7633 uint bound_limit = bound ? RXBND : -1; 7634 uint bound_limit = bound ? RXBND : -1;
7635 bool morepending;
7634 7636
7635 skb_queue_head_init(&recv_frames); 7637 skb_queue_head_init(&recv_frames);
7636 7638
7637 /* gather received frames */ 7639 /* gather received frames */
7638 while (dma_rx(wlc_hw->di[fifo], &recv_frames)) { 7640 do {
7639
7640 /* !give others some time to run! */ 7641 /* !give others some time to run! */
7641 if (++n >= bound_limit) 7642 if (n >= bound_limit)
7642 break; 7643 break;
7643 } 7644
7645 morepending = dma_rx(wlc_hw->di[fifo], &recv_frames);
7646 n++;
7647 } while (morepending);
7644 7648
7645 /* post more rbufs */ 7649 /* post more rbufs */
7646 dma_rxfill(wlc_hw->di[fifo]); 7650 dma_rxfill(wlc_hw->di[fifo]);
@@ -7670,7 +7674,7 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
7670 brcms_c_recv(wlc_hw->wlc, p); 7674 brcms_c_recv(wlc_hw->wlc, p);
7671 } 7675 }
7672 7676
7673 return n >= bound_limit; 7677 return morepending;
7674} 7678}
7675 7679
7676/* second-level interrupt processing 7680/* second-level interrupt processing