- Use the gem_tick() callout instead of if_slowtimo() for driving
gem_watchdog() in order to avoid races accessing if_timer. While at it relax the watchdog a bit by reloading it in gem_tint() if there are still packets enqueued. - Don't bother to set if_mtu to ETHERMTU, ether_ifattach() does that. - Fix inconsistencies in prototypes.
This commit is contained in:
parent
b1d161435e
commit
8cb37876d6
@ -83,16 +83,16 @@ static void gem_cddma_callback(void *, bus_dma_segment_t *, int, int);
|
||||
static void gem_txdma_callback(void *, bus_dma_segment_t *, int,
|
||||
bus_size_t, int);
|
||||
static void gem_tick(void *);
|
||||
static void gem_watchdog(struct ifnet *);
|
||||
static int gem_watchdog(struct gem_softc *);
|
||||
static void gem_init(void *);
|
||||
static void gem_init_locked(struct gem_softc *sc);
|
||||
static void gem_init_regs(struct gem_softc *sc);
|
||||
static void gem_init_locked(struct gem_softc *);
|
||||
static void gem_init_regs(struct gem_softc *);
|
||||
static int gem_ringsize(int sz);
|
||||
static int gem_meminit(struct gem_softc *);
|
||||
static int gem_load_txmbuf(struct gem_softc *, struct mbuf *);
|
||||
static void gem_mifinit(struct gem_softc *);
|
||||
static int gem_bitwait(struct gem_softc *sc, bus_addr_t r,
|
||||
u_int32_t clr, u_int32_t set);
|
||||
static int gem_bitwait(struct gem_softc *, bus_addr_t, u_int32_t,
|
||||
u_int32_t);
|
||||
static int gem_reset_rx(struct gem_softc *);
|
||||
static int gem_reset_tx(struct gem_softc *);
|
||||
static int gem_disable_rx(struct gem_softc *);
|
||||
@ -268,11 +268,9 @@ gem_attach(sc)
|
||||
ifp->if_softc = sc;
|
||||
if_initname(ifp, device_get_name(sc->sc_dev),
|
||||
device_get_unit(sc->sc_dev));
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||
ifp->if_start = gem_start;
|
||||
ifp->if_ioctl = gem_ioctl;
|
||||
ifp->if_watchdog = gem_watchdog;
|
||||
ifp->if_init = gem_init;
|
||||
ifp->if_snd.ifq_maxlen = GEM_TXQUEUELEN;
|
||||
/*
|
||||
@ -544,6 +542,9 @@ gem_tick(arg)
|
||||
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
||||
mii_tick(sc->sc_mii);
|
||||
|
||||
if (gem_watchdog(sc) == EJUSTRETURN)
|
||||
return;
|
||||
|
||||
callout_reset(&sc->sc_tick_ch, hz, gem_tick, sc);
|
||||
}
|
||||
|
||||
@ -657,7 +658,7 @@ gem_stop(ifp, disable)
|
||||
* Mark the interface down and cancel the watchdog timer.
|
||||
*/
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
||||
ifp->if_timer = 0;
|
||||
sc->sc_wdog_timer = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -982,11 +983,11 @@ gem_init_locked(sc)
|
||||
bus_space_write_4(t, h, GEM_RX_KICK, GEM_NRXDESC-4);
|
||||
|
||||
/* Start the one second timer. */
|
||||
sc->sc_wdog_timer = 0;
|
||||
callout_reset(&sc->sc_tick_ch, hz, gem_tick, sc);
|
||||
|
||||
ifp->if_drv_flags |= IFF_DRV_RUNNING;
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
ifp->if_timer = 0;
|
||||
sc->sc_ifflags = ifp->if_flags;
|
||||
}
|
||||
|
||||
@ -1223,10 +1224,10 @@ gem_start_locked(ifp)
|
||||
#endif
|
||||
|
||||
/* Set a watchdog timer in case the chip flakes out. */
|
||||
ifp->if_timer = 5;
|
||||
sc->sc_wdog_timer = 5;
|
||||
#ifdef GEM_DEBUG
|
||||
CTR2(KTR_GEM, "%s: gem_start: watchdog %d",
|
||||
device_get_name(sc->sc_dev), ifp->if_timer);
|
||||
device_get_name(sc->sc_dev), sc->sc_wdog_timer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -1355,13 +1356,12 @@ gem_tint(sc)
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
gem_start_locked(ifp);
|
||||
|
||||
if (STAILQ_EMPTY(&sc->sc_txdirtyq))
|
||||
ifp->if_timer = 0;
|
||||
sc->sc_wdog_timer = STAILQ_EMPTY(&sc->sc_txdirtyq) ? 0 : 5;
|
||||
}
|
||||
|
||||
#ifdef GEM_DEBUG
|
||||
CTR2(KTR_GEM, "%s: gem_tint: watchdog %d",
|
||||
device_get_name(sc->sc_dev), ifp->if_timer);
|
||||
device_get_name(sc->sc_dev), sc->sc_wdog_timer);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1616,14 +1616,13 @@ gem_intr(v)
|
||||
GEM_UNLOCK(sc);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gem_watchdog(ifp)
|
||||
struct ifnet *ifp;
|
||||
static int
|
||||
gem_watchdog(sc)
|
||||
struct gem_softc *sc;
|
||||
{
|
||||
struct gem_softc *sc = ifp->if_softc;
|
||||
|
||||
GEM_LOCK(sc);
|
||||
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
||||
|
||||
#ifdef GEM_DEBUG
|
||||
CTR3(KTR_GEM, "gem_watchdog: GEM_RX_CONFIG %x GEM_MAC_RX_STATUS %x "
|
||||
"GEM_MAC_RX_CONFIG %x",
|
||||
@ -1637,12 +1636,15 @@ gem_watchdog(ifp)
|
||||
bus_space_read_4(sc->sc_bustag, sc->sc_h, GEM_MAC_TX_CONFIG));
|
||||
#endif
|
||||
|
||||
if (sc->sc_wdog_timer == 0 || --sc->sc_wdog_timer != 0)
|
||||
return (0);
|
||||
|
||||
device_printf(sc->sc_dev, "device timeout\n");
|
||||
++ifp->if_oerrors;
|
||||
++sc->sc_ifp->if_oerrors;
|
||||
|
||||
/* Try to get more packets going. */
|
||||
gem_init_locked(sc);
|
||||
GEM_UNLOCK(sc);
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -130,6 +130,7 @@ struct gem_softc {
|
||||
u_char sc_enaddr[6];
|
||||
struct callout sc_tick_ch; /* tick callout */
|
||||
struct callout sc_rx_ch; /* delayed rx callout */
|
||||
int sc_wdog_timer; /* watchdog timer */
|
||||
|
||||
/* The following bus handles are to be provided by the bus front-end */
|
||||
bus_space_tag_t sc_bustag; /* bus tag */
|
||||
|
Loading…
x
Reference in New Issue
Block a user