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;

Reply via email to