Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Aug 2008 01:15:50 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 148145 for review
Message-ID:  <200808230115.m7N1Fopw092981@repoman.freebsd.org>

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

Change 148145 by sam@sam_ebb on 2008/08/23 01:15:17

	Revamp ht ie handling a bit:
	o change ieee80211_parse_htcap and ieee80211_parse_htinfo to save only
	  internal state obtained from the ie's; no dynamic state such as
	  ni_chw is altered
	o add ieee80211_ht_updateparams to parse ht cap+info ie's and update
	  dynamic node state
	o change ieee80211_ht_node_init to not take an htcap ie that is parsed;
	  instead have the caller make a separate call as one caller wants to
	  parse the ie while another wants to parse both cap+info ie's and
	  update state so can better do this with ieee80211_ht_updateparams
	
	These changes fix sta mode state handling where the node's channel
	width was shifted to ht20/ht40 prematurely.

Affected files ...

.. //depot/projects/vap/sys/net80211/ieee80211_hostap.c#23 edit
.. //depot/projects/vap/sys/net80211/ieee80211_ht.c#37 edit
.. //depot/projects/vap/sys/net80211/ieee80211_ht.h#18 edit
.. //depot/projects/vap/sys/net80211/ieee80211_sta.c#13 edit

Differences ...

==== //depot/projects/vap/sys/net80211/ieee80211_hostap.c#23 (text+ko) ====

@@ -2038,7 +2038,8 @@
 				vap->iv_stats.is_ht_assoc_norate++;
 				return;
 			}
-			ieee80211_ht_node_init(ni, htcap);
+			ieee80211_ht_node_init(ni);
+			ieee80211_parse_htcap(ni, htcap);
 		} else if (ni->ni_flags & IEEE80211_NODE_HT)
 			ieee80211_ht_node_cleanup(ni);
 		/*

==== //depot/projects/vap/sys/net80211/ieee80211_ht.c#37 (text+ko) ====

@@ -782,7 +782,7 @@
  * work for temporary and/or legacy sta's.
  */
 void
-ieee80211_ht_node_init(struct ieee80211_node *ni, const uint8_t *htcap)
+ieee80211_ht_node_init(struct ieee80211_node *ni)
 {
 	struct ieee80211_tx_ampdu *tap;
 	int ac;
@@ -795,7 +795,6 @@
 		 */
 		ieee80211_ht_node_cleanup(ni);
 	}
