diff options
author | Andriy Voskoboinyk <avos@FreeBSD.org> | 2016-05-26 11:12:36 +0000 |
---|---|---|
committer | Andriy Voskoboinyk <avos@FreeBSD.org> | 2016-05-26 11:12:36 +0000 |
commit | 1447d404e0fd2f05e08af5f7de66e9ef2d381656 (patch) | |
tree | e075ff1027e81a32adc29c2bd2a8239e20773e19 /sys/dev/iwn/if_iwn.c | |
parent | fc271df3416a5162043a33b8533951a5f08120ea (diff) |
iwn: add watchdog for scanning.
Restart device if scanning was not done in time.
Tested by: david@catwhisker.org
PR: 209198
Differential Revision: https://reviews.freebsd.org/D6176
Notes
Notes:
svn path=/head/; revision=300732
Diffstat (limited to 'sys/dev/iwn/if_iwn.c')
-rw-r--r-- | sys/dev/iwn/if_iwn.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index 9545fe39dbf8..7372e60f27d4 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -235,6 +235,7 @@ static void iwn_xmit_task(void *arg0, int pending); static int iwn_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static int iwn_transmit(struct ieee80211com *, struct mbuf *); +static void iwn_scan_timeout(void *); static void iwn_watchdog(void *); static int iwn_ioctl(struct ieee80211com *, u_long , void *); static void iwn_parent(struct ieee80211com *); @@ -675,6 +676,7 @@ iwn_attach(device_t dev) iwn_radiotap_attach(sc); callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0); + callout_init_mtx(&sc->scan_timeout, &sc->sc_mtx, 0); callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0); TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc); TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc); @@ -1406,6 +1408,7 @@ iwn_detach(device_t dev) taskqueue_free(sc->sc_tq); callout_drain(&sc->watchdog_to); + callout_drain(&sc->scan_timeout); callout_drain(&sc->calib_to); ieee80211_ifdetach(&sc->sc_ic); } @@ -3937,6 +3940,7 @@ iwn_notif_intr(struct iwn_softc *sc) scan->nchan, scan->status, scan->chan); #endif sc->sc_is_scanning = 0; + callout_stop(&sc->scan_timeout); IWN_UNLOCK(sc); ieee80211_scan_next(vap); IWN_LOCK(sc); @@ -4955,6 +4959,16 @@ iwn_transmit(struct ieee80211com *ic, struct mbuf *m) } static void +iwn_scan_timeout(void *arg) +{ + struct iwn_softc *sc = arg; + struct ieee80211com *ic = &sc->sc_ic; + + ic_printf(ic, "scan timeout\n"); + ieee80211_restart_all(ic); +} + +static void iwn_watchdog(void *arg) { struct iwn_softc *sc = arg; @@ -6972,6 +6986,8 @@ iwn_scan(struct iwn_softc *sc, struct ieee80211vap *vap, hdr->nchan); error = iwn_cmd(sc, IWN_CMD_SCAN, buf, buflen, 1); free(buf, M_DEVBUF); + if (error == 0) + callout_reset(&sc->scan_timeout, 5*hz, iwn_scan_timeout, sc); DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__); |