svn commit: r219602 - head/sys/net80211

Bernhard Schmidt bschmidt at FreeBSD.org
Sun Mar 13 12:16:23 UTC 2011


Author: bschmidt
Date: Sun Mar 13 12:16:23 2011
New Revision: 219602
URL: http://svn.freebsd.org/changeset/base/219602

Log:
  Honor device capabilities while initializing ni_htrates.
  
  Instead of hardcoding MCS0-15 generate the table dynamically, also
  restrict the MCS rates to our own capabilities while parsing a htcap
  element.

Modified:
  head/sys/net80211/ieee80211_ht.c
  head/sys/net80211/ieee80211_node.c

Modified: head/sys/net80211/ieee80211_ht.c
==============================================================================
--- head/sys/net80211/ieee80211_ht.c	Sun Mar 13 11:58:40 2011	(r219601)
+++ head/sys/net80211/ieee80211_ht.c	Sun Mar 13 12:16:23 2011	(r219602)
@@ -134,12 +134,6 @@ const struct ieee80211_mcs_rates ieee802
 	{ 429, 477,  891,  990 },	/* MCS 76 */
 };
 
-static const struct ieee80211_htrateset ieee80211_rateset_11n =
-	{ 16, {
-	          0,   1,   2,   3,   4,  5,   6,  7,  8,  9,
-		 10,  11,  12,  13,  14,  15 }
-	};
-
 #ifdef IEEE80211_AMPDU_AGE
 static	int ieee80211_ampdu_age = -1;	/* threshold for ampdu reorder q (ms) */
 SYSCTL_PROC(_net_wlan, OID_AUTO, ampdu_age, CTLTYPE_INT | CTLFLAG_RW,
@@ -417,11 +411,40 @@ ieee80211_ht_announce(struct ieee80211co
 		ht_announce(ic, IEEE80211_MODE_11NG);
 }
 
+static struct ieee80211_htrateset htrateset;
+
 const struct ieee80211_htrateset *
 ieee80211_get_suphtrates(struct ieee80211com *ic,
-	const struct ieee80211_channel *c)
+    const struct ieee80211_channel *c)
 {
-	return &ieee80211_rateset_11n;
+#define	ADDRATE(x)	do {						\
+	htrateset.rs_rates[htrateset.rs_nrates] = x;			\
+	htrateset.rs_nrates++;						\
+} while (0)
+	int i;
+
+	memset(&htrateset, 0, sizeof(struct ieee80211_htrateset));
+	for (i = 0; i < ic->ic_txstream * 8; i++)
+		ADDRATE(i);
+	if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) &&
+	    (ic->ic_htcaps & IEEE80211_HTC_TXMCS32))
+		ADDRATE(i);
+	if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) {
+		if (ic->ic_txstream >= 2) {
+			 for (i = 33; i <= 38; i++)
+				ADDRATE(i);
+		}
+		if (ic->ic_txstream >= 3) {
+			for (i = 39; i <= 52; i++)
+				ADDRATE(i);
+		}
+		if (ic->ic_txstream == 4) {
+			for (i = 53; i <= 76; i++)
+				ADDRATE(i);
+		}
+	}
+	return &htrateset;
+#undef	ADDRATE
 }
 
 /*
@@ -1559,10 +1582,22 @@ ieee80211_ht_updatehtcap(struct ieee8021
 int
 ieee80211_setup_htrates(struct ieee80211_node *ni, const uint8_t *ie, int flags)
 {
+	struct ieee80211com *ic = ni->ni_ic;
 	struct ieee80211vap *vap = ni->ni_vap;
 	const struct ieee80211_ie_htcap *htcap;
 	struct ieee80211_htrateset *rs;
-	int i;
+	int i, maxequalmcs, maxunequalmcs;
+
+	maxequalmcs = ic->ic_txstream * 8 - 1;
+	if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) {
+		if (ic->ic_txstream >= 2)
+			maxunequalmcs = 38;
+		if (ic->ic_txstream >= 3)
+			maxunequalmcs = 52;
+		if (ic->ic_txstream >= 4)
+			maxunequalmcs = 76;
+	} else
+		maxunequalmcs = 0;
 
 	rs = &ni->ni_htrates;
 	memset(rs, 0, sizeof(*rs));
@@ -1581,6 +1616,13 @@ ieee80211_setup_htrates(struct ieee80211
 				vap->iv_stats.is_rx_rstoobig++;
 				break;
 			}
+			if (i <= 31 && i > maxequalmcs)
+				continue;
+			if (i == 32 &&
+			    (ic->ic_htcaps & IEEE80211_HTC_TXMCS32) == 0)
+				continue;
+			if (i > 32 && i > maxunequalmcs)
+				continue;
 			rs->rs_rates[rs->rs_nrates++] = i;
 		}
 	}

Modified: head/sys/net80211/ieee80211_node.c
==============================================================================
--- head/sys/net80211/ieee80211_node.c	Sun Mar 13 11:58:40 2011	(r219601)
+++ head/sys/net80211/ieee80211_node.c	Sun Mar 13 12:16:23 2011	(r219602)
@@ -285,10 +285,7 @@ ieee80211_node_set_chan(struct ieee80211
 	mode = ieee80211_chan2mode(chan);
 	if (IEEE80211_IS_CHAN_HT(chan)) {
 		/*
-		 * XXX Gotta be careful here; the rate set returned by
-		 * ieee80211_get_suprates is actually any HT rate
-		 * set so blindly copying it will be bad.  We must
-		 * install the legacy rate est in ni_rates and the
+		 * We must install the legacy rate est in ni_rates and the
 		 * HT rate set in ni_htrates.
 		 */
 		ni->ni_htrates = *ieee80211_get_suphtrates(ic, chan);


More information about the svn-src-all mailing list