-	ieee80211_parse_htcap(ni, htcap);
 	for (ac = 0; ac < WME_NUM_AC; ac++) {
 		tap = &ni->ni_tx_ampdu[ac];
 		tap->txa_ac = ac;
@@ -1144,8 +1143,6 @@
 void
 ieee80211_parse_htcap(struct ieee80211_node *ni, const uint8_t *ie)
 {
-	struct ieee80211vap *vap = ni->ni_vap;
-
 	if (ie[0] == IEEE80211_ELEMID_VENDOR) {
 		/*
 		 * Station used Vendor OUI ie to associate;
@@ -1160,43 +1157,53 @@
 	ni->ni_htcap = LE_READ_2(ie +
 		__offsetof(struct ieee80211_ie_htcap, hc_cap));
 	ni->ni_htparam = ie[__offsetof(struct ieee80211_ie_htcap, hc_param)];
-	/* XXX needed or will ieee80211_parse_htinfo always be called? */
-	ni->ni_chw = (ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) &&
-		     (vap->iv_flags_ext & IEEE80211_FEXT_USEHT40) ? 40 : 20;
+}
+
+static void
+htinfo_parse(struct ieee80211_node *ni,
+	const struct ieee80211_ie_htinfo *htinfo)
+{
+	uint16_t w;
+
+	ni->ni_htctlchan = htinfo->hi_ctrlchannel;
+	ni->ni_ht2ndchan = SM(htinfo->hi_byte1, IEEE80211_HTINFO_2NDCHAN);
+	w = LE_READ_2(&htinfo->hi_byte2);
+	ni->ni_htopmode = SM(w, IEEE80211_HTINFO_OPMODE);
+	w = LE_READ_2(&htinfo->hi_byte45);
+	ni->ni_htstbc = SM(w, IEEE80211_HTINFO_BASIC_STBCMCS);
 }
 
 /*
- * Process an 802.11n HT info ie and update the node state.
- * Note that we handle use this information to identify the
- * correct channel (HT20, HT40+, HT40-, legacy).  The caller
- * is responsible for insuring any required channel change is
- * done (e.g. in sta mode when parsing the contents of a
- * beacon frame).
+ * Parse an 802.11n HT info ie and save useful information
+ * to the node state.  Note this does not effect any state
+ * changes such as for channel width change.
  */
 void
 ieee80211_parse_htinfo(struct ieee80211_node *ni, const uint8_t *ie)
 {
+	if (ie[0] == IEEE80211_ELEMID_VENDOR)
+		ie += 4;
+	htinfo_parse(ni, (const struct ieee80211_ie_htinfo *) ie);
+}
+
+/*
+ * Handle 11n channel switch.  Use the received HT ie's to
+ * identify the right channel to use.  If we cannot locate it
+ * in the channel table then fallback to legacy operation.
+ * Note that we use this information to identify the node's
+ * channel only; the caller is responsible for insuring any
+ * required channel change is done (e.g. in sta mode when
+ * parsing the contents of a beacon frame).
+ */
+static void
+htinfo_update_chw(struct ieee80211_node *ni,
+	const struct ieee80211_ie_htinfo *htinfo)
+{
 	struct ieee80211com *ic = ni->ni_ic;
 	struct ieee80211vap *vap = ni->ni_vap;
- 	const struct ieee80211_ie_htinfo *htinfo;
 	struct ieee80211_channel *c;
-	uint16_t w;
 	int htflags, chanflags;
 
-	if (ie[0] == IEEE80211_ELEMID_VENDOR)
-		ie += 4;
- 	htinfo = (const struct ieee80211_ie_htinfo *) ie;
-	ni->ni_htctlchan = htinfo->hi_ctrlchannel;
-	ni->ni_ht2ndchan = SM(htinfo->hi_byte1, IEEE80211_HTINFO_2NDCHAN);
-	w = LE_READ_2(&htinfo->hi_byte2);
-	ni->ni_htopmode = SM(w, IEEE80211_HTINFO_OPMODE);
-	w = LE_READ_2(&htinfo->hi_byte45);
-	ni->ni_htstbc = SM(w, IEEE80211_HTINFO_BASIC_STBCMCS);
-	/*
-	 * Handle 11n channel switch.  Use the received HT ie's to
-	 * identify the right channel to use.  If we cannot locate it
-	 * in the channel table then fallback to legacy operation.
-	 */
 	/* NB: honor operating mode constraint */
 	htflags = (vap->iv_flags_ext & IEEE80211_FEXT_HT) ?
 	    IEEE80211_CHAN_HT20 : 0;
@@ -1209,6 +1216,7 @@
 	}
 	chanflags = (ni->ni_chan->ic_flags &~ IEEE80211_CHAN_HT) | htflags;
 	if (chanflags != ni->ni_chan->ic_flags) {
+		/* XXX not right for ht40- */
 		c = ieee80211_find_channel(ic, ni->ni_chan->ic_freq, chanflags);
 		if (c == NULL && (htflags & IEEE80211_CHAN_HT40)) {
 			/*
@@ -1216,10 +1224,12 @@
 			 * to HT20 operation.  This should not happen.
 			 */
 			c = findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT20);
+#if 0
 			IEEE80211_NOTE(vap,
 			    IEEE80211_MSG_ASSOC | IEEE80211_MSG_11N, ni,
 			    "no HT40 channel (freq %u), falling back to HT20",
 			    ni->ni_chan->ic_freq);
+#endif
 			/* XXX stat */
 		}
 		if (c != NULL && c != ni->ni_chan) {
@@ -1237,6 +1247,21 @@
 }
 
 /*
+ * Parse and update HT-related state extracted from
+ * the HT cap and info ie's.
+ */
+void
+ieee80211_ht_updateparams(struct ieee80211_node *ni,
+	const uint8_t *htcapie, const uint8_t *htinfoie)
+{
+	ieee80211_parse_htcap(ni, htcapie);
+	if (htinfoie[0] == IEEE80211_ELEMID_VENDOR)
+		htinfoie += 4;
+	htinfo_parse(ni, (const struct ieee80211_ie_htinfo *) htinfoie);
+	htinfo_update_chw(ni, (const struct ieee80211_ie_htinfo *) htinfoie);
+}
+
+/*
  * Install received HT rate set by parsing the HT cap ie.
  */
 int

==== //depot/projects/vap/sys/net80211/ieee80211_ht.h#18 (text+ko) ====

@@ -165,7 +165,7 @@
 struct mbuf *ieee80211_decap_amsdu(struct ieee80211_node *, struct mbuf *);
 int	ieee80211_ampdu_reorder(struct ieee80211_node *, struct mbuf *);
 void	ieee80211_recv_bar(struct ieee80211_node *, struct mbuf *);
-void	ieee80211_ht_node_init(struct ieee80211_node *, const uint8_t *);
+void	ieee80211_ht_node_init(struct ieee80211_node *);
 void	ieee80211_ht_node_cleanup(struct ieee80211_node *);
 void	ieee80211_ht_node_age(struct ieee80211_node *);
 
@@ -178,6 +178,8 @@
 void	ieee80211_ht_timeout(struct ieee80211com *);
 void	ieee80211_parse_htcap(struct ieee80211_node *, const uint8_t *);
 void	ieee80211_parse_htinfo(struct ieee80211_node *, const uint8_t *);
+void	ieee80211_ht_updateparams(struct ieee80211_node *, const uint8_t *,
+		const uint8_t *);
 void	ieee80211_recv_action(struct ieee80211_node *,
 		const uint8_t *, const uint8_t *);
 int	ieee80211_ampdu_request(struct ieee80211_node *,

==== //depot/projects/vap/sys/net80211/ieee80211_sta.c#13 (text+ko) ====

@@ -1269,8 +1269,8 @@
 			if (scan.ath != NULL)
 				ieee80211_parse_athparams(ni, scan.ath, wh);
 			if (scan.htcap != NULL && scan.htinfo != NULL) {
-				ieee80211_parse_htcap(ni, scan.htcap);
-				ieee80211_parse_htinfo(ni, scan.htinfo);
+				ieee80211_ht_updateparams(ni,
+				    scan.htcap, scan.htinfo);
 				/* XXX state changes? */
 			}
 			if (scan.tim != NULL) {
@@ -1503,8 +1503,8 @@
 		 */
 		if (htcap != NULL && htinfo != NULL &&
 		    (vap->iv_flags_ext & IEEE80211_FEXT_HT)) {
-			ieee80211_ht_node_init(ni, htcap);
-			ieee80211_parse_htinfo(ni, htinfo);
+			ieee80211_ht_node_init(ni);
+			ieee80211_ht_updateparams(ni, htcap, htinfo);
 			ieee80211_setup_htrates(ni, htcap,
 			     IEEE80211_F_JOIN | IEEE80211_F_DOBRS);
 			ieee80211_setup_basic_htrates(ni, htinfo);



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