PERFORCE change 139489 for review
Sam Leffler
sam at FreeBSD.org
Mon Apr 7 02:06:26 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=139489
Change 139489 by sam at sam_ebb on 2008/04/07 02:05:30
Split rfkill polling into it's own callout that's run only when
the rfkill switch is set to the off position; we have to unblock
the taskq to get this to work which is a bit worrisome
Note we don't always reset state properly on radio on because
ieee80211_start_all isn't able to clock the state machine when
the vaps are set in manual roaming mode (e.g. by wpa_supplicant).
We need to add events to mark radio on/off so user apps can
rebuild state.
Affected files ...
.. //depot/projects/vap/sys/dev/iwi/if_iwi.c#21 edit
.. //depot/projects/vap/sys/dev/iwi/if_iwivar.h#14 edit
Differences ...
==== //depot/projects/vap/sys/dev/iwi/if_iwi.c#21 (text+ko) ====
@@ -308,6 +308,7 @@
TASK_INIT(&sc->sc_opstask, 0, iwi_ops, sc);
TASK_INIT(&sc->sc_scanaborttask, 0, iwi_scanabort, sc);
callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0);
+ callout_init_mtx(&sc->sc_rftimer, &sc->sc_mtx, 0);
if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
device_printf(dev, "chip is in D%d power mode "
@@ -2022,19 +2023,6 @@
taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask);
}
}
- if (sc->sc_rfkill_timer > 0) {
- if (--sc->sc_rfkill_timer == 0) {
- /*
- * Check for a change in rfkill state. We get an
- * interrupt when a radio is disabled but not when
- * it is enabled so we must poll for the latter.
- */
- if (!iwi_getrfkill(sc))
- taskqueue_enqueue(sc->sc_tq, &sc->sc_radiontask);
- else
- sc->sc_rfkill_timer = 2;
- }
- }
if (sc->sc_state_timer > 0) {
if (--sc->sc_state_timer == 0) {
if_printf(ifp, "firmware stuck in state %d, resetting\n",
@@ -2053,9 +2041,7 @@
taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask);
}
}
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc);
+ callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc);
}
static int
@@ -2074,14 +2060,6 @@
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
iwi_stop(sc);
- else {
- /*
- * If device was stopped due to rfkill then
- * marked down we'll have the polling thread
- * running; stop it explicitly.
- */
- sc->sc_rfkill_timer = 0;
- }
}
break;
case SIOCGIFMEDIA:
@@ -3202,6 +3180,7 @@
sc->sc_blinking = 0;
}
callout_stop(&sc->sc_wdtimer);
+ callout_stop(&sc->sc_rftimer);
iwi_stop_master(sc);
@@ -3217,7 +3196,6 @@
memset(sc->sc_cmd, 0, sizeof(sc->sc_cmd));
sc->sc_tx_timer = 0;
- sc->sc_rfkill_timer = 0;
sc->sc_state_timer = 0;
sc->sc_busy_timer = 0;
sc->flags &= ~(IWI_FLAG_BUSY | IWI_FLAG_ASSOCIATED);
@@ -3266,6 +3244,26 @@
}
static void
+iwi_rfkill_poll(void *arg)
+{
+ struct iwi_softc *sc = arg;
+
+ IWI_LOCK_ASSERT(sc);
+
+ /*
+ * Check for a change in rfkill state. We get an
+ * interrupt when a radio is disabled but not when
+ * it is enabled so we must poll for the latter.
+ */
+ if (!iwi_getrfkill(sc)) {
+ taskqueue_unblock(sc->sc_tq);
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_radiontask);
+ return;
+ }
+ callout_reset(&sc->sc_rftimer, 2*hz, iwi_rfkill_poll, sc);
+}
+
+static void
iwi_radio_off(void *arg, int pending)
{
struct iwi_softc *sc = arg;
@@ -3275,7 +3273,7 @@
IWI_LOCK(sc);
iwi_stop_locked(sc);
- sc->sc_rfkill_timer = 2;
+ iwi_rfkill_poll(sc);
IWI_UNLOCK(sc);
}
==== //depot/projects/vap/sys/dev/iwi/if_iwivar.h#14 (text+ko) ====
@@ -213,9 +213,9 @@
u_int16_t sc_ledoff; /* off time for current blink */
struct callout sc_ledtimer; /* led off timer */
struct callout sc_wdtimer; /* watchdog timer */
+ struct callout sc_rftimer; /* rfkill timer */
int sc_tx_timer;
- int sc_rfkill_timer;/* poll for rfkill change */
int sc_state_timer; /* firmware state timer */
int sc_busy_timer; /* firmware cmd timer */
More information about the p4-projects
mailing list