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);
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);
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");
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);
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;
/* 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];
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;