diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-03-23 12:28:42 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-03-27 20:13:23 -0400 |
commit | e4e72fb4de93e3d4047a4ee3f08778422e17ed0d (patch) | |
tree | dd133a749e6fa6960c9aa708041d996110f6440e /net/mac80211/agg-tx.c | |
parent | cd8ffc800ce18e558335c4946b2217864fc16045 (diff) |
mac80211/iwlwifi: move virtual A-MDPU queue bookkeeping to iwlwifi
This patch removes all the virtual A-MPDU-queue bookkeeping from
mac80211. Curiously, iwlwifi already does its own bookkeeping, so
it doesn't require much changes except where it needs to handle
starting and stopping the queues in mac80211.
To handle the queue stop/wake properly, we rewrite the software
queue number for aggregation frames and internally to iwlwifi keep
track of the queues that map into the same AC queue, and only talk
to mac80211 about the AC queue. The implementation requires calling
two new functions, iwl_stop_queue and iwl_wake_queue instead of the
mac80211 counterparts.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Cc: Reinette Chattre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r-- | net/mac80211/agg-tx.c | 44 |
1 files changed, 3 insertions, 41 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 64b839bfbf1..947aaaad35d 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -131,14 +131,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
131 | 131 | ||
132 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 132 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
133 | 133 | ||
134 | if (local->hw.ampdu_queues) { | ||
135 | /* | ||
136 | * Pretend the driver woke the queue, just in case | ||
137 | * it disabled it before the session was stopped. | ||
138 | */ | ||
139 | ieee80211_wake_queue( | ||
140 | &local->hw, local->hw.queues + sta->tid_to_tx_q[tid]); | ||
141 | } | ||
142 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | | 134 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | |
143 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 135 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
144 | 136 | ||
@@ -206,7 +198,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
206 | struct sta_info *sta; | 198 | struct sta_info *sta; |
207 | struct ieee80211_sub_if_data *sdata; | 199 | struct ieee80211_sub_if_data *sdata; |
208 | u8 *state; | 200 | u8 *state; |
209 | int i, qn = -1, ret = 0; | 201 | int ret = 0; |
210 | u16 start_seq_num; | 202 | u16 start_seq_num; |
211 | 203 | ||
212 | if (WARN_ON(!local->ops->ampdu_action)) | 204 | if (WARN_ON(!local->ops->ampdu_action)) |
@@ -275,29 +267,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
275 | goto err_unlock_sta; | 267 | goto err_unlock_sta; |
276 | } | 268 | } |
277 | 269 | ||
278 | if (hw->ampdu_queues) { | ||
279 | spin_lock(&local->queue_stop_reason_lock); | ||
280 | /* reserve a new queue for this session */ | ||
281 | for (i = 0; i < local->hw.ampdu_queues; i++) { | ||
282 | if (local->ampdu_ac_queue[i] < 0) { | ||
283 | qn = i; | ||
284 | local->ampdu_ac_queue[qn] = | ||
285 | ieee80211_ac_from_tid(tid); | ||
286 | break; | ||
287 | } | ||
288 | } | ||
289 | spin_unlock(&local->queue_stop_reason_lock); | ||
290 | |||
291 | if (qn < 0) { | ||
292 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
293 | printk(KERN_DEBUG "BA request denied - " | ||
294 | "queue unavailable for tid %d\n", tid); | ||
295 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
296 | ret = -ENOSPC; | ||
297 | goto err_unlock_sta; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | /* | 270 | /* |
302 | * While we're asking the driver about the aggregation, | 271 | * While we're asking the driver about the aggregation, |
303 | * stop the AC queue so that we don't have to worry | 272 | * stop the AC queue so that we don't have to worry |
@@ -319,7 +288,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
319 | tid); | 288 | tid); |
320 | #endif | 289 | #endif |
321 | ret = -ENOMEM; | 290 | ret = -ENOMEM; |
322 | goto err_return_queue; | 291 | goto err_wake_queue; |
323 | } | 292 | } |
324 | 293 | ||
325 | skb_queue_head_init(&sta->ampdu_mlme.tid_tx[tid]->pending); | 294 | skb_queue_head_init(&sta->ampdu_mlme.tid_tx[tid]->pending); |
@@ -348,7 +317,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
348 | *state = HT_AGG_STATE_IDLE; | 317 | *state = HT_AGG_STATE_IDLE; |
349 | goto err_free; | 318 | goto err_free; |
350 | } | 319 | } |
351 | sta->tid_to_tx_q[tid] = qn; | ||
352 | 320 | ||
353 | /* Driver vetoed or OKed, but we can take packets again now */ | 321 | /* Driver vetoed or OKed, but we can take packets again now */ |
354 | ieee80211_wake_queue_by_reason( | 322 | ieee80211_wake_queue_by_reason( |
@@ -380,13 +348,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
380 | err_free: | 348 | err_free: |
381 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 349 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
382 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 350 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
383 | err_return_queue: | 351 | err_wake_queue: |
384 | if (qn >= 0) { | ||
385 | /* give queue back to pool */ | ||
386 | spin_lock(&local->queue_stop_reason_lock); | ||
387 | local->ampdu_ac_queue[qn] = -1; | ||
388 | spin_unlock(&local->queue_stop_reason_lock); | ||
389 | } | ||
390 | ieee80211_wake_queue_by_reason( | 352 | ieee80211_wake_queue_by_reason( |
391 | &local->hw, ieee80211_ac_from_tid(tid), | 353 | &local->hw, ieee80211_ac_from_tid(tid), |
392 | IEEE80211_QUEUE_STOP_REASON_AGGREGATION); | 354 | IEEE80211_QUEUE_STOP_REASON_AGGREGATION); |