diff options
author | Roland Vossen <rvossen@broadcom.com> | 2011-04-12 08:34:41 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-04-25 19:32:28 -0400 |
commit | e9c661e08c2a6015c1b7cba1cecefa27a089df71 (patch) | |
tree | bb326898b1a0fb04ca1012a7885c2a46f0dca646 | |
parent | a1c5ad817d9316926372a4a708027edda80146e4 (diff) |
staging: brcm80211: bugfix for div by zero in minstrel_ht_tx_status
Caused by brcmsmac.ko suppling a 0 value to Mac80211. Mac80211 subsequently
divides by this number. Bug only occurred on AMPDU traffic. This is a fix
for https://bugzilla.kernel.org/show_bug.cgi?id=32032, titled
'Divide error in minstrel_ht_tx_status followed by hang', reported by
Wouter Cloetens.
Signed-off-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 13 |
1 files changed, 3 insertions, 10 deletions
diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 980344912ee7..07fbc3d46c8e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | |||
@@ -1122,21 +1122,12 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1122 | ini->txretry[index] = 0; | 1122 | ini->txretry[index] = 0; |
1123 | 1123 | ||
1124 | /* ampdu_ack_len: number of acked aggregated frames */ | 1124 | /* ampdu_ack_len: number of acked aggregated frames */ |
1125 | /* ampdu_ack_map: block ack bit map for the aggregation */ | ||
1126 | /* ampdu_len: number of aggregated frames */ | 1125 | /* ampdu_len: number of aggregated frames */ |
1127 | rate_status(wlc, tx_info, txs, mcs); | 1126 | rate_status(wlc, tx_info, txs, mcs); |
1128 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 1127 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
1129 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU; | 1128 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU; |
1130 | |||
1131 | /* XXX TODO: Make these accurate. */ | ||
1132 | tx_info->status.ampdu_ack_len = | 1129 | tx_info->status.ampdu_ack_len = |
1133 | (txs-> | 1130 | tx_info->status.ampdu_len = 1; |
1134 | status & TX_STATUS_FRM_RTX_MASK) >> | ||
1135 | TX_STATUS_FRM_RTX_SHIFT; | ||
1136 | tx_info->status.ampdu_len = | ||
1137 | (txs-> | ||
1138 | status & TX_STATUS_FRM_RTX_MASK) >> | ||
1139 | TX_STATUS_FRM_RTX_SHIFT; | ||
1140 | 1131 | ||
1141 | skb_pull(p, D11_PHY_HDR_LEN); | 1132 | skb_pull(p, D11_PHY_HDR_LEN); |
1142 | skb_pull(p, D11_TXH_LEN); | 1133 | skb_pull(p, D11_TXH_LEN); |
@@ -1162,6 +1153,8 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1162 | /* Retry timeout */ | 1153 | /* Retry timeout */ |
1163 | ini->tx_in_transit--; | 1154 | ini->tx_in_transit--; |
1164 | ieee80211_tx_info_clear_status(tx_info); | 1155 | ieee80211_tx_info_clear_status(tx_info); |
1156 | tx_info->status.ampdu_ack_len = 0; | ||
1157 | tx_info->status.ampdu_len = 1; | ||
1165 | tx_info->flags |= | 1158 | tx_info->flags |= |
1166 | IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1159 | IEEE80211_TX_STAT_AMPDU_NO_BACK; |
1167 | skb_pull(p, D11_PHY_HDR_LEN); | 1160 | skb_pull(p, D11_PHY_HDR_LEN); |