PERFORCE change 140217 for review

Sam Leffler sam at FreeBSD.org
Fri Apr 18 18:17:36 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=140217

Change 140217 by sam at sam_ebb on 2008/04/18 18:16:56

	don't hold the softc lock over ieee80211_start_all and
	untangle some other locking; also make watchdog timer handling
	consistent

Affected files ...

.. //depot/projects/vap/sys/dev/ral/rt2560.c#27 edit
.. //depot/projects/vap/sys/dev/ral/rt2661.c#25 edit

Differences ...

==== //depot/projects/vap/sys/dev/ral/rt2560.c#27 (text) ====

@@ -158,7 +158,9 @@
 static int		rt2560_bbp_init(struct rt2560_softc *);
 static void		rt2560_set_txantenna(struct rt2560_softc *, int);
 static void		rt2560_set_rxantenna(struct rt2560_softc *, int);
+static void		rt2560_init_locked(struct rt2560_softc *);
 static void		rt2560_init(void *);
+static void		rt2560_stop_locked(struct rt2560_softc *);
 static int		rt2560_raw_xmit(struct ieee80211_node *, struct mbuf *,
 				const struct ieee80211_bpf_params *);
 
@@ -1978,20 +1980,22 @@
 	struct rt2560_softc *sc = arg;
 	struct ifnet *ifp = sc->sc_ifp;
 
-	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+	RAL_LOCK_ASSERT(sc);
+
+	KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
+
+	if (sc->sc_invalid)		/* card ejected */
 		return;
 
 	rt2560_encryption_intr(sc);
 	rt2560_tx_intr(sc);
 
-	if (sc->sc_tx_timer > 0) {
-		if (--sc->sc_tx_timer == 0) {
-			device_printf(sc->sc_dev, "device timeout\n");
-			rt2560_init(sc);
-			ifp->if_oerrors++;
-			/* watchdog timeout is set in rt2560_init() */
-			return;
-		}
+	if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
+		if_printf(ifp, "device timeout\n");
+		rt2560_init_locked(sc);
+		ifp->if_oerrors++;
+		/* NB: callout is reset in rt2560_init() */
+		return;
 	}
 	callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc);
 }
@@ -2002,21 +2006,25 @@
 	struct rt2560_softc *sc = ifp->if_softc;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ifreq *ifr = (struct ifreq *) data;
-	int error = 0;
+	int error = 0, startall;
 
 	switch (cmd) {
 	case SIOCSIFFLAGS:
+		RAL_LOCK(sc);
+		startall = 0;
 		if (ifp->if_flags & IFF_UP) {
-			RAL_LOCK(sc);
-			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+				rt2560_init_locked(sc);
+				startall = 1;
+			} else
 				rt2560_update_promisc(ifp);
-			else
-				rt2560_init(sc);
-			RAL_UNLOCK(sc);
 		} else {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-				rt2560_stop(sc);
+				rt2560_stop_locked(sc);
 		}
+		RAL_UNLOCK(sc);
+		if (startall)		/* NB: need to drop lock */
+			ieee80211_start_all(ic);
 		break;
 	case SIOCGIFMEDIA:
 	case SIOCSIFMEDIA:
@@ -2621,18 +2629,18 @@
 }
 
 static void
-rt2560_init(void *priv)
+rt2560_init_locked(struct rt2560_softc *sc)
 {
 #define N(a)	(sizeof (a) / sizeof ((a)[0]))
-	struct rt2560_softc *sc = priv;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	uint32_t tmp;
 	int i;
 
-	rt2560_stop(sc);
+	RAL_LOCK_ASSERT(sc);
+
+	rt2560_stop_locked(sc);
 
-	RAL_LOCK(sc);
 	/* setup tx rings */
 	tmp = RT2560_PRIO_RING_COUNT << 24 |
 	      RT2560_ATIM_RING_COUNT << 16 |
@@ -2706,27 +2714,36 @@
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 
 	callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc);
+#undef N
+}
 
