summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ath/if_ath.c14
-rw-r--r--sys/dev/ath/if_ath_sysctl.c24
-rw-r--r--sys/dev/ath/if_athioctl.h4
-rw-r--r--sys/dev/ath/if_athvar.h1
4 files changed, 42 insertions, 1 deletions
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index f2552a6..5888800 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -1495,6 +1495,15 @@ ath_intr(void *arg)
ah->ah_intrstate[3],
ah->ah_intrstate[6]);
#endif
+
+ /* Squirrel away SYNC interrupt debugging */
+ if (ah->ah_syncstate != 0) {
+ int i;
+ for (i = 0; i < 32; i++)
+ if (ah->ah_syncstate & (i << i))
+ sc->sc_intr_stats.sync_intr[i]++;
+ }
+
status &= sc->sc_imask; /* discard unasked for bits */
/* Short-circuit un-handled interrupts */
@@ -6476,8 +6485,11 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ifr->ifr_data, sizeof (sc->sc_stats));
case SIOCZATHSTATS:
error = priv_check(curthread, PRIV_DRIVER);
- if (error == 0)
+ if (error == 0) {
memset(&sc->sc_stats, 0, sizeof(sc->sc_stats));
+ memset(&sc->sc_intr_stats, 0,
+ sizeof(sc->sc_intr_stats));
+ }
break;
#ifdef ATH_DIAGAPI
case SIOCGATHDIAG:
diff --git a/sys/dev/ath/if_ath_sysctl.c b/sys/dev/ath/if_ath_sysctl.c
index 95c0615..6e7c2c8 100644
--- a/sys/dev/ath/if_ath_sysctl.c
+++ b/sys/dev/ath/if_ath_sysctl.c
@@ -655,6 +655,7 @@ ath_sysctl_clearstats(SYSCTL_HANDLER_ARGS)
return 0; /* Not clearing the stats is still valid */
memset(&sc->sc_stats, 0, sizeof(sc->sc_stats));
memset(&sc->sc_aggr_stats, 0, sizeof(sc->sc_aggr_stats));
+ memset(&sc->sc_intr_stats, 0, sizeof(sc->sc_intr_stats));
val = 0;
return 0;
@@ -677,6 +678,26 @@ ath_sysctl_stats_attach_rxphyerr(struct ath_softc *sc, struct sysctl_oid_list *p
}
}
+static void
+ath_sysctl_stats_attach_intr(struct ath_softc *sc,
+ struct sysctl_oid_list *parent)
+{
+ struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
+ struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
+ struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
+ int i;
+ char sn[8];
+
+ tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "sync_intr",
+ CTLFLAG_RD, NULL, "Sync 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->sc_intr_stats.sync_intr[i], 0, "");
+ }
+}
+
void
ath_sysctl_stats_attach(struct ath_softc *sc)
{
@@ -904,6 +925,9 @@ ath_sysctl_stats_attach(struct ath_softc *sc)
/* Attach the RX phy error array */
ath_sysctl_stats_attach_rxphyerr(sc, child);
+
+ /* Attach the interrupt statistics array */
+ ath_sysctl_stats_attach_intr(sc, child);
}
/*
diff --git a/sys/dev/ath/if_athioctl.h b/sys/dev/ath/if_athioctl.h
index 23ce3b1..8627a6b 100644
--- a/sys/dev/ath/if_athioctl.h
+++ b/sys/dev/ath/if_athioctl.h
@@ -46,6 +46,10 @@ struct ath_tx_aggr_stats {
u_int32_t aggr_rts_aggr_limited;
};
+struct ath_intr_stats {
+ u_int32_t sync_intr[32];
+};
+
struct ath_stats {
u_int32_t ast_watchdog; /* device reset by watchdog */
u_int32_t ast_hardware; /* fatal hardware error interrupts */
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index 77e7066..1b2b9ab 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -349,6 +349,7 @@ struct ath_softc {
struct ifnet *sc_ifp; /* interface common */
struct ath_stats sc_stats; /* interface statistics */
struct ath_tx_aggr_stats sc_aggr_stats;
+ struct ath_intr_stats sc_intr_stats;
int sc_debug;
int sc_nvaps; /* # vaps */
int sc_nstavaps; /* # station vaps */
OpenPOWER on IntegriCloud