diff options
author | Piotr Haber <phaber@broadcom.com> | 2012-11-28 15:44:07 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-11-30 13:38:17 -0500 |
commit | 57fe504817ccec9b6ac23e973d2925343bf1e3b6 (patch) | |
tree | e2d352683f674a21e7bfcde05d619aa4d4ef4f4b | |
parent | 94d9902dc06a28a1b25cf56a7cdc057608bdf48b (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.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) | |||
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 |