Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Jul 2005 16:56:37 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 80453 for review
Message-ID:  <200507181656.j6IGubhj064239@repoman.freebsd.org>

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

Change 80453 by sam@sam_ebb on 2005/07/18 16:56:28

	Checkpoint backmerge of new scanning+roaming+power save support.
	While here nuke wiconfig compatbility ioctls and update some api's
	to conform to vap work.  Still more things to cleanup/fix but
	bg scan+roam works.

Affected files ...

.. //depot/projects/wifi/sys/net80211/_ieee80211.h#7 edit
.. //depot/projects/wifi/sys/net80211/ieee80211.c#24 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_freebsd.h#17 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_input.c#53 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#40 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.h#25 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.c#54 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.h#25 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_output.c#44 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_power.c#1 add
.. //depot/projects/wifi/sys/net80211/ieee80211_power.h#1 add
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.c#28 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.h#18 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_scan.c#1 add
.. //depot/projects/wifi/sys/net80211/ieee80211_scan.h#1 add
.. //depot/projects/wifi/sys/net80211/ieee80211_scan_ap.c#1 add
.. //depot/projects/wifi/sys/net80211/ieee80211_scan_sta.c#1 add
.. //depot/projects/wifi/sys/net80211/ieee80211_var.h#28 edit

Differences ...

==== //depot/projects/wifi/sys/net80211/_ieee80211.h#7 (text+ko) ====

@@ -216,4 +216,14 @@
 	u_int8_t		rs_rates[IEEE80211_RATE_MAXSIZE];
 };
 
+struct ieee80211_roam {
+	int8_t			rssi11a;	/* rssi thresh for 11a bss */
+	int8_t			rssi11b;	/* for 11g sta in 11b bss */
+	int8_t			rssi11bOnly;	/* for 11b sta */
+	u_int8_t		pad1;
+	u_int8_t		rate11a;	/* rate thresh for 11a bss */
+	u_int8_t		rate11b;	/* for 11g sta in 11b bss */
+	u_int8_t		rate11bOnly;	/* for 11b sta */
+	u_int8_t		pad2;
+};
 #endif /* _NET80211__IEEE80211_H_ */

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

@@ -129,8 +129,6 @@
 	bpfattach2(ifp, DLT_IEEE802_11,
 	    sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf);
 
-	ieee80211_crypto_attach(ic);
-
 	/*
 	 * Fill in 802.11 available channel set, mark
 	 * all available channels as active, and pick
@@ -187,12 +185,16 @@
 		ic->ic_lintval = IEEE80211_BINTVAL_DEFAULT;
 	ic->ic_bmisstimeout = 7*ic->ic_lintval;	/* default 7 beacons */
 	ic->ic_dtim_period = IEEE80211_DTIM_DEFAULT;
+	IEEE80211_LOCK_INIT(ic, "ieee80211com");
 	IEEE80211_BEACON_LOCK_INIT(ic, "beacon");
 
 	ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;
 
+	ieee80211_crypto_attach(ic);
 	ieee80211_node_attach(ic);
+	ieee80211_power_attach(ic);
 	ieee80211_proto_attach(ic);
+	ieee80211_scan_attach(ic);
 
 	ieee80211_add_vap(ic);
 
@@ -214,11 +216,14 @@
 	ieee80211_remove_vap(ic);
 
 	ieee80211_sysctl_detach(ic);
+	ieee80211_scan_detach(ic);
 	ieee80211_proto_detach(ic);
 	ieee80211_crypto_detach(ic);
+	ieee80211_power_detach(ic);
 	ieee80211_node_detach(ic);
 	ifmedia_removeall(&ic->ic_media);
 
+	IEEE80211_LOCK_DESTROY(ic);
 	IEEE80211_BEACON_LOCK_DESTROY(ic);
 
 	bpfdetach(ifp);
@@ -339,6 +344,7 @@
 	 * (i.e. driver) work such as overriding methods.
 	 */
 	ieee80211_node_lateattach(ic);
+	ieee80211_power_lateattach(ic);
 
 	/*
 	 * Fill in media characteristics.
@@ -483,19 +489,6 @@
 	}
 }
 
-static int
-findrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate)
-{
-#define	IEEERATE(_ic,_m,_i) \
-	((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL)
-	int i, nrates = ic->ic_sup_rates[mode].rs_nrates;
-	for (i = 0; i < nrates; i++)
-		if (IEEERATE(ic, mode, i) == rate)
-			return i;
-	return -1;
-#undef IEEERATE
-}
-
 /*
  * Find an instance by it's mac address.
  */
@@ -524,7 +517,51 @@
 	return NULL;
 }
 