+static void
+rt2560_init(void *priv)
+{
+	struct rt2560_softc *sc = priv;
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+
+	RAL_LOCK(sc);
+	rt2560_init_locked(sc);
 	RAL_UNLOCK(sc);
 
-	ieee80211_start_all(ic);		/* start all vap's */
-#undef N
+	ieee80211_start_all(ic);
 }
 
-void
-rt2560_stop(void *arg)
+static void
+rt2560_stop_locked(struct rt2560_softc *sc)
 {
-	struct rt2560_softc *sc = arg;
 	struct ifnet *ifp = sc->sc_ifp;
 	volatile int *flags = &sc->sc_flags;
 
-	while (*flags & RT2560_F_INPUT_RUNNING) {
-		tsleep(sc, 0, "ralrunning", hz/10);
-	}
+	RAL_LOCK_ASSERT(sc);
 
-	RAL_LOCK(sc);
+	while (*flags & RT2560_F_INPUT_RUNNING)
+		msleep(sc, &sc->sc_mtx, 0, "ralrunning", hz/10);
 
 	callout_stop(&sc->watchdog_ch);
+	sc->sc_tx_timer = 0;
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 		ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
@@ -2751,9 +2768,16 @@
 		rt2560_reset_tx_ring(sc, &sc->bcnq);
 		rt2560_reset_rx_ring(sc, &sc->rxq);
 	}
-	sc->sc_tx_timer = 0;
 	sc->sc_flags &= ~(RT2560_F_PRIO_OACTIVE | RT2560_F_DATA_OACTIVE);
+}
+
+void
+rt2560_stop(void *arg)
+{
+	struct rt2560_softc *sc = arg;
 
+	RAL_LOCK(sc);
+	rt2560_stop_locked(sc);
 	RAL_UNLOCK(sc);
 }
 

==== //depot/projects/vap/sys/dev/ral/rt2661.c#25 (text) ====

@@ -157,9 +157,10 @@
 static void		rt2661_read_eeprom(struct rt2661_softc *,
 			    struct ieee80211com *);
 static int		rt2661_bbp_init(struct rt2661_softc *);
+static void		rt2661_init_locked(struct rt2661_softc *);
 static void		rt2661_init(void *);
+static void             rt2661_stop_locked(struct rt2661_softc *);
 static void		rt2661_stop(void *);
-static void             rt2661_stop_locked(struct rt2661_softc *);
 static int		rt2661_load_microcode(struct rt2661_softc *);
 #ifdef notyet
 static void		rt2661_rx_tune(struct rt2661_softc *);
@@ -357,7 +358,6 @@
 	
 	RAL_LOCK(sc);
 	rt2661_stop_locked(sc);
-	callout_stop(&sc->watchdog_ch);
 	RAL_UNLOCK(sc);
 
 	bpfdetach(ifp);
@@ -1660,7 +1660,6 @@
 		}
 
 		sc->sc_tx_timer = 5;
-		callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
 	}
 }
 
@@ -1709,7 +1708,6 @@
 	if (rt2661_tx_mgt(sc, m, ni) != 0)
 		goto bad;
 	sc->sc_tx_timer = 5;
-	callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
 
 	RAL_UNLOCK(sc);
 
@@ -1725,16 +1723,23 @@
 rt2661_watchdog(void *arg)
 {
 	struct rt2661_softc *sc = (struct rt2661_softc *)arg;
+	struct ifnet *ifp = sc->sc_ifp;
+
+	RAL_LOCK_ASSERT(sc);
+
+	KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
 
-	if (sc->sc_tx_timer > 0 && !sc->sc_invalid) {
-		if (--sc->sc_tx_timer == 0) {
-			device_printf(sc->sc_dev, "device timeout\n");
-			rt2661_init(sc);
-			sc->sc_ifp->if_oerrors++;
-			return;
-		}
-		callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
+	if (sc->sc_invalid)		/* card ejected */
+		return;
+
+	if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
+		if_printf(ifp, "device timeout\n");
+		rt2661_init_locked(sc);
+		ifp->if_oerrors++;
+		/* NB: callout is reset in rt2661_init() */
+		return;
 	}
+	callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
 }
 
 static int
