aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-02-11 18:51:53 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-27 14:51:42 -0500
commit96f5e66e8a79810e2982cdcfa28e554f3d97da21 (patch)
treed16a0e083b83ab488f20b995c56a496a4ec2c9c8 /net/mac80211/sta_info.c
parentf3734ee6df3ac57151e02d091f47d5e52e646539 (diff)
mac80211: fix aggregation for hardware with ampdu queues
Hardware with AMPDU queues currently has broken aggregation. This patch fixes it by making all A-MPDUs go over the regular AC queues, but keeping track of the hardware queues in mac80211. As a first rough version, it actually stops the AC queue for extended periods of time, which can be removed by adding buffering internal to mac80211, but is currently not a huge problem because people rarely use multiple TIDs that are in the same AC (and iwlwifi currently doesn't operate as AP). This is a short-term fix, my current medium-term plan, which I hope to execute soon as well, but am not sure can finish before .30, looks like this: 1) rework the internal queuing layer in mac80211 that we use for fragments if the driver stopped queue in the middle of a fragmented frame to be able to queue more frames at once (rather than just a single frame with its fragments) 2) instead of stopping the entire AC queue, queue up the frames in a per-station/per-TID queue during aggregation session initiation, when the session has come up take all those frames and put them onto the queue from 1) 3) push the ampdu queue layer abstraction this patch introduces in mac80211 into the driver, and remove the virtual queue stuff from mac80211 again This plan will probably also affect ath9k in that mac80211 queues the frames instead of passing them down, even when there are no ampdu queues. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 634f65c0130e..4ba3c540fcf3 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -202,6 +202,18 @@ void sta_info_destroy(struct sta_info *sta)
202 /* Make sure timer won't free the tid_rx struct, see below */ 202 /* Make sure timer won't free the tid_rx struct, see below */
203 if (tid_rx) 203 if (tid_rx)
204 tid_rx->shutdown = true; 204 tid_rx->shutdown = true;
205
206 /*
207 * The stop callback cannot find this station any more, but
208 * it didn't complete its work -- start the queue if necessary
209 */
210 if (sta->ampdu_mlme.tid_state_tx[i] & HT_AGG_STATE_INITIATOR_MSK &&
211 sta->ampdu_mlme.tid_state_tx[i] & HT_AGG_STATE_REQ_STOP_BA_MSK &&
212 local->hw.ampdu_queues)
213 ieee80211_wake_queue_by_reason(&local->hw,
214 local->hw.queues + sta->tid_to_tx_q[i],
215 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
216
205 spin_unlock_bh(&sta->lock); 217 spin_unlock_bh(&sta->lock);
206 218
207 /* 219 /*
@@ -275,8 +287,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
275 * enable session_timer's data differentiation. refer to 287 * enable session_timer's data differentiation. refer to
276 * sta_rx_agg_session_timer_expired for useage */ 288 * sta_rx_agg_session_timer_expired for useage */
277 sta->timer_to_tid[i] = i; 289 sta->timer_to_tid[i] = i;
278 /* tid to tx queue: initialize according to HW (0 is valid) */ 290 sta->tid_to_tx_q[i] = -1;
279 sta->tid_to_tx_q[i] = ieee80211_num_queues(&local->hw);
280 /* rx */ 291 /* rx */
281 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; 292 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
282 sta->ampdu_mlme.tid_rx[i] = NULL; 293 sta->ampdu_mlme.tid_rx[i] = NULL;