diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/agg-tx.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index eea6e5c8d168..331472ce038c 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -192,6 +192,20 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
192 | */ | 192 | */ |
193 | clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); | 193 | clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); |
194 | 194 | ||
195 | /* | ||
196 | * There might be a few packets being processed right now (on | ||
197 | * another CPU) that have already gotten past the aggregation | ||
198 | * check when it was still OPERATIONAL and consequently have | ||
199 | * IEEE80211_TX_CTL_AMPDU set. In that case, this code might | ||
200 | * call into the driver at the same time or even before the | ||
201 | * TX paths calls into it, which could confuse the driver. | ||
202 | * | ||
203 | * Wait for all currently running TX paths to finish before | ||
204 | * telling the driver. New packets will not go through since | ||
205 | * the aggregation session is no longer OPERATIONAL. | ||
206 | */ | ||
207 | synchronize_net(); | ||
208 | |||
195 | tid_tx->stop_initiator = initiator; | 209 | tid_tx->stop_initiator = initiator; |
196 | tid_tx->tx_stop = tx; | 210 | tid_tx->tx_stop = tx; |
197 | 211 | ||