For hostap interfaces, ifconfig scan currently shows the maximum supported
Rx Rate or RX MCS of associated stations. E.g. for an iwn(4) device associated
to an athn(4) AP in 11g mode, the AP will show 'HT-MCS7' in ifconfig scan:

  # ifconfig athn0 scan | grep 34:13:e8:d0:60:a9
  lladdr 34:13:e8:d0:60:a9 77dBm HT-MCS7 short_preamble,short_slottime assoc

It shows that 'HT-MCS7' is the maximum supported rate by iwn(4).
Showing the maximum supported rate makes sense when searching for APs.
But on an AP it is more useful to show the current Tx rate our AP is
using to send frames to the associated node.
The diff below implements this, and we get:

  # ifconfig athn0 scan | grep 34:13:e8:d0:60:a9
  lladdr 34:13:e8:d0:60:a9 80dBm 24M short_preamble,short_slottime assoc

Requires ifconfig to be recompiled to run on the new kernel.

Index: sbin/ifconfig/ifconfig.c
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.324
diff -u -p -r1.324 ifconfig.c
--- sbin/ifconfig/ifconfig.c    15 Jun 2016 19:39:33 -0000      1.324
+++ sbin/ifconfig/ifconfig.c    3 Jul 2016 12:59:05 -0000
@@ -2341,8 +2341,19 @@ ieee80211_printnode(struct ieee80211_nod
 
        if (nr->nr_pwrsave)
                printf("powersave ");
-       /* Only print the fastest rate */
-       if (nr->nr_max_rxrate) {
+       /* 
+        * Print our current Tx rate for associated nodes.
+        * Print the fastest supported rate for APs.
+        */
+       if ((nr->nr_flags & (IEEE80211_NODEREQ_AP)) == 0) {
+               if (nr->nr_flags & IEEE80211_NODEREQ_HT) {
+                       printf("HT-MCS%d ", nr->nr_txmcs);
+               } else if (nr->nr_rates) {
+                       printf("%uM ",
+                           (nr->nr_rates[nr->nr_txrate] & IEEE80211_RATE_VAL)
+                           / 2);
+               }
+       } else 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--) {
@@ -2351,9 +2362,8 @@ ieee80211_printnode(struct ieee80211_nod
                }
                printf("HT-MCS%d ", i);
        } else if (nr->nr_nrates) {
-               printf("%uM",
+               printf("%uM ",
                    (nr->nr_rates[nr->nr_nrates - 1] & IEEE80211_RATE_VAL) / 2);
-               putchar(' ');
        }
        /* ESS is the default, skip it */
        nr->nr_capinfo &= ~IEEE80211_CAPINFO_ESS;
Index: sys/net80211/ieee80211_ioctl.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_ioctl.c,v
retrieving revision 1.41
diff -u -p -r1.41 ieee80211_ioctl.c
--- sys/net80211/ieee80211_ioctl.c      28 Apr 2016 13:50:14 -0000      1.41
+++ sys/net80211/ieee80211_ioctl.c      3 Jul 2016 13:00:32 -0000
@@ -112,6 +112,9 @@ ieee80211_node2req(struct ieee80211com *
        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;
+       nr->nr_txmcs = ni->ni_txmcs;
+       if (ni->ni_flags & IEEE80211_NODE_HT)
+               nr->nr_flags |= IEEE80211_NODEREQ_HT;
 }
 
 void
Index: sys/net80211/ieee80211_ioctl.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_ioctl.h,v
retrieving revision 1.26
diff -u -p -r1.26 ieee80211_ioctl.h
--- sys/net80211/ieee80211_ioctl.h      28 Apr 2016 14:46:10 -0000      1.26
+++ sys/net80211/ieee80211_ioctl.h      3 Jul 2016 12:58:58 -0000
@@ -339,6 +339,7 @@ struct ieee80211_nodereq {
        uint8_t                 nr_rxmcs[howmany(80,NBBY)];
        uint16_t                nr_max_rxrate;  /* in Mb/s, 0 <= rate <= 1023 */
        uint8_t                 nr_tx_mcs_set;
+       uint8_t                 nr_txmcs;
 };
 
 #define IEEE80211_NODEREQ_STATE(_s)    (1 << _s)
@@ -352,6 +353,7 @@ struct ieee80211_nodereq {
 #define IEEE80211_NODEREQ_AP           0x01    /* access point */
 #define IEEE80211_NODEREQ_AP_BSS       0x02    /* current bss access point */
 #define IEEE80211_NODEREQ_COPY         0x04    /* add node with flags */
+#define IEEE80211_NODEREQ_HT           0x08    /* HT negotiated */
 
 #define SIOCG80211NODE         _IOWR('i', 211, struct ieee80211_nodereq)
 #define SIOCS80211NODE          _IOW('i', 212, struct ieee80211_nodereq)

Reply via email to