Date: Fri, 15 Apr 2011 20:17:52 +0000 (UTC) From: Bernhard Schmidt <bschmidt@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r220667 - head/sys/dev/iwn Message-ID: <201104152017.p3FKHqgh080624@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bschmidt Date: Fri Apr 15 20:17:52 2011 New Revision: 220667 URL: http://svn.freebsd.org/changeset/base/220667 Log: Split up watchdog and calibration callout. This allows us to use different timing on both and to remove some monitor mode specific hacks (which has no calibration). Modified: head/sys/dev/iwn/if_iwn.c head/sys/dev/iwn/if_iwnvar.h Modified: head/sys/dev/iwn/if_iwn.c ============================================================================== --- head/sys/dev/iwn/if_iwn.c Fri Apr 15 19:50:38 2011 (r220666) +++ head/sys/dev/iwn/if_iwn.c Fri Apr 15 20:17:52 2011 (r220667) @@ -123,10 +123,9 @@ static struct ieee80211_node *iwn_node_a const uint8_t mac[IEEE80211_ADDR_LEN]); static int iwn_media_change(struct ifnet *); static int iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); +static void iwn_calib_timeout(void *); static void iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *, struct iwn_rx_data *); -static void iwn_timer_timeout(void *); -static void iwn_calib_reset(struct iwn_softc *); static void iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *, struct iwn_rx_data *); #if 0 /* HT */ @@ -161,7 +160,7 @@ static int iwn_raw_xmit(struct ieee80211 const struct ieee80211_bpf_params *); static void iwn_start(struct ifnet *); static void iwn_start_locked(struct ifnet *); -static void iwn_watchdog(struct iwn_softc *sc); +static void iwn_watchdog(void *); static int iwn_ioctl(struct ifnet *, u_long, caddr_t); static int iwn_cmd(struct iwn_softc *, int, const void *, int, int); static int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *, @@ -475,7 +474,6 @@ iwn_attach(device_t dev) } IWN_LOCK_INIT(sc); - callout_init_mtx(&sc->sc_timer_to, &sc->sc_mtx, 0); TASK_INIT(&sc->sc_reinit_task, 0, iwn_hw_reset, sc ); TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc ); TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc ); @@ -668,6 +666,10 @@ iwn_attach(device_t dev) #endif iwn_radiotap_attach(sc); + + callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0); + callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0); + iwn_sysctlattach(sc); /* @@ -860,7 +862,8 @@ iwn_detach(device_t dev) ieee80211_draintask(ic, &sc->sc_radiooff_task); iwn_stop(sc); - callout_drain(&sc->sc_timer_to); + callout_drain(&sc->watchdog_to); + callout_drain(&sc->calib_to); ieee80211_ifdetach(ic); } @@ -1942,7 +1945,7 @@ iwn_newstate(struct ieee80211vap *vap, e IEEE80211_UNLOCK(ic); IWN_LOCK(sc); - callout_stop(&sc->sc_timer_to); + callout_stop(&sc->calib_to); switch (nstate) { case IEEE80211_S_ASSOC: @@ -1959,7 +1962,8 @@ iwn_newstate(struct ieee80211vap *vap, e */ sc->rxon.associd = 0; sc->rxon.filter &= ~htole32(IWN_FILTER_BSS); - iwn_calib_reset(sc); + sc->calib.state = IWN_CALIB_STATE_INIT; + error = iwn_auth(sc, vap); break; @@ -1967,9 +1971,8 @@ iwn_newstate(struct ieee80211vap *vap, e /* * RUN -> RUN transition; Just restart the timers. */ - if (vap->iv_state == IEEE80211_S_RUN && - vap->iv_opmode != IEEE80211_M_MONITOR) { - iwn_calib_reset(sc); + if (vap->iv_state == IEEE80211_S_RUN) { + sc->calib_cnt = 0; break; } @@ -1981,6 +1984,10 @@ iwn_newstate(struct ieee80211vap *vap, e error = iwn_run(sc, vap); break; + case IEEE80211_S_INIT: + sc->calib.state = IWN_CALIB_STATE_INIT; + break; + default: break; } @@ -1989,6 +1996,27 @@ iwn_newstate(struct ieee80211vap *vap, e return ivp->iv_newstate(vap, nstate, arg); } +static void +iwn_calib_timeout(void *arg) +{ + struct iwn_softc *sc = arg; + + IWN_LOCK_ASSERT(sc); + + /* Force automatic TX power calibration every 60 secs. */ + if (++sc->calib_cnt >= 120) { + uint32_t flags = 0; + + DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n", + "sending request for statistics"); + (void)iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags, + sizeof flags, 1); + sc->calib_cnt = 0; + } + callout_reset(&sc->calib_to, msecs_to_ticks(500), iwn_calib_timeout, + sc); +} + /* * Process an RX_PHY firmware notification. This is usually immediately * followed by an MPDU_RX_DONE notification. @@ -2007,32 +2035,6 @@ iwn_rx_phy(struct iwn_softc *sc, struct sc->last_rx_valid = 1; } -static void -iwn_timer_timeout(void *arg) -{ - struct iwn_softc *sc = arg; - uint32_t flags = 0; - - IWN_LOCK_ASSERT(sc); - - if (sc->calib_cnt && --sc->calib_cnt == 0) { - DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n", - "send statistics request"); - (void) iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags, - sizeof flags, 1); - sc->calib_cnt = 60; /* do calibration every 60s */ - } - iwn_watchdog(sc); /* NB: piggyback tx watchdog */ - callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc); -} - -static void -iwn_calib_reset(struct iwn_softc *sc) -{ - callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc); - sc->calib_cnt = 60; /* do calibration every 60s */ -} - /* * Process an RX_DONE (4965AGN only) or MPDU_RX_DONE firmware notification. * Each MPDU_RX_DONE notification must be preceded by an RX_PHY one. @@ -2222,7 +2224,7 @@ iwn_rx_statistics(struct iwn_softc *sc, bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: cmd %d\n", __func__, desc->type); - iwn_calib_reset(sc); /* Reset TX power calibration timeout. */ + sc->calib_cnt = 0; /* Reset TX power calibration timeout. */ /* Test if temperature has changed. */ if (stats->general.temp != sc->rawtemp) { @@ -3306,6 +3308,8 @@ iwn_raw_xmit(struct ieee80211_node *ni, ieee80211_free_node(ni); ifp->if_oerrors++; } + sc->sc_tx_timer = 5; + IWN_UNLOCK(sc); return error; } @@ -3352,15 +3356,24 @@ iwn_start_locked(struct ifnet *ifp) } static void -iwn_watchdog(struct iwn_softc *sc) +iwn_watchdog(void *arg) { - if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct iwn_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + IWN_LOCK_ASSERT(sc); + + KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); - if_printf(ifp, "device timeout\n"); - ieee80211_runtask(ic, &sc->sc_reinit_task); + if (sc->sc_tx_timer > 0 || counter == 50) { + if (--sc->sc_tx_timer == 0 || counter == 50) { + if_printf(ifp, "device timeout\n"); + ieee80211_runtask(ic, &sc->sc_reinit_task); + return; + } } + callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc); } static int @@ -4760,8 +4773,6 @@ iwn_auth(struct iwn_softc *sc, struct ie struct ieee80211_node *ni = vap->iv_bss; int error; - sc->calib.state = IWN_CALIB_STATE_INIT; - /* Update adapter configuration. */ IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid); sc->rxon.chan = ieee80211_chan2ieee(ic, ni->ni_chan); @@ -4954,7 +4965,9 @@ iwn_run(struct iwn_softc *sc, struct iee /* Start periodic calibration timer. */ sc->calib.state = IWN_CALIB_STATE_ASSOC; - iwn_calib_reset(sc); + sc->calib_cnt = 0; + callout_reset(&sc->calib_to, msecs_to_ticks(500), iwn_calib_timeout, + sc); /* Link LED always on while associated. */ iwn_set_led(sc, IWN_LED_LINK, 0, 1); @@ -6406,6 +6419,7 @@ iwn_init_locked(struct iwn_softc *sc) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; + callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc); return; fail: @@ -6435,7 +6449,8 @@ iwn_stop_locked(struct iwn_softc *sc) IWN_LOCK_ASSERT(sc); sc->sc_tx_timer = 0; - callout_stop(&sc->sc_timer_to); + callout_stop(&sc->watchdog_to); + callout_stop(&sc->calib_to); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); /* Power OFF hardware. */ Modified: head/sys/dev/iwn/if_iwnvar.h ============================================================================== --- head/sys/dev/iwn/if_iwnvar.h Fri Apr 15 19:50:38 2011 (r220666) +++ head/sys/dev/iwn/if_iwnvar.h Fri Apr 15 20:17:52 2011 (r220667) @@ -260,8 +260,10 @@ struct iwn_softc { struct task sc_radioon_task; struct task sc_radiooff_task; + struct callout calib_to; int calib_cnt; struct iwn_calib_state calib; + struct callout watchdog_to; u_int calib_init; u_int calib_runtime; #define IWN_CALIB_XTAL (1 << IWN_CALIB_IDX_XTAL) @@ -312,7 +314,6 @@ struct iwn_softc { uint8_t rxchainmask; uint8_t chainmask; - struct callout sc_timer_to; int sc_tx_timer; struct iwn_rx_radiotap_header sc_rxtap;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104152017.p3FKHqgh080624>