* [PATCH] b43: Add TX statistics debugging counters
@ 2008-03-07 14:50 Michael Buesch
0 siblings, 0 replies; only message in thread
From: Michael Buesch @ 2008-03-07 14:50 UTC (permalink / raw)
To: John Linville; +Cc: bcm43xx-dev, linux-wireless
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>
---
For 2.6.26
Index: wireless-testing/drivers/net/wireless/b43/dma.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/b43/dma.c 2008-03-06 16:30:32.000000000 +0100
+++ wireless-testing/drivers/net/wireless/b43/dma.c 2008-03-07 15:42:18.000000000 +0100
@@ -35,12 +35,13 @@
#include <linux/dma-mapping.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
+#include <asm/div64.h>
/* 32bit DMA ops. */
static
struct b43_dmadesc_generic *op32_idx2desc(struct b43_dmaring *ring,
int slot,
@@ -875,22 +876,58 @@ struct b43_dmaring *b43_setup_dmaring(st
err_kfree_ring:
kfree(ring);
ring = NULL;
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)
{
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.
*/
dmacontroller_cleanup(ring);
free_all_descbuffers(ring);
free_ringmemory(ring);
@@ -1267,12 +1304,44 @@ int b43_dma_tx(struct b43_wldev *dev,
out_unlock:
spin_unlock_irqrestore(&ring->lock, flags);
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)
{
const struct b43_dma_ops *ops;
struct b43_dmaring *ring;
struct b43_dmadesc_generic *desc;
@@ -1301,24 +1370,13 @@ void b43_dma_handle_txstatus(struct b43_
if (meta->is_last_fragment) {
B43_WARN_ON(!meta->skb);
/* Call back to inform the ieee80211 subsystem about the
* 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() */
meta->skb = NULL;
} else {
/* No need to call free_descriptor_buffer here, as
Index: wireless-testing/drivers/net/wireless/b43/dma.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/b43/dma.h 2008-03-06 16:15:23.000000000 +0100
+++ wireless-testing/drivers/net/wireless/b43/dma.h 2008-03-06 20:09:46.000000000 +0100
@@ -253,13 +253,19 @@ struct b43_dmaring {
struct b43_wldev *dev;
#ifdef CONFIG_B43_DEBUG
/* Maximum number of used slots. */
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)
{
return b43_read32(ring->dev, ring->mmio_base + offset);
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2008-03-07 14:51 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-07 14:50 [PATCH] b43: Add TX statistics debugging counters Michael Buesch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).