Date: Mon, 7 Apr 2008 02:06:26 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 139489 for review Message-ID: <200804070206.m3726Qjv053512@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=139489 Change 139489 by sam@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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200804070206.m3726Qjv053512>