summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/wl12xx/main.c16
-rw-r--r--drivers/net/wireless/wl12xx/tx.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h8
3 files changed, 23 insertions, 3 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index c917f69f0069..09cecb336d53 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -814,6 +814,7 @@ static void wl12xx_fw_status(struct wl1271 *wl,
struct timespec ts;
u32 old_tx_blk_count = wl->tx_blocks_available;
int avail, freed_blocks;
+ int i;
wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);
@@ -824,6 +825,15 @@ static void wl12xx_fw_status(struct wl1271 *wl,
status->drv_rx_counter,
status->tx_results_counter);
+ for (i = 0; i < NUM_TX_QUEUES; i++) {
+ /* prevent wrap-around in freed-packets counter */
+ wl->tx_allocated_pkts -=
+ (status->tx_released_pkts[i] -
+ wl->tx_pkts_freed[i]) & 0xff;
+
+ wl->tx_pkts_freed[i] = status->tx_released_pkts[i];
+ }
+
freed_blocks = le32_to_cpu(status->total_released_blks) -
wl->tx_blocks_freed;
wl->tx_blocks_freed = le32_to_cpu(status->total_released_blks);
@@ -1934,7 +1944,7 @@ out:
static void __wl1271_op_remove_interface(struct wl1271 *wl,
bool reset_tx_queues)
{
- int ret;
+ int ret, i;
wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
@@ -2050,6 +2060,10 @@ deinit:
wl->tx_blocks_freed = 0;
+ wl->tx_allocated_pkts = 0;
+ for (i = 0; i < NUM_TX_QUEUES; i++)
+ wl->tx_pkts_freed[i] = 0;
+
wl1271_debugfs_reset(wl);
kfree(wl->fw_status);
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 8fdffd08d492..7dd6d8b94f64 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -242,6 +242,8 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
wl->tx_blocks_available -= total_blocks;
wl->tx_allocated_blocks += total_blocks;
+ wl->tx_allocated_pkts++;
+
if (wl->bss_type == BSS_TYPE_AP_BSS)
wl->links[hlid].allocated_blks += total_blocks;
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 416d68ed95cf..24b40251535b 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -268,8 +268,8 @@ struct wl12xx_fw_status {
/* Size (in Memory Blocks) of TX pool */
__le32 tx_total;
- /* Cumulative counter of released mem-blocks per AC */
- u8 tx_released_blks[NUM_TX_QUEUES];
+ /* Cumulative counter of released packets per AC */
+ u8 tx_released_pkts[NUM_TX_QUEUES];
/* Cumulative counter of freed MBs per HLID */
u8 tx_lnk_free_blks[WL12XX_MAX_LINKS];
@@ -422,6 +422,10 @@ struct wl1271 {
u32 tx_allocated_blocks;
u32 tx_results_count;
+ /* Accounting for allocated / available Tx packets in HW */
+ u32 tx_pkts_freed[NUM_TX_QUEUES];
+ u32 tx_allocated_pkts;
+
/* Transmitted TX packets counter for chipset interface */
u32 tx_packets_count;