Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Jan 2004 22:06:56 -0800 (PST)
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 46243 for review
Message-ID:  <200401310606.i0V66ujq006814@repoman.freebsd.org>

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

Change 46243 by sam@sam_ebb on 2004/01/30 22:06:28

	Add 11g support based on ViVATO contribution:
	o correct basic rate set munging
	o handle short/long preamble more correctly
	o handle short/long slot time
	o implement 11g protection for AP (track long slot stations)
	o implement ERP for AP (track non-ERP stations)
	o honor ERP for station/IBSS operation
	o add ioctl to control 11g protection mode
	o revise beacon interface to support dynamic updates
	o add dynamic beacon update interface that handles
	  capabilities changes (but not yet TIM)
	o shuffle some function decls from public ieee80211_var.h
	  to private files

Affected files ...

.. //depot/projects/netperf+sockets/sys/net80211/ieee80211.c#8 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_input.c#11 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.c#13 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.h#6 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_node.c#6 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_node.h#6 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_output.c#10 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_proto.c#6 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_proto.h#5 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_var.h#8 edit

Differences ...

==== //depot/projects/netperf+sockets/sys/net80211/ieee80211.c#8 (text+ko) ====

@@ -646,11 +646,13 @@
 ieee80211_set11gbasicrates(struct ieee80211_rateset *rs, enum ieee80211_phymode mode)
 {
 	static const struct ieee80211_rateset basic[] = {
-	    { 3, { 12, 24, 48 } },		/* IEEE80211_MODE_11A */
-	    { 4, { 2, 4, 11, 22 } },		/* IEEE80211_MODE_11B */
-	    { 7, { 2, 4, 11, 22, 12, 24, 48 } },/* IEEE80211_MODE_11G */
-	    { 0 },				/* IEEE80211_MODE_FH */
-	    { 0 },				/* IEEE80211_MODE_TURBO	*/
+	    { 0 },			/* IEEE80211_MODE_AUTO */
+	    { 3, { 12, 24, 48 } },	/* IEEE80211_MODE_11A */
+	    { 2, { 2, 4 } },		/* IEEE80211_MODE_11B */
+	    { 4, { 2, 4, 11, 22 } },	/* IEEE80211_MODE_11G (mixed b/g) */
+	    { 0 },			/* IEEE80211_MODE_FH */
+					/* IEEE80211_MODE_PUREG (not yet) */
+	    { 7, { 2, 4, 11, 22, 12, 24, 48 } },
 	};
 	int i, j;
 
@@ -753,21 +755,21 @@
 	}
 
 	/*
-	 * Set/reset state flags that influence beacon contents, etc.
-	 *
-	 * XXX what if we have stations already associated???
-	 * XXX probably not right for autoselect?
+	 * Do 11b/11g mixed-mode state setup.
 	 */
-	if (ic->ic_caps & IEEE80211_C_SHPREAMBLE)
-		ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
 	if (mode == IEEE80211_MODE_11G) {
-		if (ic->ic_caps & IEEE80211_C_SHSLOT)
-			ic->ic_flags |= IEEE80211_F_SHSLOT;
+		/* use mixed 11b/11g rate set */
 		ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode],
 			IEEE80211_MODE_11G);
+	} else if (mode == IEEE80211_MODE_11B) {
+		/* force pure 11b rate set */
+		ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode],
+			IEEE80211_MODE_11B);
+		ic->ic_flags &= ~IEEE80211_F_SHSLOT;
 	} else {
 		ic->ic_flags &= ~IEEE80211_F_SHSLOT;
 	}