+static int
+findrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate)
+{
+#define	IEEERATE(_ic,_m,_i) \
+	((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL)
+	int i, nrates = ic->ic_sup_rates[mode].rs_nrates;
+	for (i = 0; i < nrates; i++)
+		if (IEEERATE(ic, mode, i) == rate)
+			return i;
+	return -1;
+#undef IEEERATE
+}
+
 /*
+ * Convert a media specification to a rate index and possibly a mode
+ * (if the rate is fixed and the mode is specified as ``auto'' then
+ * we need to lock down the mode so the index is meanginful).
+ */
+static int
+checkrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate)
+{
+
+	/*
+	 * Check the rate table for the specified/current phy.
+	 */
+	if (mode == IEEE80211_MODE_AUTO) {
+		int i;
+		/*
+		 * In autoselect mode search for the rate.
+		 */
+		for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_MAX; i++) {
+			if ((ic->ic_modecaps & (1<<i)) &&
+			    findrate(ic, i, rate) != -1)
+				return 1;
+		}
+		return 0;
+	} else {
+		/*
+		 * Mode is fixed, check for rate.
+		 */
+		return (findrate(ic, mode, rate) != -1);
+	}
+}
+
+/*
  * Handle a media change request.
  */
 int
@@ -534,7 +571,7 @@
 	struct ifmedia_entry *ime;
 	enum ieee80211_opmode newopmode;
 	enum ieee80211_phymode newphymode;
-	int i, j, newrate, error = 0;
+	int j, newrate, error = 0;
 
 	ic = ieee80211_find_instance(ifp);
 	if (!ic) {
@@ -579,40 +616,16 @@
 	/*
 	 * Next, the fixed/variable rate.
 	 */
-	i = -1;
 	newrate = ic->ic_fixed_rate;
 	if (IFM_SUBTYPE(ime->ifm_media) != IFM_AUTO) {
 		/*
 		 * Convert media subtype to rate.
 		 */
 		newrate = ieee80211_media2rate(ime->ifm_media);
-		if (newrate == 0)
+		if (newrate == 0 || !checkrate(ic, newphymode, newrate))
 			return EINVAL;
-		/*
-		 * Check the rate table for the specified/current phy.
-		 */
-		if (newphymode == IEEE80211_MODE_AUTO) {
-			/*
-			 * In autoselect mode search for the rate.
-			 */
-			for (j = IEEE80211_MODE_11A;
-			     j < IEEE80211_MODE_MAX; j++) {
-				if ((ic->ic_modecaps & (1<<j)) == 0)
-					continue;
-				i = findrate(ic, j, newrate);
-				if (i != -1) {
-					/* lock mode too */
-					newphymode = j;
-					break;
-				}
-			}
-		} else {
-			i = findrate(ic, newphymode, newrate);
-		}
-		if (i == -1)			/* mode/rate mismatch */
-			return EINVAL;
-	}
-	/* NB: defer rate setting to later */
+	} else
+		newrate = IEEE80211_FIXED_RATE_NONE;
 
 	/*
 	 * Deduce new operating mode but don't install it just yet.
@@ -647,10 +660,8 @@
 	/*
 	 * Handle phy mode change.
 	 */
