- 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:
Marius Strobl 2006-12-06 02:04:25 +00:00
parent b1d161435e
commit 8cb37876d6
2 changed files with 25 additions and 22 deletions

View File

@ -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);
}
/*

View File

@ -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 */