diff options
author | Arik Nemtsov <arik@wizery.com> | 2011-06-24 06:03:37 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-07-05 14:33:44 -0400 |
commit | 708bb3cf58a9bc90f3171ba64f30601f690e5aaa (patch) | |
tree | bb64ac4a73af18a37e0290bf9a8642e0ed5d43fd /drivers/net/wireless/wl12xx/tx.c | |
parent | 787b2dc44aa1ae2524f022659c6c6b2d3c979e04 (diff) |
wl12xx: implement Tx watermarks per AC
Each AC is stopped when its queue is filled up to the high watermark,
and restarted when its queue it lower than the low watermark. This
ensures congested ACs are not able to starve other ACs.
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/tx.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index e6e5f54b8e49..75984dc81a8d 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
@@ -444,14 +444,19 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) | |||
444 | void wl1271_handle_tx_low_watermark(struct wl1271 *wl) | 444 | void wl1271_handle_tx_low_watermark(struct wl1271 *wl) |
445 | { | 445 | { |
446 | unsigned long flags; | 446 | unsigned long flags; |
447 | int i; | ||
447 | 448 | ||
448 | if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && | 449 | for (i = 0; i < NUM_TX_QUEUES; i++) { |
449 | wl->tx_queue_count <= WL1271_TX_QUEUE_LOW_WATERMARK) { | 450 | if (test_bit(i, &wl->stopped_queues_map) && |
450 | /* firmware buffer has space, restart queues */ | 451 | skb_queue_len(&wl->tx_queue[i]) <= |
451 | spin_lock_irqsave(&wl->wl_lock, flags); | 452 | WL1271_TX_QUEUE_LOW_WATERMARK) { |
452 | ieee80211_wake_queues(wl->hw); | 453 | /* firmware buffer has space, restart queues */ |
453 | clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); | 454 | spin_lock_irqsave(&wl->wl_lock, flags); |
454 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 455 | ieee80211_wake_queue(wl->hw, |
456 | wl1271_tx_get_mac80211_queue(i)); | ||
457 | clear_bit(i, &wl->stopped_queues_map); | ||
458 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
459 | } | ||
455 | } | 460 | } |
456 | } | 461 | } |
457 | 462 | ||
@@ -863,6 +868,7 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues) | |||
863 | } | 868 | } |
864 | 869 | ||
865 | wl->tx_queue_count = 0; | 870 | wl->tx_queue_count = 0; |
871 | wl->stopped_queues_map = 0; | ||
866 | 872 | ||
867 | /* | 873 | /* |
868 | * Make sure the driver is at a consistent state, in case this | 874 | * Make sure the driver is at a consistent state, in case this |