aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/agg-tx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-11-24 14:06:14 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-28 13:46:41 -0500
commit24f50a9d165745fd0701c6e089d35f58a229ea69 (patch)
treef43007765e54da07e5da5a5801d77fea168baa92 /net/mac80211/agg-tx.c
parente007b857e88097c96c45620bf3b04a4e309053d1 (diff)
mac80211: don't stop a single aggregation session twice
Nikolay noticed (by code review) that mac80211 can attempt to stop an aggregation session while it is already being stopped. So to fix it, check whether stop is already being done and bail out if so. Also move setting the STOPPING state into the lock so things are properly atomic. Cc: stable@vger.kernel.org Reported-by: Nikolay Martynov <mar.kolya@gmail.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r--net/mac80211/agg-tx.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 2ac033989e0..674b345ade8 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -160,6 +160,12 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
160 return -ENOENT; 160 return -ENOENT;
161 } 161 }
162 162
163 /* if we're already stopping ignore any new requests to stop */
164 if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
165 spin_unlock_bh(&sta->lock);
166 return -EALREADY;
167 }
168
163 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) { 169 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
164 /* not even started yet! */ 170 /* not even started yet! */
165 ieee80211_assign_tid_tx(sta, tid, NULL); 171 ieee80211_assign_tid_tx(sta, tid, NULL);
@@ -168,6 +174,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
168 return 0; 174 return 0;
169 } 175 }
170 176
177 set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
178
171 spin_unlock_bh(&sta->lock); 179 spin_unlock_bh(&sta->lock);
172 180
173#ifdef CONFIG_MAC80211_HT_DEBUG 181#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -175,8 +183,6 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
175 sta->sta.addr, tid); 183 sta->sta.addr, tid);
176#endif /* CONFIG_MAC80211_HT_DEBUG */ 184#endif /* CONFIG_MAC80211_HT_DEBUG */
177 185
178 set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
179
180 del_timer_sync(&tid_tx->addba_resp_timer); 186 del_timer_sync(&tid_tx->addba_resp_timer);
181 187
182 /* 188 /*