svn commit: r223238 - stable/8/sys/dev/iwn
Bernhard Schmidt
bschmidt at FreeBSD.org
Sat Jun 18 11:33:56 UTC 2011
Author: bschmidt
Date: Sat Jun 18 11:33:55 2011
New Revision: 223238
URL: http://svn.freebsd.org/changeset/base/223238
Log:
MFC r220667+220668:
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:
stable/8/sys/dev/iwn/if_iwn.c
stable/8/sys/dev/iwn/if_iwnvar.h
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
Modified: stable/8/sys/dev/iwn/if_iwn.c
==============================================================================
--- stable/8/sys/dev/iwn/if_iwn.c Sat Jun 18 11:31:19 2011 (r223237)
+++ stable/8/sys/dev/iwn/if_iwn.c Sat Jun 18 11:33:55 2011 (r223238)
@@ -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) {
+ if (--sc->sc_tx_timer == 0) {
+ 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: stable/8/sys/dev/iwn/if_iwnvar.h
==============================================================================
--- stable/8/sys/dev/iwn/if_iwnvar.h Sat Jun 18 11:31:19 2011 (r223237)
+++ stable/8/sys/dev/iwn/if_iwnvar.h Sat Jun 18 11:33:55 2011 (r223238)
@@ -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;
More information about the svn-src-all
mailing list