aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/agg-tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r--net/mac80211/agg-tx.c549
1 files changed, 311 insertions, 238 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index d1b6664a2532..c893f236acea 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -6,7 +6,7 @@
6 * Copyright 2005-2006, Devicescape Software, Inc. 6 * Copyright 2005-2006, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 * Copyright 2007-2009, Intel Corporation 9 * Copyright 2007-2010, Intel Corporation
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -21,28 +21,39 @@
21#include "wme.h" 21#include "wme.h"
22 22
23/** 23/**
24 * DOC: TX aggregation 24 * DOC: TX A-MPDU aggregation
25 * 25 *
26 * Aggregation on the TX side requires setting the hardware flag 26 * Aggregation on the TX side requires setting the hardware flag
27 * %IEEE80211_HW_AMPDU_AGGREGATION as well as, if present, the @ampdu_queues 27 * %IEEE80211_HW_AMPDU_AGGREGATION. The driver will then be handed
28 * hardware parameter to the number of hardware AMPDU queues. If there are no 28 * packets with a flag indicating A-MPDU aggregation. The driver
29 * hardware queues then the driver will (currently) have to do all frame 29 * or device is responsible for actually aggregating the frames,
30 * buffering. 30 * as well as deciding how many and which to aggregate.
31 * 31 *
32 * When TX aggregation is started by some subsystem (usually the rate control 32 * When TX aggregation is started by some subsystem (usually the rate
33 * algorithm would be appropriate) by calling the 33 * control algorithm would be appropriate) by calling the
34 * ieee80211_start_tx_ba_session() function, the driver will be notified via 34 * ieee80211_start_tx_ba_session() function, the driver will be
35 * its @ampdu_action function, with the %IEEE80211_AMPDU_TX_START action. 35 * notified via its @ampdu_action function, with the
36 * %IEEE80211_AMPDU_TX_START action.
36 * 37 *
37 * In response to that, the driver is later required to call the 38 * In response to that, the driver is later required to call the
38 * ieee80211_start_tx_ba_cb() (or ieee80211_start_tx_ba_cb_irqsafe()) 39 * ieee80211_start_tx_ba_cb_irqsafe() function, which will really
39 * function, which will start the aggregation session. 40 * start the aggregation session after the peer has also responded.
41 * If the peer responds negatively, the session will be stopped
42 * again right away. Note that it is possible for the aggregation
43 * session to be stopped before the driver has indicated that it
44 * is done setting it up, in which case it must not indicate the
45 * setup completion.
40 * 46 *
41 * Similarly, when the aggregation session is stopped by 47 * Also note that, since we also need to wait for a response from
42 * ieee80211_stop_tx_ba_session(), the driver's @ampdu_action function will 48 * the peer, the driver is notified of the completion of the
43 * be called with the action %IEEE80211_AMPDU_TX_STOP. In this case, the 49 * handshake by the %IEEE80211_AMPDU_TX_OPERATIONAL action to the
44 * call must not fail, and the driver must later call ieee80211_stop_tx_ba_cb() 50 * @ampdu_action callback.
45 * (or ieee80211_stop_tx_ba_cb_irqsafe()). 51 *
52 * Similarly, when the aggregation session is stopped by the peer
53 * or something calling ieee80211_stop_tx_ba_session(), the driver's
54 * @ampdu_action function will be called with the action
55 * %IEEE80211_AMPDU_TX_STOP. In this case, the call must not fail,
56 * and the driver must later call ieee80211_stop_tx_ba_cb_irqsafe().
46 */ 57 */
47 58
48static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, 59static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
@@ -125,25 +136,53 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
125 ieee80211_tx_skb(sdata, skb); 136 ieee80211_tx_skb(sdata, skb);
126} 137}
127 138
139static void kfree_tid_tx(struct rcu_head *rcu_head)
140{
141 struct tid_ampdu_tx *tid_tx =
142 container_of(rcu_head, struct tid_ampdu_tx, rcu_head);
143
144 kfree(tid_tx);
145}
146
128int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, 147int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
129 enum ieee80211_back_parties initiator) 148 enum ieee80211_back_parties initiator)
130{ 149{
131 struct ieee80211_local *local = sta->local; 150 struct ieee80211_local *local = sta->local;
151 struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid];
132 int ret; 152 int ret;
133 u8 *state; 153
154 lockdep_assert_held(&sta->ampdu_mlme.mtx);
155
156 if (!tid_tx)
157 return -ENOENT;
158
159 spin_lock_bh(&sta->lock);
160
161 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
162 /* not even started yet! */
163 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL);
164 spin_unlock_bh(&sta->lock);
165 call_rcu(&tid_tx->rcu_head, kfree_tid_tx);
166 return 0;
167 }
168
169 spin_unlock_bh(&sta->lock);
134 170
135#ifdef CONFIG_MAC80211_HT_DEBUG 171#ifdef CONFIG_MAC80211_HT_DEBUG
136 printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", 172 printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
137 sta->sta.addr, tid); 173 sta->sta.addr, tid);
138#endif /* CONFIG_MAC80211_HT_DEBUG */ 174#endif /* CONFIG_MAC80211_HT_DEBUG */
139 175
140 state = &sta->ampdu_mlme.tid_state_tx[tid]; 176 set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
141 177
142 if (*state == HT_AGG_STATE_OPERATIONAL) 178 /*
143 sta->ampdu_mlme.addba_req_num[tid] = 0; 179 * After this packets are no longer handed right through
180 * to the driver but are put onto tid_tx->pending instead,
181 * with locking to ensure proper access.
182 */
183 clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
144 184
145 *state = HT_AGG_STATE_REQ_STOP_BA_MSK | 185 tid_tx->stop_initiator = initiator;
146 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
147 186
148 ret = drv_ampdu_action(local, sta->sdata, 187 ret = drv_ampdu_action(local, sta->sdata,
149 IEEE80211_AMPDU_TX_STOP, 188 IEEE80211_AMPDU_TX_STOP,
@@ -174,16 +213,14 @@ static void sta_addba_resp_timer_expired(unsigned long data)
174 u16 tid = *(u8 *)data; 213 u16 tid = *(u8 *)data;
175 struct sta_info *sta = container_of((void *)data, 214 struct sta_info *sta = container_of((void *)data,
176 struct sta_info, timer_to_tid[tid]); 215 struct sta_info, timer_to_tid[tid]);
177 u8 *state; 216 struct tid_ampdu_tx *tid_tx;
178
179 state = &sta->ampdu_mlme.tid_state_tx[tid];
180 217
181 /* check if the TID waits for addBA response */ 218 /* check if the TID waits for addBA response */
182 spin_lock_bh(&sta->lock); 219 rcu_read_lock();
183 if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK | 220 tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
184 HT_AGG_STATE_REQ_STOP_BA_MSK)) != 221 if (!tid_tx ||
185 HT_ADDBA_REQUESTED_MSK) { 222 test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) {
186 spin_unlock_bh(&sta->lock); 223 rcu_read_unlock();
187#ifdef CONFIG_MAC80211_HT_DEBUG 224#ifdef CONFIG_MAC80211_HT_DEBUG
188 printk(KERN_DEBUG "timer expired on tid %d but we are not " 225 printk(KERN_DEBUG "timer expired on tid %d but we are not "
189 "(or no longer) expecting addBA response there\n", 226 "(or no longer) expecting addBA response there\n",
@@ -196,8 +233,8 @@ static void sta_addba_resp_timer_expired(unsigned long data)
196 printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid); 233 printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
197#endif 234#endif
198 235
199 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); 236 ieee80211_stop_tx_ba_session(&sta->sta, tid);
200 spin_unlock_bh(&sta->lock); 237 rcu_read_unlock();
201} 238}
202 239
203static inline int ieee80211_ac_from_tid(int tid) 240static inline int ieee80211_ac_from_tid(int tid)
@@ -205,14 +242,112 @@ static inline int ieee80211_ac_from_tid(int tid)
205 return ieee802_1d_to_ac[tid & 7]; 242 return ieee802_1d_to_ac[tid & 7];
206} 243}
207 244
245/*
246 * When multiple aggregation sessions on multiple stations
247 * are being created/destroyed simultaneously, we need to
248 * refcount the global queue stop caused by that in order
249 * to not get into a situation where one of the aggregation
250 * setup or teardown re-enables queues before the other is
251 * ready to handle that.
252 *
253 * These two functions take care of this issue by keeping
254 * a global "agg_queue_stop" refcount.
255 */
256static void __acquires(agg_queue)
257ieee80211_stop_queue_agg(struct ieee80211_local *local, int tid)
258{
259 int queue = ieee80211_ac_from_tid(tid);
260
261 if (atomic_inc_return(&local->agg_queue_stop[queue]) == 1)
262 ieee80211_stop_queue_by_reason(
263 &local->hw, queue,
264 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
265 __acquire(agg_queue);
266}
267
268static void __releases(agg_queue)
269ieee80211_wake_queue_agg(struct ieee80211_local *local, int tid)
270{
271 int queue = ieee80211_ac_from_tid(tid);
272
273 if (atomic_dec_return(&local->agg_queue_stop[queue]) == 0)
274 ieee80211_wake_queue_by_reason(
275 &local->hw, queue,
276 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
277 __release(agg_queue);
278}
279
280void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
281{
282 struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid];
283 struct ieee80211_local *local = sta->local;
284 struct ieee80211_sub_if_data *sdata = sta->sdata;
285 u16 start_seq_num;
286 int ret;
287
288 lockdep_assert_held(&sta->ampdu_mlme.mtx);
289
290 /*
291 * While we're asking the driver about the aggregation,
292 * stop the AC queue so that we don't have to worry
293 * about frames that came in while we were doing that,
294 * which would require us to put them to the AC pending
295 * afterwards which just makes the code more complex.
296 */
297 ieee80211_stop_queue_agg(local, tid);
298
299 clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
300
301 /*
302 * make sure no packets are being processed to get
303 * valid starting sequence number
304 */
305 synchronize_net();
306
307 start_seq_num = sta->tid_seq[tid] >> 4;
308
309 ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START,
310 &sta->sta, tid, &start_seq_num);
311 if (ret) {
312#ifdef CONFIG_MAC80211_HT_DEBUG
313 printk(KERN_DEBUG "BA request denied - HW unavailable for"
314 " tid %d\n", tid);
315#endif
316 spin_lock_bh(&sta->lock);
317 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL);
318 spin_unlock_bh(&sta->lock);
319
320 ieee80211_wake_queue_agg(local, tid);
321 call_rcu(&tid_tx->rcu_head, kfree_tid_tx);
322 return;
323 }
324
325 /* we can take packets again now */
326 ieee80211_wake_queue_agg(local, tid);
327
328 /* activate the timer for the recipient's addBA response */
329 mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL);
330#ifdef CONFIG_MAC80211_HT_DEBUG
331 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
332#endif
333
334 spin_lock_bh(&sta->lock);
335 sta->ampdu_mlme.addba_req_num[tid]++;
336 spin_unlock_bh(&sta->lock);
337
338 /* send AddBA request */
339 ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
340 tid_tx->dialog_token, start_seq_num,
341 0x40, 5000);
342}
343
208int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) 344int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
209{ 345{
210 struct sta_info *sta = container_of(pubsta, struct sta_info, sta); 346 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
211 struct ieee80211_sub_if_data *sdata = sta->sdata; 347 struct ieee80211_sub_if_data *sdata = sta->sdata;
212 struct ieee80211_local *local = sdata->local; 348 struct ieee80211_local *local = sdata->local;
213 u8 *state; 349 struct tid_ampdu_tx *tid_tx;
214 int ret = 0; 350 int ret = 0;
215 u16 start_seq_num;
216 351
217 trace_api_start_tx_ba_session(pubsta, tid); 352 trace_api_start_tx_ba_session(pubsta, tid);
218 353
@@ -239,24 +374,15 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
239 sdata->vif.type != NL80211_IFTYPE_AP) 374 sdata->vif.type != NL80211_IFTYPE_AP)
240 return -EINVAL; 375 return -EINVAL;
241 376
242 if (test_sta_flags(sta, WLAN_STA_DISASSOC)) {
243#ifdef CONFIG_MAC80211_HT_DEBUG
244 printk(KERN_DEBUG "Disassociation is in progress. "
245 "Denying BA session request\n");
246#endif
247 return -EINVAL;
248 }
249
250 if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) { 377 if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
251#ifdef CONFIG_MAC80211_HT_DEBUG 378#ifdef CONFIG_MAC80211_HT_DEBUG
252 printk(KERN_DEBUG "Suspend in progress. " 379 printk(KERN_DEBUG "BA sessions blocked. "
253 "Denying BA session request\n"); 380 "Denying BA session request\n");
254#endif 381#endif
255 return -EINVAL; 382 return -EINVAL;
256 } 383 }
257 384
258 spin_lock_bh(&sta->lock); 385 spin_lock_bh(&sta->lock);
259 spin_lock(&local->ampdu_lock);
260 386
261 /* we have tried too many times, receiver does not want A-MPDU */ 387 /* we have tried too many times, receiver does not want A-MPDU */
262 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { 388 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
@@ -264,9 +390,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
264 goto err_unlock_sta; 390 goto err_unlock_sta;
265 } 391 }
266 392
267 state = &sta->ampdu_mlme.tid_state_tx[tid]; 393 tid_tx = sta->ampdu_mlme.tid_tx[tid];
268 /* check if the TID is not in aggregation flow already */ 394 /* check if the TID is not in aggregation flow already */
269 if (*state != HT_AGG_STATE_IDLE) { 395 if (tid_tx) {
270#ifdef CONFIG_MAC80211_HT_DEBUG 396#ifdef CONFIG_MAC80211_HT_DEBUG
271 printk(KERN_DEBUG "BA request denied - session is not " 397 printk(KERN_DEBUG "BA request denied - session is not "
272 "idle on tid %u\n", tid); 398 "idle on tid %u\n", tid);
@@ -275,96 +401,37 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
275 goto err_unlock_sta; 401 goto err_unlock_sta;
276 } 402 }
277 403
278 /*
279 * While we're asking the driver about the aggregation,
280 * stop the AC queue so that we don't have to worry
281 * about frames that came in while we were doing that,
282 * which would require us to put them to the AC pending
283 * afterwards which just makes the code more complex.
284 */
285 ieee80211_stop_queue_by_reason(
286 &local->hw, ieee80211_ac_from_tid(tid),
287 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
288
289 /* prepare A-MPDU MLME for Tx aggregation */ 404 /* prepare A-MPDU MLME for Tx aggregation */
290 sta->ampdu_mlme.tid_tx[tid] = 405 tid_tx = kzalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
291 kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); 406 if (!tid_tx) {
292 if (!sta->ampdu_mlme.tid_tx[tid]) {
293#ifdef CONFIG_MAC80211_HT_DEBUG 407#ifdef CONFIG_MAC80211_HT_DEBUG
294 if (net_ratelimit()) 408 if (net_ratelimit())
295 printk(KERN_ERR "allocate tx mlme to tid %d failed\n", 409 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
296 tid); 410 tid);
297#endif 411#endif
298 ret = -ENOMEM; 412 ret = -ENOMEM;
299 goto err_wake_queue; 413 goto err_unlock_sta;
300 } 414 }
301 415
302 skb_queue_head_init(&sta->ampdu_mlme.tid_tx[tid]->pending); 416 skb_queue_head_init(&tid_tx->pending);
417 __set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
303 418
304 /* Tx timer */ 419 /* Tx timer */
305 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = 420 tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired;
306 sta_addba_resp_timer_expired; 421 tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid];
307 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data = 422 init_timer(&tid_tx->addba_resp_timer);
308 (unsigned long)&sta->timer_to_tid[tid];
309 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
310
311 /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
312 * call back right away, it must see that the flow has begun */
313 *state |= HT_ADDBA_REQUESTED_MSK;
314
315 start_seq_num = sta->tid_seq[tid] >> 4;
316
317 ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START,
318 pubsta, tid, &start_seq_num);
319 423
320 if (ret) { 424 /* assign a dialog token */
321#ifdef CONFIG_MAC80211_HT_DEBUG
322 printk(KERN_DEBUG "BA request denied - HW unavailable for"
323 " tid %d\n", tid);
324#endif /* CONFIG_MAC80211_HT_DEBUG */
325 *state = HT_AGG_STATE_IDLE;
326 goto err_free;
327 }
328
329 /* Driver vetoed or OKed, but we can take packets again now */
330 ieee80211_wake_queue_by_reason(
331 &local->hw, ieee80211_ac_from_tid(tid),
332 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
333
334 spin_unlock(&local->ampdu_lock);
335
336 /* prepare tid data */
337 sta->ampdu_mlme.dialog_token_allocator++; 425 sta->ampdu_mlme.dialog_token_allocator++;
338 sta->ampdu_mlme.tid_tx[tid]->dialog_token = 426 tid_tx->dialog_token = sta->ampdu_mlme.dialog_token_allocator;
339 sta->ampdu_mlme.dialog_token_allocator;
340 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
341 427
342 spin_unlock_bh(&sta->lock); 428 /* finally, assign it to the array */
429 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx);
343 430
344 /* send AddBA request */ 431 ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
345 ieee80211_send_addba_request(sdata, pubsta->addr, tid, 432
346 sta->ampdu_mlme.tid_tx[tid]->dialog_token, 433 /* this flow continues off the work */
347 sta->ampdu_mlme.tid_tx[tid]->ssn,
348 0x40, 5000);
349 sta->ampdu_mlme.addba_req_num[tid]++;
350 /* activate the timer for the recipient's addBA response */
351 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
352 jiffies + ADDBA_RESP_INTERVAL;
353 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
354#ifdef CONFIG_MAC80211_HT_DEBUG
355 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
356#endif
357 return 0;
358
359 err_free:
360 kfree(sta->ampdu_mlme.tid_tx[tid]);
361 sta->ampdu_mlme.tid_tx[tid] = NULL;
362 err_wake_queue:
363 ieee80211_wake_queue_by_reason(
364 &local->hw, ieee80211_ac_from_tid(tid),
365 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
366 err_unlock_sta: 434 err_unlock_sta:
367 spin_unlock(&local->ampdu_lock);
368 spin_unlock_bh(&sta->lock); 435 spin_unlock_bh(&sta->lock);
369 return ret; 436 return ret;
370} 437}
@@ -372,69 +439,65 @@ EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
372 439
373/* 440/*
374 * splice packets from the STA's pending to the local pending, 441 * splice packets from the STA's pending to the local pending,
375 * requires a call to ieee80211_agg_splice_finish and holding 442 * requires a call to ieee80211_agg_splice_finish later
376 * local->ampdu_lock across both calls.
377 */ 443 */
378static void ieee80211_agg_splice_packets(struct ieee80211_local *local, 444static void __acquires(agg_queue)
379 struct sta_info *sta, u16 tid) 445ieee80211_agg_splice_packets(struct ieee80211_local *local,
446 struct tid_ampdu_tx *tid_tx, u16 tid)
380{ 447{
448 int queue = ieee80211_ac_from_tid(tid);
381 unsigned long flags; 449 unsigned long flags;
382 u16 queue = ieee80211_ac_from_tid(tid);
383
384 ieee80211_stop_queue_by_reason(
385 &local->hw, queue,
386 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
387 450
388 if (!(sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK)) 451 ieee80211_stop_queue_agg(local, tid);
389 return;
390 452
391 if (WARN(!sta->ampdu_mlme.tid_tx[tid], 453 if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates"
392 "TID %d gone but expected when splicing aggregates from" 454 " from the pending queue\n", tid))
393 "the pending queue\n", tid))
394 return; 455 return;
395 456
396 if (!skb_queue_empty(&sta->ampdu_mlme.tid_tx[tid]->pending)) { 457 if (!skb_queue_empty(&tid_tx->pending)) {
397 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 458 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
398 /* copy over remaining packets */ 459 /* copy over remaining packets */
399 skb_queue_splice_tail_init( 460 skb_queue_splice_tail_init(&tid_tx->pending,
400 &sta->ampdu_mlme.tid_tx[tid]->pending, 461 &local->pending[queue]);
401 &local->pending[queue]);
402 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 462 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
403 } 463 }
404} 464}
405 465
406static void ieee80211_agg_splice_finish(struct ieee80211_local *local, 466static void __releases(agg_queue)
407 struct sta_info *sta, u16 tid) 467ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
408{ 468{
409 u16 queue = ieee80211_ac_from_tid(tid); 469 ieee80211_wake_queue_agg(local, tid);
410
411 ieee80211_wake_queue_by_reason(
412 &local->hw, queue,
413 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
414} 470}
415 471
416/* caller must hold sta->lock */
417static void ieee80211_agg_tx_operational(struct ieee80211_local *local, 472static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
418 struct sta_info *sta, u16 tid) 473 struct sta_info *sta, u16 tid)
419{ 474{
475 lockdep_assert_held(&sta->ampdu_mlme.mtx);
476
420#ifdef CONFIG_MAC80211_HT_DEBUG 477#ifdef CONFIG_MAC80211_HT_DEBUG
421 printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid); 478 printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid);
422#endif 479#endif
423 480
424 spin_lock(&local->ampdu_lock);
425 ieee80211_agg_splice_packets(local, sta, tid);
426 /*
427 * NB: we rely on sta->lock being taken in the TX
428 * processing here when adding to the pending queue,
429 * otherwise we could only change the state of the
430 * session to OPERATIONAL _here_.
431 */
432 ieee80211_agg_splice_finish(local, sta, tid);
433 spin_unlock(&local->ampdu_lock);
434
435 drv_ampdu_action(local, sta->sdata, 481 drv_ampdu_action(local, sta->sdata,
436 IEEE80211_AMPDU_TX_OPERATIONAL, 482 IEEE80211_AMPDU_TX_OPERATIONAL,
437 &sta->sta, tid, NULL); 483 &sta->sta, tid, NULL);
484
485 /*
486 * synchronize with TX path, while splicing the TX path
487 * should block so it won't put more packets onto pending.
488 */
489 spin_lock_bh(&sta->lock);
490
491 ieee80211_agg_splice_packets(local, sta->ampdu_mlme.tid_tx[tid], tid);
492 /*
493 * Now mark as operational. This will be visible
494 * in the TX path, and lets it go lock-free in
495 * the common case.
496 */
497 set_bit(HT_AGG_STATE_OPERATIONAL, &sta->ampdu_mlme.tid_tx[tid]->state);
498 ieee80211_agg_splice_finish(local, tid);
499
500 spin_unlock_bh(&sta->lock);
438} 501}
439 502
440void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) 503void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
@@ -442,7 +505,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
442 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 505 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
443 struct ieee80211_local *local = sdata->local; 506 struct ieee80211_local *local = sdata->local;
444 struct sta_info *sta; 507 struct sta_info *sta;
445 u8 *state; 508 struct tid_ampdu_tx *tid_tx;
446 509
447 trace_api_start_tx_ba_cb(sdata, ra, tid); 510 trace_api_start_tx_ba_cb(sdata, ra, tid);
448 511
@@ -454,42 +517,36 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
454 return; 517 return;
455 } 518 }
456 519
457 rcu_read_lock(); 520 mutex_lock(&local->sta_mtx);
458 sta = sta_info_get(sdata, ra); 521 sta = sta_info_get(sdata, ra);
459 if (!sta) { 522 if (!sta) {
460 rcu_read_unlock(); 523 mutex_unlock(&local->sta_mtx);
461#ifdef CONFIG_MAC80211_HT_DEBUG 524#ifdef CONFIG_MAC80211_HT_DEBUG
462 printk(KERN_DEBUG "Could not find station: %pM\n", ra); 525 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
463#endif 526#endif
464 return; 527 return;
465 } 528 }
466 529
467 state = &sta->ampdu_mlme.tid_state_tx[tid]; 530 mutex_lock(&sta->ampdu_mlme.mtx);
468 spin_lock_bh(&sta->lock); 531 tid_tx = sta->ampdu_mlme.tid_tx[tid];
469 532
470 if (WARN_ON(!(*state & HT_ADDBA_REQUESTED_MSK))) { 533 if (WARN_ON(!tid_tx)) {
471#ifdef CONFIG_MAC80211_HT_DEBUG 534#ifdef CONFIG_MAC80211_HT_DEBUG
472 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", 535 printk(KERN_DEBUG "addBA was not requested!\n");
473 *state);
474#endif 536#endif
475 spin_unlock_bh(&sta->lock); 537 goto unlock;
476 rcu_read_unlock();
477 return;
478 } 538 }
479 539
480 if (WARN_ON(*state & HT_ADDBA_DRV_READY_MSK)) 540 if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)))
481 goto out; 541 goto unlock;
482
483 *state |= HT_ADDBA_DRV_READY_MSK;
484 542
485 if (*state == HT_AGG_STATE_OPERATIONAL) 543 if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state))
486 ieee80211_agg_tx_operational(local, sta, tid); 544 ieee80211_agg_tx_operational(local, sta, tid);
487 545
488 out: 546 unlock:
489 spin_unlock_bh(&sta->lock); 547 mutex_unlock(&sta->ampdu_mlme.mtx);
490 rcu_read_unlock(); 548 mutex_unlock(&local->sta_mtx);
491} 549}
492EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
493 550
494void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, 551void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
495 const u8 *ra, u16 tid) 552 const u8 *ra, u16 tid)
@@ -510,33 +567,24 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
510 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 567 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
511 memcpy(&ra_tid->ra, ra, ETH_ALEN); 568 memcpy(&ra_tid->ra, ra, ETH_ALEN);
512 ra_tid->tid = tid; 569 ra_tid->tid = tid;
513 ra_tid->vif = vif;
514 570
515 skb->pkt_type = IEEE80211_ADDBA_MSG; 571 skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_START;
516 skb_queue_tail(&local->skb_queue, skb); 572 skb_queue_tail(&sdata->skb_queue, skb);
517 tasklet_schedule(&local->tasklet); 573 ieee80211_queue_work(&local->hw, &sdata->work);
518} 574}
519EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); 575EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
520 576
521int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, 577int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
522 enum ieee80211_back_parties initiator) 578 enum ieee80211_back_parties initiator)
523{ 579{
524 u8 *state;
525 int ret; 580 int ret;
526 581
527 /* check if the TID is in aggregation */ 582 mutex_lock(&sta->ampdu_mlme.mtx);
528 state = &sta->ampdu_mlme.tid_state_tx[tid];
529 spin_lock_bh(&sta->lock);
530
531 if (*state != HT_AGG_STATE_OPERATIONAL) {
532 ret = -ENOENT;
533 goto unlock;
534 }
535 583
536 ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); 584 ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator);
537 585
538 unlock: 586 mutex_unlock(&sta->ampdu_mlme.mtx);
539 spin_unlock_bh(&sta->lock); 587
540 return ret; 588 return ret;
541} 589}
542 590
@@ -545,6 +593,8 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
545 struct sta_info *sta = container_of(pubsta, struct sta_info, sta); 593 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
546 struct ieee80211_sub_if_data *sdata = sta->sdata; 594 struct ieee80211_sub_if_data *sdata = sta->sdata;
547 struct ieee80211_local *local = sdata->local; 595 struct ieee80211_local *local = sdata->local;
596 struct tid_ampdu_tx *tid_tx;
597 int ret = 0;
548 598
549 trace_api_stop_tx_ba_session(pubsta, tid); 599 trace_api_stop_tx_ba_session(pubsta, tid);
550 600
@@ -554,7 +604,26 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
554 if (tid >= STA_TID_NUM) 604 if (tid >= STA_TID_NUM)
555 return -EINVAL; 605 return -EINVAL;
556 606
557 return __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); 607 spin_lock_bh(&sta->lock);
608 tid_tx = sta->ampdu_mlme.tid_tx[tid];
609
610 if (!tid_tx) {
611 ret = -ENOENT;
612 goto unlock;
613 }
614
615 if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
616 /* already in progress stopping it */
617 ret = 0;
618 goto unlock;
619 }
620
621 set_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state);
622 ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
623
624 unlock:
625 spin_unlock_bh(&sta->lock);
626 return ret;
558} 627}
559EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); 628EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
560 629
@@ -563,7 +632,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
563 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 632 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
564 struct ieee80211_local *local = sdata->local; 633 struct ieee80211_local *local = sdata->local;
565 struct sta_info *sta; 634 struct sta_info *sta;
566 u8 *state; 635 struct tid_ampdu_tx *tid_tx;
567 636
568 trace_api_stop_tx_ba_cb(sdata, ra, tid); 637 trace_api_stop_tx_ba_cb(sdata, ra, tid);
569 638
@@ -580,51 +649,56 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
580 ra, tid); 649 ra, tid);
581#endif /* CONFIG_MAC80211_HT_DEBUG */ 650#endif /* CONFIG_MAC80211_HT_DEBUG */
582 651
583 rcu_read_lock(); 652 mutex_lock(&local->sta_mtx);
653
584 sta = sta_info_get(sdata, ra); 654 sta = sta_info_get(sdata, ra);
585 if (!sta) { 655 if (!sta) {
586#ifdef CONFIG_MAC80211_HT_DEBUG 656#ifdef CONFIG_MAC80211_HT_DEBUG
587 printk(KERN_DEBUG "Could not find station: %pM\n", ra); 657 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
588#endif 658#endif
589 rcu_read_unlock(); 659 goto unlock;
590 return;
591 } 660 }
592 state = &sta->ampdu_mlme.tid_state_tx[tid];
593 661
594 /* NOTE: no need to use sta->lock in this state check, as 662 mutex_lock(&sta->ampdu_mlme.mtx);
595 * ieee80211_stop_tx_ba_session will let only one stop call to 663 spin_lock_bh(&sta->lock);
596 * pass through per sta/tid 664 tid_tx = sta->ampdu_mlme.tid_tx[tid];
597 */ 665
598 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { 666 if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
599#ifdef CONFIG_MAC80211_HT_DEBUG 667#ifdef CONFIG_MAC80211_HT_DEBUG
600 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); 668 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
601#endif 669#endif
602 rcu_read_unlock(); 670 goto unlock_sta;
603 return;
604 } 671 }
605 672
606 if (*state & HT_AGG_STATE_INITIATOR_MSK) 673 if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR)
607 ieee80211_send_delba(sta->sdata, ra, tid, 674 ieee80211_send_delba(sta->sdata, ra, tid,
608 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); 675 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
609 676
610 spin_lock_bh(&sta->lock); 677 /*
611 spin_lock(&local->ampdu_lock); 678 * When we get here, the TX path will not be lockless any more wrt.
679 * aggregation, since the OPERATIONAL bit has long been cleared.
680 * Thus it will block on getting the lock, if it occurs. So if we
681 * stop the queue now, we will not get any more packets, and any
682 * that might be being processed will wait for us here, thereby
683 * guaranteeing that no packets go to the tid_tx pending queue any
684 * more.
685 */
612 686
613 ieee80211_agg_splice_packets(local, sta, tid); 687 ieee80211_agg_splice_packets(local, tid_tx, tid);
614 688
615 *state = HT_AGG_STATE_IDLE; 689 /* future packets must not find the tid_tx struct any more */
616 /* from now on packets are no longer put onto sta->pending */ 690 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL);
617 kfree(sta->ampdu_mlme.tid_tx[tid]);
618 sta->ampdu_mlme.tid_tx[tid] = NULL;
619 691
620 ieee80211_agg_splice_finish(local, sta, tid); 692 ieee80211_agg_splice_finish(local, tid);
621 693
622 spin_unlock(&local->ampdu_lock); 694 call_rcu(&tid_tx->rcu_head, kfree_tid_tx);
623 spin_unlock_bh(&sta->lock);
624 695
625 rcu_read_unlock(); 696 unlock_sta:
697 spin_unlock_bh(&sta->lock);
698 mutex_unlock(&sta->ampdu_mlme.mtx);
699 unlock:
700 mutex_unlock(&local->sta_mtx);
626} 701}
627EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
628 702
629void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, 703void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
630 const u8 *ra, u16 tid) 704 const u8 *ra, u16 tid)
@@ -645,11 +719,10 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
645 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 719 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
646 memcpy(&ra_tid->ra, ra, ETH_ALEN); 720 memcpy(&ra_tid->ra, ra, ETH_ALEN);
647 ra_tid->tid = tid; 721 ra_tid->tid = tid;
648 ra_tid->vif = vif;
649 722
650 skb->pkt_type = IEEE80211_DELBA_MSG; 723 skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_STOP;
651 skb_queue_tail(&local->skb_queue, skb); 724 skb_queue_tail(&sdata->skb_queue, skb);
652 tasklet_schedule(&local->tasklet); 725 ieee80211_queue_work(&local->hw, &sdata->work);
653} 726}
654EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe); 727EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
655 728
@@ -659,40 +732,40 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
659 struct ieee80211_mgmt *mgmt, 732 struct ieee80211_mgmt *mgmt,
660 size_t len) 733 size_t len)
661{ 734{
735 struct tid_ampdu_tx *tid_tx;
662 u16 capab, tid; 736 u16 capab, tid;
663 u8 *state;
664 737
665 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 738 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
666 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 739 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
667 740
668 state = &sta->ampdu_mlme.tid_state_tx[tid]; 741 mutex_lock(&sta->ampdu_mlme.mtx);
669
670 spin_lock_bh(&sta->lock);
671 742
672 if (!(*state & HT_ADDBA_REQUESTED_MSK)) 743 tid_tx = sta->ampdu_mlme.tid_tx[tid];
744 if (!tid_tx)
673 goto out; 745 goto out;
674 746
675 if (mgmt->u.action.u.addba_resp.dialog_token != 747 if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) {
676 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
677#ifdef CONFIG_MAC80211_HT_DEBUG 748#ifdef CONFIG_MAC80211_HT_DEBUG
678 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); 749 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
679#endif /* CONFIG_MAC80211_HT_DEBUG */ 750#endif
680 goto out; 751 goto out;
681 } 752 }
682 753
683 del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 754 del_timer(&tid_tx->addba_resp_timer);
684 755
685#ifdef CONFIG_MAC80211_HT_DEBUG 756#ifdef CONFIG_MAC80211_HT_DEBUG
686 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid); 757 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
687#endif /* CONFIG_MAC80211_HT_DEBUG */ 758#endif
688 759
689 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 760 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
690 == WLAN_STATUS_SUCCESS) { 761 == WLAN_STATUS_SUCCESS) {
691 u8 curstate = *state; 762 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED,
692 763 &tid_tx->state)) {
693 *state |= HT_ADDBA_RECEIVED_MSK; 764 /* ignore duplicate response */
765 goto out;
766 }
694 767
695 if (*state != curstate && *state == HT_AGG_STATE_OPERATIONAL) 768 if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))
696 ieee80211_agg_tx_operational(local, sta, tid); 769 ieee80211_agg_tx_operational(local, sta, tid);
697 770
698 sta->ampdu_mlme.addba_req_num[tid] = 0; 771 sta->ampdu_mlme.addba_req_num[tid] = 0;
@@ -701,5 +774,5 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
701 } 774 }
702 775
703 out: 776 out:
704 spin_unlock_bh(&sta->lock); 777 mutex_unlock(&sta->ampdu_mlme.mtx);
705} 778}