PERFORCE change 81452 for review

Sam Leffler sam at FreeBSD.org
Thu Aug 4 16:15:55 GMT 2005


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

Change 81452 by sam at sam_ebb on 2005/08/04 16:15:47

	revamp ath protocol handling to be like madwifi

Affected files ...

.. //depot/projects/wifi/sys/net80211/ieee80211.h#12 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_input.c#59 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.c#61 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.h#30 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_output.c#53 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.c#34 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.h#21 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_var.h#33 edit

Differences ...

==== //depot/projects/wifi/sys/net80211/ieee80211.h#12 (text+ko) ====

@@ -445,7 +445,10 @@
 #define	ATHEROS_CAP_TURBO_PRIME		0x01	/* dynamic turbo--aka Turbo' */
 #define	ATHEROS_CAP_COMPRESSION		0x02	/* data compression */
 #define	ATHEROS_CAP_FAST_FRAME		0x04	/* fast (jumbo) frames */
-/* bits 3-6 reserved */
+#define	ATHEROS_CAP_XR			0x08	/* Xtended Range support */
+#define	ATHEROS_CAP_AR			0x10	/* Advanded Radar support */
+#define	ATHEROS_CAP_BURST		0x20	/* Bursting - not negotiated */
+#define	ATHEROS_CAP_WME			0x40	/* CWMin tuning */
 #define	ATHEROS_CAP_BOOST		0x80	/* use turbo/!turbo mode */
 	u_int8_t	ath_defkeyix[2];
 } __packed;

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

@@ -479,7 +479,7 @@
 		IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len);
 
 #define	FF_LLC_SIZE	(sizeof(struct ether_header) + sizeof(struct llc))
-		if ((ni->ni_flags & IEEE80211_NODE_FF) &&
+		if ((ni->ni_ath_flags & IEEE80211_NODE_FF) &&
 		    m->m_pkthdr.len >= 3*FF_LLC_SIZE) {
 			struct llc *llc;
 
@@ -1824,7 +1824,8 @@
 	struct ieee80211com *ic = ni->ni_ic;
 	const struct ieee80211_ath_ie *ath;
 	u_int len = frm[1];
-	int caps;
+	int capschanged;
+	u_int16_t defkeyix;
 
 	if (len < sizeof(struct ieee80211_ath_ie)-2) {
 		IEEE80211_DISCARD_IE(ic,
@@ -1833,22 +1834,44 @@
 		return -1;
 	}
 	ath = (const struct ieee80211_ath_ie *)frm;
-	caps = 0;
-	if ((ath->ath_capability & ATHEROS_CAP_TURBO_PRIME) &&
-	    (ic->ic_flags & IEEE80211_F_TURBOP))
-		caps |= IEEE80211_NODE_TURBOP;
-	if ((ath->ath_capability & ATHEROS_CAP_FAST_FRAME) &&
-	    (ic->ic_flags & IEEE80211_F_FF))
-		caps |= IEEE80211_NODE_FF;
-	if ((ni->ni_flags ^ caps) & IEEE80211_NODE_ATH) {
+	capschanged = (ni->ni_ath_flags != ath->ath_capability);
+	defkeyix = LE_READ_2(ath->ath_defkeyix);
+	if (capschanged || defkeyix != ni->ni_ath_defkeyix) {
+		ni->ni_ath_flags = ath->ath_capability;
+		ni->ni_ath_defkeyix = defkeyix;
 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SUPERG,
-		    "[%s] ath ie: caps 0x%x defkeyix 0x%x, use 0x%x\n",
+		    "[%s] ath ie change: new caps 0x%x defkeyix 0x%x\n",
 		    ether_sprintf(ni->ni_macaddr),
-		    ath->ath_capability, LE_READ_2(ath->ath_defkeyix), caps);
-		ni->ni_flags = (ni->ni_flags &~ IEEE80211_NODE_ATH) | caps;
-		return 1;
-	} else
-		return 0;			/* NB: no change */
+		    ni->ni_ath_flags, ni->ni_ath_defkeyix);
+	}
+	if (IEEE80211_ATH_CAP(ic, ni, ATHEROS_CAP_TURBO_PRIME)) {
+		u_int16_t curflags, newflags;
+
+		/*
+		 * Check for turbo mode switch.  Calculate flags
+		 * for the new mode and effect the switch.
+		 */
+		newflags = curflags = ic->ic_bsschan->ic_flags;
+		/* NB: BOOST is not in ic_flags, so get it from the ie */
+		if (ath->ath_capability & ATHEROS_CAP_BOOST) 
+			newflags |= IEEE80211_CHAN_TURBO;
+		else
+			newflags &= ~IEEE80211_CHAN_TURBO;
+		if (newflags != curflags)
+			ieee80211_dturbo_switch(ic, newflags);
+	}
+	return capschanged;
+}
+
+void
+ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie)
+{
+	const struct ieee80211_ath_ie *ath =
+		(const struct ieee80211_ath_ie *) ie;
+
+	ni->ni_ath_flags = ath->ath_capability;
+	ni->ni_ath_defkeyix = LE_READ_2(&ath->ath_defkeyix);
+	ieee80211_saveie(&ni->ni_ath_ie, ie);
 }
 
 void
