aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorKalle Valo <kalle.valo@nokia.com>2008-12-18 16:35:20 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-12-19 15:23:59 -0500
commitce7c9111a97492d04c504f40736a669c235d664a (patch)
tree6a294d373e19a99048dafa632966096371f3b1bb /net/mac80211/util.c
parente0cb686ff879dc9ac045ad7258ec687088d4e450 (diff)
mac80211: track master queue status
This is a preparation for the dynamic power save support. In future there are two paths to stop the master queues and we need to track this properly to avoid starting queues incorrectly. Implement this by adding a status array for each queue. The original idea and design is from Johannes Berg, I just did the implementation based on his notes. All the bugs are mine, of course. Signed-off-by: Kalle Valo <kalle.valo@nokia.com> Acked-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c86
1 files changed, 80 insertions, 6 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 71a8391c54f6..fb89e1d0aa03 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -330,10 +330,20 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
330} 330}
331EXPORT_SYMBOL(ieee80211_ctstoself_duration); 331EXPORT_SYMBOL(ieee80211_ctstoself_duration);
332 332
333void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) 333static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
334 enum queue_stop_reason reason)
334{ 335{
335 struct ieee80211_local *local = hw_to_local(hw); 336 struct ieee80211_local *local = hw_to_local(hw);
336 337
338 /* we don't need to track ampdu queues */
339 if (queue < ieee80211_num_regular_queues(hw)) {
340 __clear_bit(reason, &local->queue_stop_reasons[queue]);
341
342 if (local->queue_stop_reasons[queue] != 0)
343 /* someone still has this queue stopped */
344 return;
345 }
346
337 if (test_bit(queue, local->queues_pending)) { 347 if (test_bit(queue, local->queues_pending)) {
338 set_bit(queue, local->queues_pending_run); 348 set_bit(queue, local->queues_pending_run);
339 tasklet_schedule(&local->tx_pending_tasklet); 349 tasklet_schedule(&local->tx_pending_tasklet);
@@ -341,22 +351,74 @@ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
341 netif_wake_subqueue(local->mdev, queue); 351 netif_wake_subqueue(local->mdev, queue);
342 } 352 }
343} 353}
354
355void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
356 enum queue_stop_reason reason)
357{
358 struct ieee80211_local *local = hw_to_local(hw);
359 unsigned long flags;
360
361 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
362 __ieee80211_wake_queue(hw, queue, reason);
363 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
364}
365
366void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
367{
368 ieee80211_wake_queue_by_reason(hw, queue,
369 IEEE80211_QUEUE_STOP_REASON_DRIVER);
370}
344EXPORT_SYMBOL(ieee80211_wake_queue); 371EXPORT_SYMBOL(ieee80211_wake_queue);
345 372
346void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) 373static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
374 enum queue_stop_reason reason)
347{ 375{
348 struct ieee80211_local *local = hw_to_local(hw); 376 struct ieee80211_local *local = hw_to_local(hw);
349 377
378 /* we don't need to track ampdu queues */
379 if (queue < ieee80211_num_regular_queues(hw))
380 __set_bit(reason, &local->queue_stop_reasons[queue]);
381
350 netif_stop_subqueue(local->mdev, queue); 382 netif_stop_subqueue(local->mdev, queue);
351} 383}
384
385void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
386 enum queue_stop_reason reason)
387{
388 struct ieee80211_local *local = hw_to_local(hw);
389 unsigned long flags;
390
391 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
392 __ieee80211_stop_queue(hw, queue, reason);
393 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
394}
395
396void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
397{
398 ieee80211_stop_queue_by_reason(hw, queue,
399 IEEE80211_QUEUE_STOP_REASON_DRIVER);
400}
352EXPORT_SYMBOL(ieee80211_stop_queue); 401EXPORT_SYMBOL(ieee80211_stop_queue);
353 402
354void ieee80211_stop_queues(struct ieee80211_hw *hw) 403void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
404 enum queue_stop_reason reason)
355{ 405{
406 struct ieee80211_local *local = hw_to_local(hw);
407 unsigned long flags;
356 int i; 408 int i;
357 409
410 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
411
358 for (i = 0; i < ieee80211_num_queues(hw); i++) 412 for (i = 0; i < ieee80211_num_queues(hw); i++)
359 ieee80211_stop_queue(hw, i); 413 __ieee80211_stop_queue(hw, i, reason);
414
415 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
416}
417
418void ieee80211_stop_queues(struct ieee80211_hw *hw)
419{
420 ieee80211_stop_queues_by_reason(hw,
421 IEEE80211_QUEUE_STOP_REASON_DRIVER);
360} 422}
361EXPORT_SYMBOL(ieee80211_stop_queues); 423EXPORT_SYMBOL(ieee80211_stop_queues);
362 424
@@ -367,12 +429,24 @@ int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
367} 429}
368EXPORT_SYMBOL(ieee80211_queue_stopped); 430EXPORT_SYMBOL(ieee80211_queue_stopped);
369 431
370void ieee80211_wake_queues(struct ieee80211_hw *hw) 432void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
433 enum queue_stop_reason reason)
371{ 434{
435 struct ieee80211_local *local = hw_to_local(hw);
436 unsigned long flags;
372 int i; 437 int i;
373 438
439 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
440
374 for (i = 0; i < hw->queues + hw->ampdu_queues; i++) 441 for (i = 0; i < hw->queues + hw->ampdu_queues; i++)
375 ieee80211_wake_queue(hw, i); 442 __ieee80211_wake_queue(hw, i, reason);
443
444 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
445}
446
447void ieee80211_wake_queues(struct ieee80211_hw *hw)
448{
449 ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_DRIVER);
376} 450}
377EXPORT_SYMBOL(ieee80211_wake_queues); 451EXPORT_SYMBOL(ieee80211_wake_queues);
378 452