+	ieee80211_reset_erp(ic, mode);		/* reset ERP state */
 
 	/*
 	 * Setup an initial rate set according to the
@@ -784,6 +786,29 @@
 }
 
 /*
+ * Reset 11g-related state.
+ */
+void
+ieee80211_reset_erp(struct ieee80211com *ic, enum ieee80211_phymode mode)
+{
+	ic->ic_flags &= ~IEEE80211_F_USEPROT;
+	ic->ic_nonerpsta = 0;
+	ic->ic_longslotsta = 0;
+	if (mode == IEEE80211_MODE_11G && (ic->ic_caps & IEEE80211_C_SHSLOT))
+		ic->ic_flags &= ~IEEE80211_F_SHSLOT;
+	/*
+	 * Set short preamble and ERP barker-preamble flags.
+	 */
+	if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) {
+		ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
+		ic->ic_flags &= ~IEEE80211_F_USEBARKER;
+	} else {
+		ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
+		ic->ic_flags |= IEEE80211_F_USEBARKER;
+	}
+}
+
+/*
  * Return the phy mode for with the specified channel so the
  * caller can select a rate set.  This is problematic and the
  * work here assumes how things work elsewhere in this code.

==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_input.c#11 (text+ko) ====

@@ -1220,7 +1220,15 @@
 		ni->ni_chan = &ic->ic_channels[chan];
 		ni->ni_fhdwell = fhdwell;
 		ni->ni_fhindex = fhindex;
-		ni->ni_erp = erp;
+		/*
+		 * Honor ERP: enable protection and/or disable
+		 * the use of short slot time.
+		 * XXX where do we reset this state?
+		 */
+		if (erp & IEEE80211_ERP_USE_PROTECTION)
+			ic->ic_flags |= IEEE80211_F_USEPROT;
+		if (erp & IEEE80211_ERP_LONG_PREAMBLE)
+			ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
 		/* NB: must be after ni_chan is setup */
 		ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT);
 		ieee80211_unref_node(&ni);
@@ -1493,8 +1501,39 @@
 			}
 		} else
 			newassoc = 0;
-		/* XXX for 11g must turn off short slot time if long
-	           slot time sta associates */
+		/*
+		 * Station isn't capable of short slot time.  Bump
+		 * the count of long slot time stations and disable
+		 * use of short slot time.  Note that the actual switch
+		 * over to long slot time use will not occur until the
+		 * next beacon transmission (per sec. 7.3.1.4 of 11g).
+		 */
+		if ((capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) {
+			ic->ic_longslotsta++;
+			ic->ic_flags &= ~IEEE80211_F_SHSLOT;
+		}
+		/*
+		 * If the new station is not an ERP station
+		 * then bump the counter and enable protection
+		 * if configured.
+		 */
+		if (!ieee80211_iserp_rateset(ic, &ni->ni_rates)) {
+			ic->ic_nonerpsta++;
+			/*
+			 * If protection is configured, enable it.
+			 */
+			if (ic->ic_protmode != IEEE80211_PROT_NONE)
+				ic->ic_flags |= IEEE80211_F_USEPROT;
+			/*
+			 * If station does not support long preamble then
+			 * we must enable use of Barker preamble.
+			 */
+			if ((capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) == 0) {
+				ic->ic_flags |= IEEE80211_F_USEBARKER;
+				ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
+			}
+		} else
+			ni->ni_flags |= IEEE80211_NODE_ERP;
 		IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS);
 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG,
 			("station %s %s associated at aid %d\n",
@@ -1585,6 +1624,7 @@
 					("station %s deauthenticated by "
 					"peer (reason %d)\n",
 					ether_sprintf(ni->ni_macaddr), reason));
+				ieee80211_node_leave(ic, ni);
 				/* node will be free'd on return */
 				ieee80211_unref_node(&ni);
 			}
@@ -1618,7 +1658,8 @@
 				IEEE80211_AID_CLR(ni->ni_associd,
 				    ic->ic_aid_bitmap);
 				ni->ni_associd = 0;
-				/* XXX node reclaimed how? */
+				ieee80211_node_leave(ic, ni);
+				ieee80211_unref_node(&ni);	/* XXX??? */
 			}
 			break;
 		default:

==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.c#13 (text+ko) ====

@@ -897,6 +897,9 @@
 		case IEEE80211_IOC_RTSTHRESHOLD:
 			ireq->i_val = ic->ic_rtsthreshold;
 			break;
+		case IEEE80211_IOC_PROTECTION:
+			ireq->i_val = ic->ic_protmode;
+			break;
 		default:
 			error = EINVAL;
 		}
