iwinfo: add basic IEEE 802.11ax support
authorDavid Bauer <mail@david-bauer.net>
Thu, 17 Dec 2020 19:39:56 +0000 (20:39 +0100)
committerDavid Bauer <mail@david-bauer.net>
Mon, 12 Apr 2021 21:45:42 +0000 (23:45 +0200)
This adds basic support for IEEE 802.11ax when requesting HW or HT
Modelist for a PHY from iwinfo. This way, applications using iwinfo can
detect HE phys.

Signed-off-by: David Bauer <mail@david-bauer.net>
api/nl80211.h
include/iwinfo.h
iwinfo_cli.c
iwinfo_lib.c
iwinfo_lua.c
iwinfo_nl80211.c

index 5b7b5ebe7ca8731868e38bfab6218c166cb0317d..3d252e49a6ac71f7f5fadc00dd30e3b2aae4f63a 100644 (file)
@@ -2582,6 +2582,41 @@ enum nl80211_mpath_info {
        NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1
 };
 
+/**
+ * enum nl80211_band_iftype_attr - Interface type data attributes
+ *
+ * @__NL80211_BAND_IFTYPE_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_BAND_IFTYPE_ATTR_IFTYPES: nested attribute containing a flag attribute
+ *     for each interface type that supports the band data
+ * @NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC: HE MAC capabilities as in HE
+ *     capabilities IE
+ * @NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY: HE PHY capabilities as in HE
+ *     capabilities IE
+ * @NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET: HE supported NSS/MCS as in HE
+ *     capabilities IE
+ * @NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE: HE PPE thresholds information as
+ *     defined in HE capabilities IE
+ * @NL80211_BAND_IFTYPE_ATTR_MAX: highest band HE capability attribute currently
+ *     defined
+ * @NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA: HE 6GHz band capabilities (__le16),
+ *     given for all 6 GHz band channels
+ * @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_band_iftype_attr {
+       __NL80211_BAND_IFTYPE_ATTR_INVALID,
+
+       NL80211_BAND_IFTYPE_ATTR_IFTYPES,
+       NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
+       NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
+       NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
+       NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
+       NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
+
+       /* keep last */
+       __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST,
+       NL80211_BAND_IFTYPE_ATTR_MAX = __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST - 1
+};
+
 /**
  * enum nl80211_band_attr - band attributes
  * @__NL80211_BAND_ATTR_INVALID: attribute number 0 is reserved
@@ -2597,6 +2632,8 @@ enum nl80211_mpath_info {
  * @NL80211_BAND_ATTR_VHT_MCS_SET: 32-byte attribute containing the MCS set as
  *     defined in 802.11ac
  * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE
+ * @NL80211_BAND_ATTR_IFTYPE_DATA: nested array attribute, with each entry using
+ *     attributes from &enum nl80211_band_iftype_attr
  * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
  * @__NL80211_BAND_ATTR_AFTER_LAST: internal use
  */
@@ -2612,6 +2649,7 @@ enum nl80211_band_attr {
 
        NL80211_BAND_ATTR_VHT_MCS_SET,
        NL80211_BAND_ATTR_VHT_CAPA,
+       NL80211_BAND_ATTR_IFTYPE_DATA,
 
        /* keep last */
        __NL80211_BAND_ATTR_AFTER_LAST,
index 40ef3a7b60246ac5399099208dafcf47c808eed7..1956abe063f1af5b2771fe5eec11683f668e9117 100644 (file)
@@ -29,6 +29,7 @@
 #define IWINFO_80211_N       (1 << 3)
 #define IWINFO_80211_AC      (1 << 4)
 #define IWINFO_80211_AD      (1 << 5)
+#define IWINFO_80211_AX      (1 << 6)
 
 #define IWINFO_CIPHER_NONE   (1 << 0)
 #define IWINFO_CIPHER_WEP40  (1 << 1)
@@ -90,8 +91,13 @@ enum iwinfo_htmode {
        IWINFO_HTMODE_VHT80_80   = (1 << 5),
        IWINFO_HTMODE_VHT160     = (1 << 6),
        IWINFO_HTMODE_NOHT       = (1 << 7),
+       IWINFO_HTMODE_HE20       = (1 << 8),
+       IWINFO_HTMODE_HE40       = (1 << 9),
+       IWINFO_HTMODE_HE80       = (1 << 10),
+       IWINFO_HTMODE_HE80_80    = (1 << 11),
+       IWINFO_HTMODE_HE160      = (1 << 12),
 
-       IWINFO_HTMODE_COUNT      = 8
+       IWINFO_HTMODE_COUNT      = 13
 };
 
 extern const char *IWINFO_HTMODE_NAMES[IWINFO_HTMODE_COUNT];
index 4976790e835670337d4dbbe6814a6ead51e64df0..ee5a0e2dde428481dedf9ca16cfb23598bc7819c 100644 (file)
@@ -285,7 +285,8 @@ static char * format_hwmodes(int modes)
                        (modes & IWINFO_80211_G) ? "g" : "",
                        (modes & IWINFO_80211_N) ? "n" : "",
                        (modes & IWINFO_80211_AC) ? "ac" : "",
-                       (modes & IWINFO_80211_AD) ? "ad" : "");
+                       (modes & IWINFO_80211_AD) ? "ad" : "",
+                       (modes & IWINFO_80211_AX) ? "ax" : "");
 
        return buf;
 }
