summaryrefslogtreecommitdiffstats
path: root/sys/net80211/ieee80211_scan_sta.c
diff options
context:
space:
mode:
authorbschmidt <bschmidt@FreeBSD.org>2011-03-13 11:58:40 +0000
committerbschmidt <bschmidt@FreeBSD.org>2011-03-13 11:58:40 +0000
commit0e5f5b1d23647373fa0d313d70a09fcca7997490 (patch)
tree4189c501ec473474073586e730d647ae9a0d34b0 /sys/net80211/ieee80211_scan_sta.c
parentac4db85efe147dd1122d279198bb89235528db0e (diff)
downloadFreeBSD-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.
Diffstat (limited to 'sys/net80211/ieee80211_scan_sta.c')
-rw-r--r--sys/net80211/ieee80211_scan_sta.c30
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++) {
OpenPOWER on IntegriCloud