]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
iw: scan: parse HE capabilities
authorBrian Norris <briannorris@chromium.org>
Wed, 18 Nov 2020 03:39:35 +0000 (19:39 -0800)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 30 Nov 2020 08:59:19 +0000 (09:59 +0100)
Signed-off-by: Brian Norris <briannorris@chromium.org>
Link: https://lore.kernel.org/r/20201118033936.3667788-4-briannorris@chromium.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
iw.h
scan.c
util.c

diff --git a/iw.h b/iw.h
index 77ed097f229b649a65d3cd1fe08fa4c999803ea4..807adecd3b06822313f72cdf6913929b34946c84 100644 (file)
--- a/iw.h
+++ b/iw.h
@@ -213,6 +213,7 @@ 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);
+void print_he_capability(const uint8_t *ie, int len);
 void print_he_info(struct nlattr *nl_iftype);
 
 char *channel_width_name(enum nl80211_chan_width width);
diff --git a/scan.c b/scan.c
index 58a09983c5c7a61aa3c8f93a713d5ea13c7a9034..dfc136a3943e7ea912362a4f461bcec447dcbe6c 100644 (file)
--- a/scan.c
+++ b/scan.c
@@ -2272,7 +2272,15 @@ static void print_vendor(unsigned char len, unsigned char *data,
        printf("\n");
 }
 
+static void print_he_capa(const uint8_t type, uint8_t len, const uint8_t *data,
+                         const struct print_ies_data *ie_buffer)
+{
+       printf("\n");
+       print_he_capability(data, len);
+}
+
 static const struct ie_print ext_printers[] = {
+       [35] = { "HE capabilities", print_he_capa, 21, 54, BIT(PRINT_SCAN), },
 };
 
 static void print_extension(unsigned char len, unsigned char *ie,
diff --git a/util.c b/util.c
index cb694378d3e8258fadce6fa27dc35f0eb2a622d5..7cbca3529be6e519fef23b95eadca2407c47cfe2 100644 (file)
--- a/util.c
+++ b/util.c
@@ -994,6 +994,7 @@ static void __print_he_capa(const __u16 *mac_cap,
                            const __u16 *mcs_set, size_t mcs_len,
                            const __u8 *ppet, int ppet_len)
 {
+       size_t mcs_used;
        int i;
 
        #define PRINT_HE_CAP(_var, _idx, _bit, _str) \
@@ -1124,6 +1125,7 @@ static void __print_he_capa(const __u16 *mac_cap,
        PRINT_HE_PHY_CAP(5, 4, "RX Full BW SU Using HE MU PPDU with Compression SIGB");
        PRINT_HE_PHY_CAP(5, 5, "RX Full BW SU Using HE MU PPDU with Non-Compression SIGB");
 
+       mcs_used = 0;
        for (i = 0; i < 3; i++) {
                __u8 phy_cap_support[] = { BIT(1) | BIT(2), BIT(3), BIT(4) };
                char *bw[] = { "<= 80", "160", "80+80" };
@@ -1151,6 +1153,16 @@ static void __print_he_capa(const __u16 *mac_cap,
                        }
 
                }
+               mcs_used += 2 * sizeof(mcs_set[0]);
+       }
+
+       /* Caller didn't provide ppet; infer it, if there's trailing space. */
+       if (!ppet) {
+               ppet = (const void *)(mcs_set + mcs_used);
+               if (mcs_used < mcs_len)
+                       ppet_len = mcs_len - mcs_used;
+               else
+                       ppet_len = 0;
        }
 
        if (ppet_len && (phy_cap[3] & BIT(15))) {
@@ -1236,6 +1248,24 @@ void print_he_info(struct nlattr *nl_iftype)
        __print_he_capa(mac_cap, phy_cap, mcs_set, mcs_len, ppet, ppet_len);
 }
 
+void print_he_capability(const uint8_t *ie, int len)
+{
+       const void *mac_cap, *phy_cap, *mcs_set;
+       int mcs_len;
+       int i = 0;
+
+       mac_cap = &ie[i];
+       i += 6;
+
+       phy_cap = &ie[i];
+       i += 11;
+
+       mcs_set = &ie[i];
+       mcs_len = len - i;
+
+       __print_he_capa(mac_cap, phy_cap - 1, mcs_set, mcs_len, NULL, 0);
+}
+
 void iw_hexdump(const char *prefix, const __u8 *buf, size_t size)
 {
        size_t i;