diff options
author | bschmidt <bschmidt@FreeBSD.org> | 2011-03-13 11:58:40 +0000 |
---|---|---|
committer | bschmidt <bschmidt@FreeBSD.org> | 2011-03-13 11:58:40 +0000 |
commit | 0e5f5b1d23647373fa0d313d70a09fcca7997490 (patch) | |
tree | 4189c501ec473474073586e730d647ae9a0d34b0 | |
parent | ac4db85efe147dd1122d279198bb89235528db0e (diff) | |
download | FreeBSD-src-0e5f5b1d23647373fa0d313d70a09fcca7997490.zip FreeBSD-src-0e5f5b1d23647373fa0d313d70a09fcca7997490.tar.gz |
Fix rmax calculation during BSS selection.
If multiple networks are available the max bandwidth is one
condition used for selecting the "best" BSS. To achieve that
we should consider all parameters which affect the max RX rate.
This includes 20/40MHz, SGI and the of course the MCS set.
If the TX MCS parameters are available we should use those,
because an AP announcing support for receiving frames at 450Mbps
might only be able to transmit at 150Mbps (1T3R). I haven't seen
devices with support for transmitting at higher rates then
receiving, so prefering TX over RX information should be safe.
While here, remove the hardcoded assumption that MCS15 is the max
possible MCS rate, use MCS31 instead which really is the highest
rate (according to the 802.11n std). Also, fix a mismatch of an
40MHz/SGI check.
-rw-r--r-- | sys/net80211/ieee80211_scan_sta.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c index 2611a6a..987a26f 100644 --- a/sys/net80211/ieee80211_scan_sta.c +++ b/sys/net80211/ieee80211_scan_sta.c @@ -756,26 +756,38 @@ maxrate(const struct ieee80211_scan_entry *se) { const struct ieee80211_ie_htcap *htcap = (const struct ieee80211_ie_htcap *) se->se_ies.htcap_ie; - int rmax, r, i; + int rmax, r, i, txstream; uint16_t caps; + uint8_t txparams; rmax = 0; if (htcap != NULL) { /* * HT station; inspect supported MCS and then adjust - * rate by channel width. Could also include short GI - * in this if we want to be extra accurate. + * rate by channel width. */ - /* XXX assumes MCS15 is max */ - for (i = 15; i >= 0 && isclr(htcap->hc_mcsset, i); i--) - ; + txparams = htcap->hc_mcsset[12]; + if (txparams & 0x3) { + /* + * TX MCS parameters defined and not equal to RX, + * extract the number of spartial streams and + * map it to the highest MCS rate. + */ + txstream = ((txparams & 0xc) >> 2) + 1; + i = txstream * 8 - 1; + } else + for (i = 31; i >= 0 && isclr(htcap->hc_mcsset, i); i--); if (i >= 0) { caps = LE_READ_2(&htcap->hc_cap); - /* XXX short/long GI */ - if (caps & IEEE80211_HTCAP_CHWIDTH40) + if ((caps & IEEE80211_HTCAP_CHWIDTH40) && + (caps & IEEE80211_HTCAP_SHORTGI40)) rmax = ieee80211_htrates[i].ht40_rate_400ns; - else + else if (caps & IEEE80211_HTCAP_CHWIDTH40) rmax = ieee80211_htrates[i].ht40_rate_800ns; + else if (caps & IEEE80211_HTCAP_SHORTGI20) + rmax = ieee80211_htrates[i].ht20_rate_400ns; + else + rmax = ieee80211_htrates[i].ht20_rate_800ns; } } for (i = 0; i < se->se_rates[1]; i++) { |