Add netdump support to re(4).

Tested with a RealTek 8101E adapter.

Reviewed by:	sbruno
MFC after:	1 month
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D15260
This commit is contained in:
Mark Johnston 2018-05-06 00:52:17 +00:00
parent eb07d67ef3
commit 306c97e2d8

View File

@ -139,6 +139,8 @@ __FBSDID("$FreeBSD$");
#include <net/bpf.h>
#include <netinet/netdump/netdump.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
@ -279,6 +281,7 @@ static void re_tick (void *);
static void re_int_task (void *, int);
static void re_start (struct ifnet *);
static void re_start_locked (struct ifnet *);
static void re_start_tx (struct rl_softc *);
static int re_ioctl (struct ifnet *, u_long, caddr_t);
static void re_init (void *);
static void re_init_locked (struct rl_softc *);
@ -307,6 +310,8 @@ static void re_setwol (struct rl_softc *);
static void re_clrwol (struct rl_softc *);
static void re_set_linkspeed (struct rl_softc *);
NETDUMP_DEFINE(re);
#ifdef DEV_NETMAP /* see ixgbe.c for details */
#include <dev/netmap/if_re_netmap.h>
MODULE_DEPEND(re, netmap, 1, 1, 1);
@ -1737,8 +1742,11 @@ re_attach(device_t dev)
if (error) {
device_printf(dev, "couldn't set up irq\n");
ether_ifdetach(ifp);
goto fail;
}
NETDUMP_SET(ifp, re);
fail:
if (error)
re_detach(dev);
@ -2981,8 +2989,14 @@ re_start_locked(struct ifnet *ifp)
return;
}
/* Flush the TX descriptors */
re_start_tx(sc);
}
static void
re_start_tx(struct rl_softc *sc)
{
/* Flush the TX descriptors */
bus_dmamap_sync(sc->rl_ldata.rl_tx_list_tag,
sc->rl_ldata.rl_tx_list_map,
BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
@ -4078,3 +4092,59 @@ sysctl_hw_re_int_mod(SYSCTL_HANDLER_ARGS)
return (sysctl_int_range(oidp, arg1, arg2, req, RL_TIMER_MIN,
RL_TIMER_MAX));
}
#ifdef NETDUMP
static void
re_netdump_init(struct ifnet *ifp, int *nrxr, int *ncl, int *clsize)
{
struct rl_softc *sc;
sc = if_getsoftc(ifp);
RL_LOCK(sc);
*nrxr = sc->rl_ldata.rl_rx_desc_cnt;
*ncl = NETDUMP_MAX_IN_FLIGHT;
*clsize = (ifp->if_mtu > RL_MTU &&
(sc->rl_flags & RL_FLAG_JUMBOV2) != 0) ? MJUM9BYTES : MCLBYTES;
RL_UNLOCK(sc);
}
static void
re_netdump_event(struct ifnet *ifp __unused, enum netdump_ev event __unused)
{
}
static int
re_netdump_transmit(struct ifnet *ifp, struct mbuf *m)
{
struct rl_softc *sc;
int error;
sc = if_getsoftc(ifp);
if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
IFF_DRV_RUNNING || (sc->rl_flags & RL_FLAG_LINK) == 0)
return (EBUSY);
error = re_encap(sc, &m);
if (error == 0)
re_start_tx(sc);
return (error);
}
static int
re_netdump_poll(struct ifnet *ifp, int count)
{
struct rl_softc *sc;
int error;
sc = if_getsoftc(ifp);
if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0 ||
(sc->rl_flags & RL_FLAG_LINK) == 0)
return (EBUSY);
re_txeof(sc);
error = re_rxeof(sc, NULL);
if (error != 0 && error != EAGAIN)
return (error);
return (0);
}
#endif /* NETDUMP */