@@ -1048,6 +1051,15 @@
 			ic->ic_rtsthreshold = ireq->i_val;
 			error = ieee80211_reset(ic);
 			break;
+		case IEEE80211_IOC_PROTECTION:
+			if (!(IEEE80211_PROTECTION_OFF <= ireq->i_val &&
+			      ireq->i_val <= IEEE80211_PROTECTION_RTSCTS)) {
+				error = EINVAL;
+				break;
+			}
+			ic->ic_protmode = ireq->i_val;
+			error = ieee80211_reset(ic);	/* ???XXX */
+			break;
 		default:
 			error = EINVAL;
 			break;

==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.h#6 (text+ko) ====

@@ -161,6 +161,11 @@
 #define 	IEEE80211_POWERSAVE_ON		IEEE80211_POWERSAVE_CAM
 #define IEEE80211_IOC_POWERSAVESLEEP	11
 #define	IEEE80211_IOC_RTSTHRESHOLD	12
+#define IEEE80211_IOC_PROTECTION	13
+#define 	IEEE80211_PROTECTION_NOSUP	-1
+#define 	IEEE80211_PROTECTION_OFF	0
+#define 	IEEE80211_PROTECTION_CTS	1
+#define 	IEEE80211_PROTECTION_RTSCTS	2
 
 #ifndef IEEE80211_CHAN_ANY
 #define	IEEE80211_CHAN_ANY	0xffff		/* token for ``any channel'' */

==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_node.c#6 (text+ko) ====

@@ -613,6 +613,7 @@
 			    ("station %s timed out due to inactivity (%u secs)\n",
 			    ether_sprintf(ni->ni_macaddr),
 			    ni->ni_inact));
+			ieee80211_node_leave(ic, ni);
 			/*
 			 * Send a deauthenticate frame.
 			 *

==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_node.h#6 (text+ko) ====

@@ -72,6 +72,7 @@
 #define	IEEE80211_NODE_AUTH	0x0001		/* 802.1x auth complete */
 #define	IEEE80211_NODE_WPA	0x0002		/* WPA enabled */
 #define	IEEE80211_NODE_QOS	0x0004		/* QoS enabled */
+#define	IEEE80211_NODE_ERP	0x0008		/* ERP enabled */
 /* NB: this must have the same value as IEEE80211_FC1_PWR_MGT */
 #define	IEEE80211_NODE_PWR_MGT	0x0010		/* power save mode enabled */
 	u_int16_t		ni_associd;	/* assoc response */
@@ -102,7 +103,6 @@
 	struct ieee80211_channel *ni_chan;
 	u_int16_t		ni_fhdwell;	/* FH only */
 	u_int8_t		ni_fhindex;	/* FH only */
-	u_int8_t		ni_erp;		/* 11g only */
 
 #ifdef notyet
 	/* DTIM and contention free period (CFP) */

==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_output.c#10 (text+ko) ====

@@ -304,6 +304,27 @@
 }
 
 /*
+ * Add an erp element to a frame.
+ */
+static u_int8_t *
+ieee80211_add_erp(u_int8_t *frm, struct ieee80211com *ic)
+{
+	u_int8_t erp;
+
+	*frm++ = IEEE80211_ELEMID_ERP;
+	*frm++ = 1;
+	erp = 0;
+	if (ic->ic_nonerpsta != 0)
+		erp |= IEEE80211_ERP_NON_ERP_PRESENT;
+	if (ic->ic_flags & IEEE80211_F_USEPROT)
+		erp |= IEEE80211_ERP_USE_PROTECTION;
+	if (ic->ic_flags & IEEE80211_F_USEBARKER)
+		erp |= IEEE80211_ERP_LONG_PREAMBLE;
+	*frm++ = erp;
+	return frm;
+}
+
+/*
  * Send a management frame.  The node is for the destination (or ic_bss
  * when in station mode).  Nodes other than ic_bss have their reference
  * count bumped to reflect our use for an indeterminant time.
@@ -362,6 +383,7 @@
 		 *	[tlv] supported rates
 		 *	[tlv] parameter set (FH/DS)
 		 *	[tlv] parameter set (IBSS)
+		 *	[tlv] extended rate phy (ERP)
 		 *	[tlv] extended supported rates
 		 */
 		m = ieee80211_getmgtframe(&frm,
@@ -370,6 +392,7 @@
 		       + 2 + IEEE80211_RATE_SIZE
 		       + (ic->ic_phytype == IEEE80211_T_FH ? 7 : 3)
 		       + 6
+		       + (ic->ic_curmode == IEEE80211_MODE_11G ? 3 : 0)
 		       + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE));
 		if (m == NULL)
 			senderr(ENOMEM, is_tx_nobuf);
