Squirrel away SYNC interrupt debugging if it's enabled in the HAL.

Bus errors will show up as various SYNC interrupts which will be passed
back up to ath_intr().
This commit is contained in:
Adrian Chadd 2012-04-10 07:23:37 +00:00
parent eddd7521f1
commit 9467e3f3fc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=234090
4 changed files with 42 additions and 1 deletions

View File

@ -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:

View File

@ -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);
}
/*

View File

@ -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 */

View File

@ -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 */