git: 686323c1820c - main - if_rge: add debugnet/netdump support
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 13 Oct 2026 16:35:02 UTC
The branch main has been updated by olivier:
URL: https://cgit.FreeBSD.org/src/commit/?id=686323c1820cc4b2ef5434c0b6fa0ac38466fe5e
commit 686323c1820cc4b2ef5434c0b6fa0ac38466fe5e
Author: Olivier Cochard <olivier@FreeBSD.org>
AuthorDate: 2026-10-13 16:22:19 +0000
Commit: Olivier Cochard <olivier@FreeBSD.org>
CommitDate: 2026-10-13 16:31:50 +0000
if_rge: add debugnet/netdump support
Implement the debugnet KPI in rge(4) by mirroring the re(4) pattern.
Tested with a RTL8125 2.5GbE NIC.
Approved by: adrian
Differential Revision: https://reviews.freebsd.org/D60135
---
sys/dev/rge/if_rge.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/sys/dev/rge/if_rge.c b/sys/dev/rge/if_rge.c
index 89287450a01d..12b25c855b59 100644
--- a/sys/dev/rge/if_rge.c
+++ b/sys/dev/rge/if_rge.c
@@ -49,6 +49,7 @@
#include <net/if_media.h>
#include <net/if_types.h>
#include <net/if_vlan_var.h>
+#include <net/debugnet.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -105,6 +106,10 @@ static void rge_tick(void *);
static void rge_link_state(struct rge_softc *);
static void rge_setwol(struct rge_softc *);
+#ifdef DEBUGNET
+DEBUGNET_DEFINE(rge);
+#endif
+
struct rge_matchid {
uint16_t vendor;
uint16_t device;
@@ -180,6 +185,10 @@ rge_attach_if(struct rge_softc *sc, const char *eaddr)
/* TODO: is this needed for iftransmit? */
if_setsendqlen(sc->sc_ifp, RGE_TX_LIST_CNT - 1);
if_setsendqready(sc->sc_ifp);
+
+#ifdef DEBUGNET
+ DEBUGNET_SET(sc->sc_ifp, rge);
+#endif
}
static int
@@ -2674,6 +2683,84 @@ rge_shutdown(device_t dev)
return (0);
}
+#ifdef DEBUGNET
+static void
+rge_debugnet_init(if_t ifp, int *nrxr, int *ncl, int *clsize)
+{
+ struct rge_softc *sc;
+
+ sc = if_getsoftc(ifp);
+ RGE_LOCK(sc);
+ *nrxr = RGE_RX_LIST_CNT;
+ *ncl = DEBUGNET_MAX_IN_FLIGHT;
+ *clsize = MCLBYTES;
+ RGE_UNLOCK(sc);
+}
+
+static void
+rge_debugnet_event(if_t ifp __unused, enum debugnet_ev event __unused)
+{
+}
+
+static int
+rge_debugnet_transmit(if_t ifp, struct mbuf *m)
+{
+ struct rge_softc *sc;
+ struct rge_queues *q;
+ int idx, free, used;
+
+ sc = if_getsoftc(ifp);
+ if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0 ||
+ sc->sc_stopped)
+ return (EBUSY);
+
+ q = sc->sc_queues;
+ idx = q->q_tx.rge_txq_prodidx;
+ free = q->q_tx.rge_txq_considx;
+ if (free <= idx)
+ free += RGE_TX_LIST_CNT;
+ free -= idx;
+ if (free < RGE_TX_NSEGS + 2)
+ return (ENOBUFS);
+
+ used = rge_encap(sc, q, &m, idx);
+ if (used <= 0) {
+ m_freem(m);
+ return (ENOBUFS);
+ }
+
+ idx += used;
+ if (idx >= RGE_TX_LIST_CNT)
+ idx -= RGE_TX_LIST_CNT;
+ q->q_tx.rge_txq_prodidx = idx;
+
+ RGE_WRITE_2(sc, RGE_TXSTART, RGE_TXSTART_START);
+ return (0);
+}
+
+static int
+rge_debugnet_poll(if_t ifp, int count __unused)
+{
+ struct rge_softc *sc;
+ struct rge_queues *q;
+ struct mbufq rx_mq;
+ struct mbuf *m;
+
+ sc = if_getsoftc(ifp);
+ if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0 ||
+ sc->sc_stopped)
+ return (EBUSY);
+
+ q = sc->sc_queues;
+ rge_txeof(q);
+ mbufq_init(&rx_mq, RGE_RX_LIST_CNT);
+ (void)rge_rxeof(q, &rx_mq);
+ while ((m = mbufq_dequeue(&rx_mq)) != NULL)
+ if_input(ifp, m);
+ return (0);
+}
+#endif /* DEBUGNET */
+
static device_method_t rge_methods[] = {
DEVMETHOD(device_probe, rge_probe),
DEVMETHOD(device_attach, rge_attach),