summaryrefslogtreecommitdiffstats
path: root/sys/mips/atheros
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2015-10-28 05:11:06 +0000
committeradrian <adrian@FreeBSD.org>2015-10-28 05:11:06 +0000
commit39fb527bf90f6a5cb03d93bd49c310bbca016a45 (patch)
treeb86f3d09c4a931aa7bed5653d879d73cbe709afe /sys/mips/atheros
parent3746182ae944db3a78bec9b7c7ce40fec197367c (diff)
downloadFreeBSD-src-39fb527bf90f6a5cb03d93bd49c310bbca016a45.zip
FreeBSD-src-39fb527bf90f6a5cb03d93bd49c310bbca016a45.tar.gz
Add some debugging code (under ARGE_DEBUG) that counts each interrupt source.
This should make it easier to track down interrupt storms from arge. Tested: * AP135 (QCA955x) SoC - defaults to ARGE_DEBUG enabled * Carambola2 (AR9331 SoC) - defaults to ARGE_DEBUG disabled
Diffstat (limited to 'sys/mips/atheros')
-rw-r--r--sys/mips/atheros/if_arge.c34
-rw-r--r--sys/mips/atheros/if_argevar.h3
2 files changed, 37 insertions, 0 deletions
diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c
index 06a5be3..f93b7bd 100644
--- a/sys/mips/atheros/if_arge.c
+++ b/sys/mips/atheros/if_arge.c
@@ -277,6 +277,28 @@ arge_probe(device_t dev)
return (BUS_PROBE_NOWILDCARD);
}
+#ifdef ARGE_DEBUG
+static void
+arge_attach_intr_sysctl(device_t dev, struct sysctl_oid_list *parent)
+{
+ struct arge_softc *sc = device_get_softc(dev);
+ struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
+ struct sysctl_oid *tree = device_get_sysctl_tree(dev);
+ struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
+ char sn[8];
+ int i;
+
+ tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "intr",
+ CTLFLAG_RD, NULL, "Interrupt statistics");
+ child = SYSCTL_CHILDREN(tree);
+ for (i = 0; i < 32; i++) {
+ snprintf(sn, sizeof(sn), "%d", i);
+ SYSCTL_ADD_UINT(ctx, child, OID_AUTO, sn, CTLFLAG_RD,
+ &sc->intr_stats.count[i], 0, "");
+ }
+}
+#endif
+
static void
arge_attach_sysctl(device_t dev)
{
@@ -288,6 +310,7 @@ arge_attach_sysctl(device_t dev)
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"debug", CTLFLAG_RW, &sc->arge_debug, 0,
"arge interface debugging flags");
+ arge_attach_intr_sysctl(dev, SYSCTL_CHILDREN(tree));
#endif
SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
@@ -2440,6 +2463,9 @@ arge_intr(void *arg)
struct arge_softc *sc = arg;
uint32_t status;
struct ifnet *ifp = sc->arge_ifp;
+#ifdef ARGE_DEBUG
+ int i;
+#endif
status = ARGE_READ(sc, AR71XX_DMA_INTR_STATUS);
status |= sc->arge_intr_status;
@@ -2456,6 +2482,14 @@ arge_intr(void *arg)
return;
}
+#ifdef ARGE_DEBUG
+ for (i = 0; i < 32; i++) {
+ if (status & (1 << i)) {
+ sc->intr_stats.count[1 << i]++;
+ }
+ }
+#endif
+
if (status & DMA_INTR_RX_BUS_ERROR) {
ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_BUS_ERROR);
device_printf(sc->arge_dev, "RX bus error");
diff --git a/sys/mips/atheros/if_argevar.h b/sys/mips/atheros/if_argevar.h
index ae94588..cb533ac 100644
--- a/sys/mips/atheros/if_argevar.h
+++ b/sys/mips/atheros/if_argevar.h
@@ -214,6 +214,9 @@ struct arge_softc {
uint32_t intr_stray2;
uint32_t intr_ok;
} stats;
+ struct {
+ uint32_t count[32];
+ } intr_stats;
};
#endif /* __IF_ARGEVAR_H__ */
OpenPOWER on IntegriCloud