]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
print VHT capabilities
authorJohannes Berg <johannes.berg@intel.com>
Mon, 12 Nov 2012 12:07:18 +0000 (13:07 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 12 Nov 2012 12:07:18 +0000 (13:07 +0100)
ieee80211.h
info.c
iw.h
scan.c
util.c

index 622b042ec42747375d3868fcee2db15b70b78b4f..87456084e2a6202900822ab5317a2349aa550e06 100644 (file)
@@ -46,4 +46,16 @@ struct ieee80211_ht_cap {
        __u8 antenna_selection_info;
 } __attribute__ ((packed));
 
+struct ieee80211_vht_mcs_info {
+       __u16 rx_vht_mcs;
+       __u16 rx_highest;
+       __u16 tx_vht_mcs;
+       __u16 tx_highest;
+} __attribute__ ((packed));
+
+struct ieee80211_vht_cap {
+       __u32 cap_info;
+       struct ieee80211_vht_mcs_info mcs;
+} __attribute__ ((packed));
+
 #endif /* __IEEE80211 */
diff --git a/info.c b/info.c
index 5dab1e8897bb000e668f8a1d1d1e30d5d6394f5d..5d99bf82b599766b7ee0505fe24cf70beeb4b706 100644 (file)
--- a/info.c
+++ b/info.c
@@ -98,7 +98,6 @@ static int print_phy_handler(struct nl_msg *msg, void *arg)
                nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
                          nla_len(nl_band), NULL);
 
-#ifdef NL80211_BAND_ATTR_HT_CAPA
                if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) {
                        __u16 cap = nla_get_u16(tb_band[NL80211_BAND_ATTR_HT_CAPA]);
                        print_ht_capability(cap);
@@ -114,7 +113,10 @@ static int print_phy_handler(struct nl_msg *msg, void *arg)
                if (tb_band[NL80211_BAND_ATTR_HT_MCS_SET] &&
                    nla_len(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]) == 16)
                        print_ht_mcs(nla_data(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]));
-#endif
+               if (tb_band[NL80211_BAND_ATTR_VHT_CAPA] &&
+                   tb_band[NL80211_BAND_ATTR_VHT_MCS_SET])
+                       print_vht_info(nla_get_u32(tb_band[NL80211_BAND_ATTR_VHT_CAPA]),
+                                      nla_data(tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]));
 
                printf("\t\tFrequencies:\n");
 
diff --git a/iw.h b/iw.h
index 54ecbc3d584a3d6732c8435f29e5cfd10033c3c6..3e83bd2c65fc2c347b757589dcfd8e606a6ec2fc 100644 (file)
--- a/iw.h
+++ b/iw.h
@@ -143,6 +143,7 @@ void print_ht_mcs(const __u8 *mcs);
 void print_ampdu_length(__u8 exponent);
 void print_ampdu_spacing(__u8 spacing);
 void print_ht_capability(__u16 cap);
+void print_vht_info(__u32 capa, const __u8 *mcs);
 
 const char *iftype_name(enum nl80211_iftype iftype);
 const char *command_name(enum nl80211_commands cmd);
diff --git a/scan.c b/scan.c
index ec564d715d90a5b9fe247a1b2f7d08f415a801bd..38762b03184b617887ce004410bab0927505426b 100644 (file)
--- a/scan.c
+++ b/scan.c
@@ -671,6 +671,14 @@ static void print_tim(const uint8_t type, uint8_t len, const uint8_t *data)
        printf("\n");
 }
 
+static void print_vht_capa(const uint8_t type, uint8_t len, const uint8_t *data)
+{
+       printf("\n");
+       print_vht_info(data[0] | (data[1] << 8) |
+                      (data[2] << 16) | (data[3] << 24),
+                      data + 4);
+}
+
 struct ie_print {
        const char *name;
        void (*print)(const uint8_t type, uint8_t len, const uint8_t *data);
@@ -720,6 +728,7 @@ static const struct ie_print ieprinters[] = {
        [42] = { "ERP", print_erp, 1, 255, BIT(PRINT_SCAN), },
        [45] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), },
        [61] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), },
