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)