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
This commit is contained in:
Olivier Cochard committed 2026-10-13 18:31:50 +02:00
1 parent 8fdf03cd36
commit 686323c182
1 file changed
+87
+87
View File
@@ -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),