Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Apr 2008 16:23:26 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 139270 for review
Message-ID:  <200804031623.m33GNQEp085072@repoman.freebsd.org>

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

Change 139270 by sam@sam_ebb on 2008/04/03 16:23:11

	defer net80211 state machine callbacks from interrupt context to
	taskqueue_swi to eliminate LOR's

Affected files ...

.. //depot/projects/vap/sys/dev/wi/if_wi.c#23 edit
.. //depot/projects/vap/sys/dev/wi/if_wivar.h#15 edit

Differences ...

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

@@ -78,6 +78,7 @@
 #include <sys/random.h>
 #include <sys/syslog.h>
 #include <sys/sysctl.h>
+#include <sys/taskqueue.h>
 
 #include <machine/bus.h>
 #include <machine/resource.h>
@@ -131,6 +132,11 @@
 static void wi_rx_intr(struct wi_softc *);
 static void wi_tx_intr(struct wi_softc *);
 static void wi_tx_ex_intr(struct wi_softc *);
+
+static void wi_status_connected(void *, int);
+static void wi_status_disconnected(void *, int);
+static void wi_status_oor(void *, int);
+static void wi_status_assoc_failed(void *, int);
 static void wi_info_intr(struct wi_softc *);
 
 static int  wi_write_txrate(struct wi_softc *, struct ieee80211vap *);
@@ -431,6 +437,7 @@
 	}
 
 	sc->sc_portnum = WI_DEFAULT_PORT;
+	TASK_INIT(&sc->sc_oor_task, 0, wi_status_oor, ic);
 
 	ieee80211_ifattach(ic);
 	ic->ic_raw_xmit = wi_raw_xmit;
@@ -506,6 +513,7 @@
 	    M_80211_VAP, M_NOWAIT | M_ZERO);
 	if (wvp == NULL)
 		return NULL;
+
 	vap = &wvp->wv_vap;
 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
 
@@ -540,6 +548,10 @@
 		break;
 	}
 
+	TASK_INIT(&wvp->wv_connected_task, 0, wi_status_connected, vap);
+	TASK_INIT(&wvp->wv_disconnected_task, 0, wi_status_disconnected, vap);
+	TASK_INIT(&wvp->wv_assoc_failed_task, 0, wi_status_assoc_failed, vap);
+
 	/* complete setup */
 	ieee80211_vap_attach(vap, ieee80211_media_change, wi_media_status);
 	ic->ic_opmode = opmode;
@@ -1447,11 +1459,52 @@
 	}
 }
 
+static void
+wi_status_connected(void *arg, int pending)
+{
+	struct ieee80211vap *vap = arg;
+	struct ieee80211com *ic = vap->iv_ic;
+
+	IEEE80211_LOCK(ic);
+	WI_VAP(vap)->wv_newstate(vap, IEEE80211_S_RUN, 0);
+	if (vap->iv_newstate_cb != NULL)
+		vap->iv_newstate_cb(vap, IEEE80211_S_RUN, 0);
+	IEEE80211_UNLOCK(ic);
+}
+
+static void
+wi_status_disconnected(void *arg, int pending)
+{
+	struct ieee80211vap *vap = arg;
+
+	if (vap->iv_state == IEEE80211_S_RUN) {
+		vap->iv_stats.is_rx_deauth++;
+		ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
+	}
+}
+
+static void
+wi_status_oor(void *arg, int pending)
+{
+	struct ieee80211com *ic = arg;
+
+	ieee80211_beacon_miss(ic);
+}
+
+static void
+wi_status_assoc_failed(void *arg, int pending)
+{
+	struct ieee80211vap *vap = arg;
+
+	ieee80211_new_state(vap, IEEE80211_S_SCAN, IEEE80211_SCAN_FAIL_TIMEOUT);
+}
+
 static __noinline void
 wi_info_intr(struct wi_softc *sc)
 {
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+	struct wi_vap *wvp = WI_VAP(vap);
 	struct ifnet *ifp = sc->sc_ifp;
 	int i, fid, len, off;
 	u_int16_t ltbuf[2];
@@ -1472,28 +1525,22 @@
 				break;
 			/* fall thru... */
 		case WI_INFO_LINK_STAT_AP_CHG:
-			IEEE80211_LOCK(ic);
-			WI_VAP(vap)->wv_newstate(vap, IEEE80211_S_RUN, 0);
-			if (vap->iv_newstate_cb != NULL)
-				vap->iv_newstate_cb(vap, IEEE80211_S_RUN, 0);
-			IEEE80211_UNLOCK(ic);
+			taskqueue_enqueue(taskqueue_swi, &wvp->wv_connected_task);
 			break;
 		case WI_INFO_LINK_STAT_AP_INR:
 			break;
 		case WI_INFO_LINK_STAT_DISCONNECTED:
 			/* we dropped off the net; e.g. due to deauth/disassoc */
-			if (vap->iv_state == IEEE80211_S_RUN) {
-				vap->iv_stats.is_rx_deauth++;
-				ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
-			}
+			taskqueue_enqueue(taskqueue_swi, &wvp->wv_disconnected_task);
 			break;
 		case WI_INFO_LINK_STAT_AP_OOR:
-			ieee80211_beacon_miss(ic);
+			/* XXX does this need to be per-vap? */
+			taskqueue_enqueue(taskqueue_swi, &sc->sc_oor_task);
 			break;
 		case WI_INFO_LINK_STAT_ASSOC_FAILED:
 			if (vap->iv_opmode == IEEE80211_M_STA)
-				ieee80211_new_state(vap, IEEE80211_S_SCAN,
-				    IEEE80211_SCAN_FAIL_TIMEOUT);
+				taskqueue_enqueue(taskqueue_swi,
+				    &wvp->wv_assoc_failed_task);
 			break;
 		}
 		break;

==== //depot/projects/vap/sys/dev/wi/if_wivar.h#15 (text+ko) ====

@@ -59,6 +59,9 @@
 struct wi_vap {
 	struct ieee80211vap	wv_vap;
 	struct ieee80211_beacon_offsets	wv_bo;
+	struct task		wv_connected_task;
+	struct task		wv_disconnected_task;
+	struct task		wv_assoc_failed_task;
 
 	void		(*wv_recv_mgmt)(struct ieee80211_node *,
 			    struct mbuf *, int, int, int, u_int32_t);
@@ -73,6 +76,7 @@
 	device_t		sc_dev;
 	struct mtx		sc_mtx;
 	struct callout		sc_watchdog;
+	struct task		sc_oor_task;
 	int			sc_unit;
 	int			wi_gone;
 	int			sc_enabled;



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