PERFORCE change 87342 for review

Sam Leffler sam at FreeBSD.org
Mon Nov 28 06:48:36 GMT 2005


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

Change 87342 by sam at sam_ebb on 2005/11/28 06:48:04

	beacon miss updates:
	o bring in code to send a probe req on bmiss before clocking
	  the state machine
	o bring in s/w beacon miss support
	o remove ic_bmisstimeout it was never kept in sync with the
	  beacon interval; users must now caclulate the value

Affected files ...

.. //depot/projects/wifi/sys/net80211/ieee80211.c#32 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_freebsd.c#20 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_input.c#66 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.c#40 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_var.h#38 edit

Differences ...

==== //depot/projects/wifi/sys/net80211/ieee80211.c#32 (text+ko) ====

@@ -186,7 +186,7 @@
 
 	if (ic->ic_bintval == 0)
 		ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT;
-	ic->ic_bmisstimeout = 7*ic->ic_bintval;	/* default 7 beacons */
+	ic->ic_bmissthreshold = 7;		/* 7 consecutive beacons */
 	ic->ic_dtim_period = IEEE80211_DTIM_DEFAULT;
 	IEEE80211_LOCK_INIT(ic, "ieee80211com");
 	IEEE80211_BEACON_LOCK_INIT(ic, "beacon");

==== //depot/projects/wifi/sys/net80211/ieee80211_freebsd.c#20 (text+ko) ====

@@ -126,6 +126,9 @@
 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
 		"driver_caps", CTLFLAG_RW, &ic->ic_caps, 0,
 		"driver capabilities");
+	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+		"bmiss_max", CTLFLAG_RW, &ic->ic_bmiss_max, 0,
+		"consecutive beacon misses before scanning");
 	ic->ic_sysctl = ctx;
 }
 

==== //depot/projects/wifi/sys/net80211/ieee80211_input.c#66 (text+ko) ====

@@ -2098,6 +2098,9 @@
 			/* record tsf of last beacon */
 			memcpy(ni->ni_tstamp.data, scan.tstamp,
 				sizeof(ni->ni_tstamp));