@@ -1868,18 +1891,6 @@
 	/* XXX note failure */
 }
 
-void
-ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie)
-{
-#if 0
-	const struct ieee80211_ath_ie *ath =
-		(const struct ieee80211_ath_ie *) ie;
-
-	ni->ni_ath_flags = ath->ath_capability;
-#endif
-	ieee80211_saveie(&ni->ni_ath_ie, ie);
-}
-
 static __inline int
 contbgscan(struct ieee80211com *ic)
 {
@@ -2245,10 +2256,6 @@
 		    "[%s] recv probe req\n", ether_sprintf(wh->i_addr2));
 		ni->ni_rssi = rssi;
 		ni->ni_rstamp = rstamp;
-		if (ath != NULL) {
-			ieee80211_saveie(&ni->ni_ath_ie, ath);
-			(void) ieee80211_parse_athparams(ni, ath, wh);
-		}
 		rate = ieee80211_setup_rates(ni, rates, xrates,
 			  IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE
 			| IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
@@ -2264,7 +2271,8 @@
 		if (allocbs && ic->ic_opmode != IEEE80211_M_IBSS) {
 			/* reclaim immediately */
 			ieee80211_free_node(ni);
-		}
+		} else if (ath != NULL)
+			ieee80211_saveath(ni, ath);
 		break;
 
 	case IEEE80211_FC0_SUBTYPE_AUTH: {
@@ -2543,15 +2551,14 @@
 			 * record the information element for
 			 * applications that require it.
 			 */
-			ieee80211_saveie(&ni->ni_ath_ie, ath);
-			(void) ieee80211_parse_athparams(ni, ath, wh);
+			ieee80211_saveath(ni, ath);
 		} else if (ni->ni_ath_ie != NULL) {
 			/*
 			 * Flush any state from a previous association.
 			 */
 			FREE(ni->ni_ath_ie, M_DEVBUF);
 			ni->ni_ath_ie = NULL;
-			ni->ni_flags &= ~IEEE80211_NODE_ATH;
+			ni->ni_ath_flags = 0;
 		}
 		ieee80211_node_join(ic, ni, resp);
 		break;
@@ -2672,8 +2679,10 @@
 		    ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long",
 		    ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "",
 		    ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "",
-		    ni->ni_flags & IEEE80211_NODE_FF ? ", fast-frames" : "",
-		    ni->ni_flags & IEEE80211_NODE_TURBOP ? ", turbo'" : ""
+		    IEEE80211_ATH_CAP(ic, ni, IEEE80211_NODE_FF) ?
+			", fast-frames" : "",
+		    IEEE80211_ATH_CAP(ic, ni, IEEE80211_NODE_TURBOP) ?
+			", turbo" : ""
 		);
 		ieee80211_new_state(ic, IEEE80211_S_RUN, subtype);
 		break;

==== //depot/projects/wifi/sys/net80211/ieee80211_node.c#61 (text+ko) ====

@@ -727,6 +727,7 @@
 	ieee80211_crypto_resetkey(ic, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE);
 	ni->ni_inact_reload = nt->nt_inact_init;
 	ni->ni_inact = ni->ni_inact_reload;
