Module Name: src Committed By: mrg Date: Sun Jan 9 00:36:28 UTC 2022
Modified Files: src/sys/dev/ic: dwc_eqos.c dwc_eqos_reg.h dwc_eqos_var.h Log Message: eqos: handle the GMAC_MTL_INTERRUPT_STATUS register having something drain a couple of registers that want either a read or a write-1-to- clear bit, and keep track of how many happen via evcnt. i had this trigger one time, but not since adding instrumentation to see exactly it was saying (the GMAC_MTL_INTERRUPT_STATUS_Q0IS bit was set, and it requires some handling now implemented.) ok jmcneill To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/ic/dwc_eqos.c \ src/sys/dev/ic/dwc_eqos_reg.h src/sys/dev/ic/dwc_eqos_var.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ic/dwc_eqos.c diff -u src/sys/dev/ic/dwc_eqos.c:1.2 src/sys/dev/ic/dwc_eqos.c:1.3 --- src/sys/dev/ic/dwc_eqos.c:1.2 Sat Jan 8 22:24:53 2022 +++ src/sys/dev/ic/dwc_eqos.c Sun Jan 9 00:36:28 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_eqos.c,v 1.2 2022/01/08 22:24:53 mrg Exp $ */ +/* $NetBSD: dwc_eqos.c,v 1.3 2022/01/09 00:36:28 mrg Exp $ */ /*- * Copyright (c) 2022 Jared McNeill <jmcne...@invisible.ca> @@ -33,7 +33,7 @@ #include "opt_net_mpsafe.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dwc_eqos.c,v 1.2 2022/01/08 22:24:53 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dwc_eqos.c,v 1.3 2022/01/09 00:36:28 mrg Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -870,6 +870,49 @@ eqos_start(struct ifnet *ifp) EQOS_TXUNLOCK(sc); } +static void +eqos_intr_mtl(struct eqos_softc *sc, uint32_t mtl_status) +{ + uint32_t debug_data __unused = 0, ictrl = 0; + + if (mtl_status == 0) + return; + + /* Drain the errors reported by MTL_INTERRUPT_STATUS */ + sc->sc_ev_mtl.ev_count++; + + if ((mtl_status & GMAC_MTL_INTERRUPT_STATUS_DBGIS) != 0) { + debug_data = RD4(sc, GMAC_MTL_FIFO_DEBUG_DATA); + sc->sc_ev_mtl_debugdata.ev_count++; + } + if ((mtl_status & GMAC_MTL_INTERRUPT_STATUS_Q0IS) != 0) { + uint32_t new_status = 0; + + ictrl = RD4(sc, GMAC_MTL_Q0_INTERRUPT_CTRL_STATUS); + if ((ictrl & GMAC_MTL_Q0_INTERRUPT_CTRL_STATUS_RXOVFIS) != 0) { + new_status |= GMAC_MTL_Q0_INTERRUPT_CTRL_STATUS_RXOVFIS; + sc->sc_ev_mtl_rxovfis.ev_count++; + } + if ((ictrl & GMAC_MTL_Q0_INTERRUPT_CTRL_STATUS_TXUNFIS) != 0) { + new_status |= GMAC_MTL_Q0_INTERRUPT_CTRL_STATUS_TXUNFIS; + sc->sc_ev_mtl_txovfis.ev_count++; + } + if (new_status) { + new_status |= (ictrl & + (GMAC_MTL_Q0_INTERRUPT_CTRL_STATUS_RXOIE| + GMAC_MTL_Q0_INTERRUPT_CTRL_STATUS_TXUIE)); + WR4(sc, GMAC_MTL_Q0_INTERRUPT_CTRL_STATUS, new_status); + } + } +#ifdef DEBUG_LOUD + device_printf(sc->sc_dev, + "GMAC_MTL_INTERRUPT_STATUS = 0x%08X, " + "GMAC_MTL_FIFO_DEBUG_DATA = 0x%08X, " + "GMAC_MTL_INTERRUPT_STATUS_Q0IS = 0x%08X\n", + mtl_status, debug_data, ictrl); +#endif +} + int eqos_intr(void *arg) { @@ -891,13 +934,7 @@ eqos_intr(void *arg) } mtl_status = RD4(sc, GMAC_MTL_INTERRUPT_STATUS); - if (mtl_status) { - sc->sc_ev_mtl.ev_count++; -#ifdef DEBUG_LOUD - device_printf(sc->sc_dev, - "GMAC_MTL_INTERRUPT_STATUS = 0x%08X\n", mtl_status); -#endif - } + eqos_intr_mtl(sc, mtl_status); dma_status = RD4(sc, GMAC_DMA_CHAN0_STATUS); dma_status &= RD4(sc, GMAC_DMA_CHAN0_INTR_ENABLE); @@ -1305,6 +1342,14 @@ eqos_attach(struct eqos_softc *sc) evcnt_attach_dynamic(&sc->sc_ev_status, EVCNT_TYPE_INTR, &sc->sc_ev_intr, device_xname(sc->sc_dev), "rxtxstatus"); + /* MAC Status specific type, using macstatus interrupt */ + evcnt_attach_dynamic(&sc->sc_ev_mtl_debugdata, EVCNT_TYPE_INTR, + &sc->sc_ev_mtl, device_xname(sc->sc_dev), "debugdata"); + evcnt_attach_dynamic(&sc->sc_ev_mtl_rxovfis, EVCNT_TYPE_INTR, + &sc->sc_ev_mtl, device_xname(sc->sc_dev), "rxovfis"); + evcnt_attach_dynamic(&sc->sc_ev_mtl_txovfis, EVCNT_TYPE_INTR, + &sc->sc_ev_mtl, device_xname(sc->sc_dev), "txovfis"); + /* RX/TX Status specific type, using rxtxstatus interrupt */ evcnt_attach_dynamic(&sc->sc_ev_rwt, EVCNT_TYPE_INTR, &sc->sc_ev_status, device_xname(sc->sc_dev), "rwt"); Index: src/sys/dev/ic/dwc_eqos_reg.h diff -u src/sys/dev/ic/dwc_eqos_reg.h:1.2 src/sys/dev/ic/dwc_eqos_reg.h:1.3 --- src/sys/dev/ic/dwc_eqos_reg.h:1.2 Sat Jan 8 22:24:53 2022 +++ src/sys/dev/ic/dwc_eqos_reg.h Sun Jan 9 00:36:28 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_eqos_reg.h,v 1.2 2022/01/08 22:24:53 mrg Exp $ */ +/* $NetBSD: dwc_eqos_reg.h,v 1.3 2022/01/09 00:36:28 mrg Exp $ */ /*- * Copyright (c) 2022 Jared McNeill <jmcne...@invisible.ca> @@ -171,6 +171,8 @@ #define GMAC_MTL_DBG_STS 0x0C0C #define GMAC_MTL_FIFO_DEBUG_DATA 0x0C10 #define GMAC_MTL_INTERRUPT_STATUS 0x0C20 +#define GMAC_MTL_INTERRUPT_STATUS_DBGIS (1U << 17) +#define GMAC_MTL_INTERRUPT_STATUS_Q0IS (1U << 0) #define GMAC_MTL_TXQ0_OPERATION_MODE 0x0D00 #define GMAC_MTL_TXQ0_OPERATION_MODE_TXQEN_SHIFT 2 #define GMAC_MTL_TXQ0_OPERATION_MODE_TXQEN_MASK (0x3U << GMAC_MTL_TXQ0_OPERATION_MODE_TXQEN_SHIFT) Index: src/sys/dev/ic/dwc_eqos_var.h diff -u src/sys/dev/ic/dwc_eqos_var.h:1.2 src/sys/dev/ic/dwc_eqos_var.h:1.3 --- src/sys/dev/ic/dwc_eqos_var.h:1.2 Sat Jan 8 22:24:53 2022 +++ src/sys/dev/ic/dwc_eqos_var.h Sun Jan 9 00:36:28 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_eqos_var.h,v 1.2 2022/01/08 22:24:53 mrg Exp $ */ +/* $NetBSD: dwc_eqos_var.h,v 1.3 2022/01/09 00:36:28 mrg Exp $ */ /*- * Copyright (c) 2022 Jared McNeill <jmcne...@invisible.ca> @@ -79,6 +79,9 @@ struct eqos_softc { struct evcnt sc_ev_txintr; struct evcnt sc_ev_mac; struct evcnt sc_ev_mtl; + struct evcnt sc_ev_mtl_debugdata; + struct evcnt sc_ev_mtl_rxovfis; + struct evcnt sc_ev_mtl_txovfis; struct evcnt sc_ev_status; struct evcnt sc_ev_rwt; struct evcnt sc_ev_excol;