b43: Add TX statistics debugging counters
authorMichael Buesch <mb@bu3sch.de>
Fri, 7 Mar 2008 14:50:02 +0000 (15:50 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 7 Mar 2008 21:02:59 +0000 (16:02 -0500)
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>
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/dma.h

index 3b1f0e76b9a4316c4a172b434a3a7dc593de512a..8e9497c526af28cb23f6cd847d19ef6f1b2c1ac2 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/etherdevice.h>
+#include <asm/div64.h>
 
 
 /* 32bit DMA ops. */
@@ -878,6 +879,17 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
        goto out;
 }
 
+#define divide(a, b)   ({      \
+       typeof(a) __a = a;      \
+       do_div(__a, b);         \
+       __a;                    \
+  })
+
+#define modulo(a, b)   ({      \
+       typeof(a) __a = a;      \
+       do_div(__a, b);         \
+  })
+
 /* Main cleanup function. */
 static void b43_destroy_dmaring(struct b43_dmaring *ring,
                                const char *ringname)
@@ -885,9 +897,34 @@ static void b43_destroy_dmaring(struct b43_dmaring *ring,
        if (!ring)
                return;
 
-       b43dbg(ring->dev->wl, "DMA-%u %s max used slots: %d/%d\n",
-              (unsigned int)(ring->type), ringname,
-              ring->max_used_slots, ring->nr_slots);
+#ifdef CONFIG_B43_DEBUG
+       {
+               /* Print some statistics. */
+               u64 failed_packets = ring->nr_failed_tx_packets;
+               u64 succeed_packets = ring->nr_succeed_tx_packets;
+               u64 nr_packets = failed_packets + succeed_packets;
+               u64 permille_failed = 0, average_tries = 0;
+
+               if (nr_packets)
+                       permille_failed = divide(failed_packets * 1000, nr_packets);
+               if (nr_packets)
+                       average_tries = divide(ring->nr_total_packet_tries * 100, nr_packets);
+
+               b43dbg(ring->dev->wl, "DMA-%u %s: "
+                      "Used slots %d/%d, Failed frames %llu/%llu = %llu.%01llu%%, "
+                      "Average tries %llu.%02llu\n",
+                      (unsigned int)(ring->type), ringname,
+                      ring->max_used_slots,
+                      ring->nr_slots,
+                      (unsigned long long)failed_packets,
+                      (unsigned long long)succeed_packets,
+                      (unsigned long long)divide(permille_failed, 10),
+                      (unsigned long long)modulo(permille_failed, 10),
+                      (unsigned long long)divide(average_tries, 100),
+                      (unsigned long long)modulo(average_tries, 100));
+       }
+#endif /* DEBUG */
+
        /* Device IRQs are disabled prior entering this function,
         * so no need to take care of concurrency with rx handler stuff.
         */
@@ -1270,6 +1307,38 @@ out_unlock:
        return err;
 }
 
+static void b43_fill_txstatus_report(struct b43_dmaring *ring,
+                                   struct ieee80211_tx_status *report,
+                                   const struct b43_txstatus *status)
+{
+       bool frame_failed = 0;
+
+       if (status->acked) {
+               /* The frame was ACKed. */
+               report->flags |= IEEE80211_TX_STATUS_ACK;
+       } else {
+               /* The frame was not ACKed... */
+               if (!(report->control.flags & IEEE80211_TXCTL_NO_ACK)) {
+                       /* ...but we expected an ACK. */
+                       frame_failed = 1;
+                       report->excessive_retries = 1;
+               }
+       }
+       if (status->frame_count == 0) {
+               /* The frame was not transmitted at all. */
+               report->retry_count = 0;
+       } else {
+               report->retry_count = status->frame_count - 1;
+#ifdef CONFIG_B43_DEBUG
+               if (frame_failed)
+                       ring->nr_failed_tx_packets++;
+               else
+                       ring->nr_succeed_tx_packets++;
+               ring->nr_total_packet_tries += status->frame_count;
+#endif /* DEBUG */
+       }
+}
+
 void b43_dma_handle_txstatus(struct b43_wldev *dev,
                             const struct b43_txstatus *status)
 {
@@ -1304,18 +1373,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
                         * status of the transmission.
                         * Some fields of txstat are already filled in dma_tx().
                         */
-                       if (status->acked) {
-                               meta->txstat.flags |= IEEE80211_TX_STATUS_ACK;
-                       } else {
-                               if (!(meta->txstat.control.flags
-                                     & IEEE80211_TXCTL_NO_ACK))
-                                       meta->txstat.excessive_retries = 1;
-                       }
-                       if (status->frame_count == 0) {
-                               /* The frame was not transmitted at all. */
-                               meta->txstat.retry_count = 0;
-                       } else
-                               meta->txstat.retry_count = status->frame_count - 1;
+                       b43_fill_txstatus_report(ring, &(meta->txstat), status);
                        ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb,
                                                    &(meta->txstat));
                        /* skb is freed by ieee80211_tx_status_irqsafe() */
index 9336286d97a7e1d5bf165581f4d09c6abce4b939..ea27085dec0e427f8bfb91f9aa2df07eca844f2d 100644 (file)
@@ -256,7 +256,13 @@ struct b43_dmaring {
        int max_used_slots;
        /* Last time we injected a ring overflow. */
        unsigned long last_injected_overflow;
-#endif                         /* CONFIG_B43_DEBUG */
+       /* Statistics: Number of successfully transmitted packets */
+       u64 nr_succeed_tx_packets;
+       /* Statistics: Number of failed TX packets */
+       u64 nr_failed_tx_packets;
+       /* Statistics: Total number of TX plus all retries. */
+       u64 nr_total_packet_tries;
+#endif /* CONFIG_B43_DEBUG */
 };
 
 static inline u32 b43_dma_read(struct b43_dmaring *ring, u16 offset)