summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
authorbschmidt <bschmidt@FreeBSD.org>2011-03-13 11:45:58 +0000
committerbschmidt <bschmidt@FreeBSD.org>2011-03-13 11:45:58 +0000
commitcc089361067545187c0723bb96884ed3e4155609 (patch)
tree981c3f8d4c30e639b35a31dcbb412e07f4115357 /sys/net80211
parentf5e1e08d0ebdf10cb21214b3df0de94cd76c676d (diff)
downloadFreeBSD-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
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_ht.c131
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 *
OpenPOWER on IntegriCloud