aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-03-23 12:28:39 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-03-27 20:13:22 -0400
commitb1720231ca07dee3382980f3b25e6581bd2e54e9 (patch)
tree4258dec3d4774ee5968f181533c77766c8584b79
parent1870cd71e87da1a1afb904f2c84086f487a07135 (diff)
mac80211: unify and fix TX aggregation start
When TX aggregation becomes operational, we do a number of steps: 1) print a debug message 2) wake the virtual queue 3) notify the driver Unfortunately, 1) and 3) are only done if the driver is first to reply to the aggregation request, it is, however, possible that the remote station replies before the driver! Thus, unify the code for this and call the new function ieee80211_agg_tx_operational in both places where TX aggregation can become operational. Additionally, rename the driver notification from IEEE80211_AMPDU_TX_RESUME to IEEE80211_AMPDU_TX_OPERATIONAL. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath9k/main.c2
-rw-r--r--include/net/mac80211.h4
-rw-r--r--net/mac80211/agg-tx.c63
3 files changed, 30 insertions, 39 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index c13e4e536341..13d4e6756c99 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -2730,7 +2730,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
2730 2730
2731 ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); 2731 ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2732 break; 2732 break;
2733 case IEEE80211_AMPDU_TX_RESUME: 2733 case IEEE80211_AMPDU_TX_OPERATIONAL:
2734 ath_tx_aggr_resume(sc, sta, tid); 2734 ath_tx_aggr_resume(sc, sta, tid);
2735 break; 2735 break;
2736 default: 2736 default:
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 6f3bc4cc53e5..07fe9875506e 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1236,14 +1236,14 @@ enum ieee80211_filter_flags {
1236 * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation 1236 * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation
1237 * @IEEE80211_AMPDU_TX_START: start Tx aggregation 1237 * @IEEE80211_AMPDU_TX_START: start Tx aggregation
1238 * @IEEE80211_AMPDU_TX_STOP: stop Tx aggregation 1238 * @IEEE80211_AMPDU_TX_STOP: stop Tx aggregation
1239 * @IEEE80211_AMPDU_TX_RESUME: resume TX aggregation 1239 * @IEEE80211_AMPDU_TX_OPERATIONAL: TX aggregation has become operational
1240 */ 1240 */
1241enum ieee80211_ampdu_mlme_action { 1241enum ieee80211_ampdu_mlme_action {
1242 IEEE80211_AMPDU_RX_START, 1242 IEEE80211_AMPDU_RX_START,
1243 IEEE80211_AMPDU_RX_STOP, 1243 IEEE80211_AMPDU_RX_STOP,
1244 IEEE80211_AMPDU_TX_START, 1244 IEEE80211_AMPDU_TX_START,
1245 IEEE80211_AMPDU_TX_STOP, 1245 IEEE80211_AMPDU_TX_STOP,
1246 IEEE80211_AMPDU_TX_RESUME, 1246 IEEE80211_AMPDU_TX_OPERATIONAL,
1247}; 1247};
1248 1248
1249/** 1249/**
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index e5776ef1717a..fd718e2b29f7 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -404,6 +404,27 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
404} 404}
405EXPORT_SYMBOL(ieee80211_start_tx_ba_session); 405EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
406 406
407static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
408 struct sta_info *sta, u16 tid)
409{
410#ifdef CONFIG_MAC80211_HT_DEBUG
411 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
412#endif
413
414 if (local->hw.ampdu_queues) {
415 /*
416 * Wake up the A-MPDU queue, we stopped it earlier,
417 * this will in turn wake the entire AC.
418 */
419 ieee80211_wake_queue_by_reason(&local->hw,
420 local->hw.queues + sta->tid_to_tx_q[tid],
421 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
422 }
423
424 local->ops->ampdu_action(&local->hw, IEEE80211_AMPDU_TX_OPERATIONAL,
425 &sta->sta, tid, NULL);
426}
427
407void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) 428void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
408{ 429{
409 struct ieee80211_local *local = hw_to_local(hw); 430 struct ieee80211_local *local = hw_to_local(hw);
@@ -446,20 +467,8 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
446 467
447 *state |= HT_ADDBA_DRV_READY_MSK; 468 *state |= HT_ADDBA_DRV_READY_MSK;
448 469
449 if (*state == HT_AGG_STATE_OPERATIONAL) { 470 if (*state == HT_AGG_STATE_OPERATIONAL)
450#ifdef CONFIG_MAC80211_HT_DEBUG 471 ieee80211_agg_tx_operational(local, sta, tid);
451 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
452#endif
453 if (hw->ampdu_queues) {
454 /*
455 * Wake up this queue, we stopped it earlier,
456 * this will in turn wake the entire AC.
457 */
458 ieee80211_wake_queue_by_reason(hw,
459 hw->queues + sta->tid_to_tx_q[tid],
460 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
461 }
462 }
463 472
464 out: 473 out:
465 spin_unlock_bh(&sta->lock); 474 spin_unlock_bh(&sta->lock);
@@ -646,9 +655,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
646 struct ieee80211_mgmt *mgmt, 655 struct ieee80211_mgmt *mgmt,
647 size_t len) 656 size_t len)
648{ 657{
649 struct ieee80211_hw *hw = &local->hw; 658 u16 capab, tid;
650 u16 capab;
651 u16 tid, start_seq_num;
652 u8 *state; 659 u8 *state;
653 660
654 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 661 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
@@ -682,26 +689,10 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
682 689
683 *state |= HT_ADDBA_RECEIVED_MSK; 690 *state |= HT_ADDBA_RECEIVED_MSK;
684 691
685 if (hw->ampdu_queues && *state != curstate && 692 if (*state != curstate && *state == HT_AGG_STATE_OPERATIONAL)
686 *state == HT_AGG_STATE_OPERATIONAL) { 693 ieee80211_agg_tx_operational(local, sta, tid);
687 /*
688 * Wake up this queue, we stopped it earlier,
689 * this will in turn wake the entire AC.
690 */
691 ieee80211_wake_queue_by_reason(hw,
692 hw->queues + sta->tid_to_tx_q[tid],
693 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
694 }
695 sta->ampdu_mlme.addba_req_num[tid] = 0;
696 694
697 if (local->ops->ampdu_action) { 695 sta->ampdu_mlme.addba_req_num[tid] = 0;
698 (void)local->ops->ampdu_action(hw,
699 IEEE80211_AMPDU_TX_RESUME,
700 &sta->sta, tid, &start_seq_num);
701 }
702#ifdef CONFIG_MAC80211_HT_DEBUG
703 printk(KERN_DEBUG "Resuming TX aggregation for tid %d\n", tid);
704#endif /* CONFIG_MAC80211_HT_DEBUG */
705 } else { 696 } else {
706 sta->ampdu_mlme.addba_req_num[tid]++; 697 sta->ampdu_mlme.addba_req_num[tid]++;
707 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); 698 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);