aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-03-23 12:28:42 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-03-27 20:13:23 -0400
commite4e72fb4de93e3d4047a4ee3f08778422e17ed0d (patch)
treedd133a749e6fa6960c9aa708041d996110f6440e /net/mac80211/util.c
parentcd8ffc800ce18e558335c4946b2217864fc16045 (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/util.c')
-rw-r--r--net/mac80211/util.c58
1 files changed, 7 insertions, 51 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 0247d8022f5f..fdf432f14554 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -339,29 +339,8 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
339{ 339{
340 struct ieee80211_local *local = hw_to_local(hw); 340 struct ieee80211_local *local = hw_to_local(hw);
341 341
342 if (queue >= hw->queues) { 342 if (WARN_ON(queue >= hw->queues))
343 if (local->ampdu_ac_queue[queue - hw->queues] < 0) 343 return;
344 return;
345
346 /*
347 * for virtual aggregation queues, we need to refcount the
348 * internal mac80211 disable (multiple times!), keep track of
349 * driver disable _and_ make sure the regular queue is
350 * actually enabled.
351 */
352 if (reason == IEEE80211_QUEUE_STOP_REASON_AGGREGATION)
353 local->amdpu_ac_stop_refcnt[queue - hw->queues]--;
354 else
355 __clear_bit(reason, &local->queue_stop_reasons[queue]);
356
357 if (local->queue_stop_reasons[queue] ||
358 local->amdpu_ac_stop_refcnt[queue - hw->queues])
359 return;
360
361 /* now go on to treat the corresponding regular queue */
362 queue = local->ampdu_ac_queue[queue - hw->queues];
363 reason = IEEE80211_QUEUE_STOP_REASON_AGGREGATION;
364 }
365 344
366 __clear_bit(reason, &local->queue_stop_reasons[queue]); 345 __clear_bit(reason, &local->queue_stop_reasons[queue]);
367 346
@@ -400,25 +379,8 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
400{ 379{
401 struct ieee80211_local *local = hw_to_local(hw); 380 struct ieee80211_local *local = hw_to_local(hw);
402 381
403 if (queue >= hw->queues) { 382 if (WARN_ON(queue >= hw->queues))
404 if (local->ampdu_ac_queue[queue - hw->queues] < 0) 383 return;
405 return;
406
407 /*
408 * for virtual aggregation queues, we need to refcount the
409 * internal mac80211 disable (multiple times!), keep track of
410 * driver disable _and_ make sure the regular queue is
411 * actually enabled.
412 */
413 if (reason == IEEE80211_QUEUE_STOP_REASON_AGGREGATION)
414 local->amdpu_ac_stop_refcnt[queue - hw->queues]++;
415 else
416 __set_bit(reason, &local->queue_stop_reasons[queue]);
417
418 /* now go on to treat the corresponding regular queue */
419 queue = local->ampdu_ac_queue[queue - hw->queues];
420 reason = IEEE80211_QUEUE_STOP_REASON_AGGREGATION;
421 }
422 384
423 /* 385 /*
424 * Only stop if it was previously running, this is necessary 386 * Only stop if it was previously running, this is necessary
@@ -474,15 +436,9 @@ EXPORT_SYMBOL(ieee80211_stop_queues);
474int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) 436int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
475{ 437{
476 struct ieee80211_local *local = hw_to_local(hw); 438 struct ieee80211_local *local = hw_to_local(hw);
477 unsigned long flags;
478 439
479 if (queue >= hw->queues) { 440 if (WARN_ON(queue >= hw->queues))
480 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 441 return true;
481 queue = local->ampdu_ac_queue[queue - hw->queues];
482 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
483 if (queue < 0)
484 return true;
485 }
486 442
487 return __netif_subqueue_stopped(local->mdev, queue); 443 return __netif_subqueue_stopped(local->mdev, queue);
488} 444}
@@ -497,7 +453,7 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
497 453
498 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 454 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
499 455
500 for (i = 0; i < hw->queues + hw->ampdu_queues; i++) 456 for (i = 0; i < hw->queues; i++)
501 __ieee80211_wake_queue(hw, i, reason); 457 __ieee80211_wake_queue(hw, i, reason);
502 458
503 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 459 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);