@@ -1743,19 +1748,25 @@
 	struct rt2661_softc *sc = ifp->if_softc;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ifreq *ifr = (struct ifreq *) data;
-	int error = 0;
+	int error = 0, startall;
 
 	switch (cmd) {
 	case SIOCSIFFLAGS:
+		RAL_LOCK(sc);
+		startall = 0;
 		if (ifp->if_flags & IFF_UP) {
-			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+				rt2661_init_locked(sc);
+				startall = 1;
+			} else
 				rt2661_update_promisc(ifp);
-			else
-				rt2661_init(sc);
 		} else {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-				rt2661_stop(sc);
+				rt2661_stop_locked(sc);
 		}
+		RAL_UNLOCK(sc);
+		if (startall)		/* NB: need to drop lock */
+			ieee80211_start_all(ic);
 		break;
 	case SIOCGIFMEDIA:
 	case SIOCSIFMEDIA:
@@ -2317,16 +2328,15 @@
 }
 
 static void
-rt2661_init(void *priv)
+rt2661_init_locked(struct rt2661_softc *sc)
 {
 #define N(a)	(sizeof (a) / sizeof ((a)[0]))
-	struct rt2661_softc *sc = priv;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	uint32_t tmp, sta[3];
 	int i, error, ntries;
 
-	RAL_LOCK(sc);
+	RAL_LOCK_ASSERT(sc);
 
 	if ((sc->sc_flags & RAL_FW_LOADED) == 0) {
 		error = rt2661_load_microcode(sc);
@@ -2334,7 +2344,6 @@
 			if_printf(ifp,
 			    "%s: could not load 8051 microcode, error %d\n",
 			    __func__, error);
-			RAL_UNLOCK(sc);
 			return;
 		}
 		sc->sc_flags |= RAL_FW_LOADED;
@@ -2401,13 +2410,11 @@
 	if (ntries == 1000) {
 		printf("timeout waiting for BBP/RF to wakeup\n");
 		rt2661_stop_locked(sc);
-		RAL_UNLOCK(sc);
 		return;
 	}
 
 	if (rt2661_bbp_init(sc) != 0) {
 		rt2661_stop_locked(sc);
-		RAL_UNLOCK(sc);
 		return;
 	}
 
@@ -2451,20 +2458,22 @@
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 
-	RAL_UNLOCK(sc);
-
-	ieee80211_start_all(ic);		/* start all vap's */
+	callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
 #undef N
 }
 
-void
-rt2661_stop(void *priv)
+static void
+rt2661_init(void *priv)
 {
 	struct rt2661_softc *sc = priv;
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
 
 	RAL_LOCK(sc);
-	rt2661_stop_locked(sc);
+	rt2661_init_locked(sc);
 	RAL_UNLOCK(sc);
+
+	ieee80211_start_all(ic);
 }
 
 void
@@ -2474,12 +2483,13 @@
 	uint32_t tmp;
 	volatile int *flags = &sc->sc_flags;
 
-	while (*flags & RAL_INPUT_RUNNING) {
+	while (*flags & RAL_INPUT_RUNNING)
 		msleep(sc, &sc->sc_mtx, 0, "ralrunning", hz/10);
-	}
+
+	callout_stop(&sc->watchdog_ch);
+	sc->sc_tx_timer = 0;
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		sc->sc_tx_timer = 0;
 		ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 
 		/* abort Tx (for all 5 Tx rings) */
@@ -2511,6 +2521,16 @@
 	}
 }
 
+void
+rt2661_stop(void *priv)
+{
+	struct rt2661_softc *sc = priv;
+
+	RAL_LOCK(sc);
+	rt2661_stop_locked(sc);
+	RAL_UNLOCK(sc);
+}
+
 static int
 rt2661_load_microcode(struct rt2661_softc *sc)
 {


More information about the p4-projects mailing list