aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-03-07 09:50:02 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-03-07 16:02:59 -0500
commit57df40d278df552ad5fb4926fa05d06065c8150c (patch)
tree6c5e7219869c53a606b1c597484da2f6a1751f62
parentb27faf8ebf256429df8851477e02609448c0781f (diff)
b43: Add TX statistics debugging counters
This adds a few debugging counters, that are useful for debugging the "card does not transmit" or "connection is unstable" kind of problems. It's also useful for tuning an RC algorithm. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/b43/dma.c88
-rw-r--r--drivers/net/wireless/b43/dma.h8
2 files changed, 80 insertions, 16 deletions
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 3b1f0e76b9a4..8e9497c526af 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -38,6 +38,7 @@
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/skbuff.h> 39#include <linux/skbuff.h>
40#include <linux/etherdevice.h> 40#include <linux/etherdevice.h>
41#include <asm/div64.h>
41 42
42 43
43/* 32bit DMA ops. */ 44/* 32bit DMA ops. */
@@ -878,6 +879,17 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
878 goto out; 879 goto out;
879} 880}
880 881
882#define divide(a, b) ({ \
883 typeof(a) __a = a; \
884 do_div(__a, b); \
885 __a; \
886 })
887
888#define modulo(a, b) ({ \
889 typeof(a) __a = a; \
890 do_div(__a, b); \
891 })
892
881/* Main cleanup function. */ 893/* Main cleanup function. */
882static void b43_destroy_dmaring(struct b43_dmaring *ring, 894static void b43_destroy_dmaring(struct b43_dmaring *ring,
883 const char *ringname) 895 const char *ringname)
@@ -885,9 +897,34 @@ static void b43_destroy_dmaring(struct b43_dmaring *ring,
885 if (!ring) 897 if (!ring)
886 return; 898 return;
887 899
888 b43dbg(ring->dev->wl, "DMA-%u %s max used slots: %d/%d\n", 900#ifdef CONFIG_B43_DEBUG
889 (unsigned int)(ring->type), ringname, 901 {
890 ring->max_used_slots, ring->nr_slots); 902 /* Print some statistics. */
903 u64 failed_packets = ring->nr_failed_tx_packets;
904 u64 succeed_packets = ring->nr_succeed_tx_packets;
905 u64 nr_packets = failed_packets + succeed_packets;
906 u64 permille_failed = 0, average_tries = 0;
907
908 if (nr_packets)
909 permille_failed = divide(failed_packets * 1000, nr_packets);
910 if (nr_packets)
911 average_tries = divide(ring->nr_total_packet_tries * 100, nr_packets);
912
913 b43dbg(ring->dev->wl, "DMA-%u %s: "
914 "Used slots %d/%d, Failed frames %llu/%llu = %llu.%01llu%%, "
915 "Average tries %llu.%02llu\n",
916 (unsigned int)(ring->type), ringname,
917 ring->max_used_slots,
918 ring->nr_slots,
919 (unsigned long long)failed_packets,
920 (unsigned long long)succeed_packets,
921 (unsigned long long)divide(permille_failed, 10),
922 (unsigned long long)modulo(permille_failed, 10),
923 (unsigned long long)divide(average_tries, 100),
924 (unsigned long long)modulo(average_tries, 100));
925 }
926#endif /* DEBUG */
927
891 /* Device IRQs are disabled prior entering this function, 928 /* Device IRQs are disabled prior entering this function,
892 * so no need to take care of concurrency with rx handler stuff. 929 * so no need to take care of concurrency with rx handler stuff.
893 */ 930 */
@@ -1270,6 +1307,38 @@ out_unlock:
1270 return err; 1307 return err;
1271} 1308}
1272 1309
1310static void b43_fill_txstatus_report(struct b43_dmaring *ring,
1311 struct ieee80211_tx_status *report,
1312 const struct b43_txstatus *status)
1313{
1314 bool frame_failed = 0;
1315
1316 if (status->acked) {
1317 /* The frame was ACKed. */
1318 report->flags |= IEEE80211_TX_STATUS_ACK;
1319 } else {
1320 /* The frame was not ACKed... */
1321 if (!(report->control.flags & IEEE80211_TXCTL_NO_ACK)) {
1322 /* ...but we expected an ACK. */
1323 frame_failed = 1;
1324 report->excessive_retries = 1;
1325 }
1326 }
1327 if (status->frame_count == 0) {
1328 /* The frame was not transmitted at all. */
1329 report->retry_count = 0;
1330 } else {
1331 report->retry_count = status->frame_count - 1;
1332#ifdef CONFIG_B43_DEBUG
1333 if (frame_failed)
1334 ring->nr_failed_tx_packets++;
1335 else
1336 ring->nr_succeed_tx_packets++;
1337 ring->nr_total_packet_tries += status->frame_count;
1338#endif /* DEBUG */
1339 }
1340}
1341
1273void b43_dma_handle_txstatus(struct b43_wldev *dev, 1342void b43_dma_handle_txstatus(struct b43_wldev *dev,
1274 const struct b43_txstatus *status) 1343 const struct b43_txstatus *status)
1275{ 1344{
@@ -1304,18 +1373,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1304 * status of the transmission. 1373 * status of the transmission.
1305 * Some fields of txstat are already filled in dma_tx(). 1374 * Some fields of txstat are already filled in dma_tx().
1306 */ 1375 */
1307 if (status->acked) { 1376 b43_fill_txstatus_report(ring, &(meta->txstat), status);
1308 meta->txstat.flags |= IEEE80211_TX_STATUS_ACK;
1309 } else {
1310 if (!(meta->txstat.control.flags
1311 & IEEE80211_TXCTL_NO_ACK))
1312 meta->txstat.excessive_retries = 1;
1313 }
1314 if (status->frame_count == 0) {
1315 /* The frame was not transmitted at all. */
1316 meta->txstat.retry_count = 0;
1317 } else
1318 meta->txstat.retry_count = status->frame_count - 1;
1319 ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb, 1377 ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb,
1320 &(meta->txstat)); 1378 &(meta->txstat));
1321 /* skb is freed by ieee80211_tx_status_irqsafe() */ 1379 /* skb is freed by ieee80211_tx_status_irqsafe() */
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index 9336286d97a7..ea27085dec0e 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -256,7 +256,13 @@ struct b43_dmaring {
256 int max_used_slots; 256 int max_used_slots;
257 /* Last time we injected a ring overflow. */ 257 /* Last time we injected a ring overflow. */
258 unsigned long last_injected_overflow; 258 unsigned long last_injected_overflow;
259#endif /* CONFIG_B43_DEBUG */ 259 /* Statistics: Number of successfully transmitted packets */
260 u64 nr_succeed_tx_packets;
261 /* Statistics: Number of failed TX packets */
262 u64 nr_failed_tx_packets;
263 /* Statistics: Total number of TX plus all retries. */
264 u64 nr_total_packet_tries;
265#endif /* CONFIG_B43_DEBUG */
260}; 266};
261 267
262static inline u32 b43_dma_read(struct b43_dmaring *ring, u16 offset) 268static inline u32 b43_dma_read(struct b43_dmaring *ring, u16 offset)