-	if (ic->ic_curmode != newphymode) {		/* change phy mode */
-		error = ieee80211_setmode(ic, newphymode);
-		if (error != 0)
-			return error;
+	if (ic->ic_des_mode != newphymode) {		/* change phy mode */
+		ic->ic_des_mode = newphymode;
 		error = ENETRESET;
 	}
 
@@ -787,26 +798,12 @@
 void
 ieee80211_watchdog(struct ieee80211com *ic)
 {
-	struct ieee80211_node_table *nt;
-	int need_inact_timer = 0;
 
 	if (ic->ic_state != IEEE80211_S_INIT) {
 		if (ic->ic_mgt_timer && --ic->ic_mgt_timer == 0)
 			ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
-		nt = &ic->ic_scan;
-		if (nt->nt_inact_timer) {
-			if (--nt->nt_inact_timer == 0)
-				nt->nt_timeout(nt);
-			need_inact_timer += nt->nt_inact_timer;
-		}
-		nt = &ic->ic_sta;
-		if (nt->nt_inact_timer) {
-			if (--nt->nt_inact_timer == 0)
-				nt->nt_timeout(nt);
-			need_inact_timer += nt->nt_inact_timer;
-		}
 	}
-	if (ic->ic_mgt_timer != 0 || need_inact_timer)
+	if (ic->ic_mgt_timer != 0)
 		ic->ic_ifp->if_timer = 1;
 }
 

==== //depot/projects/wifi/sys/net80211/ieee80211_freebsd.h#17 (text+ko) ====

@@ -30,6 +30,18 @@
 #define _NET80211_IEEE80211_FREEBSD_H_
 
 /*
+ * Common state locking definitions.
+ */
+typedef struct mtx ieee80211_com_lock_t;
+#define	IEEE80211_LOCK_INIT(_ic, _name) \
+	mtx_init(&(_ic)->ic_comlock, _name, "802.11 com lock", MTX_DEF)
+#define	IEEE80211_LOCK_DESTROY(_ic) mtx_destroy(&(_ic)->ic_comlock)
+#define	IEEE80211_LOCK(_ic)	   mtx_lock(&(_ic)->ic_comlock)
+#define	IEEE80211_UNLOCK(_ic)	   mtx_unlock(&(_ic)->ic_comlock)
+#define	IEEE80211_LOCK_ASSERT(_ic) \
+	mtx_assert(&(_ic)->ic_comlock, MA_OWNED)
+
+/*
  * Beacon locking definitions.
  */
 typedef struct mtx ieee80211_beacon_lock_t;
@@ -58,7 +70,7 @@
  */
 typedef struct mtx ieee80211_scan_lock_t;
 #define	IEEE80211_SCAN_LOCK_INIT(_nt, _name) \
-	mtx_init(&(_nt)->nt_scanlock, _name, "802.11 scangen", MTX_DEF)
+	mtx_init(&(_nt)->nt_scanlock, _name, "802.11 node scangen", MTX_DEF)
 #define	IEEE80211_SCAN_LOCK_DESTROY(_nt)	mtx_destroy(&(_nt)->nt_scanlock)
 #define	IEEE80211_SCAN_LOCK(_nt)		mtx_lock(&(_nt)->nt_scanlock)
 #define	IEEE80211_SCAN_UNLOCK(_nt)		mtx_unlock(&(_nt)->nt_scanlock)
@@ -145,6 +157,12 @@
 int	ieee80211_node_dectestref(struct ieee80211_node *ni);
 #define	ieee80211_node_refcnt(_ni)	(_ni)->ni_refcnt
 
+#define	msecs_to_ticks(ms)	((ms)*1000/hz)
+#define time_after(a,b) 	((long)(b) - (long)(a) < 0)
+#define time_before(a,b)	time_after(b,a)
+#define time_after_eq(a,b)	((long)(a) - (long)(b) >= 0)
+#define time_before_eq(a,b)	time_after_eq(b,a)
+
 struct mbuf *ieee80211_getmgtframe(u_int8_t **frm, u_int pktlen);
 #define	M_LINK0		M_PROTO1		/* WEP requested */
 #define	M_PWR_SAV	M_PROTO4		/* bypass PS handling */

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

@@ -116,7 +116,6 @@
 	struct ieee80211_node *, struct mbuf *);
 static struct mbuf *ieee80211_decap_fastframe(struct ieee80211com *,
 	struct ieee80211_node *, struct mbuf *);
-static void ieee80211_node_pwrsave(struct ieee80211_node *, int enable);
 static void ieee80211_recv_pspoll(struct ieee80211com *,
 	struct ieee80211_node *, struct mbuf *);
 
@@ -938,10 +937,11 @@
 /*
  * Install received rate set information in the node's state block.
  */
-static int
-ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni,
-	u_int8_t *rates, u_int8_t *xrates, int flags)
+int
+ieee80211_setup_rates(struct ieee80211_node *ni,
+	const u_int8_t *rates, const u_int8_t *xrates, int flags)
 {
+	struct ieee80211com *ic = ni->ni_ic;
 	struct ieee80211_rateset *rs = &ni->ni_rates;
 
 	memset(rs, 0, sizeof(*rs));
@@ -964,7 +964,7 @@
 		memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates);
 		rs->rs_nrates += nxrates;
 	}
-	return ieee80211_fix_rate(ic, ni, flags);
+	return ieee80211_fix_rate(ni, flags);
 }
 
 static void
@@ -1027,7 +1027,7 @@
 		 * authorized at this point so traffic can flow.
 		 */
 		if (ni->ni_authmode != IEEE80211_AUTH_8021X)
-			ieee80211_node_authorize(ic, ni);
+			ieee80211_node_authorize(ni);
 		break;
 
 	case IEEE80211_M_STA:
@@ -1251,7 +1251,7 @@
 			    IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
 			    "[%s] station authenticated (shared key)\n",
 			    ether_sprintf(ni->ni_macaddr));
-			ieee80211_node_authorize(ic, ni);
+			ieee80211_node_authorize(ni);
 			break;
 		default:
 			IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
@@ -1832,7 +1832,7 @@
 		return 0;			/* NB: no change */
 }
 
-static void
+void
 ieee80211_saveie(u_int8_t **iep, const u_int8_t *ie)
 {
 	u_int ielen = ie[1]+2;
@@ -1849,37 +1849,33 @@
 	/* XXX note failure */
 }
 
