Author: bschmidt
Date: Sun Mar 13 11:45:58 2011
New Revision: 219598
URL: http://svn.freebsd.org/changeset/base/219598

Log:
  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

Modified:
  head/sys/net80211/ieee80211_ht.c

Modified: head/sys/net80211/ieee80211_ht.c
==============================================================================
--- head/sys/net80211/ieee80211_ht.c    Sun Mar 13 11:44:16 2011        
(r219597)
+++ head/sys/net80211/ieee80211_ht.c    Sun Mar 13 11:45:58 2011        
(r219598)
@@ -308,68 +308,113 @@ ieee80211_ht_vdetach(struct ieee80211vap
 {
 }
 
+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 *
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to