aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/agg-tx.c86
1 files changed, 41 insertions, 45 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 331472ce038c..d448f7a3dbc0 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -302,6 +302,38 @@ ieee80211_wake_queue_agg(struct ieee80211_local *local, int tid)
302 __release(agg_queue); 302 __release(agg_queue);
303} 303}
304 304
305/*
306 * splice packets from the STA's pending to the local pending,
307 * requires a call to ieee80211_agg_splice_finish later
308 */
309static void __acquires(agg_queue)
310ieee80211_agg_splice_packets(struct ieee80211_local *local,
311 struct tid_ampdu_tx *tid_tx, u16 tid)
312{
313 int queue = ieee80211_ac_from_tid(tid);
314 unsigned long flags;
315
316 ieee80211_stop_queue_agg(local, tid);
317
318 if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates"
319 " from the pending queue\n", tid))
320 return;
321
322 if (!skb_queue_empty(&tid_tx->pending)) {
323 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
324 /* copy over remaining packets */
325 skb_queue_splice_tail_init(&tid_tx->pending,
326 &local->pending[queue]);
327 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
328 }
329}
330
331static void __releases(agg_queue)
332ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
333{
334 ieee80211_wake_queue_agg(local, tid);
335}
336
305void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) 337void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
306{ 338{
307 struct tid_ampdu_tx *tid_tx; 339 struct tid_ampdu_tx *tid_tx;
@@ -313,19 +345,17 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
313 tid_tx = rcu_dereference_protected_tid_tx(sta, tid); 345 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
314 346
315 /* 347 /*
316 * While we're asking the driver about the aggregation, 348 * Start queuing up packets for this aggregation session.
317 * stop the AC queue so that we don't have to worry 349 * We're going to release them once the driver is OK with
318 * about frames that came in while we were doing that, 350 * that.
319 * which would require us to put them to the AC pending
320 * afterwards which just makes the code more complex.
321 */ 351 */
322 ieee80211_stop_queue_agg(local, tid);
323
324 clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); 352 clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
325 353
326 /* 354 /*
327 * make sure no packets are being processed to get 355 * Make sure no packets are being processed. This ensures that
328 * valid starting sequence number 356 * we have a valid starting sequence number and that in-flight
357 * packets have been flushed out and no packets for this TID
358 * will go into the driver during the ampdu_action call.
329 */ 359 */
330 synchronize_net(); 360 synchronize_net();
331 361
@@ -339,17 +369,15 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
339 " tid %d\n", tid); 369 " tid %d\n", tid);
340#endif 370#endif
341 spin_lock_bh(&sta->lock); 371 spin_lock_bh(&sta->lock);
372 ieee80211_agg_splice_packets(local, tid_tx, tid);
342 ieee80211_assign_tid_tx(sta, tid, NULL); 373 ieee80211_assign_tid_tx(sta, tid, NULL);
374 ieee80211_agg_splice_finish(local, tid);
343 spin_unlock_bh(&sta->lock); 375 spin_unlock_bh(&sta->lock);
344 376
345 ieee80211_wake_queue_agg(local, tid);
346 kfree_rcu(tid_tx, rcu_head); 377 kfree_rcu(tid_tx, rcu_head);
347 return; 378 return;
348 } 379 }
349 380
350 /* we can take packets again now */
351 ieee80211_wake_queue_agg(local, tid);
352
353 /* activate the timer for the recipient's addBA response */ 381 /* activate the timer for the recipient's addBA response */
354 mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); 382 mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL);
355#ifdef CONFIG_MAC80211_HT_DEBUG 383#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -465,38 +493,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
465} 493}
466EXPORT_SYMBOL(ieee80211_start_tx_ba_session); 494EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
467 495
468/*
469 * splice packets from the STA's pending to the local pending,
470 * requires a call to ieee80211_agg_splice_finish later
471 */
472static void __acquires(agg_queue)
473ieee80211_agg_splice_packets(struct ieee80211_local *local,
474 struct tid_ampdu_tx *tid_tx, u16 tid)
475{
476 int queue = ieee80211_ac_from_tid(tid);
477 unsigned long flags;
478
479 ieee80211_stop_queue_agg(local, tid);
480
481 if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates"
482 " from the pending queue\n", tid))
483 return;
484
485 if (!skb_queue_empty(&tid_tx->pending)) {
486 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
487 /* copy over remaining packets */
488 skb_queue_splice_tail_init(&tid_tx->pending,
489 &local->pending[queue]);
490 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
491 }
492}
493
494static void __releases(agg_queue)
495ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
496{
497 ieee80211_wake_queue_agg(local, tid);
498}
499
500static void ieee80211_agg_tx_operational(struct ieee80211_local *local, 496static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
501 struct sta_info *sta, u16 tid) 497 struct sta_info *sta, u16 tid)
502{ 498{