-#ifdef IEEE80211_DEBUG
-static void
-dump_probe_beacon(u_int8_t subtype, int isnew,
-	const u_int8_t mac[IEEE80211_ADDR_LEN],
-	u_int8_t chan, u_int8_t bchan, u_int16_t capinfo, u_int16_t bintval,
-	u_int8_t erp, u_int8_t *ssid, u_int8_t *country)
+void
+ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie)
 {
-	printf("[%s] %s%s on chan %u (bss chan %u) ",
-	    ether_sprintf(mac), isnew ? "new " : "",
-	    ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT],
-	    chan, bchan);
-	ieee80211_print_essid(ssid + 2, ssid[1]);
-	printf("\n");
+#if 0
+	const struct ieee80211_ath_ie *ath =
+		(const struct ieee80211_ath_ie *) ie;
 
-	if (isnew) {
-		printf("[%s] caps 0x%x bintval %u erp 0x%x", 
-			ether_sprintf(mac), capinfo, bintval, erp);
-		if (country) {
-#ifdef __FreeBSD__
-			printf(" country info %*D", country[1], country+2, " ");
-#else
-			int i;
-			printf(" country info");
-			for (i = 0; i < country[1]; i++)
-				printf(" %02x", country[i+2]);
+	ni->ni_ath_flags = ath->ath_capability;
 #endif
-		}
-		printf("\n");
-	}
+	ieee80211_saveie(&ni->ni_ath_ie, ie);
+}
+
+static __inline int
+contbgscan(struct ieee80211com *ic)
+{
+	return ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) &&
+	    time_after(ticks, ic->ic_lastdata + ic->ic_bgscanidle));
+}
+
+static __inline int
+startbgscan(struct ieee80211com *ic)
+{
+	return ((ic->ic_flags & IEEE80211_F_BGSCAN) &&
+	    !IEEE80211_IS_CHAN_DTURBO(ic->ic_curchan) &&
+	    time_after(ticks, ic->ic_lastscan + ic->ic_bgscanintvl) &&
+	    time_after(ticks, ic->ic_lastdata + ic->ic_bgscanidle));
 }
-#endif /* IEEE80211_DEBUG */
 
 void
 ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
