diff options
author | bschmidt <bschmidt@FreeBSD.org> | 2011-03-13 11:45:58 +0000 |
---|---|---|
committer | bschmidt <bschmidt@FreeBSD.org> | 2011-03-13 11:45:58 +0000 |
commit | cc089361067545187c0723bb96884ed3e4155609 (patch) | |
tree | 981c3f8d4c30e639b35a31dcbb412e07f4115357 | |
parent | f5e1e08d0ebdf10cb21214b3df0de94cd76c676d (diff) | |
download | FreeBSD-src-cc089361067545187c0723bb96884ed3e4155609.zip FreeBSD-src-cc089361067545187c0723bb96884ed3e4155609.tar.gz |
Change the way HT capatibilities are announced.
Get rid of the assumption that every device is capable of 40MHz,
SGI and 2 spartial streams. Instead of printing, in the worst case,
8 times 76 MCS rates, print logically connect ranges and the
support RX/TX streams.
A device without 40MHz and SGI support looks like:
ath0: 2T2R
ath0: 11na MCS 20Mhz
ath0: MCS 0-7: 6.5Mbps - 65Mbps
ath0: MCS 8-15: 13Mbps - 130Mbps
ath0: 11ng MCS 20Mhz
ath0: MCS 0-7: 6.5Mbps - 65Mbps
ath0: MCS 8-15: 13Mbps - 130Mbps
-rw-r--r-- | sys/net80211/ieee80211_ht.c | 131 |
1 files changed, 88 insertions, 43 deletions
diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c index 55be801..9fedc00 100644 --- a/sys/net80211/ieee80211_ht.c +++ b/sys/net80211/ieee80211_ht.c @@ -308,68 +308,113 @@ ieee80211_ht_vdetach(struct ieee80211vap *vap) { } +static int +ht_getrate(struct ieee80211com *ic, int index, int mode, int ratetype) +{ + int mword, rate; + + mword = ieee80211_rate2media(ic, index | IEEE80211_RATE_MCS, mode); + if (IFM_SUBTYPE(mword) != IFM_IEEE80211_MCS) + return (0); + switch (ratetype) { + case 0: + rate = ieee80211_htrates[index].ht20_rate_800ns; + break; + case 1: + rate = ieee80211_htrates[index].ht20_rate_400ns; + break; + case 2: + rate = ieee80211_htrates[index].ht40_rate_800ns; + break; + default: + rate = ieee80211_htrates[index].ht40_rate_400ns; + break; + } + return (rate); +} + +static struct printranges { + int minmcs; + int maxmcs; + int txstream; + int ratetype; + int htcapflags; +} ranges[] = { + { 0, 7, 1, 0, 0 }, + { 8, 15, 2, 0, 0 }, + { 16, 23, 3, 0, 0 }, + { 24, 31, 4, 0, 0 }, + { 32, 0, 1, 2, IEEE80211_HTC_TXMCS32 }, + { 33, 38, 2, 0, IEEE80211_HTC_TXUNEQUAL }, + { 39, 52, 3, 0, IEEE80211_HTC_TXUNEQUAL }, + { 53, 76, 4, 0, IEEE80211_HTC_TXUNEQUAL }, + { 0, 0, 0, 0, 0 }, +}; + static void -ht_rateprint(struct ieee80211com *ic, int mode, - const struct ieee80211_htrateset *rs, int maxmcs, int ratetype) +ht_rateprint(struct ieee80211com *ic, int mode, int ratetype) { - int i, rate, mword; + struct ifnet *ifp = ic->ic_ifp; + int minrate, maxrate; + struct printranges *range; - for (i = 0; i < rs->rs_nrates && i < maxmcs; i++) { - mword = ieee80211_rate2media(ic, - rs->rs_rates[i] | IEEE80211_RATE_MCS, mode); - if (IFM_SUBTYPE(mword) != IFM_IEEE80211_MCS) + for (range = ranges; range->txstream != 0; range++) { + if (ic->ic_txstream < range->txstream) continue; - switch (ratetype) { - case 0: - rate = ieee80211_htrates[ - rs->rs_rates[i]].ht20_rate_800ns; - break; - case 1: - rate = ieee80211_htrates[ - rs->rs_rates[i]].ht20_rate_400ns; - break; - case 2: - rate = ieee80211_htrates[ - rs->rs_rates[i]].ht40_rate_800ns; - break; - default: - rate = ieee80211_htrates[ - rs->rs_rates[i]].ht40_rate_400ns; - break; + if (range->htcapflags && + (ic->ic_htcaps & range->htcapflags) == 0) + continue; + if (ratetype < range->ratetype) + continue; + minrate = ht_getrate(ic, range->minmcs, mode, ratetype); + maxrate = ht_getrate(ic, range->maxmcs, mode, ratetype); + if (range->maxmcs) { + if_printf(ifp, "MCS %d-%d: %d%sMbps - %d%sMbps\n", + range->minmcs, range->maxmcs, + minrate/2, ((minrate & 0x1) != 0 ? ".5" : ""), + maxrate/2, ((maxrate & 0x1) != 0 ? ".5" : "")); + } else { + if_printf(ifp, "MCS %d: %d%sMbps\n", range->minmcs, + minrate/2, ((minrate & 0x1) != 0 ? ".5" : "")); } - printf("%s%d%sMbps", (i != 0 ? " " : ""), - rate / 2, ((rate & 0x1) != 0 ? ".5" : "")); } - printf("\n"); } static void -ht_announce(struct ieee80211com *ic, int mode, - const struct ieee80211_htrateset *rs) +ht_announce(struct ieee80211com *ic, int mode) { struct ifnet *ifp = ic->ic_ifp; - int maxmcs = 2 * 8; const char *modestr = ieee80211_phymode_name[mode]; - - KASSERT(maxmcs <= 16, ("maxmcs > 16")); - if_printf(ifp, "%d MCS rates\n", maxmcs); - if_printf(ifp, "%s MCS 20Mhz: ", modestr); - ht_rateprint(ic, mode, rs, maxmcs, 0); - if_printf(ifp, "%s MCS 20Mhz SGI: ", modestr); - ht_rateprint(ic, mode, rs, maxmcs, 1); - if_printf(ifp, "%s MCS 40Mhz: ", modestr); - ht_rateprint(ic, mode, rs, maxmcs, 2); - if_printf(ifp, "%s MCS 40Mhz SGI: ", modestr); - ht_rateprint(ic, mode, rs, maxmcs, 3); + + if_printf(ifp, "%s MCS 20Mhz\n", modestr); + ht_rateprint(ic, mode, 0); + if (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20) { + if_printf(ifp, "%s MCS 20Mhz SGI\n", modestr); + ht_rateprint(ic, mode, 1); + } + if (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) { + if_printf(ifp, "%s MCS 40Mhz:\n", modestr); + ht_rateprint(ic, mode, 2); + } + if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) && + (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40)) { + if_printf(ifp, "%s MCS 40Mhz SGI:\n", modestr); + ht_rateprint(ic, mode, 3); + } } void ieee80211_ht_announce(struct ieee80211com *ic) { + struct ifnet *ifp = ic->ic_ifp; + + if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA) || + isset(ic->ic_modecaps, IEEE80211_MODE_11NG)) + if_printf(ifp, "%dT%dR\n", ic->ic_txstream, ic->ic_rxstream); if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA)) - ht_announce(ic, IEEE80211_MODE_11NA, &ieee80211_rateset_11n); + ht_announce(ic, IEEE80211_MODE_11NA); if (isset(ic->ic_modecaps, IEEE80211_MODE_11NG)) - ht_announce(ic, IEEE80211_MODE_11NG, &ieee80211_rateset_11n); + ht_announce(ic, IEEE80211_MODE_11NG); } const struct ieee80211_htrateset * |