diff mbox series

[iwinfo] iwinfo: add basic IEEE 802.11ax support

Message ID 20210203192011.256391-1-mail@david-bauer.net
State Accepted
Delegated to: David Bauer
Headers show
Series [iwinfo] iwinfo: add basic IEEE 802.11ax support | expand

Commit Message

David Bauer Feb. 3, 2021, 7:20 p.m. UTC
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    | 38 ++++++++++++++++++++++++++++++++++++++
 include/iwinfo.h |  8 +++++++-
 iwinfo_cli.c     |  3 ++-
 iwinfo_lib.c     |  7 ++++++-
 iwinfo_lua.c     |  3 +++
 iwinfo_nl80211.c | 34 ++++++++++++++++++++++++++++++++++
 6 files changed, 90 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/api/nl80211.h b/api/nl80211.h
index 5b7b5eb..3d252e4 100644
--- a/api/nl80211.h
+++ b/api/nl80211.h
@@ -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,
diff --git a/include/iwinfo.h b/include/iwinfo.h
index 5e64294..d1753ef 100644
--- a/include/iwinfo.h
+++ b/include/iwinfo.h
@@ -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)
@@ -89,8 +90,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];
diff --git a/iwinfo_cli.c b/iwinfo_cli.c
index 0332bc2..c18ea49 100644
--- a/iwinfo_cli.c
+++ b/iwinfo_cli.c
@@ -282,7 +282,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;
 }
diff --git a/iwinfo_lib.c b/iwinfo_lib.c
index 7a33a35..70b080c 100644
--- a/iwinfo_lib.c
+++ b/iwinfo_lib.c
@@ -65,7 +65,12 @@  const char *IWINFO_HTMODE_NAMES[] = {
 	"VHT80",
 	"VHT80+80",
 	"VHT160",
-	"NOHT"
+	"NOHT",
+	"HE20",
+	"HE40",
+	"HE80",
+	"HE80+80",
+	"HE160"
 };
 
 
diff --git a/iwinfo_lua.c b/iwinfo_lua.c
index 58a5537..652633b 100644
--- a/iwinfo_lua.c
+++ b/iwinfo_lua.c
@@ -527,6 +527,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;
 	}
 
diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c
index 2b2a043..8b13782 100644
--- a/iwinfo_nl80211.c
+++ b/iwinfo_nl80211.c
@@ -2887,6 +2887,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)
 			{