Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 2 Mar 2008 23:53:01 GMT
From:      Andrew Thompson <thompsa@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 136704 for review
Message-ID:  <200803022353.m22Nr1HY047927@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=136704

Change 136704 by thompsa@thompsa_heff on 2008/03/02 23:52:22

	MF //depot/user/benjsc/wpi/sys/dev/wpi/if_wpi.c@134347
	
	Poll the HW switch.

Affected files ...

.. //depot/projects/wifi/sys/dev/wpi/if_wpi.c#13 edit
.. //depot/projects/wifi/sys/dev/wpi/if_wpivar.h#4 edit

Differences ...

==== //depot/projects/wifi/sys/dev/wpi/if_wpi.c#13 (text+ko) ====

@@ -129,6 +129,7 @@
 	WPI_DEBUG_TEMP		= 0x00000200,   /* TXPower/Temp Calibration */
 	WPI_DEBUG_OPS		= 0x00000400,   /* wpi_ops taskq debug */
 	WPI_DEBUG_WATCHDOG	= 0x00000800,   /* Watch dog debug */
+	WPI_DEBUG_HWSWITCH	= 0x00001000,   /* Watch hwswitch callout */
 	WPI_DEBUG_ANY		= 0xffffffff
 };
 
@@ -201,10 +202,6 @@
 static uint8_t	wpi_plcp_signal(int);
 static int	wpi_queue_cmd(struct wpi_softc *, int);
 static void	wpi_tick(void *);
-#if 0
-static void	wpi_radio_on(void *, int);
-static void	wpi_radio_off(void *, int);
-#endif
 static int	wpi_tx_data(struct wpi_softc *, struct mbuf *,
 		    struct ieee80211_node *, int);
 static void	wpi_start(struct ifnet *);
@@ -246,6 +243,7 @@
 static void	wpi_power_calibration(struct wpi_softc *, int);
 static int	wpi_get_power_index(struct wpi_softc *,
 		    struct wpi_power_group *, struct ieee80211_channel *, int);
+static void	wpi_radio(void *);
 static const char *wpi_cmd_str(int);
 static int wpi_probe(device_t);
 static int wpi_attach(device_t);
@@ -539,16 +537,13 @@
 #endif
 
 	/* Create the tasks that can be queued */
-#if 0
-	TASK_INIT(&sc->sc_radioontask, 0, wpi_radio_on, sc);
-	TASK_INIT(&sc->sc_radioofftask, 0, wpi_radio_off, sc);
-#endif
 	TASK_INIT(&sc->sc_opstask, 0, wpi_ops, sc);
 	TASK_INIT(&sc->sc_restarttask, 0, wpi_restart, sc);
 
 	WPI_LOCK_INIT(sc);
 	WPI_CMD_LOCK_INIT(sc);
 
+	callout_init_mtx(&sc->hwswitch_to, &sc->sc_mtx, 0);
 	callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0);
 	callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0);
 
@@ -778,6 +773,7 @@
 		wpi_stop(sc);
 		callout_drain(&sc->watchdog_to);
 		callout_drain(&sc->calib_to);
+		callout_drain(&sc->hwswitch_to);
 		bpfdetach(ifp);
 		ieee80211_ifdetach(ic);
 	}
@@ -1851,6 +1847,7 @@
 				device_printf(sc->sc_dev,
 				    "Radio transmitter is switched off\n");
 				sc->flags |= WPI_FLAG_HW_RADIO_OFF;
+				/* XXX Do something? */
 				break;
 			}
 			sc->flags &= ~WPI_FLAG_HW_RADIO_OFF;
@@ -3183,7 +3180,7 @@
 	/* At this point the firmware is up and running. If the hardware
 	 * RF switch is turned off thermal calibration will fail, though
 	 * the card is still happy to continue to accept commands, catch
-	 * this case and record the hw is disabled.
+	 * this case and schedule a task to watch for it to be turned on.
 	 */
 	wpi_mem_lock(sc);
 	tmp = wpi_mem_read(sc, WPI_MEM_HW_RADIO_OFF);
@@ -3194,6 +3191,7 @@
 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 		ifp->if_drv_flags |= IFF_DRV_RUNNING;
 		device_printf(sc->sc_dev,"Radio Transmitter is switched off\n");
+		callout_reset(&sc->hwswitch_to, hz, wpi_tick, sc);
 		goto fail;
 	}
 
@@ -3601,23 +3599,41 @@
 #undef fdivround
 }
 
-#if 0
+/**
+ * Called from a callout, wpi_radio checks the state of hw switch and
+ * if it's enabled restarts the device. The hardware doesn't give us an
+ * interupt when the hw switch is toggled on, only off hence we poll
+ * the device checking. Calling callout locks mtx;
+ */
 static void
-wpi_radio_on(void *arg, int pending)
+wpi_radio(void *arg)
 {
 	struct wpi_softc *sc = arg;
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	int tmp;
 
-	device_printf(sc->sc_dev, "radio turned on\n");
-}
+	wpi_mem_lock(sc);
+	tmp = wpi_mem_read(sc, WPI_MEM_HW_RADIO_OFF);
+	wpi_mem_unlock(sc);
+
+	DPRINTFN(WPI_DEBUG_HWSWITCH,
+		 ("wpi_radio callout: radio %d\n",tmp&0x1));
 
-static void
-wpi_radio_off(void *arg, int pending)
-{
-	struct wpi_softc *sc = arg;
+	if (tmp & 0x1) {
+		// Radio enabled
+		device_printf(sc->sc_dev, "Hardware Switch Enabled\n");
+		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+		ifp->if_drv_flags |= IFF_DRV_RUNNING;
 
-	device_printf(sc->sc_dev, "radio turned off\n");
+		callout_reset(&sc->watchdog_to, hz, wpi_tick, sc);
+		if (ic->ic_opmode == IEEE80211_M_MONITOR)
+			ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+		else if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
+			ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+	} else
+		callout_reset(&sc->hwswitch_to, hz, wpi_radio, sc);
 }
-#endif
 
 /**
  * Called by net80211 framework to indicate that a scan

==== //depot/projects/wifi/sys/dev/wpi/if_wpivar.h#4 (text+ko) ====

@@ -142,6 +142,9 @@
 
 	struct callout		amrr_ch;
 
+	/* Hardware switch polling timer */
+	struct callout		hwswitch_to;
+
 	struct resource		*irq;
 	struct resource		*mem;
 	bus_space_tag_t		sc_st;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803022353.m22Nr1HY047927>