Index: if_bce.c =================================================================== RCS file: /home/ncvs/src/sys/dev/bce/if_bce.c,v retrieving revision 1.2.2.6.2.1 diff -u -r1.2.2.6.2.1 if_bce.c --- if_bce.c 28 Nov 2006 17:14:07 -0000 1.2.2.6.2.1 +++ if_bce.c 25 Dec 2006 07:24:00 -0000 @@ -303,7 +303,7 @@ static void bce_start_locked (struct ifnet *); static void bce_start (struct ifnet *); static int bce_ioctl (struct ifnet *, u_long, caddr_t); -static void bce_watchdog (struct ifnet *); +static void bce_watchdog (struct bce_softc *); static int bce_ifmedia_upd (struct ifnet *); static void bce_ifmedia_sts (struct ifnet *, struct ifmediareq *); static void bce_init_locked (struct bce_softc *); @@ -716,8 +716,6 @@ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = bce_ioctl; ifp->if_start = bce_start; - ifp->if_timer = 0; - ifp->if_watchdog = bce_watchdog; ifp->if_init = bce_init; ifp->if_mtu = ETHERMTU; ifp->if_hwassist = BCE_IF_HWASSIST; @@ -3115,7 +3113,7 @@ } ifp->if_flags = itmp; - ifp->if_timer = 0; + sc->watchdog_timer = 0; sc->bce_link = 0; @@ -4289,7 +4287,7 @@ } /* Clear the TX timeout timer. */ - ifp->if_timer = 0; + sc->watchdog_timer = 0; /* Clear the tx hardware queue full flag. */ if ((sc->used_tx_bd + BCE_TX_SLACK_SPACE) < USABLE_TX_BD) { @@ -4757,7 +4755,7 @@ REG_WR(sc, MB_TX_CID_ADDR + BCE_L2CTX_TX_HOST_BSEQ, sc->tx_prod_bseq); /* Set the tx timeout. */ - ifp->if_timer = BCE_TX_TIMEOUT; + sc->watchdog_timer = BCE_TX_TIMEOUT; bce_start_locked_exit: return; @@ -4990,25 +4988,27 @@ /* Nothing. */ /****************************************************************************/ static void -bce_watchdog(struct ifnet *ifp) +bce_watchdog(struct bce_softc *sc) { - struct bce_softc *sc = ifp->if_softc; DBRUN(BCE_WARN_SEND, bce_dump_driver_state(sc); bce_dump_status_block(sc)); + BCE_LOCK_ASSERT(sc); + + if (sc->watchdog_timer == 0 || --sc->watchdog_timer) + return; + BCE_PRINTF(sc, "%s(%d): Watchdog timeout occurred, resetting!\n", __FILE__, __LINE__); /* DBRUN(BCE_FATAL, bce_breakpoint(sc)); */ - BCE_LOCK(sc); - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + sc->bce_ifp->if_drv_flags &= ~IFF_DRV_RUNNING; bce_init_locked(sc); - ifp->if_oerrors++; - BCE_UNLOCK(sc); + sc->bce_ifp->if_oerrors++; } @@ -5530,6 +5530,9 @@ /* Update the statistics from the hardware statistics block. */ bce_stats_update(sc); + /* Check that chip hasn't hang. */ + bce_watchdog(sc); + /* Schedule the next tick. */ callout_reset( &sc->bce_stat_ch, /* callout */ Index: if_bcereg.h =================================================================== RCS file: /home/ncvs/src/sys/dev/bce/if_bcereg.h,v retrieving revision 1.1.2.3.2.1 diff -u -r1.1.2.3.2.1 if_bcereg.h --- if_bcereg.h 28 Nov 2006 17:14:07 -0000 1.1.2.3.2.1 +++ if_bcereg.h 25 Dec 2006 08:48:48 -0000 @@ -4755,6 +4755,8 @@ int bce_link; struct callout bce_stat_ch; + int watchdog_timer; /* ticks until chip reset */ + /* Frame size and mbuf allocation size for RX frames. */ u32 max_frame_size; int mbuf_alloc_size;