aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/agg-tx.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-12-14 14:35:41 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-14 14:35:41 -0500
commit5d22df200beccb1dea26fe4d8684ed93ae2f0aeb (patch)
tree05220b08a0c9d170ad88e3b9ed0390750d22d8ea /net/mac80211/agg-tx.c
parent8b1fdb53075bd794a209a611bc94aedaf7ecf9e2 (diff)
parent78feb35b8161acd95c33a703ed6ab6f554d29387 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts: drivers/net/wireless/iwlwifi/iwl-agn.c
Diffstat (limited to 'net/mac80211/agg-tx.c')
-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 5c7f0c3c74cb..88754c067f1e 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -309,6 +309,38 @@ ieee80211_wake_queue_agg(struct ieee80211_local *local, int tid)
309 __release(agg_queue); 309 __release(agg_queue);
310} 310}
311 311
312/*
313 * splice packets from the STA's pending to the local pending,
314 * requires a call to ieee80211_agg_splice_finish later
315 */
316static void __acquires(agg_queue)
317ieee80211_agg_splice_packets(struct ieee80211_local *local,
318 struct tid_ampdu_tx *tid_tx, u16 tid)
319{
320 int queue = ieee80211_ac_from_tid(tid);
321 unsigned long flags;
322
323 ieee80211_stop_queue_agg(local, tid);
324
325 if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates"
326 " from the pending queue\n", tid))
327 return;
328
329 if (!skb_queue_empty(&tid_tx->pending)) {
330 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
331 /* copy over remaining packets */
332 skb_queue_splice_tail_init(&tid_tx->pending,
333 &local->pending[queue]);
334 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
335 }
336}
337
338static void __releases(agg_queue)
339ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
340{
341 ieee80211_wake_queue_agg(local, tid);
342}
343
312void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) 344void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
313{ 345{
314 struct tid_ampdu_tx *tid_tx; 346 struct tid_ampdu_tx *tid_tx;
@@ -320,19 +352,17 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
320 tid_tx = rcu_dereference_protected_tid_tx(sta, tid); 352 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
321 353
322 /* 354 /*
323 * While we're asking the driver about the aggregation, 355 * Start queuing up packets for this aggregation session.
324 * stop the AC queue so that we don't have to worry 356 * We're going to release them once the driver is OK with
325 * about frames that came in while we were doing that, 357 * that.
326 * which would require us to put them to the AC pending
327 * afterwards which just makes the code more complex.
328 */ 358 */
329 ieee80211_stop_queue_agg(local, tid);
330
331 clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); 359 clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
332 360
333 /* 361 /*
334 * make sure no packets are being processed to get 362 * Make sure no packets are being processed. This ensures that
335 * valid starting sequence number 363 * we have a valid starting sequence number and that in-flight
364 * packets have been flushed out and no packets for this TID
365 * will go into the driver during the ampdu_action call.
336 */ 366 */
337 synchronize_net(); 367 synchronize_net();
338 368
@@ -346,17 +376,15 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
346 " tid %d\n", tid); 376 " tid %d\n", tid);
347#endif 377#endif
348 spin_lock_bh(&sta->lock); 378 spin_lock_bh(&sta->lock);
379 ieee80211_agg_splice_packets(local, tid_tx, tid);
349 ieee80211_assign_tid_tx(sta, tid, NULL); 380 ieee80211_assign_tid_tx(sta, tid, NULL);
381 ieee80211_agg_splice_finish(local, tid);
350 spin_unlock_bh(&sta->lock); 382 spin_unlock_bh(&sta->lock);
351 383
352 ieee80211_wake_queue_agg(local, tid);
353 kfree_rcu(tid_tx, rcu_head); 384 kfree_rcu(tid_tx, rcu_head);
354 return; 385 return;
355 } 386 }
356 387
357 /* we can take packets again now */
358 ieee80211_wake_queue_agg(local, tid);
359
360 /* activate the timer for the recipient's addBA response */ 388 /* activate the timer for the recipient's addBA response */
361 mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); 389 mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL);
362#ifdef CONFIG_MAC80211_HT_DEBUG 390#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -516,38 +544,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
516} 544}
517EXPORT_SYMBOL(ieee80211_start_tx_ba_session); 545EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
518 546
519/*
520 * splice packets from the STA's pending to the local pending,
521 * requires a call to ieee80211_agg_splice_finish later
522 */
523static void __acquires(agg_queue)
524ieee80211_agg_splice_packets(struct ieee80211_local *local,
525 struct tid_ampdu_tx *tid_tx, u16 tid)
526{
527 int queue = ieee80211_ac_from_tid(tid);
528 unsigned long flags;
529
530 ieee80211_stop_queue_agg(local, tid);
531
532 if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates"
533 " from the pending queue\n", tid))
534 return;
535
536 if (!skb_queue_empty(&tid_tx->pending)) {
537 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
538 /* copy over remaining packets */
539 skb_queue_splice_tail_init(&tid_tx->pending,
540 &local->pending[queue]);
541 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
542 }
543}
544
545static void __releases(agg_queue)
546ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
547{
548 ieee80211_wake_queue_agg(local, tid);
549}
550
551static void ieee80211_agg_tx_operational(struct ieee80211_local *local, 547static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
552 struct sta_info *sta, u16 tid) 548 struct sta_info *sta, u16 tid)
553{ 549{