+	ni->ni_ath_defkeyix = 0x7fff;
 	IEEE80211_NODE_SAVEQ_INIT(ni, "unknown");
 
 	IEEE80211_NODE_LOCK(nt);
@@ -1552,8 +1553,10 @@
 	    ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long",
 	    ic->ic_flags & IEEE80211_F_USEPROT ? ", protection" : "",
 	    ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "",
-	    ni->ni_flags & IEEE80211_NODE_FF ? ", fast-frames" : "",
-	    ni->ni_flags & IEEE80211_NODE_TURBOP ? ", turbo'" : ""
+	    IEEE80211_ATH_CAP(ic, ni, IEEE80211_NODE_FF) ?
+		", fast-frames" : "",
+	    IEEE80211_ATH_CAP(ic, ni, IEEE80211_NODE_TURBOP) ?
+		", turbo" : ""
 	);
 
 	/* give driver a chance to setup state like ni_txrate */

==== //depot/projects/wifi/sys/net80211/ieee80211_node.h#30 (text+ko) ====

@@ -94,6 +94,15 @@
 	u_int			ni_refcnt;
 	u_int			ni_scangen;	/* gen# for timeout scan */
 	u_int8_t		ni_authmode;	/* authentication algorithm */
+	u_int8_t		ni_ath_flags;	/* Atheros feature flags */
+	/* NB: These must have the same values as IEEE80211_ATHC_* */
+#define IEEE80211_NODE_TURBOP	0x0001		/* Turbo prime enable */
+#define IEEE80211_NODE_COMP	0x0002		/* Compresssion enable */
+#define IEEE80211_NODE_FF	0x0004          /* Fast Frame capable */
+#define IEEE80211_NODE_XR	0x0008		/* Atheros WME enable */
+#define IEEE80211_NODE_AR	0x0010		/* AR capable */
+#define IEEE80211_NODE_BOOST	0x0080 
+#define IEEE80211_NODE_PS_CHANGED	0x0200	/* PS state change */ 
 	u_int16_t		ni_flags;	/* special-purpose state */
 #define	IEEE80211_NODE_AUTH	0x0001		/* authorized for data */
 #define	IEEE80211_NODE_QOS	0x0002		/* QoS enabled */
@@ -101,8 +110,7 @@
 /* NB: this must have the same value as IEEE80211_FC1_PWR_MGT */
 #define	IEEE80211_NODE_PWR_MGT	0x0010		/* power save mode enabled */
 #define	IEEE80211_NODE_AREF	0x0020		/* authentication ref held */
-#define IEEE80211_NODE_FF	0x0040          /* Atheros fast-frames enabled*/
-#define IEEE80211_NODE_TURBOP	0x0080		/* Atheros Turbo' enabled */
+	u_int16_t		ni_ath_defkeyix;/* Atheros def key index */
 	u_int16_t		ni_associd;	/* assoc response */
 	u_int16_t		ni_txpower;	/* current transmit power */
 	u_int16_t		ni_vlan;	/* vlan tag */

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

@@ -1252,7 +1252,7 @@
  * Add a WME information element to a frame.
  */
 static u_int8_t *
-ieee80211_add_ath(u_int8_t *frm, struct ieee80211_node *ni)
+ieee80211_add_ath(u_int8_t *frm, u_int8_t caps, u_int16_t defkeyix)
 {
 	static const struct ieee80211_ath_ie info = {
 		.ath_id		= IEEE80211_ELEMID_VENDOR,
@@ -1261,15 +1261,13 @@
 		.ath_oui_type	= ATH_OUI_TYPE,
 		.ath_oui_subtype= ATH_OUI_SUBTYPE,
 		.ath_version	= ATH_OUI_VERSION,
-		.ath_defkeyix	= { 0x7f, 0xff, },
 	};
 	struct ieee80211_ath_ie *ath = (struct ieee80211_ath_ie *) frm;
 
 	memcpy(frm, &info, sizeof(info));
-	if (ni->ni_flags & IEEE80211_NODE_FF)
-		ath->ath_capability |= ATHEROS_CAP_FAST_FRAME;
-	if (ni->ni_flags & IEEE80211_NODE_TURBOP)
-		ath->ath_capability |= ATHEROS_CAP_TURBO_PRIME;
+	ath->ath_capability = caps;
+	ath->ath_defkeyix[0] = (defkeyix & 0xff);
+	ath->ath_defkeyix[1] = ((defkeyix >> 8) & 0xff);
 	return frm + sizeof(info); 
 }
 #undef ATH_OUI_BYTES
