wl12xx: track freed packets in FW by AC

Track the number of freed packets in each AC when receiving an interrupt
from the FW. This paves the way for tracking allocated packets per AC.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Eliad Peller <eliad@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 c917f69..09cecb3 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -814,6 +814,7 @@
 	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 @@
 		     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 @@
 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 @@
 
 	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);