wl12xx: handle wrap-around overflow in released Tx blocks FW counter
authorArik Nemtsov <arik@wizery.com>
Sun, 14 Aug 2011 10:17:34 +0000 (13:17 +0300)
committerLuciano Coelho <coelho@ti.com>
Mon, 22 Aug 2011 09:35:30 +0000 (12:35 +0300)
When the FW Tx released blocks counter wraps around, we should correct
our calculation of released blocks. Otherwise we add a large negative
figure to our driver freed blocks counter

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
drivers/net/wireless/wl12xx/main.c

index 027b6742a1511d4ccfd2cc78aa9a0ea8fc62fe3f..0fa3a2281ddb347184550371a7a0d3397df06207 100644 (file)
@@ -834,8 +834,15 @@ static void wl12xx_fw_status(struct wl1271 *wl,
                wl->tx_pkts_freed[i] = status->tx_released_pkts[i];
        }
 
-       freed_blocks = le32_to_cpu(status->total_released_blks) -
-                      wl->tx_blocks_freed;
+       /* prevent wrap-around in total blocks counter */
+       if (likely(wl->tx_blocks_freed <=
+                  le32_to_cpu(status->total_released_blks)))
+               freed_blocks = le32_to_cpu(status->total_released_blks) -
+                              wl->tx_blocks_freed;
+       else
+               freed_blocks = 0x100000000LL - wl->tx_blocks_freed +
+                              le32_to_cpu(status->total_released_blks);
+
        wl->tx_blocks_freed = le32_to_cpu(status->total_released_blks);
 
        wl->tx_allocated_blocks -= freed_blocks;