+			/* count beacon frame for s/w bmiss handling */
+			ic->ic_swbmiss_count++;
+			ic->ic_bmiss_count = 0;
 			if (ni->ni_erp != scan.erp) {
 				IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
 				    "[%s] erp change: was 0x%x, now 0x%x\n",

==== //depot/projects/wifi/sys/net80211/ieee80211_proto.c#40 (text+ko) ====

@@ -97,6 +97,8 @@
 	ic->ic_rtsthreshold = IEEE80211_RTS_DEFAULT;
 	ic->ic_fragthreshold = IEEE80211_FRAG_DEFAULT;
 	ic->ic_fixed_rate = IEEE80211_FIXED_RATE_NONE;
+	ic->ic_bmiss_max = IEEE80211_BMISS_MAX;
+	callout_init(&ic->ic_swbmiss, CALLOUT_MPSAFE);
 	callout_init(&ic->ic_mgtsend, CALLOUT_MPSAFE);
 	ic->ic_mcast_rate = IEEE80211_MCAST_RATE_DEFAULT;
 	ic->ic_protmode = IEEE80211_PROT_CTSONLY;
@@ -849,14 +851,11 @@
 int
 ieee80211_init(struct ieee80211com *ic, int forcescan)
 {
-	struct ifnet *ifp = ic->ic_ifp;
 
 	IEEE80211_DPRINTF(ic,
 		IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
 		"%s\n", "start running");
 
-	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
-		ifp->if_init(ifp);
 	/*
 	 * Kick the 802.11 state machine as appropriate.
 	 */
@@ -940,9 +939,23 @@
 	 * associated; any other conditions else will be handled
 	 * through different means (e.g. the tx timeout on mgt frames).
 	 */
-	if (ic->ic_opmode != IEEE80211_M_STA ||
-	    ic->ic_state != IEEE80211_S_RUN)
+	if (ic->ic_opmode != IEEE80211_M_STA || ic->ic_state != IEEE80211_S_RUN)
+		return;
+
+	if (++ic->ic_bmiss_count < ic->ic_bmiss_max) {
+		/*
+		 * Send a directed probe req before falling back to a scan;
+		 * if we receive a response ic_bmiss_count will be reset.
+		 * Some cards mistakenly report beacon miss so this avoids
+		 * the expensive scan if the ap is still there.
+		 */
+		ieee80211_send_probereq(ic->ic_bss, ic->ic_myaddr,
+			ic->ic_bss->ni_bssid, ic->ic_bss->ni_bssid,
+			ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen,
+			ic->ic_opt_ie, ic->ic_opt_ie_len);
 		return;
+	}
+	ic->ic_bmiss_count = 0;
 	if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
 		/* 
 		 * If we receive a beacon miss interrupt when using
@@ -967,7 +980,27 @@
 	}
 }
 
+/*
+ * Software beacon miss handling.  Check if any beacons
+ * were received in the last period.  If not post a
+ * beacon miss; otherwise reset the counter.
+ */
 static void
+ieee80211_swbmiss(void *arg)
+{
+	struct ieee80211com *ic = arg;
+
+	if (ic->ic_swbmiss_count == 0) {
+		ieee80211_beacon_miss(ic);
+		if (ic->ic_bmiss_count == 0)	/* don't re-arm timer */
+			return;
+	} else
+		ic->ic_swbmiss_count = 0;
+	callout_reset(&ic->ic_swbmiss, ic->ic_swbmiss_period,
+		ieee80211_swbmiss, ic);
+}
+
+static void
 sta_disassoc(void *arg, struct ieee80211_node *ni)
 {
 	struct ieee80211com *ic = arg;
@@ -1002,6 +1035,8 @@
 	callout_stop(&ic->ic_mgtsend);		/* XXX callout_drain */
 	if (ostate != IEEE80211_S_SCAN)
 		ieee80211_cancel_scan(ic);	/* background scan */
+	if (ic->ic_flags_ext & IEEE80211_FEXT_SWBMISS)
+		callout_stop(&ic->ic_swbmiss);
 	ni = ic->ic_bss;			/* NB: no reference held */
 	switch (nstate) {
 	case IEEE80211_S_INIT:
@@ -1238,6 +1273,20 @@
 			if_start(ifp);		/* XXX not authorized yet */
 			break;
 		}
+		if (ostate != IEEE80211_S_RUN &&
+		    ic->ic_opmode == IEEE80211_M_STA &&
+		    (ic->ic_flags_ext & IEEE80211_FEXT_SWBMISS)) {
+			/*
+			 * Start s/w beacon miss timer for devices w/o
+			 * hardware support.  We fudge a bit here since
+			 * we're doing this in software.
+			 */
+			ic->ic_swbmiss_period = IEEE80211_TU_TO_TICKS(
+				2 * ic->ic_bmissthreshold * ni->ni_intval);
+			ic->ic_swbmiss_count = 0;
+			callout_reset(&ic->ic_swbmiss, ic->ic_swbmiss_period,
+				ieee80211_swbmiss, ic);
+		}
 		/*
 		 * Start/stop the authenticator when operating as an
 		 * AP.  We delay until here to allow configuration to

==== //depot/projects/wifi/sys/net80211/ieee80211_var.h#38 (text+ko) ====

@@ -72,6 +72,9 @@
 #define	IEEE80211_BINTVAL_MIN	25	/* min beacon interval (TU's) */
 #define	IEEE80211_BINTVAL_DEFAULT 100	/* default beacon interval (TU's) */
 
+#define	IEEE80211_BMISS_MAX	2	/* maximum consecutive bmiss allowed */
+#define	IEEE80211_SWBMISS_THRESHOLD 50	/* s/w bmiss threshold (TU's) */
+
 #define	IEEE80211_BGSCAN_INTVAL_MIN	15	/* min bg scan intvl (secs) */
 #define	IEEE80211_BGSCAN_INTVAL_DEFAULT	(5*60)	/* default bg scan intvl */
 
@@ -89,6 +92,7 @@
 
 #define	IEEE80211_MS_TO_TU(x)	(((x) * 1000) / 1024)
 #define	IEEE80211_TU_TO_MS(x)	(((x) * 1024) / 1000)
+#define	IEEE80211_TU_TO_TICKS(x)(((x) * hz) / 1024)
 
 struct ieee80211_aclator;
 struct sysctl_ctx_list;
@@ -118,7 +122,6 @@
 	u_int16_t		ic_bintval;	/* beacon interval */
 	u_int16_t		ic_lintval;	/* listen interval */
 	u_int16_t		ic_holdover;	/* PM hold over duration */
-	u_int16_t		ic_bmisstimeout;/* beacon miss threshold (ms) */
 	u_int16_t		ic_txpowlimit;	/* global tx power limit */
 
 	/*
@@ -192,6 +195,12 @@
 	int			ic_mcast_rate;	/* rate for mcast frames */
 	u_int16_t		ic_rtsthreshold;
 	u_int16_t		ic_fragthreshold;
+	u_int8_t		ic_bmissthreshold;
+	u_int8_t		ic_bmiss_count;	/* current beacon miss count */
+	int			ic_bmiss_max;	/* max bmiss before scan */
+	u_int16_t		ic_swbmiss_count;/* beacons in last period */
+	u_int16_t		ic_swbmiss_period;/* s/w bmiss period */
+	struct callout		ic_swbmiss;	/* s/w beacon miss timer */
 
 	u_int16_t		ic_txmin;	/* min tx retry count */
 	u_int16_t		ic_txmax;	/* max tx retry count */
@@ -295,6 +304,7 @@
 #define	IEEE80211_FEXT_WDS	0x00000001	/* CONF: 4 addr allowed */
 /* 0x00000006 reserved */
 #define	IEEE80211_FEXT_BGSCAN	0x00000008	/* STATUS: enable full bgscan completion */
+#define	IEEE80211_FEXT_SWBMISS	0x00000400	/* CONFF: do bmiss in s/w */
 
 /* ic_caps */
 #define	IEEE80211_C_WEP		0x00000001	/* CAPABILITY: WEP available */


More information about the p4-projects mailing list