@@ -387,6 +410,8 @@
 		if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
 		    IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
 			capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
+		if (ic->ic_flags & IEEE80211_F_SHSLOT)
+			capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
 		*(u_int16_t *)frm = htole16(capinfo);
 		frm += 2;
 
@@ -414,15 +439,9 @@
 			*frm++ = IEEE80211_ELEMID_IBSSPARMS;
 			*frm++ = 2;
 			*frm++ = 0; *frm++ = 0;		/* TODO: ATIM window */
-		} else {	/* IEEE80211_M_HOSTAP */
-			/* TODO: TIM */
-			*frm++ = IEEE80211_ELEMID_TIM;
-			*frm++ = 4;	/* length */
-			*frm++ = 0;	/* DTIM count */
-			*frm++ = 1;	/* DTIM period */
-			*frm++ = 0;	/* bitmap control */
-			*frm++ = 0;	/* Partial Virtual Bitmap (variable length) */
 		}
+		if (ic->ic_curmode == IEEE80211_MODE_11G)
+			ieee80211_add_erp(frm, ic);
 		frm = ieee80211_add_xrates(frm, &ic->ic_bss->ni_rates);
 		m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 		break;
@@ -613,13 +632,14 @@
  * Allocate a beacon frame and fillin the appropriate bits.
  */
 struct mbuf *
-ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni)
+ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni,
+	struct ieee80211_beacon_offsets *bo)
 {
 	struct ifnet *ifp = ic->ic_ifp;
 	struct ieee80211_frame *wh;
 	struct mbuf *m;
 	int pktlen;
-	u_int8_t *frm;
+	u_int8_t *frm, *efrm;
 	u_int16_t capinfo;
 	struct ieee80211_rateset *rs;
 
@@ -632,6 +652,7 @@
 	 *	[tlv] supported rates
 	 *	[3] parameter set (DS)
 	 *	[tlv] parameter set (IBSS/TIM)
+	 *	[tlv] extended rate phy (ERP)
 	 *	[tlv] extended supported rates
 	 * XXX WME, WPA, etc.
 	 * XXX Vendor-specific OIDs (e.g. Atheros)
@@ -645,6 +666,8 @@
 		 + 6;
 	if (ic->ic_curmode != IEEE80211_MODE_FH)
 		 pktlen += 3;		/* DS parameter set */
+	if (ic->ic_curmode == IEEE80211_MODE_11G)
+		 pktlen += 3;		/* ERP information element */
 	if (rs->rs_nrates > IEEE80211_RATE_SIZE)
 		pktlen += 2;		/* extended rate set */
 	m = ieee80211_getmgtframe(&frm, pktlen);
@@ -680,6 +703,7 @@
 		capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
 	if (ic->ic_flags & IEEE80211_F_SHSLOT)
 		capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
+	bo->bo_caps = (u_int16_t *)frm;
 	*(u_int16_t *)frm = htole16(capinfo);
 	frm += 2;
 	*frm++ = IEEE80211_ELEMID_SSID;
@@ -696,7 +720,10 @@
 		*frm++ = IEEE80211_ELEMID_IBSSPARMS;
 		*frm++ = 2;
 		*frm++ = 0; *frm++ = 0;		/* TODO: ATIM window */
+		bo->bo_dtim = NULL;
+		bo->bo_dtim_len = 0;
 	} else {
+		bo->bo_dtim = frm;
 		/* TODO: TIM */
 		*frm++ = IEEE80211_ELEMID_TIM;
 		*frm++ = 4;	/* length */
@@ -704,9 +731,14 @@
 		*frm++ = 1;	/* DTIM period */
 		*frm++ = 0;	/* bitmap control */
 		*frm++ = 0;	/* Partial Virtual Bitmap (variable length) */
+		bo->bo_dtim_len = 6;
 	}