@@ -1900,10 +1896,7 @@
 	switch (subtype) {
 	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
 	case IEEE80211_FC0_SUBTYPE_BEACON: {
-		u_int8_t *tstamp, *country, *tim;
-		u_int8_t chan, bchan, fhindex, erp;
-		u_int16_t capinfo, bintval, timoff;
-		u_int16_t fhdwell;
+		struct ieee80211_scanparams scan;
 
 		/*
 		 * We process beacon/probe response frames:
@@ -1935,32 +1928,29 @@
 		 *	[tlv] Atheros capabilities
 		 */
 		IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
-		tstamp  = frm;				frm += 8;
-		bintval = le16toh(*(u_int16_t *)frm);	frm += 2;
-		capinfo = le16toh(*(u_int16_t *)frm);	frm += 2;
-		ssid = rates = xrates = country = wpa = wme = tim = ath = NULL;
-		bchan = ieee80211_chan2ieee(ic, ic->ic_curchan);
-		chan = bchan;
-		fhdwell = 0;
-		fhindex = 0;
-		erp = 0;
-		timoff = 0;
+		memset(&scan, 0, sizeof(scan));
+		scan.tstamp  = frm;				frm += 8;
+		scan.bintval = le16toh(*(u_int16_t *)frm);	frm += 2;
+		scan.capinfo = le16toh(*(u_int16_t *)frm);	frm += 2;
+		scan.bchan = ieee80211_chan2ieee(ic, ic->ic_curchan);
+		scan.chan = scan.bchan;
+
 		while (frm < efrm) {
 			switch (*frm) {
 			case IEEE80211_ELEMID_SSID:
-				ssid = frm;
+				scan.ssid = frm;
 				break;
 			case IEEE80211_ELEMID_RATES:
-				rates = frm;
+				scan.rates = frm;
 				break;
 			case IEEE80211_ELEMID_COUNTRY:
-				country = frm;
+				scan.country = frm;
 				break;
 			case IEEE80211_ELEMID_FHPARMS:
 				if (ic->ic_phytype == IEEE80211_T_FH) {
-					fhdwell = LE_READ_2(&frm[2]);
-					chan = IEEE80211_FH_CHAN(frm[4], frm[5]);
-					fhindex = frm[6];
+					scan.fhdwell = LE_READ_2(&frm[2]);
+					scan.chan = IEEE80211_FH_CHAN(frm[4], frm[5]);
+					scan.fhindex = frm[6];
 				}
 				break;
 			case IEEE80211_ELEMID_DSPARMS:
@@ -1969,17 +1959,17 @@
 				 * is problematic for multi-mode devices.
 				 */
 				if (ic->ic_phytype != IEEE80211_T_FH)
-					chan = frm[2];
+					scan.chan = frm[2];
 				break;
 			case IEEE80211_ELEMID_TIM:
 				/* XXX ATIM? */
-				tim = frm;
-				timoff = frm - mtod(m0, u_int8_t *);
+				scan.tim = frm;
+				scan.timoff = frm - mtod(m0, u_int8_t *);
 				break;
 			case IEEE80211_ELEMID_IBSSPARMS:
 				break;
 			case IEEE80211_ELEMID_XRATES:
-				xrates = frm;
+				scan.xrates = frm;
 				break;
 			case IEEE80211_ELEMID_ERP:
 				if (frm[1] != 1) {
@@ -1989,18 +1979,18 @@
 					ic->ic_stats.is_rx_elem_toobig++;
 					break;
 				}
-				erp = frm[2];
+				scan.erp = frm[2];
 				break;
 			case IEEE80211_ELEMID_RSN:
-				wpa = frm;
+				scan.wpa = frm;
 				break;
 			case IEEE80211_ELEMID_VENDOR:
 				if (iswpaoui(frm))
-					wpa = frm;
+					scan.wpa = frm;
 				else if (iswmeparam(frm) || iswmeinfo(frm))
-					wme = frm;
+					scan.wme = frm;
 				else if (isatherosoui(frm))
-					ath = frm;
+					scan.ath = frm;
 				break;
 			default:
 				IEEE80211_DISCARD_IE(ic, IEEE80211_MSG_ELEMID,
@@ -2011,10 +2001,10 @@
 			}
 			frm += frm[1] + 2;
 		}
-		IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
-		IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
+		IEEE80211_VERIFY_ELEMENT(scan.rates, IEEE80211_RATE_MAXSIZE);
+		IEEE80211_VERIFY_ELEMENT(scan.ssid, IEEE80211_NWID_LEN);
 #if IEEE80211_CHAN_MAX < 255
-		if (chan > IEEE80211_CHAN_MAX) {
+		if (scan.chan > IEEE80211_CHAN_MAX) {
 			IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID,
 			    wh, ieee80211_mgt_subtype_name[subtype >>
 				IEEE80211_FC0_SUBTYPE_SHIFT],
@@ -2023,7 +2013,8 @@
 			return;
 		}
 #endif
-		if (chan != bchan && ic->ic_phytype != IEEE80211_T_FH) {
+		if (scan.chan != scan.bchan &&
+		    ic->ic_phytype != IEEE80211_T_FH) {
 			/*
 			 * Frame was received on a channel different from the
 			 * one indicated in the DS params element id;
@@ -2037,7 +2028,7 @@
 			IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID,
 			    wh, ieee80211_mgt_subtype_name[subtype >>
 				IEEE80211_FC0_SUBTYPE_SHIFT],
-			    "for off-channel %u", chan);
+			    "for off-channel %u", scan.chan);
 			ic->ic_stats.is_rx_chanmismatch++;
 			return;
 		}
@@ -2061,27 +2052,27 @@
 		    ((ic->ic_flags & IEEE80211_F_SCAN) == 0 ||
 		     IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))) {
 			/* record tsf of last beacon */
-			memcpy(ni->ni_tstamp.data, tstamp,
+			memcpy(ni->ni_tstamp.data, scan.tstamp,
 				sizeof(ni->ni_tstamp));
-			if (ni->ni_erp != erp) {
+			if (ni->ni_erp != scan.erp) {
 				IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
 				    "[%s] erp change: was 0x%x, now 0x%x\n",
 				    ether_sprintf(wh->i_addr2),
-				    ni->ni_erp, erp);
+				    ni->ni_erp, scan.erp);
 				if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) &&
 				    (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
 					ic->ic_flags |= IEEE80211_F_USEPROT;
 				else
 					ic->ic_flags &= ~IEEE80211_F_USEPROT;
-				ni->ni_erp = erp;
+				ni->ni_erp = scan.erp;
 				/* XXX statistic */
 			}
-			if ((ni->ni_capinfo ^ capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) {
+			if ((ni->ni_capinfo ^ scan.capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) {
 				IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
 				    "[%s] capabilities change: before 0x%x,"
 				     " now 0x%x\n",
 				     ether_sprintf(wh->i_addr2),
-				     ni->ni_capinfo, capinfo);
+				     ni->ni_capinfo, scan.capinfo);
 				/*
 				 * NB: we assume short preamble doesn't
 				 *     change dynamically
@@ -2089,111 +2080,78 @@
 				ieee80211_set_shortslottime(ic,
 					IEEE80211_IS_CHAN_A(ic->ic_bsschan) ||
 					(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
-				ni->ni_capinfo = capinfo;
+				ni->ni_capinfo = scan.capinfo;
 				/* XXX statistic */
 			}
-			if (wme != NULL &&
+			if (scan.wme != NULL &&
 			    (ni->ni_flags & IEEE80211_NODE_QOS) &&
-			    ieee80211_parse_wmeparams(ic, wme, wh) > 0)
+			    ieee80211_parse_wmeparams(ic, scan.wme, wh) > 0)
 				ieee80211_wme_updateparams(ic);
-			if (tim != NULL) {
-				struct ieee80211_tim_ie *ie =
-				    (struct ieee80211_tim_ie *) tim;
-
-				ni->ni_dtim_count = ie->tim_count;
-				ni->ni_dtim_period = ie->tim_period;
+			if (scan.ath != NULL)
+				ieee80211_parse_athparams(ni, scan.ath, wh);
+			if (scan.tim != NULL) {
+				struct ieee80211_tim_ie *tim =
+				    (struct ieee80211_tim_ie *) scan.tim;
+#if 0
+				int aid = IEEE80211_AID(ni->ni_associd);
+				int ix = aid / NBBY;
+				int min = tim->tim_bitctl &~ 1;
+				int max = tim->tim_len + min - 4;
+				if ((tim->tim_bitctl&1) ||
+				    (min <= ix && ix <= max &&
+				     isset(tim->tim_bitmap - min, aid)))
+					ieee80211_sta_pwrsave(ic, 0);
+#endif
+				ni->ni_dtim_count = tim->tim_count;
+				ni->ni_dtim_period = tim->tim_period;
 			}
-			if (ath != NULL)
-				ieee80211_parse_athparams(ni, ath, wh);
-			/* NB: don't need the rest of this */
-			if ((ic->ic_flags & IEEE80211_F_SCAN) == 0)
-				return;
-		}
-
-		if (ni == ic->ic_bss &&
-		    !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) {
-#ifdef IEEE80211_DEBUG
-			if (ieee80211_msg_scan(ic))
-				dump_probe_beacon(subtype, 1,
-				    wh->i_addr2, chan, bchan, capinfo,
-				    bintval, erp, ssid, country);
-#endif
 			/*
-			 * Create a new entry.  If scanning the entry goes
-			 * in the scan cache.  Otherwise, be particular when
-			 * operating in adhoc mode--only take nodes marked
-			 * as ibss participants so we don't populate our
-			 * neighbor table with unintersting sta's.
+			 * If scanning, pass the info to the scan module.
+			 * Otherwise, check if it's the right time to do
+			 * a background scan.  Background scanning must
+			 * be enabled and we must not be operating in the
+			 * turbo phase of dynamic turbo mode.  Then,
+			 * it's been a while since the last background
+			 * scan and if no data frames have come through
+			 * recently, kick off a scan.  Note that this
+			 * is the mechanism by which a background scan
+			 * is started _and_ continued each time we
+			 * return on-channel to receive a beacon from
+			 * our ap.
 			 */
-			if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
-				if ((capinfo & IEEE80211_CAPINFO_IBSS) == 0)
-					return;
-				ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
-						wh->i_addr2);
-			} else
-				ni = ieee80211_dup_bss(&ic->ic_scan, wh->i_addr2);
-			if (ni == NULL)
-				return;
-			ni->ni_esslen = ssid[1];
-			memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
-			memcpy(ni->ni_essid, ssid + 2, ssid[1]);
-		} else if (ssid[1] != 0 &&
-		    (ISPROBE(subtype) || ni->ni_esslen == 0)) {
-			/*
-			 * Update ESSID at probe response to adopt
-			 * hidden AP by Lucent/Cisco, which announces
-			 * null ESSID in beacon.
-			 */
-#ifdef IEEE80211_DEBUG
-			if (ieee80211_msg_scan(ic) ||
-			    ieee80211_msg_debug(ic))
-				dump_probe_beacon(subtype, 0,
-				    wh->i_addr2, chan, bchan, capinfo,
-				    bintval, erp, ssid, country);
-#endif
-			ni->ni_esslen = ssid[1];
-			memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
-			memcpy(ni->ni_essid, ssid + 2, ssid[1]);
-		}
-		ni->ni_scangen = ic->ic_scan.nt_scangen;
-		IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
-		ni->ni_rssi = rssi;
-		ni->ni_rstamp = rstamp;
-		memcpy(ni->ni_tstamp.data, tstamp, sizeof(ni->ni_tstamp));
-		ni->ni_intval = bintval;
-		ni->ni_capinfo = capinfo;
-		ni->ni_chan = ic->ic_curchan;
-		ni->ni_fhdwell = fhdwell;
-		ni->ni_fhindex = fhindex;
-		ni->ni_erp = erp;
-		if (tim != NULL) {
-			struct ieee80211_tim_ie *ie =
-			    (struct ieee80211_tim_ie *) tim;
-
-			ni->ni_dtim_count = ie->tim_count;
-			ni->ni_dtim_period = ie->tim_period;
+			if (ic->ic_flags & IEEE80211_F_SCAN)
+				ieee80211_add_scan(ic, &scan, wh,
+					subtype, rssi, rstamp);
+			else if (contbgscan(ic) || startbgscan(ic))
+				ieee80211_bg_scan(ic);
+			return;
 		}
 		/*
-		 * Record the byte offset from the mac header to
-		 * the start of the TIM information element for
-		 * use by hardware and/or to speedup software
-		 * processing of beacon frames.
+		 * If scanning, just pass information to the scan module.
 		 */
-		ni->ni_timoff = timoff;
-		/*
-		 * Record optional information elements that might be
-		 * used by applications or drivers.
-		 */
-		if (wme != NULL)
-			ieee80211_saveie(&ni->ni_wme_ie, wme);
-		if (wpa != NULL)
-			ieee80211_saveie(&ni->ni_wpa_ie, wpa);
-		if (ath != NULL) {
-			ieee80211_saveie(&ni->ni_ath_ie, ath);
-			(void) ieee80211_parse_athparams(ni, ath, wh);
+		if (ic->ic_flags & IEEE80211_F_SCAN) {
+			ieee80211_add_scan(ic, &scan, wh,
+				subtype, rssi, rstamp);
+			return;
+		}
+		if (scan.capinfo & IEEE80211_CAPINFO_IBSS) {
+			if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
+				/*
+				 * Create a new entry in the neighbor table.
+				 */
+				ni = ieee80211_add_neighbor(ic, wh, &scan);
+			} else {
+				/*
+				 * Record tsf for potential resync.
+				 */
+				memcpy(ni->ni_tstamp.data, scan.tstamp,
+					sizeof(ni->ni_tstamp));
+			}
+			if (ni != NULL) {
+				ni->ni_rssi = rssi;
+				ni->ni_rstamp = rstamp;
+			}
 		}
-		/* NB: must be after ni_chan is setup */
-		ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT);
 		break;
 	}
 
@@ -2272,7 +2230,7 @@
 			ieee80211_saveie(&ni->ni_ath_ie, ath);
 			(void) ieee80211_parse_athparams(ni, ath, wh);
 		}
-		rate = ieee80211_setup_rates(ic, ni, rates, xrates,
+		rate = ieee80211_setup_rates(ni, rates, xrates,
 			  IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE
 			| IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
 		if (rate & IEEE80211_RATE_BASIC) {
@@ -2496,7 +2454,7 @@
 			ic->ic_stats.is_rx_assoc_capmismatch++;
 			return;
 		}
-		rate = ieee80211_setup_rates(ic, ni, rates, xrates,
+		rate = ieee80211_setup_rates(ni, rates, xrates,
 				IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
 				IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
 		/*
@@ -2634,7 +2592,7 @@
 		}
 
 		IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
-		rate = ieee80211_setup_rates(ic, ni, rates, xrates,
+		rate = ieee80211_setup_rates(ni, rates, xrates,
 				IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
 				IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
 		if (rate & IEEE80211_RATE_BASIC) {
@@ -2782,66 +2740,6 @@
 #undef IEEE80211_VERIFY_ELEMENT
 
 /*
- * Handle station power-save state change.
- */
-static void
-ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable)
-{
-	struct ieee80211com *ic = ni->ni_ic;
-	struct mbuf *m;
-
-	if (enable) {
-		if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0)
-			ic->ic_ps_sta++;
-		ni->ni_flags |= IEEE80211_NODE_PWR_MGT;
-		IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
-		    "[%s] power save mode on, %u sta's in ps mode\n",
-		    ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta);
-		return;
-	}
-
-	if (ni->ni_flags & IEEE80211_NODE_PWR_MGT)
-		ic->ic_ps_sta--;
-	ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT;
-	IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
-	    "[%s] power save mode off, %u sta's in ps mode\n",
-	    ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta);
-	/* XXX if no stations in ps mode, flush mc frames */
-
-	/*
-	 * Flush queued unicast frames.
-	 */
-	if (IEEE80211_NODE_SAVEQ_QLEN(ni) == 0) {
-		if (ic->ic_set_tim != NULL)
-			ic->ic_set_tim(ic, ni, 0);	/* just in case */
-		return;
-	}
-	IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
-	    "[%s] flush ps queue, %u packets queued\n",
-	    ether_sprintf(ni->ni_macaddr), IEEE80211_NODE_SAVEQ_QLEN(ni));
-	for (;;) {
-		int qlen;
-
-		IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen);
-		if (m == NULL)
-			break;
-		/* 
-		 * If this is the last packet, turn off the TIM bit.
-		 * If there are more packets, set the more packets bit
-		 * in the mbuf so ieee80211_encap will mark the 802.11
-		 * head to indicate more data frames will follow.
-		 */
-		if (qlen != 0)
-			m->m_flags |= M_MORE_DATA;
-		/* XXX need different driver interface */
-		/* XXX bypasses q max */
-		IF_ENQUEUE(&ic->ic_ifp->if_snd, m);
-	}
-	if (ic->ic_set_tim != NULL)
-		ic->ic_set_tim(ic, ni, 0);
-}
-
-/*
  * Process a received ps-poll frame.
  */
 static void
