diff options
-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++) { |