@@ -1476,7 +1474,8 @@
 		if (ic->ic_flags & IEEE80211_F_WME)
 			frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
 		if (ni->ni_ath_ie != NULL)
-			frm = ieee80211_add_ath(frm, ni);
+			frm = ieee80211_add_ath(frm, ni->ni_ath_flags,
+				ni->ni_ath_defkeyix);
 		m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 		break;
 
@@ -1567,7 +1566,7 @@
 		 *	[tlv] supported rates
 		 *	[tlv] extended supported rates
 		 *	[tlv] WME
-		 *	[tlv] Atheros capabilities
+		 *	[tlv] Atheros capabilities (if negotiated)
 		 *	[tlv] user-specified ie's
 		 */
 		m = ieee80211_getmgtframe(&frm,
@@ -1617,8 +1616,13 @@
 		frm = ieee80211_add_xrates(frm, &ni->ni_rates);
 		if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
 			frm = ieee80211_add_wme_info(frm, &ic->ic_wme);
-		if (ni->ni_ath_ie != NULL)
-			frm = ieee80211_add_ath(frm, ni);
+		if (IEEE80211_ATH_CAP(ic, ni, IEEE80211_F_ATHEROS))
+			frm = ieee80211_add_ath(frm,
+				IEEE80211_ATH_CAP(ic, ni, IEEE80211_F_ATHEROS),
+				(ic->ic_flags & IEEE80211_F_WPA) == 0 &&
+				ni->ni_authmode != IEEE80211_AUTH_8021X &&
+				ic->ic_def_txkey != IEEE80211_KEYIX_NONE ?
+				ic->ic_def_txkey : 0x7fff);
 		if (ic->ic_opt_ie != NULL) {
 			memcpy(frm, ic->ic_opt_ie, ic->ic_opt_ie_len);
 			frm += ic->ic_opt_ie_len;
@@ -1638,6 +1642,7 @@
 		 *	[tlv] supported rates
 		 *	[tlv] extended supported rates
 		 *	[tlv] WME (if enabled and STA enabled)
+		 *	[tlv] Atheros capabilities (if enabled and STA enabled)
 		 */
 		m = ieee80211_getmgtframe(&frm,
 			 sizeof(u_int16_t)
@@ -1646,6 +1651,7 @@
 		       + 2 + IEEE80211_RATE_SIZE
 		       + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
 		       + sizeof(struct ieee80211_wme_param)
+		       + sizeof(struct ieee80211_ath_ie)
 		);
 		if (m == NULL)
 			senderr(ENOMEM, is_tx_nobuf);
@@ -1675,6 +1681,10 @@
 		frm = ieee80211_add_xrates(frm, &ni->ni_rates);
 		if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
 			frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
+		if (IEEE80211_ATH_CAP(ic, ni, IEEE80211_F_ATHEROS))
+			frm = ieee80211_add_ath(frm,
+				IEEE80211_ATH_CAP(ic, ni, IEEE80211_F_ATHEROS),
+				ni->ni_ath_defkeyix);
 		m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 		break;
 

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

@@ -842,7 +842,39 @@
 	}
 }
 
+/*
+ * Switch between turbo and non-turbo operating modes.
+ * Use the specified channel flags to locate the new
+ * channel, update 802.11 state, and then call back into
+ * the driver to effect the change.
+ */
 void