index 7a33a35a34e62a6c0a39d5ba2932153c73312d49..70b080cedfc07be6b001f7084ad63ffe69d92f3f 100644 (file)
@@ -65,7 +65,12 @@ const char *IWINFO_HTMODE_NAMES[] = {
        "VHT80",
        "VHT80+80",
        "VHT160",
-       "NOHT"
+       "NOHT",
+       "HE20",
+       "HE40",
+       "HE80",
+       "HE80+80",
+       "HE160"
 };
 
 
index abe848bc4c2a058448f57a3d82d4f17231286e7c..9935a8daa5d7a840cbbaec199496fe3de662af8c 100644 (file)
@@ -530,6 +530,9 @@ static int iwinfo_L_hwmodelist(lua_State *L, int (*func)(const char *, int *))
                lua_pushboolean(L, hwmodes & IWINFO_80211_AD);
                lua_setfield(L, -2, "ad");
 
+               lua_pushboolean(L, hwmodes & IWINFO_80211_AX);
+               lua_setfield(L, -2, "ax");
+
                return 1;
        }
 
index 08b5dece85bdf2016f141ffb104ed60082628be7..6e79ec8974088c4c9fb2a0dd7b303acc59cfe2cc 100644 (file)
@@ -2974,6 +2974,40 @@ static int nl80211_get_modelist_cb(struct nl_msg *msg, void *arg)
                                        m->ht |= IWINFO_HTMODE_HT40;
                        }
 
+                       if (bands[NL80211_BAND_ATTR_IFTYPE_DATA]) {
+                               struct nlattr *tb[NL80211_BAND_IFTYPE_ATTR_MAX + 1];
+                               uint16_t phy_cap[6] = { 0 };
+                               struct nlattr *nl_iftype;
+                               int rem_band;
+                               int len;
+
+                               m->hw |= IWINFO_80211_AX;
+                               m->ht |= IWINFO_HTMODE_HE20;
+
+                               nla_for_each_nested(nl_iftype, bands[NL80211_BAND_ATTR_IFTYPE_DATA], rem_band) {
+                                       nla_parse(tb, NL80211_BAND_IFTYPE_ATTR_MAX,
+                                                 nla_data(nl_iftype), nla_len(nl_iftype), NULL);
+                                       if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]) {
+                                               len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]);
+
+                                               if (len > sizeof(phy_cap) - 1)
+                                                       len = sizeof(phy_cap) - 1;
+                                               memcpy(&((__u8 *)phy_cap)[1],
+                                                       nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]),
+                                                       len);
+                                       }
+
+                                       if (phy_cap[0] & BIT(9))
+                                               m->ht |= IWINFO_HTMODE_HE40;
+                                       if (phy_cap[0] & BIT(10))
+                                               m->ht |= IWINFO_HTMODE_HE40 | IWINFO_HTMODE_HE80;
+                                       if (phy_cap[0] & BIT(11))
+                                               m->ht |= IWINFO_HTMODE_HE160;
+                                       if (phy_cap[0] & BIT(12))
+                                               m->ht |= IWINFO_HTMODE_HE160 | IWINFO_HTMODE_HE80_80;
+                               }
+                       }
+
                        nla_for_each_nested(freq, bands[NL80211_BAND_ATTR_FREQS],
                                            freqs_remain)
                        {