Index: head/sys/dev/re/if_re.c =================================================================== --- head/sys/dev/re/if_re.c +++ head/sys/dev/re/if_re.c @@ -139,6 +139,8 @@ #include +#include + #include #include #include @@ -279,6 +281,7 @@ 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_clrwol (struct rl_softc *); static void re_set_linkspeed (struct rl_softc *); +NETDUMP_DEFINE(re); + #ifdef DEV_NETMAP /* see ixgbe.c for details */ #include MODULE_DEPEND(re, netmap, 1, 1, 1); @@ -1737,8 +1742,11 @@ 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 @@ 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 @@ 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 */