From owner-p4-projects@FreeBSD.ORG Mon Apr 7 02:06:26 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8A3B8106567B; Mon, 7 Apr 2008 02:06:26 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 34005106566B for ; Mon, 7 Apr 2008 02:06:26 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 2D72C8FC16 for ; Mon, 7 Apr 2008 02:06:26 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m3726Q8u053514 for ; Mon, 7 Apr 2008 02:06:26 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m3726Qjv053512 for perforce@freebsd.org; Mon, 7 Apr 2008 02:06:26 GMT (envelope-from sam@freebsd.org) Date: Mon, 7 Apr 2008 02:06:26 GMT Message-Id: <200804070206.m3726Qjv053512@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 139489 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Apr 2008 02:06:26 -0000 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 */