Copy out some 11n information to net80211 ioctl node records.
Use a subset of this info to display the highest AP Rx rate during scan.

Since 11n implies support for 11a/b/g rates up to 54Mbit/s, we
only show a legacy rate if the AP doesn't support 11n.

In theory, 11n rate suport is not symmetric, ie. the max Tx rate can differ
from the max Rx rate. I'd like to keep things simple for now and just show Rx.
Rx is more straightforward to parse and, in practice, assymmetric rate support
is rare.

Note that converting an MCS index to Mbit/s is non-trivial since the actual
rate depends on several feature toggles (short guard, wide channels, etc.).
Some of these toggles can change at run time so it's impossible to make a
good guess in advance. If you really want to know the max Mbit/s value for
a given MCS index, go to mcsindex.com. But that won't tell you the actual
run-time throughput.

Kernel and ifconfig diffs follow. ok?

Index: ieee80211_ioctl.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_ioctl.c,v
retrieving revision 1.40
diff -u -p -r1.40 ieee80211_ioctl.c
--- ieee80211_ioctl.c   4 Jan 2016 12:28:46 -0000       1.40
+++ ieee80211_ioctl.c   27 Apr 2016 11:52:23 -0000
@@ -106,6 +106,12 @@ ieee80211_node2req(struct ieee80211com *
                nr->nr_flags |= IEEE80211_NODEREQ_AP;
        if (ni == ic->ic_bss)
                nr->nr_flags |= IEEE80211_NODEREQ_AP_BSS;
+
+       /* HT */
+       nr->nr_htcaps = ni->ni_htcaps;
+       memcpy(nr->nr_rxmcs, ni->ni_rxmcs, sizeof(nr->nr_rxmcs));
+       nr->nr_max_rxrate = ni->ni_max_rxrate;
+       nr->nr_tx_mcs_set = ni->ni_tx_mcs_set;
 }
 
 void
Index: ieee80211_ioctl.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_ioctl.h,v
retrieving revision 1.24
diff -u -p -r1.24 ieee80211_ioctl.h
--- ieee80211_ioctl.h   27 Apr 2016 11:58:10 -0000      1.24
+++ ieee80211_ioctl.h   27 Apr 2016 12:39:01 -0000
@@ -332,6 +332,12 @@ struct ieee80211_nodereq {
 
        /* Node flags */
        u_int8_t        nr_flags;
+
+       /* HT */
+       uint16_t                nr_htcaps;
+       uint8_t                 nr_rxmcs[howmany(80,NBBY)];
+       uint16_t                nr_max_rxrate;  /* in Mb/s, 0 <= rate <= 1023 */
+       uint8_t                 nr_tx_mcs_set;
 };
 
 #define IEEE80211_NODEREQ_STATE(_s)    (1 << _s)




Index: ifconfig.c
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.320
diff -u -p -r1.320 ifconfig.c
--- ifconfig.c  18 Apr 2016 06:20:23 -0000      1.320
+++ ifconfig.c  27 Apr 2016 12:14:02 -0000
@@ -63,6 +63,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
+#include <sys/param.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
@@ -2283,7 +2284,7 @@ ieee80211_listnodes(void)
 void
 ieee80211_printnode(struct ieee80211_nodereq *nr)
 {
-       int len;
+       int len, i;
 
        if (nr->nr_flags & IEEE80211_NODEREQ_AP ||
            nr->nr_capinfo & IEEE80211_CAPINFO_IBSS) {
@@ -2311,8 +2312,15 @@ ieee80211_printnode(struct ieee80211_nod
 
        if (nr->nr_pwrsave)
                printf("powersave ");
-       if (nr->nr_nrates) {
-               /* Only print the fastest rate */
+       /* Only print the fastest rate */
+       if (nr->nr_max_rxrate) {
+               printf("%uM HT ", nr->nr_max_rxrate);
+       } else if (nr->nr_rxmcs[0] != 0) {
+               for (i = IEEE80211_HT_NUM_MCS - 1; i >= 0; i--)
+                       if (isset(nr->nr_rxmcs, i))
+                               break;
+               printf("HT-MCS%d ", i);
+       } else if (nr->nr_nrates) {
                printf("%uM",
                    (nr->nr_rates[nr->nr_nrates - 1] & IEEE80211_RATE_VAL) / 2);
                putchar(' ');

Reply via email to