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;