diff options
author | bschmidt <bschmidt@FreeBSD.org> | 2011-03-13 12:16:23 +0000 |
---|---|---|
committer | bschmidt <bschmidt@FreeBSD.org> | 2011-03-13 12:16:23 +0000 |
commit | 6a3ac63bc7819f937745e47dd8baf0f9ef97e008 (patch) | |
tree | a7a09f96e5180f791953e23bbf4ee08f39fca298 /sys/net80211 | |
parent | 0e5f5b1d23647373fa0d313d70a09fcca7997490 (diff) | |
download | FreeBSD-src-6a3ac63bc7819f937745e47dd8baf0f9ef97e008.zip FreeBSD-src-6a3ac63bc7819f937745e47dd8baf0f9ef97e008.tar.gz |
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.
Diffstat (limited to 'sys/net80211')
-rw-r--r-- | sys/net80211/ieee80211_ht.c | 60 | ||||
-rw-r--r-- | sys/net80211/ieee80211_node.c | 5 |
2 files changed, 52 insertions, 13 deletions
diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c index 5b8c248..958a8c6 100644 --- a/sys/net80211/ieee80211_ht.c +++ b/sys/net80211/ieee80211_ht.c @@ -134,12 +134,6 @@ const struct ieee80211_mcs_rates ieee80211_htrates[IEEE80211_HTRATE_MAXSIZE] = { { 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 ieee80211com *ic) 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 ieee80211_node *ni, const uint8_t *htcapie) 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_node *ni, const uint8_t *ie, int flags) 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; } } diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index 7752c6d..104513a 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -285,10 +285,7 @@ ieee80211_node_set_chan(struct ieee80211_node *ni, 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); |