Skip site navigation (1)Skip section navigation (2)
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>