+       [191] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), },
        [48] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), },
        [50] = { "Extended supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), },
        [114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
diff --git a/util.c b/util.c
index 39a533e64819eca6ae3434e375119f0625cd14ca..c272c1dae9e3ad5b80415fa30c3da4ed893a3283 100644 (file)
--- a/util.c
+++ b/util.c
@@ -600,3 +600,77 @@ void print_ht_mcs(const __u8 *mcs)
                printf("\t\tHT TX MCS rate indexes are undefined\n");
        }
 }
+
+void print_vht_info(__u32 capa, const __u8 *mcs)
+{
+       __u16 tmp;
+       int i;
+
+       printf("\t\tVHT Capabilities (0x%.8x):\n", capa);
+
+#define PRINT_VHT_CAPA(_bit, _str) \
+       do { \
+               if (capa & BIT(_bit)) \
+                       printf("\t\t\t" _str "\n"); \
+       } while (0)
+
+       printf("\t\t\tMax MPDU length: ");
+       switch (capa & 3) {
+       case 0: printf("3895\n"); break;
+       case 1: printf("7991\n"); break;
+       case 2: printf("11454\n"); break;
+       case 3: printf("(reserved)\n");
+       }
+       printf("\t\t\tSupported Channel Width: ");
+       switch ((capa >> 2) & 3) {
+       case 0: printf("neither 160 nor 80+80\n"); break;
+       case 1: printf("160 MHz\n"); break;
+       case 2: printf("160 MHz, 80+80 MHz\n"); break;
+       case 3: printf("(reserved)\n");
+       }
+       PRINT_VHT_CAPA(4, "RX LDPC");
+       PRINT_VHT_CAPA(5, "short GI (80 MHz)");
+       PRINT_VHT_CAPA(6, "short GI (160/80+80 MHz)");
+       PRINT_VHT_CAPA(7, "TX STBC");
+       /* RX STBC */
+       PRINT_VHT_CAPA(11, "SU Beamformer");
+       PRINT_VHT_CAPA(12, "SU Beamformee");
+       /* compressed steering */
+       /* # of sounding dimensions */
+       PRINT_VHT_CAPA(19, "MU Beamformer");
+       PRINT_VHT_CAPA(20, "MU Beamformee");
+       PRINT_VHT_CAPA(21, "VHT TXOP PS");
+       PRINT_VHT_CAPA(22, "+HTC-VHT");
+       /* max A-MPDU */
+       /* VHT link adaptation */
+       PRINT_VHT_CAPA(29, "RX antenna pattern consistency");
+       PRINT_VHT_CAPA(30, "TX antenna pattern consistency");
+
+       printf("\t\tVHT RX MCS set:\n");
+       tmp = mcs[0] | (mcs[1] << 8);
+       for (i = 1; i <= 8; i++) {
+               printf("\t\t\t%d streams: ", i);
+               switch ((tmp >> ((i-1)*2) ) & 3) {
+               case 0: printf("MCS 0-7\n"); break;
+               case 1: printf("MCS 0-8\n"); break;
+               case 2: printf("MCS 0-9\n"); break;
+               case 3: printf("not supported\n"); break;
+               }
+       }
+       tmp = mcs[2] | (mcs[3] << 8);
+       printf("\t\tVHT RX highest supported: %d Mbps\n", tmp & 0x1fff);
+
+       printf("\t\tVHT TX MCS set:\n");
+       tmp = mcs[4] | (mcs[5] << 8);
+       for (i = 1; i <= 8; i++) {
+               printf("\t\t\t%d streams: ", i);
+               switch ((tmp >> ((i-1)*2) ) & 3) {
+               case 0: printf("MCS 0-7\n"); break;
+               case 1: printf("MCS 0-8\n"); break;
+               case 2: printf("MCS 0-9\n"); break;
+               case 3: printf("not supported\n"); break;
+               }
+       }
+       tmp = mcs[6] | (mcs[7] << 8);
+       printf("\t\tVHT TX highest supported: %d Mbps\n", tmp & 0x1fff);
+}