@@ -2882,10 +2780,10 @@
 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
 		    "[%s] recv ps-poll, but queue empty\n",
 		    ether_sprintf(wh->i_addr2));
-		ieee80211_send_nulldata(ic, ni);
+		ieee80211_send_nulldata(ni);
 		ic->ic_stats.is_ps_qempty++;	/* XXX node stat */
 		if (ic->ic_set_tim != NULL)
-			ic->ic_set_tim(ic, ni, 0);	/* just in case */
+			ic->ic_set_tim(ni, 0);		/* just in case */
 		return;
 	}
 	/* 
@@ -2903,7 +2801,7 @@
 		    "[%s] recv ps-poll, send packet, queue empty\n",
 		    ether_sprintf(ni->ni_macaddr));
 		if (ic->ic_set_tim != NULL)
-			ic->ic_set_tim(ic, ni, 0);
+			ic->ic_set_tim(ni, 0);
 	}
 	m->m_flags |= M_PWR_SAV;		/* bypass PS handling */
 	IF_ENQUEUE(&ic->ic_ifp->if_snd, m);
@@ -2929,6 +2827,48 @@
 	return wh->i_addr3;
 }
 
+void
+ieee80211_note(struct ieee80211com *ic, const char *fmt, ...)
+{
+	char buf[128];		/* XXX */
+	va_list ap;
+
+	va_start(ap, fmt);
+	vsnprintf(buf, sizeof(buf), fmt, ap);
+	va_end(ap);
+
+	if_printf(ic->ic_ifp, "%s", buf);	/* NB: no \n */
+}
+
+void
+ieee80211_note_frame(struct ieee80211com *ic,
+	const struct ieee80211_frame *wh,
+	const char *fmt, ...)
+{
+	char buf[128];		/* XXX */
+	va_list ap;
+
+	va_start(ap, fmt);
+	vsnprintf(buf, sizeof(buf), fmt, ap);
+	va_end(ap);
+	if_printf(ic->ic_ifp, "[%s] %s\n",
+		ether_sprintf(ieee80211_getbssid(ic, wh)), buf);
+}
+
+void
+ieee80211_note_mac(struct ieee80211com *ic,
+	const u_int8_t mac[IEEE80211_ADDR_LEN],
+	const char *fmt, ...)
+{
+	char buf[128];		/* XXX */
+	va_list ap;
+
+	va_start(ap, fmt);
+	vsnprintf(buf, sizeof(buf), fmt, ap);
+	va_end(ap);
+	if_printf(ic->ic_ifp, "[%s] %s\n", ether_sprintf(mac), buf);
+}
+
 static void
 ieee80211_discard_frame(struct ieee80211com *ic,
 	const struct ieee80211_frame *wh,
@@ -2936,7 +2876,8 @@
 {
 	va_list ap;
 
-	printf("[%s] discard ", ether_sprintf(ieee80211_getbssid(ic, wh)));
+	printf("[%s:%s] discard ", ic->ic_ifp->if_xname,
+		ether_sprintf(ieee80211_getbssid(ic, wh)));
 	if (type != NULL)
 		printf(" %s frame, ", type);
 	else
@@ -2954,7 +2895,8 @@
 {
 	va_list ap;
 
-	printf("[%s] discard ", ether_sprintf(ieee80211_getbssid(ic, wh)));
+	printf("[%s:%s] discard ", ic->ic_ifp->if_xname,
+		ether_sprintf(ieee80211_getbssid(ic, wh)));
 	if (type != NULL)
 		printf(" %s information element, ", type);
 	else
@@ -2972,7 +2914,7 @@
 {
 	va_list ap;
 
-	printf("[%s] discard ", ether_sprintf(mac));
+	printf("[%s:%s] discard ", ic->ic_ifp->if_xname, ether_sprintf(mac));
 	if (type != NULL)
 		printf(" %s frame, ", type);
 	else

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

@@ -65,8 +65,6 @@
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_ioctl.h>
 
-#include <dev/wi/if_wavelan_ieee.h>
-
 #define	IS_UP(_ic) \
 	(((_ic)->ic_ifp->if_flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
 #define	IS_UP_AUTO(_ic) \
@@ -76,370 +74,6 @@
 		int ieee, int mode);
 
 /*
- * XXX
- * Wireless LAN specific configuration interface, which is compatible
- * with wicontrol(8).
- */
-
-struct wi_read_ap_args {
-	int	i;		/* result count */
-	struct wi_apinfo *ap;	/* current entry in result buffer */
-	caddr_t	max;		/* result buffer bound */
-};
-
-static void
-wi_read_ap_result(void *arg, struct ieee80211_node *ni)
-{

>>> TRUNCATED FOR MAIL (1000 lines) <<<



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