PERFORCE change 140216 for review

Sam Leffler sam at FreeBSD.org
Fri Apr 18 18:16:35 UTC 2008


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

Change 140216 by sam at sam_ebb on 2008/04/18 18:16:06

	o don't hold softc lock over ieee80211_start_all
	o change watchdog timer to run when IFF_DRV_RUNNING is set
	  instead of being reprimed on every packet

Affected files ...

.. //depot/projects/vap/sys/dev/wi/if_wi.c#25 edit

Differences ...

==== //depot/projects/vap/sys/dev/wi/if_wi.c#25 (text+ko) ====

@@ -629,7 +629,7 @@
 }
 
 static int
-wi_init_locked(struct wi_softc *sc, int porttype, int mode,
+wi_setup_locked(struct wi_softc *sc, int porttype, int mode,
 	uint8_t mac[IEEE80211_ADDR_LEN])
 {
 	int i;
@@ -664,40 +664,46 @@
 	return 0;
 }
 
-void
-wi_init(void *arg)
+static void
+wi_init_locked(struct wi_softc *sc)
 {
-	struct wi_softc *sc = arg;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	int wasenabled;
 
-	WI_LOCK(sc);
-	if (sc->wi_gone) {
-		WI_UNLOCK(sc);
-		return;
-	}
+	WI_LOCK_ASSERT(sc);
+
 	wasenabled = sc->sc_enabled;
 	if (wasenabled)
 		wi_stop_locked(sc, 1);
 
 	IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
-	if (wi_init_locked(sc, sc->sc_porttype, 3, ic->ic_myaddr) != 0) {
+	if (wi_setup_locked(sc, sc->sc_porttype, 3, ic->ic_myaddr) != 0) {
 		if_printf(ifp, "interface not running\n");
 		wi_stop_locked(sc, 1);
-		WI_UNLOCK(sc);
 		return;
 	}
 
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
+	callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc);
+
 	wi_enable(sc);			/* Enable desired port */
+}
+
+void
+wi_init(void *arg)
+{
+	struct wi_softc *sc = arg;
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+
+	WI_LOCK(sc);
+	wi_init_locked(sc);
 	WI_UNLOCK(sc);
 
 	ieee80211_start_all(ic);
-
-	callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc);
 }
 
 static void
@@ -715,7 +721,7 @@
 	} else if (sc->wi_gone && disable)	/* gone --> not enabled */
 		sc->sc_enabled = 0;
 
-	callout_stop(&sc->sc_watchdog);		/* XXX drain */
+	callout_stop(&sc->sc_watchdog);
 	sc->sc_tx_timer = 0;
 	sc->sc_false_syns = 0;
 
@@ -822,7 +828,7 @@
 
 	if (nstate == IEEE80211_S_AUTH) {
 		WI_LOCK(sc);
-		wi_init_locked(sc, WI_PORTTYPE_BSS, 3, vap->iv_myaddr);
+		wi_setup_locked(sc, WI_PORTTYPE_BSS, 3, vap->iv_myaddr);
 
 		if (vap->iv_flags & IEEE80211_F_PMGTON) {
 			wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval);
@@ -894,7 +900,7 @@
 	error = WI_VAP(vap)->wv_newstate(vap, nstate, arg);
 	if (error == 0 && nstate == IEEE80211_S_RUN) {
 		WI_LOCK(sc);
-		wi_init_locked(sc, WI_PORTTYPE_HOSTAP, 0, vap->iv_myaddr);
+		wi_setup_locked(sc, WI_PORTTYPE_HOSTAP, 0, vap->iv_myaddr);
 
 		bss = vap->iv_bss;
 		wi_write_ssid(sc, WI_RID_OWN_SSID,
@@ -1153,16 +1159,16 @@
 	struct wi_softc	*sc = arg;
 	struct ifnet *ifp = sc->sc_ifp;
 
+	WI_LOCK_ASSERT(sc);
+
 	if (!sc->sc_enabled)
 		return;
 
-	if (sc->sc_tx_timer) {
-		if (--sc->sc_tx_timer == 0) {
-			if_printf(ifp, "device timeout\n");
-			ifp->if_oerrors++;
-			wi_init(ifp->if_softc);
-			return;
-		}
+	if (sc->sc_tx_timer && --sc->sc_tx_timer == 0) {
+		if_printf(ifp, "device timeout\n");
+		ifp->if_oerrors++;
+		wi_init_locked(ifp->if_softc);
+		return;
 	}
 	callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc);
 }
@@ -1173,7 +1179,7 @@
 	struct wi_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:
@@ -1189,10 +1195,14 @@
 				if ((ifp->if_flags ^ sc->sc_if_flags) & IFF_PROMISC) {
 					wi_write_val(sc, WI_RID_PROMISC,
 					    (ifp->if_flags & IFF_PROMISC) != 0);
-				} else
-					wi_init(sc);
-			} else
-				wi_init(sc);
+				} else {
+					wi_init_locked(sc);
+					startall = 1;
+				}
+			} else {
+				wi_init_locked(sc);
+				startall = 1;
+			}
 		} else {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 				wi_stop_locked(sc, 1);
@@ -1200,7 +1210,9 @@
 		}
 		sc->sc_if_flags = ifp->if_flags;
 		WI_UNLOCK(sc);
-		error = 0;
+
+		if (startall)
+			ieee80211_start_all(ic);
 		break;
 	case SIOCGIFMEDIA:
 	case SIOCSIFMEDIA:


More information about the p4-projects mailing list