diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 993f9a2..b00d82e 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -161,7 +161,7 @@ static void ndis_scan_curchan (struct ieee80211_scan_state *, unsigned long); static void ndis_scan_mindwell (struct ieee80211_scan_state *); static void ndis_init (void *); static void ndis_stop (struct ndis_softc *); -static void ndis_watchdog (struct ifnet *); +static void ndis_watchdog (void *); static int ndis_ifmedia_upd (struct ifnet *); static void ndis_ifmedia_sts (struct ifnet *, struct ifmediareq *); static void ndis_auth (void *, int); @@ -690,12 +690,13 @@ ndis_attach(dev) /* Check for task offload support. */ ndis_probe_offload(sc); + sc->ndis_timer_countdown = 0; + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_mtu = ETHERMTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = ndis_ioctl; ifp->if_start = ndis_start; - ifp->if_watchdog = ndis_watchdog; ifp->if_init = ndis_init; ifp->if_baudrate = 10000000; IFQ_SET_MAXLEN(&ifp->if_snd, 50); @@ -994,10 +995,14 @@ ndis_detach(dev) driver_object *drv; sc = device_get_softc(dev); + NDIS_LOCK(sc); ifp = sc->ifp; ifp->if_flags &= ~IFF_UP; + /* Remove any pending callouts. */ + sc->ndis_timer_countdown = 0; + if (device_is_attached(dev)) { NDIS_UNLOCK(sc); ndis_stop(sc); @@ -1540,7 +1545,7 @@ ndis_txeof(adapter, packet, status) else ifp->if_oerrors++; - ifp->if_timer = 0; + sc->ndis_timer_countdown = 0; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; NDIS_UNLOCK(sc); @@ -1649,6 +1654,17 @@ ndis_tick(xsc) callout_reset(&sc->ndis_stat_callout, hz * sc->ndis_block->nmb_checkforhangsecs, ndis_tick, sc); + NDIS_LOCK(sc); + if(sc->ndis_timer_countdown && + (sc->ndis_timer_countdown -= + sc->ndis_block->nmb_checkforhangsecs) < 1) { + sc->ndis_timer_countdown = 0; + NDIS_UNLOCK(sc); + ndis_watchdog(xsc); + } else { + NDIS_UNLOCK(sc); + } + return; } @@ -1888,7 +1904,9 @@ ndis_start(ifp) /* * Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; + if(sc->ndis_timer_countdown == 0) { + sc->ndis_timer_countdown = 5; + } NDIS_UNLOCK(sc); @@ -1983,6 +2001,9 @@ ndis_init(xsc) ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + /* The timeout on the old if_watchdog interface. */ + sc->ndis_timer_countdown = 0; + NDIS_UNLOCK(sc); /* XXX force handling */ @@ -3113,15 +3134,12 @@ ndis_resettask(d, arg) } static void -ndis_watchdog(ifp) - struct ifnet *ifp; +ndis_watchdog (void *arg) { - struct ndis_softc *sc; - - sc = ifp->if_softc; + struct ndis_softc *sc = arg; NDIS_LOCK(sc); - ifp->if_oerrors++; + sc->ifp->if_oerrors++; device_printf(sc->ndis_dev, "watchdog timeout\n"); NDIS_UNLOCK(sc); @@ -3130,7 +3148,7 @@ ndis_watchdog(ifp) WORKQUEUE_CRITICAL, sc); IoQueueWorkItem(sc->ndis_startitem, (io_workitem_func)ndis_starttask_wrap, - WORKQUEUE_CRITICAL, ifp); + WORKQUEUE_CRITICAL, sc->ifp); return; } @@ -3150,7 +3168,7 @@ ndis_stop(sc) callout_drain(&sc->ndis_stat_callout); NDIS_LOCK(sc); - ifp->if_timer = 0; + sc->ndis_timer_countdown = 0; sc->ndis_link = 0; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); NDIS_UNLOCK(sc); diff --git a/sys/dev/if_ndis/if_ndisvar.h b/sys/dev/if_ndis/if_ndisvar.h index bf4f056..a2b58d1 100644 --- a/sys/dev/if_ndis/if_ndisvar.h +++ b/sys/dev/if_ndis/if_ndisvar.h @@ -181,6 +181,7 @@ struct ndis_softc { struct task ndis_assoctask; int (*ndis_newstate)(struct ieee80211com *, enum ieee80211_state, int); + int ndis_timer_countdown; }; #define NDIS_LOCK(_sc) KeAcquireSpinLock(&(_sc)->ndis_spinlock, \