+ieee80211_dturbo_switch(struct ieee80211com *ic, int newflags)
+{
+	struct ieee80211_channel *chan;
+
+	chan = ieee80211_find_channel(ic, ic->ic_bsschan->ic_freq, newflags);
+	if (chan == NULL) {		/* XXX should not happen */
+		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SUPERG,
+		    "%s: no channel with freq %u flags 0x%x\n",
+		    __func__, ic->ic_bsschan->ic_freq, newflags);
+		return;
+	}
+
+	IEEE80211_DPRINTF(ic, IEEE80211_MSG_SUPERG,
+	    "%s: %s -> %s (freq %u flags 0x%x)\n", __func__,
+	    ieee80211_phymode_name[ieee80211_chan2mode(ic->ic_bsschan)],
+	    ieee80211_phymode_name[ieee80211_chan2mode(chan)],
+	    chan->ic_freq, chan->ic_flags);
+
+	ic->ic_bsschan = chan;
+	ic->ic_prevchan = ic->ic_curchan;
+	ic->ic_curchan = chan;
+	ic->ic_set_channel(ic);
+	/* NB: do not need to reset ERP state 'cuz we're in sta mode */
+}
+
+void
 ieee80211_beacon_miss(struct ieee80211com *ic)
 {
 
@@ -850,8 +882,7 @@
 		/* XXX check ic_curchan != ic_bsschan? */
 		return;
 	}
-	IEEE80211_DPRINTF(ic,
-		IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
+	IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
 		"%s\n", "beacon miss");
 
 	/*
@@ -863,16 +894,14 @@
 	    ic->ic_state != IEEE80211_S_RUN)
 		return;
 	if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
-#ifdef ATH_SUPERG_DYNTURBO
 		/* 
 		 * If we receive a beacon miss interrupt when using
 		 * dynamic turbo, attempt to switch modes before
 		 * reassociating.
 		 */
-		if (IEEE80211_ATH_CAP(ic, ic->ic_bss, IEEE80211_ATHC_TURBOP))
+		if (IEEE80211_ATH_CAP(ic, ic->ic_bss, IEEE80211_NODE_TURBOP))
 			ieee80211_dturbo_switch(ic,
 			    ic->ic_bsschan->ic_flags ^ IEEE80211_CHAN_TURBO);
-#endif /* ATH_SUPERG_DYNTURBO */
 		/*
 		 * Try to reassociate before scanning for a new ap.
 		 */

==== //depot/projects/wifi/sys/net80211/ieee80211_proto.h#21 (text+ko) ====

@@ -214,6 +214,7 @@
 
 #define	ieee80211_new_state(_ic, _nstate, _arg) \
 	(((_ic)->ic_newstate)((_ic), (_nstate), (_arg)))
+void	ieee80211_dturbo_switch(struct ieee80211com *, int newflags);
 void	ieee80211_beacon_miss(struct ieee80211com *);
 void	ieee80211_print_essid(const u_int8_t *, int);
 void	ieee80211_dump_pkt(struct ieee80211com *,

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

@@ -248,8 +248,9 @@
 
 /* ic_flags */
 /* NB: bits 0x4c available */
-#define	IEEE80211_F_FF		0x00000001	/* CONF: ATH FF enabled */
-#define	IEEE80211_F_TURBOP	0x00000002	/* CONF: ATH Turbo enabled*/
+#define	IEEE80211_F_TURBOP	0x00000001	/* CONF: ATH Turbo enabled*/
+#define	IEEE80211_F_COMP	0x00000002	/* CONF: ATH comp enabled */
+#define	IEEE80211_F_FF		0x00000004	/* CONF: ATH FF enabled */
 /* NB: this is intentionally setup to be IEEE80211_CAPINFO_PRIVACY */
 #define	IEEE80211_F_PRIVACY	0x00000010	/* CONF: privacy enabled */
 #define	IEEE80211_F_PUREG	0x00000020	/* CONF: 11g w/o 11b sta's */
@@ -279,6 +280,13 @@
 #define	IEEE80211_F_NOBRIDGE	0x10000000	/* CONF: dis. internal bridge */
 #define	IEEE80211_F_WMEUPDATE	0x20000000	/* STATUS: update beacon wme */
 
+/* Atheros protocol-specific flags */
+#define	IEEE80211_F_ATHEROS \
+	(IEEE80211_F_FF | IEEE80211_F_COMP | IEEE80211_F_TURBOP)
+/* Check if an Atheros capability was negotiated for use */
+#define	IEEE80211_ATH_CAP(ic, ni, bit) \
+	((ic)->ic_flags & (ni)->ni_ath_flags & (bit))
+
 /* ic_flags_ext */
 #define	IEEE80211_FEXT_WDS	0x00000001	/* CONF: 4 addr allowed */
 /* 0x00000006 reserved */


More information about the p4-projects mailing list