wl12xx: schedule TX packets according to FW occupancy
When selecting packets for transmission, prefer the ACs that are least
occupied in the FW. When packets for multiple ACs are present in the FW,
it decides which to transmit according to WMM QoS parameters.
With these changes, lower priority ACs should not be starved when higher
priority traffic is present.
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 8b929fa..08eb81e 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -824,13 +824,24 @@
}
}
+static u32 wl1271_tx_allocated_blocks(struct wl1271 *wl)
+{
+ int i;
+ u32 total_alloc_blocks = 0;
+
+ for (i = 0; i < NUM_TX_QUEUES; i++)
+ total_alloc_blocks += wl->tx_allocated_blocks[i];
+
+ return total_alloc_blocks;
+}
+
static void wl1271_fw_status(struct wl1271 *wl,
struct wl1271_fw_full_status *full_status)
{
struct wl1271_fw_common_status *status = &full_status->common;
struct timespec ts;
u32 old_tx_blk_count = wl->tx_blocks_available;
- u32 freed_blocks = 0;
+ u32 freed_blocks = 0, ac_freed_blocks;
int i;
if (wl->bss_type == BSS_TYPE_AP_BSS) {
@@ -850,21 +861,23 @@
/* update number of available TX blocks */
for (i = 0; i < NUM_TX_QUEUES; i++) {
- freed_blocks += le32_to_cpu(status->tx_released_blks[i]) -
- wl->tx_blocks_freed[i];
+ ac_freed_blocks = le32_to_cpu(status->tx_released_blks[i]) -
+ wl->tx_blocks_freed[i];
+ freed_blocks += ac_freed_blocks;
+
+ wl->tx_allocated_blocks[i] -= ac_freed_blocks;
wl->tx_blocks_freed[i] =
le32_to_cpu(status->tx_released_blks[i]);
}
- wl->tx_allocated_blocks -= freed_blocks;
-
if (wl->bss_type == BSS_TYPE_AP_BSS) {
/* Update num of allocated TX blocks per link and ps status */
wl1271_irq_update_links_status(wl, &full_status->ap);
wl->tx_blocks_available += freed_blocks;
} else {
- int avail = full_status->sta.tx_total - wl->tx_allocated_blocks;
+ int avail = full_status->sta.tx_total -
+ wl1271_tx_allocated_blocks(wl);
/*
* The FW might change the total number of TX memblocks before
@@ -1987,7 +2000,6 @@
wl->psm_entry_retry = 0;
wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
wl->tx_blocks_available = 0;
- wl->tx_allocated_blocks = 0;
wl->tx_results_count = 0;
wl->tx_packets_count = 0;
wl->time_offset = 0;
@@ -2008,8 +2020,10 @@
*/
wl->flags = 0;
- for (i = 0; i < NUM_TX_QUEUES; i++)
+ for (i = 0; i < NUM_TX_QUEUES; i++) {
wl->tx_blocks_freed[i] = 0;
+ wl->tx_allocated_blocks[i] = 0;
+ }
wl1271_debugfs_reset(wl);