-	frm = ieee80211_add_xrates(frm, rs);
-	m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
+	if (ic->ic_curmode == IEEE80211_MODE_11G)
+		ieee80211_add_erp(frm, ic);
+	bo->bo_xrates = frm;
+	efrm = ieee80211_add_xrates(frm, rs);
+	bo->bo_xrates_len = efrm - frm;
+	m->m_pkthdr.len = m->m_len = efrm - mtod(m, u_int8_t *);
 	KASSERT(m->m_pkthdr.len <= pktlen + sizeof(struct ieee80211_frame),
 		("beacon bigger than expected, len %u calculated %u",
 		m->m_pkthdr.len, pktlen + sizeof(struct ieee80211_frame)));
@@ -714,6 +746,45 @@
 }
 
 /*
+ * Update the dynamic parts of a beacon frame based on the current state.
+ */
+int
+ieee80211_beacon_update(struct ieee80211com *ic, struct ieee80211_node *ni,
+	struct ieee80211_beacon_offsets *bo, struct mbuf **m0)
+{
+	u_int16_t capinfo;
+
+	/* XXX lock out changes */
+	/* XXX only update as needed */
+	/* XXX faster to recalculate entirely or just changes? */
+	if (ic->ic_opmode == IEEE80211_M_IBSS)
+		capinfo = IEEE80211_CAPINFO_IBSS;
+	else
+		capinfo = IEEE80211_CAPINFO_ESS;
+	if (ic->ic_flags & IEEE80211_F_WEPON)
+		capinfo |= IEEE80211_CAPINFO_PRIVACY;
+	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
+	    IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
+		capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
+	if (ic->ic_flags & IEEE80211_F_SHSLOT)
+		capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
+	*bo->bo_caps = htole16(capinfo);
+
+	if (ic->ic_flags & IEEE80211_F_DTIMUPDATE) {
+		/* 
+		 * DTIM needs updating.  If it fits in the current
+		 * space allocated then just copy in the new bits.
+		 * Otherwise we need to move any extended rate set
+		 * the follows and, possibly, allocate a new mbuf
+		 * if the this current mbuf isn't large enough.
+		 */
+		/* XXX fillin */
+		ic->ic_flags &= ~IEEE80211_F_DTIMUPDATE;
+	}
+	return 0;
+}
+
+/*
  * Save an outbound packet for a node in power-save sleep state.
  * The new packet is placed on the node's saved queue, and the TIM
  * is changed, if necessary.

==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_proto.c#6 (text+ko) ====

@@ -305,6 +305,70 @@
 #undef RV
 }
 
+/*
+ * Check if the specified rate set supports ERP.
+ * NB: the rate set is assumed to be sorted.
+ */
+int
+ieee80211_iserp_rateset(struct ieee80211com *ic, struct ieee80211_rateset *rs)
+{
+#define N(a)	(sizeof(a) / sizeof(a[0]))
+	static const int rates[] = { 2, 4, 11, 22, 12, 24, 48 };
+	int i, j;
+
+	if (rs->rs_nrates < N(rates))
+		return 0;
+	for (i = 0; i < N(rates); i++) {
+		for (j = 0; j < rs->rs_nrates && rates[i] < rs->rs_rates[j]; j++)
+			;
+		if (j == rs->rs_nrates || rates[i] > rs->rs_rates[j])
+			return 0;
+	}
+	return 1;
+#undef N
+}
+
+/*
+ * Handle bookkeeping for station deauthentication/disassociation
+ * when operating as an ap.
+ */
+void
+ieee80211_node_leave(struct ieee80211com *ic, struct ieee80211_node *ni)
+{
+	KASSERT(ic->ic_opmode == IEEE80211_M_HOSTAP,
+		("not in ap mode, mode %u", ic->ic_opmode));
+
+	/*
+	 * If a long slot station do the slot time bookkeeping.
+	 */
+	if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) {
+		KASSERT(ic->ic_longslotsta > 0,
+		    ("bogus long slot station count %d", ic->ic_longslotsta));
+		ic->ic_longslotsta--;
+		if (ic->ic_longslotsta == 0 &&
+		    ic->ic_curmode == IEEE80211_MODE_11G) {
+			/* XXX check capability */
+			ic->ic_flags |= IEEE80211_F_SHSLOT;
+		}
+	}
+	/*
+	 * If a non-ERP station do the protection-related bookkeeping.
+	 */
+	if ((ni->ni_flags & IEEE80211_NODE_ERP) == 0) {
+		KASSERT(ic->ic_nonerpsta > 0,
+		    ("bogus non-ERP station count %d", ic->ic_nonerpsta));
+		ic->ic_nonerpsta--;
+		if (ic->ic_nonerpsta == 0) {
+			ic->ic_flags &= ~IEEE80211_F_USEPROT;
+			/* XXX verify mode? */
+			if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) {
+				ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
+				ic->ic_flags &= ~IEEE80211_F_USEBARKER;
+			}
+		}
+	}
+}
+
 static int
 ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int mgt)
 {
@@ -359,6 +423,8 @@
 					    IEEE80211_REASON_AUTH_LEAVE);
 				}
 				IEEE80211_NODE_UNLOCK(ic);
