Module Name:    src
Committed By:   msaitoh
Date:           Mon Oct 23 15:29:38 UTC 2023

Modified Files:
        src/sys/dev/ic: dwc_eqos.c dwc_eqos_var.h

Log Message:
eqos(4): Add sysctls for debugging.


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/dev/ic/dwc_eqos.c
cvs rdiff -u -r1.4 -r1.5 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.24 src/sys/dev/ic/dwc_eqos.c:1.25
--- src/sys/dev/ic/dwc_eqos.c:1.24	Mon Oct 23 15:11:47 2023
+++ src/sys/dev/ic/dwc_eqos.c	Mon Oct 23 15:29:38 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: dwc_eqos.c,v 1.24 2023/10/23 15:11:47 msaitoh Exp $ */
+/* $NetBSD: dwc_eqos.c,v 1.25 2023/10/23 15:29:38 msaitoh Exp $ */
 
 /*-
  * Copyright (c) 2022 Jared McNeill <jmcne...@invisible.ca>
@@ -38,7 +38,7 @@
 #include "opt_net_mpsafe.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dwc_eqos.c,v 1.24 2023/10/23 15:11:47 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dwc_eqos.c,v 1.25 2023/10/23 15:29:38 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -50,6 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: dwc_eqos.c,v
 #include <sys/callout.h>
 #include <sys/cprng.h>
 #include <sys/evcnt.h>
+#include <sys/sysctl.h>
 
 #include <sys/rndsource.h>
 
@@ -70,18 +71,18 @@ __KERNEL_RCSID(0, "$NetBSD: dwc_eqos.c,v
 CTASSERT(MCLBYTES >= EQOS_RXDMA_SIZE);
 
 #ifdef EQOS_DEBUG
-unsigned int eqos_debug;
-#define	DPRINTF(FLAG, FORMAT, ...)	\
-	if (eqos_debug & FLAG)		\
+#define	EDEB_NOTE		(1U << 0)
+#define	EDEB_INTR		(1U << 1)
+#define	EDEB_RXRING		(1U << 2)
+#define	EDEB_TXRING		(1U << 3)
+unsigned int eqos_debug;	/* Default vaule */
+#define	DPRINTF(FLAG, FORMAT, ...)			 \
+	if (sc->sc_debug & FLAG)			 \
 		device_printf(sc->sc_dev, "%s: " FORMAT, \
 		    __func__, ##__VA_ARGS__)
 #else
 #define	DPRINTF(FLAG, FORMAT, ...)	((void)0)
 #endif
-#define	EDEB_NOTE		1U<<0
-#define	EDEB_INTR		1U<<1
-#define	EDEB_RXRING		1U<<2
-#define	EDEB_TXRING		1U<<3
 
 #ifdef NET_MPSAFE
 #define	EQOS_MPSAFE		1
@@ -123,6 +124,15 @@ unsigned int eqos_debug;
 #define	WR4(sc, reg, val)		\
 	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
 
+static void	eqos_init_sysctls(struct eqos_softc *);
+static int	eqos_sysctl_tx_cur_handler(SYSCTLFN_PROTO);
+static int	eqos_sysctl_tx_end_handler(SYSCTLFN_PROTO);
+static int	eqos_sysctl_rx_cur_handler(SYSCTLFN_PROTO);
+static int	eqos_sysctl_rx_end_handler(SYSCTLFN_PROTO);
+#ifdef EQOS_DEBUG
+static int	eqos_sysctl_debug_handler(SYSCTLFN_PROTO);
+#endif
+
 static int
 eqos_mii_readreg(device_t dev, int phy, int reg, uint16_t *val)
 {
@@ -1285,6 +1295,10 @@ eqos_setup_dma(struct eqos_softc *sc, in
 	struct mbuf *m;
 	int error, nsegs, i;
 
+	/* Set back pointer */
+	sc->sc_tx.sc = sc;
+	sc->sc_rx.sc = sc;
+
 	/* Setup TX ring */
 	error = bus_dmamap_create(sc->sc_dmat, TX_DESC_SIZE, 1, TX_DESC_SIZE,
 	    DESC_BOUNDARY, BUS_DMA_WAITOK, &sc->sc_tx.desc_map);
@@ -1392,6 +1406,11 @@ eqos_attach(struct eqos_softc *sc)
 	int error;
 	int n;
 
+#ifdef EQOS_DEBUG
+	/* Load the default debug flags. */
+	sc->sc_debug = eqos_debug;
+#endif
+
 	const uint32_t ver = RD4(sc, GMAC_MAC_VERSION);
 	userver = (ver & GMAC_MAC_VERSION_USERVER_MASK) >>
 	    GMAC_MAC_VERSION_USERVER_SHIFT;
@@ -1560,8 +1579,229 @@ eqos_attach(struct eqos_softc *sc)
 	/* Attach ethernet interface */
 	ether_ifattach(ifp, eaddr);
 
+	eqos_init_sysctls(sc);
+
 	rnd_attach_source(&sc->sc_rndsource, ifp->if_xname, RND_TYPE_NET,
 	    RND_FLAG_DEFAULT);
 
 	return 0;
 }
+
+static void
+eqos_init_sysctls(struct eqos_softc *sc)
+{
+	struct sysctllog **log;
+	const struct sysctlnode *rnode, *qnode, *cnode;
+	const char *dvname;
+	int i, rv;
+
+	log = &sc->sc_sysctllog;
+	dvname = device_xname(sc->sc_dev);
+
+	rv = sysctl_createv(log, 0, NULL, &rnode,
+	    0, CTLTYPE_NODE, dvname,
+	    SYSCTL_DESCR("eqos information and settings"),
+	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
+	if (rv != 0)
+		goto err;
+
+	for (i = 0; i < 1; i++) {
+		struct eqos_ring *txr = &sc->sc_tx;
+		struct eqos_ring *rxr = &sc->sc_rx;
+		const unsigned char *name = "q0";
+
+		if (sysctl_createv(log, 0, &rnode, &qnode,
+		    0, CTLTYPE_NODE,
+		    name, SYSCTL_DESCR("Queue Name"),
+		    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL) != 0)
+			break;
+
+		if (sysctl_createv(log, 0, &qnode, &cnode,
+		    CTLFLAG_READONLY, CTLTYPE_INT,
+		    "txs_cur", SYSCTL_DESCR("TX cur"),
+		    NULL, 0, &txr->cur,
+		    0, CTL_CREATE, CTL_EOL) != 0)
+			break;
+		if (sysctl_createv(log, 0, &qnode, &cnode,
+		    CTLFLAG_READONLY, CTLTYPE_INT,
+		    "txs_next", SYSCTL_DESCR("TX next"),
+		    NULL, 0, &txr->next,
+		    0, CTL_CREATE, CTL_EOL) != 0)
+			break;
+		if (sysctl_createv(log, 0, &qnode, &cnode,
+		    CTLFLAG_READONLY, CTLTYPE_INT,
+		    "txs_queued", SYSCTL_DESCR("TX queued"),
+		    NULL, 0, &txr->queued,
+		    0, CTL_CREATE, CTL_EOL) != 0)
+			break;
+		if (sysctl_createv(log, 0, &qnode, &cnode,
+		    CTLFLAG_READONLY, CTLTYPE_INT,
+		    "txr_cur", SYSCTL_DESCR("TX descriptor cur"),
+		    eqos_sysctl_tx_cur_handler, 0, (void *)txr,
+		    0, CTL_CREATE, CTL_EOL) != 0)
+			break;
+		if (sysctl_createv(log, 0, &qnode, &cnode,
+		    CTLFLAG_READONLY, CTLTYPE_INT,
+		    "txr_end", SYSCTL_DESCR("TX descriptor end"),
+		    eqos_sysctl_tx_end_handler, 0, (void *)txr,
+		    0, CTL_CREATE, CTL_EOL) != 0)
+			break;
+		if (sysctl_createv(log, 0, &qnode, &cnode,
+		    CTLFLAG_READONLY, CTLTYPE_INT,
+		    "rxs_cur", SYSCTL_DESCR("RX cur"),
+		    NULL, 0, &rxr->cur,
+		    0, CTL_CREATE, CTL_EOL) != 0)
+			break;
+		if (sysctl_createv(log, 0, &qnode, &cnode,
+		    CTLFLAG_READONLY, CTLTYPE_INT,
+		    "rxs_next", SYSCTL_DESCR("RX next"),
+		    NULL, 0, &rxr->next,
+		    0, CTL_CREATE, CTL_EOL) != 0)
+			break;
+		if (sysctl_createv(log, 0, &qnode, &cnode,
+		    CTLFLAG_READONLY, CTLTYPE_INT,
+		    "rxs_queued", SYSCTL_DESCR("RX queued"),
+		    NULL, 0, &rxr->queued,
+		    0, CTL_CREATE, CTL_EOL) != 0)
+			break;
+		if (sysctl_createv(log, 0, &qnode, &cnode,
+		    CTLFLAG_READONLY, CTLTYPE_INT,
+		    "rxr_cur", SYSCTL_DESCR("RX descriptor cur"),
+		    eqos_sysctl_rx_cur_handler, 0, (void *)rxr,
+		    0, CTL_CREATE, CTL_EOL) != 0)
+			break;
+		if (sysctl_createv(log, 0, &qnode, &cnode,
+		    CTLFLAG_READONLY, CTLTYPE_INT,
+		    "rxr_end", SYSCTL_DESCR("RX descriptor end"),
+		    eqos_sysctl_rx_end_handler, 0, (void *)rxr,
+		    0, CTL_CREATE, CTL_EOL) != 0)
+			break;
+	}
+
+#ifdef EQOS_DEBUG
+	rv = sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
+	    CTLTYPE_INT, "debug_flags",
+	    SYSCTL_DESCR(
+		    "Debug flags:\n"	\
+		    "\t0x01 NOTE\n"	\
+		    "\t0x02 INTR\n"	\
+		    "\t0x04 RX RING\n"	\
+		    "\t0x08 TX RING\n"),
+	    eqos_sysctl_debug_handler, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
+#endif
+
+	return;
+
+err:
+	sc->sc_sysctllog = NULL;
+	device_printf(sc->sc_dev, "%s: sysctl_createv failed, rv = %d\n",
+	    __func__, rv);
+}
+
+static int
+eqos_sysctl_tx_cur_handler(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct eqos_ring *txq = (struct eqos_ring *)node.sysctl_data;
+	struct eqos_softc *sc = txq->sc;
+	uint32_t reg, index;
+
+	reg = RD4(sc, GMAC_DMA_CHAN0_CUR_TX_DESC);
+#if 0
+	printf("head  = %08x\n", (uint32_t)sc->sc_tx.desc_ring_paddr);
+	printf("cdesc = %08x\n", reg);
+	printf("index = %zu\n",
+	    (reg - (uint32_t)sc->sc_tx.desc_ring_paddr) /
+	    sizeof(struct eqos_dma_desc));
+#endif
+	if (reg == 0)
+		index = 0;
+	else {
+		index = (reg - (uint32_t)sc->sc_tx.desc_ring_paddr) /
+		    sizeof(struct eqos_dma_desc);
+	}
+	node.sysctl_data = &index;
+	return sysctl_lookup(SYSCTLFN_CALL(&node));
+}
+
+static int
+eqos_sysctl_tx_end_handler(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct eqos_ring *txq = (struct eqos_ring *)node.sysctl_data;
+	struct eqos_softc *sc = txq->sc;
+	uint32_t reg, index;
+
+	reg = RD4(sc, GMAC_DMA_CHAN0_TX_END_ADDR);
+	if (reg == 0)
+		index = 0;
+	else {
+		index = (reg - (uint32_t)sc->sc_tx.desc_ring_paddr) /
+		    sizeof(struct eqos_dma_desc);
+	}
+	node.sysctl_data = &index;
+	return sysctl_lookup(SYSCTLFN_CALL(&node));
+}
+
+static int
+eqos_sysctl_rx_cur_handler(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct eqos_ring *rxq = (struct eqos_ring *)node.sysctl_data;
+	struct eqos_softc *sc = rxq->sc;
+	uint32_t reg, index;
+
+	reg = RD4(sc, GMAC_DMA_CHAN0_CUR_RX_DESC);
+	if (reg == 0)
+		index = 0;
+	else {
+		index = (reg - (uint32_t)sc->sc_rx.desc_ring_paddr) /
+		    sizeof(struct eqos_dma_desc);
+	}
+	node.sysctl_data = &index;
+	return sysctl_lookup(SYSCTLFN_CALL(&node));
+}
+
+static int
+eqos_sysctl_rx_end_handler(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct eqos_ring *rxq = (struct eqos_ring *)node.sysctl_data;
+	struct eqos_softc *sc = rxq->sc;
+	uint32_t reg, index;
+
+	reg = RD4(sc, GMAC_DMA_CHAN0_RX_END_ADDR);
+	if (reg == 0)
+		index = 0;
+	else {
+		index = (reg - (uint32_t)sc->sc_rx.desc_ring_paddr) /
+		    sizeof(struct eqos_dma_desc);
+	}
+	node.sysctl_data = &index;
+	return sysctl_lookup(SYSCTLFN_CALL(&node));
+}
+
+#ifdef EQOS_DEBUG
+static int
+eqos_sysctl_debug_handler(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct eqos_softc *sc = (struct eqos_softc *)node.sysctl_data;
+	uint32_t dflags;
+	int error;
+
+	dflags = sc->sc_debug;
+	node.sysctl_data = &dflags;
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+
+	if (error || newp == NULL)
+		return error;
+
+	sc->sc_debug = dflags;
+#if 0
+	/* Addd debug code here if you want. */
+#endif
+
+	return 0;
+}
+#endif

Index: src/sys/dev/ic/dwc_eqos_var.h
diff -u src/sys/dev/ic/dwc_eqos_var.h:1.4 src/sys/dev/ic/dwc_eqos_var.h:1.5
--- src/sys/dev/ic/dwc_eqos_var.h:1.4	Wed Aug 24 19:22:37 2022
+++ src/sys/dev/ic/dwc_eqos_var.h	Mon Oct 23 15:29:38 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: dwc_eqos_var.h,v 1.4 2022/08/24 19:22:37 ryo Exp $ */
+/* $NetBSD: dwc_eqos_var.h,v 1.5 2023/10/23 15:29:38 msaitoh Exp $ */
 
 /*-
  * Copyright (c) 2022 Jared McNeill <jmcne...@invisible.ca>
@@ -43,6 +43,7 @@ struct eqos_bufmap {
 };
 
 struct eqos_ring {
+	struct eqos_softc	*sc;
 	bus_dmamap_t		desc_map;
 	bus_dma_segment_t	desc_dmaseg;
 	struct eqos_dma_desc	*desc_ring;
@@ -77,6 +78,8 @@ struct eqos_softc {
 	struct mbuf		*sc_rx_receiving_m_last;
 
 	krndsource_t		sc_rndsource;
+	struct sysctllog	*sc_sysctllog;
+	uint32_t		sc_debug;
 
 	/* Indents indicate groups within evcnt. */
 	struct evcnt		sc_ev_intr;

Reply via email to