diff options
author | Sujith <Sujith.Manoharan@atheros.com> | 2010-03-29 06:37:11 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-03-31 14:46:39 -0400 |
commit | ef98c3cd9b68ed27eeb94b833f74860fa1a734b7 (patch) | |
tree | 635dd6c83de38e8f3cc9c469ab1a4eb6f46d032a /drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |
parent | 0995d110118b35c0dc5195e3ddddcc0dec263830 (diff) |
ath9k_htc: Fix bug in aggregation initiation
Accessing the sta pointer in TX completion without
approprate RCU protection is wrong. Fix this.
Also, RCU protection is needed when the station's
aggregation state is updated. Handle this properly.
Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_drv_txrx.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 94e299fabbb2..838365607aa5 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -188,10 +188,20 @@ void ath9k_tx_tasklet(unsigned long data) | |||
188 | hdr = (struct ieee80211_hdr *) skb->data; | 188 | hdr = (struct ieee80211_hdr *) skb->data; |
189 | fc = hdr->frame_control; | 189 | fc = hdr->frame_control; |
190 | tx_info = IEEE80211_SKB_CB(skb); | 190 | tx_info = IEEE80211_SKB_CB(skb); |
191 | sta = tx_info->control.sta; | 191 | |
192 | memset(&tx_info->status, 0, sizeof(tx_info->status)); | ||
192 | 193 | ||
193 | rcu_read_lock(); | 194 | rcu_read_lock(); |
194 | 195 | ||
196 | sta = ieee80211_find_sta(priv->vif, hdr->addr1); | ||
197 | if (!sta) { | ||
198 | rcu_read_unlock(); | ||
199 | ieee80211_tx_status(priv->hw, skb); | ||
200 | continue; | ||
201 | } | ||
202 | |||
203 | /* Check if we need to start aggregation */ | ||
204 | |||
195 | if (sta && conf_is_ht(&priv->hw->conf) && | 205 | if (sta && conf_is_ht(&priv->hw->conf) && |
196 | (priv->op_flags & OP_TXAGGR) | 206 | (priv->op_flags & OP_TXAGGR) |
197 | && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | 207 | && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { |
@@ -213,7 +223,7 @@ void ath9k_tx_tasklet(unsigned long data) | |||
213 | 223 | ||
214 | rcu_read_unlock(); | 224 | rcu_read_unlock(); |
215 | 225 | ||
216 | memset(&tx_info->status, 0, sizeof(tx_info->status)); | 226 | /* Send status to mac80211 */ |
217 | ieee80211_tx_status(priv->hw, skb); | 227 | ieee80211_tx_status(priv->hw, skb); |
218 | } | 228 | } |
219 | } | 229 | } |