+				/* XXX??? */
+				ieee80211_reset_erp(ic, ic->ic_curmode);
 				break;
 			default:
 				break;

==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_proto.h#5 (text+ko) ====

@@ -63,16 +63,38 @@
 		struct ieee80211_node *, int, int, u_int32_t);
 extern	int ieee80211_send_mgmt(struct ieee80211com *, struct ieee80211_node *,
 		int, int);
-extern	struct mbuf * ieee80211_beacon_alloc(struct ieee80211com *,
-		struct ieee80211_node *);
 extern	void ieee80211_pwrsave(struct ieee80211com *, struct ieee80211_node *, 
 		struct mbuf *);
 extern	struct mbuf *ieee80211_encap(struct ieee80211com *, struct mbuf *,
 		struct ieee80211_node **);
+extern	int ieee80211_fix_rate(struct ieee80211com *,
+		struct ieee80211_node *, int);
+extern	int ieee80211_iserp_rateset(struct ieee80211com *,
+		struct ieee80211_rateset *);
+extern	void ieee80211_node_leave(struct ieee80211com *,
+		struct ieee80211_node *);
 #define	ieee80211_new_state(_ic, _nstate, _arg) \
 	(((_ic)->ic_newstate)((_ic), (_nstate), (_arg)))
 extern	void ieee80211_print_essid(u_int8_t *, int);
 extern	void ieee80211_dump_pkt(u_int8_t *, int, int, int);
 
 extern	const char *ieee80211_state_name[IEEE80211_S_MAX];
+
+/*
+ * Beacon frames constructed by ieee80211_beacon_alloc
+ * have the following structure filled in so drivers
+ * can update the frame later w/ minimal overhead.
+ */
+struct ieee80211_beacon_offsets {
+	u_int16_t	*bo_caps;	/* capabilities */
+	u_int8_t	*bo_dtim;	/* start of dtim */
+	u_int8_t	*bo_xrates;	/* start of extended rates */
+	u_int16_t	bo_dtim_len;	/* dtim length in bytes */
+	u_int16_t	bo_xrates_len;	/* xrates length in bytes */
+};
+extern	struct mbuf * ieee80211_beacon_alloc(struct ieee80211com *,
+		struct ieee80211_node *, struct ieee80211_beacon_offsets *);
+extern	int ieee80211_beacon_update(struct ieee80211com *,
+		struct ieee80211_node *, struct ieee80211_beacon_offsets *,
+		struct mbuf **);
 #endif /* _NET80211_IEEE80211_PROTO_H_ */

