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/util.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/util.c')
-rw-r--r-- | net/mac80211/util.c | 58 |
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); | |||
474 | int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) | 436 | int 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); |