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.
This commit is contained in:
Bernhard Schmidt 2011-03-13 11:58:40 +00:00
parent d8e14b5eac
commit 759c594d37

View File

@ -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++) {