==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_var.h#8 (text+ko) ====

@@ -89,6 +89,15 @@
 };
 
 /*
+ * 802.11g protection mode.
+ */
+enum ieee80211_protmode {
+	IEEE80211_PROT_NONE	= 0,	/* no protection */
+	IEEE80211_PROT_CTSONLY	= 1,	/* CTS to self */
+	IEEE80211_PROT_RTSCTS	= 2,	/* RTS-CTS */
+};
+
+/*
  * Channels are specified by frequency and attributes.
  */
 struct ieee80211_channel {
@@ -188,6 +197,7 @@
 	enum ieee80211_phytype	ic_phytype;	/* XXX wrong for multi-mode */
 	enum ieee80211_opmode	ic_opmode;	/* operation mode */
 	enum ieee80211_state	ic_state;	/* 802.11 state */
+	enum ieee80211_protmode	ic_protmode;	/* 802.11g protection mode */
 	u_int32_t		ic_aid_bitmap[IEEE80211_MAX_AID / 32 + 1];
 	u_int16_t		ic_max_aid;
 	struct ifmedia		ic_media;	/* interface media config */
@@ -217,6 +227,8 @@
 	u_int16_t		ic_txpower;	/* tx power setting (dbM) */
 	u_int16_t		ic_bmisstimeout;/* beacon miss threshold (ms) */
 	u_int16_t		ic_authmode;	/* authentication mode */
+	u_int16_t		ic_nonerpsta;	/* # non-ERP stations */
+	u_int16_t		ic_longslotsta;	/* # long slot time stations */
 	int			ic_mgt_timer;	/* mgmt timeout */
 	int			ic_inact_timer;	/* inactivity timer wait */
 	int			ic_des_esslen;
@@ -249,6 +261,9 @@
 #define	IEEE80211_F_SHSLOT	0x00020000	/* CONF: short slot time */
 #define	IEEE80211_F_SHPREAMBLE	0x00040000	/* CONF: short preamble */
 #define	IEEE80211_F_DATAPAD	0x00080000	/* CONF: do alignment pad */
+#define	IEEE80211_F_USEPROT	0x00100000	/* STATUS: protection enabled */
+#define	IEEE80211_F_USEBARKER	0x00200000	/* STATUS: use barker preamble*/
+#define	IEEE80211_F_DTIMUPDATE	0x00400000	/* STATUS: update beacon dtim */
 
 /* ic_caps */
 #define	IEEE80211_C_WEP		0x00000001	/* CAPABILITY: WEP available */
@@ -262,6 +277,7 @@
 #define	IEEE80211_C_SHPREAMBLE	0x00000100	/* CAPABILITY: short preamble */
 #define	IEEE80211_C_MONITOR	0x00000200	/* CAPABILITY: monitor mode */
 #define	IEEE80211_C_RCVMGT	0x00000400	/* CAPABILITY: rcv mgt frames */
+/* XXX protection/barker? */
 
 /* flags for ieee80211_fix_rate() */
 #define	IEEE80211_F_DOSORT	0x00000001	/* sort rate list */
@@ -279,7 +295,6 @@
 int	ieee80211_cfgget(struct ieee80211com *, u_long, caddr_t);
 int	ieee80211_cfgset(struct ieee80211com *, u_long, caddr_t);
 void	ieee80211_watchdog(struct ieee80211com *);
-int	ieee80211_fix_rate(struct ieee80211com *, struct ieee80211_node *, int);
 int	ieee80211_rate2media(struct ieee80211com *, int,
 		enum ieee80211_phymode);
 int	ieee80211_media2rate(int);
@@ -287,6 +302,7 @@
 u_int	ieee80211_chan2ieee(struct ieee80211com *, struct ieee80211_channel *);
 u_int	ieee80211_ieee2mhz(u_int, u_int);
 int	ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode);
+void	ieee80211_reset_erp(struct ieee80211com *, enum ieee80211_phymode);
 enum ieee80211_phymode ieee80211_chan2mode(struct ieee80211com *,
 		struct ieee80211_channel *);
 



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