[openwrt/openwrt] iw: backport WiFi 7 (EHT) scan support

LEDE Commits lede-commits at lists.infradead.org
Sun May 11 04:09:35 PDT 2025


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/3d9236d4512c5cfca9cbe6c452f56d3a682c2ada

commit 3d9236d4512c5cfca9cbe6c452f56d3a682c2ada
Author: Aleksander Jan Bajkowski <olek2 at wp.pl>
AuthorDate: Sat Mar 29 23:39:19 2025 +0100

    iw: backport WiFi 7 (EHT) scan support
    
    Backport patches to support scans of WiFi 7 APs.
    
    Signed-off-by: Aleksander Jan Bajkowski <olek2 at wp.pl>
    Link: https://github.com/openwrt/openwrt/pull/18741
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 package/network/utils/iw/Makefile                  |   2 +-
 .../103-iw-scan-add-enum-for-element-IDs.patch     | 170 ++++++++
 ...-replace-passed-ie-buffer-with-ie-context.patch | 482 +++++++++++++++++++++
 ...til-update-and-clean-up-eht-capa-printing.patch | 207 +++++++++
 .../106-iw-scan-add-eht-capability-parsing.patch   | 175 ++++++++
 ...-EHT-capabilities-on-Big-Endian-platforms.patch | 107 +++++
 ...can-Add-printing-of-EHT-Operation-Element.patch | 131 ++++++
 .../network/utils/iw/patches/200-reduce_size.patch | 107 ++---
 8 files changed, 1330 insertions(+), 51 deletions(-)

diff --git a/package/network/utils/iw/Makefile b/package/network/utils/iw/Makefile
index c59adbaab5..1734062471 100644
--- a/package/network/utils/iw/Makefile
+++ b/package/network/utils/iw/Makefile
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=iw
 PKG_VERSION:=6.9
-PKG_RELEASE:=3
+PKG_RELEASE:=4
  
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=@KERNEL/software/network/iw
diff --git a/package/network/utils/iw/patches/103-iw-scan-add-enum-for-element-IDs.patch b/package/network/utils/iw/patches/103-iw-scan-add-enum-for-element-IDs.patch
new file mode 100644
index 0000000000..abf699f2ff
--- /dev/null
+++ b/package/network/utils/iw/patches/103-iw-scan-add-enum-for-element-IDs.patch
@@ -0,0 +1,170 @@
+From 966c590bc4dcbd9a69fdf8fe9f41cec00e72e376 Mon Sep 17 00:00:00 2001
+From: Dylan Eskew <dylan.eskew at candelatech.com>
+Date: Mon, 30 Sep 2024 11:11:43 -0700
+Subject: [PATCH] iw: scan: add enum for element IDs
+
+Formerly, element IDs were hardcoded. Improve readability by using
+element ID names.
+
+Signed-off-by: Dylan Eskew <dylan.eskew at candelatech.com>
+Link: https://patch.msgid.link/20240930181145.1043048-2-dylan.eskew@candelatech.com
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+ ieee80211.h | 43 +++++++++++++++++++++++++++
+ scan.c      | 86 +++++++++++++++++++++++++++++++----------------------
+ 2 files changed, 93 insertions(+), 36 deletions(-)
+
+--- a/ieee80211.h
++++ b/ieee80211.h
+@@ -58,6 +58,49 @@ struct ieee80211_vht_cap {
+ 	struct ieee80211_vht_mcs_info mcs;
+ } __attribute__ ((packed));
+ 
++enum elem_id {
++	EID_SSID			= 0,
++	EID_SUPP_RATES			= 1,
++	EID_DS_PARAMS			= 3,
++	EID_TIM				= 5,
++	EID_IBSS_TIM_PARAMS		= 6,
++	EID_COUNTRY			= 7,
++	EID_BSS_LOAD			= 11,
++	EID_POWER_CONSTRAINT		= 32,
++	EID_TPC_REPORT			= 35,
++	EID_ERP_INFO			= 42,
++	EID_HT_CAPABILITY		= 45,
++	EID_ERP_D4_0			= 47,
++	EID_RSN				= 48,
++	EID_EXT_SUPP_RATES		= 50,
++	EID_AP_CHAN_REPORT		= 51,
++	EID_SUPP_OP_CLASSES		= 59,
++	EID_HT_OPERATION		= 61,
++	EID_SECONDARY_CH_OFFSET		= 62,
++	EID_MEASUREMENT_PILOT_TX	= 66,
++	EID_RM_ENABLED_CAPABILITIES	= 70,
++	EID_OVERLAP_BSS_SCAN_PARAM	= 74,
++	EID_INTERWORKING		= 107,
++	EID_ADVERTISEMENT		= 108,
++	EID_ROAMING_CONSORTIUM		= 111,
++	EID_MESH_CONFIG			= 113,
++	EID_MESH_ID			= 114,
++	EID_EXT_CAPABILITY		= 127,
++	EID_VHT_CAPABILITY		= 191,
++	EID_VHT_OPERATION		= 192,
++	EID_TRANSMIT_POWER_ENVELOPE	= 195,
++	EID_SHORT_BEACON_INTERVAL	= 214,
++	EID_S1G_CAPABILITY		= 217,
++	EID_VENDOR			= 221,
++	EID_S1G_OPERATION		= 232,
++	EID_EXTENSION			= 255,
++};
++
++enum elem_id_ext {
++	EID_EXT_HE_CAPABILITY		= 35,
++	EID_EXT_HE_OPERATION		= 36,
++};
++
+ #define SUITE(oui, id)  (((oui) << 8) | (id))
+ 
+ /* cipher suite selectors */
+--- a/scan.c
++++ b/scan.c
+@@ -1816,40 +1816,54 @@ static void print_ie(const struct ie_pri
+ }
+ 
+ static const struct ie_print ieprinters[] = {
+-	[0] = { "SSID", print_ssid, 0, 32,
+-		 BIT(PRINT_SCAN) | BIT(PRINT_LINK) | BIT(PRINT_LINK_MLO_MLD), },
+-	[1] = { "Supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), },
+-	[3] = { "DS Parameter set", print_ds, 1, 1, BIT(PRINT_SCAN), },
+-	[5] = { "TIM", print_tim, 4, 255, BIT(PRINT_SCAN), },
+-	[6] = { "IBSS ATIM window", print_ibssatim, 2, 2, BIT(PRINT_SCAN), },
+-	[7] = { "Country", print_country, 3, 255, BIT(PRINT_SCAN), },
+-	[11] = { "BSS Load", print_bss_load, 5, 5, BIT(PRINT_SCAN), },
+-	[32] = { "Power constraint", print_powerconstraint, 1, 1, BIT(PRINT_SCAN), },
+-	[35] = { "TPC report", print_tpcreport, 2, 2, BIT(PRINT_SCAN), },
+-	[42] = { "ERP", print_erp, 1, 255, BIT(PRINT_SCAN), },
+-	[45] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), },
+-	[47] = { "ERP D4.0", print_erp, 1, 255, BIT(PRINT_SCAN), },
+-	[51] = { "AP Channel Report", print_ap_channel_report, 1, 255, BIT(PRINT_SCAN), },
+-	[59] = { "Supported operating classes", print_supp_op_classes, 1, 255, BIT(PRINT_SCAN), },
+-	[66] = { "Measurement Pilot Transmission", print_measurement_pilot_tx, 1, 255, BIT(PRINT_SCAN), },
+-	[74] = { "Overlapping BSS scan params", print_obss_scan_params, 14, 255, BIT(PRINT_SCAN), },
+-	[61] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), },
+-	[62] = { "Secondary Channel Offset", print_secchan_offs, 1, 1, BIT(PRINT_SCAN), },
+-	[191] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), },
+-	[192] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), },
+-	[48] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), },
+-	[50] = { "Extended supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), },
+-	[70] = { "RM enabled capabilities", print_rm_enabled_capabilities, 5, 5, BIT(PRINT_SCAN), },
+-	[113] = { "MESH Configuration", print_mesh_conf, 7, 7, BIT(PRINT_SCAN), },
+-	[114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
+-	[127] = { "Extended capabilities", print_capabilities, 0, 255, BIT(PRINT_SCAN), },
+-	[107] = { "802.11u Interworking", print_interworking, 0, 255, BIT(PRINT_SCAN), },
+-	[108] = { "802.11u Advertisement", print_11u_advert, 0, 255, BIT(PRINT_SCAN), },
+-	[111] = { "802.11u Roaming Consortium", print_11u_rcon, 2, 255, BIT(PRINT_SCAN), },
+-	[195] = { "Transmit Power Envelope", print_tx_power_envelope, 2, 5, BIT(PRINT_SCAN), },
+-	[214] = { "Short beacon interval", print_short_beacon_int, 2, 2, BIT(PRINT_SCAN), },
+-	[217] = { "S1G capabilities", print_s1g_capa, 15, 15, BIT(PRINT_SCAN), },
+-	[232] = { "S1G operation", print_s1g_oper, 6, 6, BIT(PRINT_SCAN), },
++	[EID_SSID] = { "SSID", print_ssid, 0, 32,
++		       BIT(PRINT_SCAN) | BIT(PRINT_LINK) | BIT(PRINT_LINK_MLO_MLD), },
++	[EID_SUPP_RATES] = { "Supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), },
++	[EID_DS_PARAMS] = { "DS Parameter set", print_ds, 1, 1, BIT(PRINT_SCAN), },
++	[EID_TIM] = { "TIM", print_tim, 4, 255, BIT(PRINT_SCAN), },
++	[EID_IBSS_TIM_PARAMS] = { "IBSS ATIM window", print_ibssatim, 2, 2, BIT(PRINT_SCAN), },
++	[EID_COUNTRY] = { "Country", print_country, 3, 255, BIT(PRINT_SCAN), },
++	[EID_BSS_LOAD] = { "BSS Load", print_bss_load, 5, 5, BIT(PRINT_SCAN), },
++	[EID_POWER_CONSTRAINT] = { "Power constraint", print_powerconstraint,
++				   1, 1, BIT(PRINT_SCAN), },
++	[EID_TPC_REPORT] = { "TPC report", print_tpcreport, 2, 2, BIT(PRINT_SCAN), },
++	[EID_ERP_INFO] = { "ERP", print_erp, 1, 255, BIT(PRINT_SCAN), },
++	[EID_HT_CAPABILITY] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), },
++	[EID_ERP_D4_0] = { "ERP D4.0", print_erp, 1, 255, BIT(PRINT_SCAN), },
++	[EID_AP_CHAN_REPORT] = { "AP Channel Report", print_ap_channel_report,
++				 1, 255, BIT(PRINT_SCAN), },
++	[EID_SUPP_OP_CLASSES] = { "Supported operating classes",
++				  print_supp_op_classes, 1, 255, BIT(PRINT_SCAN), },
++	[EID_MEASUREMENT_PILOT_TX] = { "Measurement Pilot Transmission",
++				       print_measurement_pilot_tx, 1, 255, BIT(PRINT_SCAN), },
++	[EID_OVERLAP_BSS_SCAN_PARAM] = { "Overlapping BSS scan params",
++					 print_obss_scan_params, 14, 255, BIT(PRINT_SCAN), },
++	[EID_HT_OPERATION] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), },
++	[EID_SECONDARY_CH_OFFSET] = { "Secondary Channel Offset",
++				      print_secchan_offs, 1, 1, BIT(PRINT_SCAN), },
++	[EID_VHT_CAPABILITY] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), },
++	[EID_VHT_OPERATION] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), },
++	[EID_RSN] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), },
++	[EID_EXT_SUPP_RATES] = { "Extended supported rates", print_supprates,
++				 0, 255, BIT(PRINT_SCAN), },
++	[EID_RM_ENABLED_CAPABILITIES] = { "RM enabled capabilities",
++					  print_rm_enabled_capabilities, 5, 5, BIT(PRINT_SCAN), },
++	[EID_MESH_CONFIG] = { "MESH Configuration", print_mesh_conf, 7, 7, BIT(PRINT_SCAN), },
++	[EID_MESH_ID] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
++	[EID_EXT_CAPABILITY] = { "Extended capabilities", print_capabilities,
++				 0, 255, BIT(PRINT_SCAN), },
++	[EID_INTERWORKING] = { "802.11u Interworking", print_interworking,
++			       0, 255, BIT(PRINT_SCAN), },
++	[EID_ADVERTISEMENT] = { "802.11u Advertisement", print_11u_advert,
++				0, 255, BIT(PRINT_SCAN), },
++	[EID_ROAMING_CONSORTIUM] = { "802.11u Roaming Consortium",
++				     print_11u_rcon, 2, 255, BIT(PRINT_SCAN), },
++	[EID_TRANSMIT_POWER_ENVELOPE] = { "Transmit Power Envelope",
++					  print_tx_power_envelope, 2, 5, BIT(PRINT_SCAN), },
++	[EID_SHORT_BEACON_INTERVAL] = { "Short beacon interval",
++					print_short_beacon_int, 2, 2, BIT(PRINT_SCAN), },
++	[EID_S1G_CAPABILITY] = { "S1G capabilities", print_s1g_capa, 15, 15, BIT(PRINT_SCAN), },
++	[EID_S1G_OPERATION] = { "S1G operation", print_s1g_oper, 6, 6, BIT(PRINT_SCAN), },
+ };
+ 
+ static void print_wifi_wpa(const uint8_t type, uint8_t len, const uint8_t *data,
+@@ -2392,8 +2406,8 @@ static void print_he_oper(const uint8_t
+ }
+ 
+ static const struct ie_print ext_printers[] = {
+-	[35] = { "HE capabilities", print_he_capa, 21, 54, BIT(PRINT_SCAN), },
+-	[36] = { "HE Operation", print_he_oper, 6, 15, BIT(PRINT_SCAN), },
++	[EID_EXT_HE_CAPABILITY] = { "HE capabilities", print_he_capa, 21, 54, BIT(PRINT_SCAN), },
++	[EID_EXT_HE_OPERATION] = { "HE Operation", print_he_oper, 6, 15, BIT(PRINT_SCAN), },
+ };
+ 
+ static void print_extension(unsigned char len, unsigned char *ie,
diff --git a/package/network/utils/iw/patches/104-iw-scan-replace-passed-ie-buffer-with-ie-context.patch b/package/network/utils/iw/patches/104-iw-scan-replace-passed-ie-buffer-with-ie-context.patch
new file mode 100644
index 0000000000..aa8b8b16a0
--- /dev/null
+++ b/package/network/utils/iw/patches/104-iw-scan-replace-passed-ie-buffer-with-ie-context.patch
@@ -0,0 +1,482 @@
+From a0a7ddef29fc412cee7e3ca027905218b145a40f Mon Sep 17 00:00:00 2001
+From: Dylan Eskew <dylan.eskew at candelatech.com>
+Date: Fri, 22 Nov 2024 08:18:51 -0800
+Subject: [PATCH] iw: scan: replace passed ie buffer with ie context
+
+Since some ies require references to other ies, parse
+the ie list once before to create a context and prevent
+parsing more than the two times required.
+
+Signed-off-by: Dylan Eskew <dylan.eskew at candelatech.com>
+Link: https://patch.msgid.link/20241122161851.647214-1-dylan.eskew@candelatech.com
+[cleanups]
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+ scan.c | 141 +++++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 76 insertions(+), 65 deletions(-)
+
+--- a/scan.c
++++ b/scan.c
+@@ -554,13 +554,12 @@ static void tab_on_first(bool *first)
+ 		*first = false;
+ }
+ 
+-struct print_ies_data {
+-	unsigned char *ie;
+-	int ielen;
++struct ie_context {
++	bool is_vht_cap;
+ };
+ 
+ static void print_ssid(const uint8_t type, uint8_t len, const uint8_t *data,
+-		       const struct print_ies_data *ie_buffer)
++		       const struct ie_context *ctx)
+ {
+ 	printf(" ");
+ 	print_ssid_escaped(len, data);
+@@ -572,7 +571,7 @@ static void print_ssid(const uint8_t typ
+ 
+ static void print_supprates(const uint8_t type, uint8_t len,
+ 			    const uint8_t *data,
+-			    const struct print_ies_data *ie_buffer)
++			    const struct ie_context *ctx)
+ {
+ 	int i;
+ 
+@@ -595,7 +594,7 @@ static void print_supprates(const uint8_
+ 
+ static void print_rm_enabled_capabilities(const uint8_t type, uint8_t len,
+ 			    const uint8_t *data,
+-			    const struct print_ies_data *ie_buffer)
++			    const struct ie_context *ctx)
+ {
+ 	__u64 capa = ((__u64) data[0]) |
+ 		     ((__u64) data[1]) << 8 |
+@@ -649,7 +648,7 @@ static void print_rm_enabled_capabilitie
+ }
+ 
+ static void print_ds(const uint8_t type, uint8_t len, const uint8_t *data,
+-		     const struct print_ies_data *ie_buffer)
++		     const struct ie_context *ctx)
+ {
+ 	printf(" channel %d\n", data[0]);
+ }
+@@ -669,7 +668,7 @@ static const char *country_env_str(char
+ }
+ 
+ static void print_country(const uint8_t type, uint8_t len, const uint8_t *data,
+-			  const struct print_ies_data *ie_buffer)
++			  const struct ie_context *ctx)
+ {
+ 	printf(" %.*s", 2, data);
+ 
+@@ -716,21 +715,21 @@ static void print_country(const uint8_t
+ 
+ static void print_powerconstraint(const uint8_t type, uint8_t len,
+ 				  const uint8_t *data,
+-				  const struct print_ies_data *ie_buffer)
++				  const struct ie_context *ctx)
+ {
+ 	printf(" %d dB\n", data[0]);
+ }
+ 
+ static void print_tpcreport(const uint8_t type, uint8_t len,
+ 			    const uint8_t *data,
+-			    const struct print_ies_data *ie_buffer)
++			    const struct ie_context *ctx)
+ {
+ 	printf(" TX power: %d dBm\n", data[0]);
+ 	/* printf(" Link Margin (%d dB) is reserved in Beacons\n", data[1]); */
+ }
+ 
+ static void print_erp(const uint8_t type, uint8_t len, const uint8_t *data,
+-		      const struct print_ies_data *ie_buffer)
++		      const struct ie_context *ctx)
+ {
+ 	if (data[0] == 0x00)
+ 		printf(" <no flags>");
+@@ -744,7 +743,7 @@ static void print_erp(const uint8_t type
+ }
+ 
+ static void print_ap_channel_report(const uint8_t type, uint8_t len, const uint8_t *data,
+-				    const struct print_ies_data *ie_buffer)
++				    const struct ie_context *ctx)
+ {
+ 	uint8_t oper_class = data[0];
+ 	int i;
+@@ -1084,13 +1083,13 @@ static void print_osen_ie(const char *de
+ }
+ 
+ static void print_rsn(const uint8_t type, uint8_t len, const uint8_t *data,
+-		      const struct print_ies_data *ie_buffer)
++		      const struct ie_context *ctx)
+ {
+ 	print_rsn_ie("CCMP", "IEEE 802.1X", len, data);
+ }
+ 
+ static void print_ht_capa(const uint8_t type, uint8_t len, const uint8_t *data,
+-			  const struct print_ies_data *ie_buffer)
++			  const struct ie_context *ctx)
+ {
+ 	printf("\n");
+ 	print_ht_capability(data[0] | (data[1] << 8));
+@@ -1135,7 +1134,7 @@ static const char* vgroup_11u(uint8_t t)
+ 
+ static void print_interworking(const uint8_t type, uint8_t len,
+ 			       const uint8_t *data,
+-			       const struct print_ies_data *ie_buffer)
++			       const struct ie_context *ctx)
+ {
+ 	/* See Section 7.3.2.92 in the 802.11u spec. */
+ 	printf("\n");
+@@ -1168,7 +1167,7 @@ static void print_interworking(const uin
+ 
+ static void print_11u_advert(const uint8_t type, uint8_t len,
+ 			     const uint8_t *data,
+-			     const struct print_ies_data *ie_buffer)
++			     const struct ie_context *ctx)
+ {
+ 	/* See Section 7.3.2.93 in the 802.11u spec. */
+ 	/* TODO: This code below does not decode private protocol IDs */
+@@ -1201,7 +1200,7 @@ static void print_11u_advert(const uint8
+ }
+ 
+ static void print_11u_rcon(const uint8_t type, uint8_t len, const uint8_t *data,
+-			   const struct print_ies_data *ie_buffer)
++			   const struct ie_context *ctx)
+ {
+ 	/* See Section 7.3.2.96 in the 802.11u spec. */
+ 	int idx = 0;
+@@ -1254,7 +1253,7 @@ static void print_11u_rcon(const uint8_t
+ 
+ static void print_tx_power_envelope(const uint8_t type, uint8_t len,
+ 				    const uint8_t *data,
+-				    const struct print_ies_data *ie_buffer)
++				    const struct ie_context *ctx)
+ {
+ 	const uint8_t local_max_tx_power_count = data[0] & 7;
+ 	const uint8_t local_max_tx_power_unit_interp = (data[0] >> 3) & 7;
+@@ -1290,7 +1289,7 @@ static const char *ht_secondary_offset[4
+ };
+ 
+ static void print_ht_op(const uint8_t type, uint8_t len, const uint8_t *data,
+-			const struct print_ies_data *ie_buffer)
++			const struct ie_context *ctx)
+ {
+ 	static const char *protection[4] = {
+ 		"no",
+@@ -1322,21 +1321,10 @@ static void print_ht_op(const uint8_t ty
+ 
+ static void print_capabilities(const uint8_t type, uint8_t len,
+ 			       const uint8_t *data,
+-			       const struct print_ies_data *ie_buffer)
++			       const struct ie_context *ctx)
+ {
+ 	int i, base, bit, si_duration = 0, max_amsdu = 0;
+-	bool s_psmp_support = false, is_vht_cap = false;
+-	unsigned char *ie = ie_buffer->ie;
+-	int ielen = ie_buffer->ielen;
+-
+-	while (ielen >= 2 && ielen >= ie[1]) {
+-		if (ie[0] == 191) {
+-			is_vht_cap = true;
+-			break;
+-		}
+-		ielen -= ie[1] + 2;
+-		ie += ie[1] + 2;
+-	}
++	bool s_psmp_support = false;
+ 
+ 	for (i = 0; i < len; i++) {
+ 		base = i * 8;
+@@ -1432,8 +1420,8 @@ static void print_capabilities(const uin
+ 			CAPA(61, "TDLS Wider Bandwidth");
+ 			CAPA(62, "Operating Mode Notification");
+ 
+-			ADD_BIT_VAL(63, is_vht_cap, max_amsdu, 1);
+-			ADD_BIT_VAL(64, is_vht_cap, max_amsdu, 2);
++			ADD_BIT_VAL(63, ctx->is_vht_cap, max_amsdu, 1);
++			ADD_BIT_VAL(64, ctx->is_vht_cap, max_amsdu, 2);
+ 
+ 			CAPA(65, "Channel Schedule Management");
+ 			CAPA(66, "Geodatabase Inband Enabling Signal");
+@@ -1462,7 +1450,7 @@ static void print_capabilities(const uin
+ 		printf("\n\t\t * Service Interval Granularity is %d ms",
+ 		       (si_duration + 1) * 5);
+ 
+-	if (is_vht_cap) {
++	if (ctx->is_vht_cap) {
+ 		printf("\n\t\t * Max Number Of MSDUs In A-MSDU is ");
+ 		switch (max_amsdu) {
+ 		case 0:
+@@ -1486,7 +1474,7 @@ static void print_capabilities(const uin
+ }
+ 
+ static void print_tim(const uint8_t type, uint8_t len, const uint8_t *data,
+-		      const struct print_ies_data *ie_buffer)
++		      const struct ie_context *ctx)
+ {
+ 	printf(" DTIM Count %u DTIM Period %u Bitmap Control 0x%x "
+ 	       "Bitmap[0] 0x%x",
+@@ -1497,13 +1485,13 @@ static void print_tim(const uint8_t type
+ }
+ 
+ static void print_ibssatim(const uint8_t type, uint8_t len, const uint8_t *data,
+-			   const struct print_ies_data *ie_buffer)
++			   const struct ie_context *ctx)
+ {
+ 	printf(" %d TUs\n", (data[1] << 8) + data[0]);
+ }
+ 
+ static void print_vht_capa(const uint8_t type, uint8_t len, const uint8_t *data,
+-			   const struct print_ies_data *ie_buffer)
++			   const struct ie_context *ctx)
+ {
+ 	printf("\n");
+ 	print_vht_info((__u32) data[0] | ((__u32)data[1] << 8) |
+@@ -1512,7 +1500,7 @@ static void print_vht_capa(const uint8_t
+ }
+ 
+ static void print_vht_oper(const uint8_t type, uint8_t len, const uint8_t *data,
+-			   const struct print_ies_data *ie_buffer)
++			   const struct ie_context *ctx)
+ {
+ 	const char *chandwidths[] = {
+ 		[0] = "20 or 40 MHz",
+@@ -1531,7 +1519,7 @@ static void print_vht_oper(const uint8_t
+ 
+ static void print_supp_op_classes(const uint8_t type, uint8_t len,
+ 				  const uint8_t *data,
+-				  const struct print_ies_data *ie_buffer)
++				  const struct ie_context *ctx)
+ {
+ 	uint8_t *p = (uint8_t*) data;
+ 	const uint8_t *next_data = p + len;
+@@ -1565,7 +1553,7 @@ static void print_supp_op_classes(const
+ 
+ static void print_measurement_pilot_tx(const uint8_t type, uint8_t len,
+ 				       const uint8_t *data,
+-				       const struct print_ies_data *ie_buffer)
++				       const struct ie_context *ctx)
+ {
+ 	uint8_t *p, len_remaining;
+ 
+@@ -1614,7 +1602,7 @@ static void print_measurement_pilot_tx(c
+ 
+ static void print_obss_scan_params(const uint8_t type, uint8_t len,
+ 				   const uint8_t *data,
+-				   const struct print_ies_data *ie_buffer)
++				   const struct ie_context *ctx)
+ {
+ 	printf("\n");
+ 	printf("\t\t * passive dwell: %d TUs\n", (data[1] << 8) | data[0]);
+@@ -1629,7 +1617,7 @@ static void print_obss_scan_params(const
+ 
+ static void print_secchan_offs(const uint8_t type, uint8_t len,
+ 			       const uint8_t *data,
+-			       const struct print_ies_data *ie_buffer)
++			       const struct ie_context *ctx)
+ {
+ 	if (data[0] < ARRAY_SIZE(ht_secondary_offset))
+ 		printf(" %s (%d)\n", ht_secondary_offset[data[0]], data[0]);
+@@ -1638,7 +1626,7 @@ static void print_secchan_offs(const uin
+ }
+ 
+ static void print_bss_load(const uint8_t type, uint8_t len, const uint8_t *data,
+-			   const struct print_ies_data *ie_buffer)
++			   const struct ie_context *ctx)
+ {
+ 	printf("\n");
+ 	printf("\t\t * station count: %d\n", (data[1] << 8) | data[0]);
+@@ -1648,7 +1636,7 @@ static void print_bss_load(const uint8_t
+ 
+ static void print_mesh_conf(const uint8_t type, uint8_t len,
+ 			    const uint8_t *data,
+-			    const struct print_ies_data *ie_buffer)
++			    const struct ie_context *ctx)
+ {
+ 	printf("\n");
+ 	printf("\t\t * Active Path Selection Protocol ID: %d\n", data[0]);
+@@ -1681,7 +1669,7 @@ static void print_mesh_conf(const uint8_
+ 
+ static void print_s1g_capa(const uint8_t type, uint8_t len,
+ 			    const uint8_t *data,
+-			    const struct print_ies_data *ie_buffer)
++			    const struct ie_context *ctx)
+ {
+ 	printf("\n");
+ 	print_s1g_capability(data);
+@@ -1689,14 +1677,14 @@ static void print_s1g_capa(const uint8_t
+ 
+ static void print_short_beacon_int(const uint8_t type, uint8_t len,
+ 			    const uint8_t *data,
+-			    const struct print_ies_data *ie_buffer)
++			    const struct ie_context *ctx)
+ {
+ 	printf(" %d\n", (data[1] << 8) | data[0]);
+ }
+ 
+ static void print_s1g_oper(const uint8_t type, uint8_t len,
+ 			    const uint8_t *data,
+-			    const struct print_ies_data *ie_buffer)
++			    const struct ie_context *ctx)
+ {
+ 	int oper_ch_width, prim_ch_width;
+ 	int prim_ch_width_subfield = data[0] & 0x1;
+@@ -1777,14 +1765,14 @@ static void print_s1g_oper(const uint8_t
+ struct ie_print {
+ 	const char *name;
+ 	void (*print)(const uint8_t type, uint8_t len, const uint8_t *data,
+-		      const struct print_ies_data *ie_buffer);
++		      const struct ie_context *ctx);
+ 	uint8_t minlen, maxlen;
+ 	uint8_t flags;
+ };
+ 
+ static void print_ie(const struct ie_print *p, const uint8_t type, uint8_t len,
+ 		     const uint8_t *data,
+-		     const struct print_ies_data *ie_buffer)
++		     const struct ie_context *ctx)
+ {
+ 	int i;
+ 
+@@ -1805,7 +1793,7 @@ static void print_ie(const struct ie_pri
+ 		return;
+ 	}
+ 
+-	p->print(type, len, data, ie_buffer);
++	p->print(type, len, data, ctx);
+ }
+ 
+ #define PRINT_IGN {		\
+@@ -1867,14 +1855,14 @@ static const struct ie_print ieprinters[
+ };
+ 
+ static void print_wifi_wpa(const uint8_t type, uint8_t len, const uint8_t *data,
+-			   const struct print_ies_data *ie_buffer)
++			   const struct ie_context *ctx)
+ {
+ 	print_rsn_ie("TKIP", "IEEE 802.1X", len, data);
+ }
+ 
+ static void print_wifi_osen(const uint8_t type, uint8_t len,
+ 			    const uint8_t *data,
+-			    const struct print_ies_data *ie_buffer)
++			    const struct ie_context *ctx)
+ {
+ 	print_osen_ie("OSEN", "OSEN", len, data);
+ }
+@@ -1922,7 +1910,7 @@ static bool print_wifi_wmm_param(const u
+ }
+ 
+ static void print_wifi_wmm(const uint8_t type, uint8_t len, const uint8_t *data,
+-			   const struct print_ies_data *ie_buffer)
++			   const struct ie_context *ctx)
+ {
+ 	int i;
+ 
+@@ -1965,7 +1953,7 @@ static const char * wifi_wps_dev_passwd_
+ }
+ 
+ static void print_wifi_wps(const uint8_t type, uint8_t len, const uint8_t *data,
+-			   const struct print_ies_data *ie_buffer)
++			   const struct ie_context *ctx)
+ {
+ 	bool first = true;
+ 	__u16 subtype, sublen;
+@@ -2205,7 +2193,7 @@ static const struct ie_print wifiprinter
+ 
+ static inline void print_p2p(const uint8_t type, uint8_t len,
+ 			     const uint8_t *data,
+-			     const struct print_ies_data *ie_buffer)
++			     const struct ie_context *ctx)
+ {
+ 	bool first = true;
+ 	__u8 subtype;
+@@ -2287,7 +2275,7 @@ static inline void print_p2p(const uint8
+ 
+ static inline void print_hs20_ind(const uint8_t type, uint8_t len,
+ 				  const uint8_t *data,
+-				  const struct print_ies_data *ie_buffer)
++				  const struct ie_context *ctx)
+ {
+ 	/* I can't find the spec for this...just going off what wireshark uses. */
+ 	printf("\n");
+@@ -2299,7 +2287,7 @@ static inline void print_hs20_ind(const
+ 
+ static void print_wifi_owe_tarns(const uint8_t type, uint8_t len,
+ 				 const uint8_t *data,
+-				 const struct print_ies_data *ie_buffer)
++				 const struct ie_context *ctx)
+ {
+ 	char mac_addr[20];
+ 	int ssid_len;
+@@ -2392,14 +2380,14 @@ static void print_vendor(unsigned char l
+ }
+ 
+ static void print_he_capa(const uint8_t type, uint8_t len, const uint8_t *data,
+-			  const struct print_ies_data *ie_buffer)
++			  const struct ie_context *ctx)
+ {
+ 	printf("\n");
+ 	print_he_capability(data, len);
+ }
+ 
+ static void print_he_oper(const uint8_t type, uint8_t len, const uint8_t *data,
+-			  const struct print_ies_data *ie_buffer)
++			  const struct ie_context *ctx)
+ {
+ 	printf("\n");
+ 	print_he_operation(data, len);
+@@ -2437,23 +2425,46 @@ static void print_extension(unsigned cha
+ 	}
+ }
+ 
++static void init_context(struct ie_context *ctx,
++			 unsigned char *ie, int ielen)
++{
++	unsigned char *pos = ie;
++	int remaining = ielen;
++
++	memset(ctx, 0, sizeof(*ctx));
++
++	if (!ie || !ielen)
++		return;
++
++	while (remaining >= 2 && remaining - 2 >= pos[1]) {
++		switch (pos[0]) {
++		case EID_VHT_CAPABILITY:
++			ctx->is_vht_cap = true;
++			break;
++		}
++
++		remaining -= pos[1] + 2;
++		pos += pos[1] + 2;
++	}
++}
++
+ void print_ies(unsigned char *ie, int ielen, bool unknown,
+ 	       enum print_ie_type ptype)
+ {
+-	struct print_ies_data ie_buffer = {
+-		.ie = ie,
+-		.ielen = ielen };
++	struct ie_context ctx;
+ 
+-	if (ie == NULL || ielen < 0)
++	if (!ie)
+ 		return;
+ 
++	init_context(&ctx, ie, ielen);
++
+ 	while (ielen >= 2 && ielen - 2 >= ie[1]) {
+ 		if (ie[0] < ARRAY_SIZE(ieprinters) &&
+ 		    ieprinters[ie[0]].name &&
+ 		    ieprinters[ie[0]].flags & BIT(ptype) &&
+ 			    ie[1] > 0) {
+ 			print_ie(&ieprinters[ie[0]],
+-				 ie[0], ie[1], ie + 2, &ie_buffer);
++				 ie[0], ie[1], ie + 2, &ctx);
+ 		} else if (ie[0] == 221 /* vendor */) {
+ 			print_vendor(ie[1], ie + 2, unknown, ptype);
+ 		} else if (ie[0] == 255 /* extension */) {
diff --git a/package/network/utils/iw/patches/105-iw-util-update-and-clean-up-eht-capa-printing.patch b/package/network/utils/iw/patches/105-iw-util-update-and-clean-up-eht-capa-printing.patch
new file mode 100644
index 0000000000..3970677d74
--- /dev/null
+++ b/package/network/utils/iw/patches/105-iw-util-update-and-clean-up-eht-capa-printing.patch
@@ -0,0 +1,207 @@
+From 4c859917316b69e66ba241d85b4da6ee01292a11 Mon Sep 17 00:00:00 2001
+From: Dylan Eskew <dylan.eskew at candelatech.com>
+Date: Wed, 19 Mar 2025 11:39:17 -0700
+Subject: [PATCH] iw: util: update and clean up eht capa printing
+
+A number of fields were either missing or incorrect, so
+update to more aligned with 802.11be spec. Also clean up
+printout formatting.
+
+Signed-off-by: Dylan Eskew <dylan.eskew at candelatech.com>
+Link: https://patch.msgid.link/20250319183918.1215853-2-dylan.eskew@candelatech.com
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+ iw.h   |   2 +
+ util.c | 124 ++++++++++++++++++++++++++++++++++++++++++++-------------
+ 2 files changed, 99 insertions(+), 27 deletions(-)
+
+--- a/iw.h
++++ b/iw.h
+@@ -224,6 +224,8 @@ void print_vht_info(__u32 capa, const __
+ void print_he_capability(const uint8_t *ie, int len);
+ void print_he_operation(const uint8_t *ie, int len);
+ void print_he_info(struct nlattr *nl_iftype);
++void print_eht_capability(const uint8_t *ie, int len, const uint8_t *he_cap,
++			  bool from_ap);
+ void print_eht_info(struct nlattr *nl_iftype, int band);
+ void print_s1g_capability(const uint8_t *caps);
+ 
+--- a/util.c
++++ b/util.c
+@@ -1515,11 +1515,11 @@ static void __print_eht_capa(int band,
+ 			     const __u8 *mcs_set, size_t mcs_len,
+ 			     const __u8 *ppet, size_t ppet_len,
+ 			     const __u16 *he_phy_cap,
++			     bool from_ap,
+ 			     bool indent)
+ {
+ 	unsigned int i;
+ 	const char *pre = indent ? "\t" : "";
+-	const char *mcs[] = { "0-7", "8-9", "10-11", "12-13"};
+ 
+ 	#define PRINT_EHT_CAP(_var, _idx, _bit, _str) \
+ 	do { \
+@@ -1534,6 +1534,7 @@ static void __print_eht_capa(int band,
+ 	} while (0)
+ 
+ 	#define PRINT_EHT_MAC_CAP(...) PRINT_EHT_CAP(mac_cap, __VA_ARGS__)
++	#define PRINT_EHT_MAC_CAP_MASK(...) PRINT_EHT_CAP_MASK(mac_cap, __VA_ARGS__)
+ 	#define PRINT_EHT_PHY_CAP(...) PRINT_EHT_CAP(phy_cap, __VA_ARGS__)
+ 	#define PRINT_EHT_PHY_CAP_MASK(...) PRINT_EHT_CAP_MASK(phy_cap, __VA_ARGS__)
+ 
+@@ -1542,13 +1543,22 @@ static void __print_eht_capa(int band,
+ 		printf("%02x", mac_cap[i]);
+ 	printf("):\n");
+ 
+-	PRINT_EHT_MAC_CAP(0, 0, "NSEP priority access Supported");
++	PRINT_EHT_MAC_CAP(0, 0, "EPCS Priority Access Supported");
+ 	PRINT_EHT_MAC_CAP(0, 1, "EHT OM Control Supported");
+-	PRINT_EHT_MAC_CAP(0, 2, "Triggered TXOP Sharing Supported");
+-	PRINT_EHT_MAC_CAP(0, 3, "ARR Supported");
++	PRINT_EHT_MAC_CAP(0, 2, "Triggered TXOP Sharing Mode 1 Supported");
++	PRINT_EHT_MAC_CAP(0, 3, "Triggered TXOP Sharing Mode 2 Supported");
++	PRINT_EHT_MAC_CAP(0, 4, "Restricted TWP Supported");
++	PRINT_EHT_MAC_CAP(0, 5, "SCS Traffic Description Supported");
++	PRINT_EHT_MAC_CAP_MASK(0, 6, 0x3, "Maximum MPDU Length");
++
++	PRINT_EHT_MAC_CAP(1, 1, "Maximum A_MPDU Length Exponent Extension");
++	PRINT_EHT_MAC_CAP(1, 2, "EHT TRS Supported");
++	PRINT_EHT_MAC_CAP(1, 3, "TXOP Return In TXOP Sharing Mode 2 Supported");
++	PRINT_EHT_MAC_CAP(1, 4, "Two BQRs Supported");
++	PRINT_EHT_MAC_CAP_MASK(1, 5, 0x3, "EHT Link Adaptation Supported");
+ 
+-	printf("%s\t\tEHT PHY Capabilities: (0x", pre);
+-	for (i = 0; i < 8; i++)
++	printf("%s\t\tEHT PHY Capabilities (0x", pre);
++	for (i = 0; i < 9; i++)
+ 		printf("%02x", ((__u8 *)phy_cap)[i]);
+ 	printf("):\n");
+ 
+@@ -1594,39 +1604,77 @@ static void __print_eht_capa(int band,
+ 	PRINT_EHT_PHY_CAP(1, 28, "MU Beamformer (80MHz)");
+ 	PRINT_EHT_PHY_CAP(1, 29, "MU Beamformer (160MHz)");
+ 	PRINT_EHT_PHY_CAP(1, 30, "MU Beamformer (320MHz)");
++	PRINT_EHT_PHY_CAP(1, 31, "TB Sounding Feedback Rate Limit");
+ 
+-	printf("%s\t\tEHT MCS/NSS: (0x", pre);
+-	for (i = 0; i < mcs_len; i++)
+-		printf("%02x", ((__u8 *)mcs_set)[i]);
+-	printf("):\n");
++	PRINT_EHT_PHY_CAP(2, 0, "Rx 1024-QAM In Wider Bandwidth DL OFDMA Supported");
++	PRINT_EHT_PHY_CAP(2, 1, "Rx 4096-QAM In Wider Bandwidth DL OFDMA Supported");
+ 
+-	if (!(he_phy_cap[0] & ((BIT(2) | BIT(3) | BIT(4)) << 8))){
+-		for (i = 0; i < 4; i++)
+-			printf("%s\t\tEHT bw=20 MHz, max NSS for MCS %s: Rx=%u, Tx=%u\n",
+-			       pre, mcs[i],
+-			       mcs_set[i] & 0xf, mcs_set[i] >> 4);
++	if (!from_ap &&
++	    !(he_phy_cap[0] & ((BIT(1) | BIT(2) | BIT(3) | BIT(4)) << 8))) {
++		static const char * const mcs[] = { "0-7", "8-9", "10-11", "12-13" };
++
++		printf("%s\t\tEHT-MCS Map (20 Mhz Non-AP STA) (0x", pre);
++		for (i = 0; i < mcs_len; i++)
++			printf("%02x", ((__u8 *)mcs_set)[i]);
++		printf("):\n");
++
++		for (i = 0; i < 4; i++) {
++			printf("%s\t\t\tRx Max NSS for MCS %s: %u\n",
++			       pre, mcs[i], mcs_set[i] & 0xf);
++			printf("%s\t\t\tTx Max NSS for MCS %s: %u\n",
++			       pre, mcs[i], mcs_set[i] >> 4);
++		}
+ 	} else {
+-		if (he_phy_cap[0] & (BIT(2) << 8)) {
++		static const char * const mcs[] = { "0-9", "10-11", "12-13"};
++
++		/* Bit 1 corresponds to 2.4Ghz 40Mhz support
++		 * Bit 2 corresponds to 5/6Ghz 40 and 80Mhz support
++		 * If no Channel Width bits are set, but we are an AP, we use
++		 * this MCS logic also.
++		 */
++		if (he_phy_cap[0] & ((BIT(1) | BIT(2)) << 8) ||
++		    (from_ap && !(he_phy_cap[0] & ((BIT(1) | BIT(2) | BIT(3) | BIT(4)) << 8)))) {
++			printf("%s\t\tEHT-MCS Map (BW <= 80) (0x", pre);
+ 			for (i = 0; i < 3; i++)
+-				printf("%s\t\tEHT bw <= 80 MHz, max NSS for MCS %s: Rx=%u, Tx=%u\n",
+-				       pre, mcs[i + 1],
+-				       mcs_set[i] & 0xf, mcs_set[i] >> 4);
++				printf("%02x", ((__u8 *)mcs_set)[i]);
++			printf("):\n");
++
++			for (i = 0; i < 3; i++) {
++				printf("%s\t\t\tRx Max NSS for MCS %s: %u\n",
++				       pre, mcs[i], mcs_set[i] & 0xf);
++				printf("%s\t\t\tTx Max NSS for MCS %s: %u\n",
++				       pre, mcs[i], mcs_set[i] >> 4);
++			}
+ 		}
+ 		mcs_set += 3;
+ 
+ 		if (he_phy_cap[0] & (BIT(3) << 8)) {
++			printf("%s\t\tEHT-MCS Map (BW = 160) (0x", pre);
+ 			for (i = 0; i < 3; i++)
+-				printf("%s\t\tEHT bw=160 MHz, max NSS for MCS %s: Rx=%u, Tx=%u\n",
+-				       pre, mcs[i + 1],
+-				       mcs_set[i] & 0xf, mcs_set[i] >> 4);
++				printf("%02x", ((__u8 *)mcs_set)[i]);
++			printf("):\n");
++
++			for (i = 0; i < 3; i++) {
++				printf("%s\t\t\tRx Max NSS for MCS %s: %u\n",
++				       pre, mcs[i], mcs_set[i] & 0xf);
++				printf("%s\t\t\tTx Max NSS for MCS %s: %u\n",
++				       pre, mcs[i], mcs_set[i] >> 4);
++			}
+ 		}
+ 
+ 		mcs_set += 3;
+ 		if (band == NL80211_BAND_6GHZ && (phy_cap[0] & BIT(1))) {
++			printf("%s\t\tEHT-MCS Map (BW = 320) (0x", pre);
+ 			for (i = 0; i < 3; i++)
+-				printf("%s\t\tEHT bw=320 MHz, max NSS for MCS %s: Rx=%u, Tx=%u\n",
+-				       pre, mcs[i + 1],
+-				       mcs_set[i] & 0xf, mcs_set[i] >> 4);
++				printf("%02x", ((__u8 *)mcs_set)[i]);
++			printf("):\n");
++
++			for (i = 0; i < 3; i++) {
++				printf("%s\t\t\tRx Max NSS for MCS %s: %u\n",
++				       pre, mcs[i], mcs_set[i] & 0xf);
++				printf("%s\t\t\tTx Max NSS for MCS %s: %u\n",
++				       pre, mcs[i], mcs_set[i] >> 4);
++			}
+ 		}
+ 	}
+ 
+@@ -1713,7 +1761,29 @@ void print_eht_info(struct nlattr *nl_if
+ 	}
+ 
+ 	__print_eht_capa(band, mac_cap, phy_cap, mcs_set, mcs_len, ppet, ppet_len,
+-			 he_phy_cap, true);
++			 he_phy_cap, false, true);
++}
++
++void print_eht_capability(const uint8_t *ie, int len, const uint8_t *he_cap,
++			  bool from_ap)
++{
++	const void *mac_cap, *phy_cap, *mcs_set, *he_phy_cap;
++	int mcs_len;
++	int i = 0;
++
++	mac_cap = &ie[i];
++	i += 2;
++
++	phy_cap = &ie[i];
++	i += 9;
++
++	mcs_set = &ie[i];
++	mcs_len = len - i;
++
++	he_phy_cap = &he_cap[6];
++
++	__print_eht_capa(NL80211_BAND_6GHZ, mac_cap, phy_cap, mcs_set, mcs_len,
++			 NULL, 0, he_phy_cap - 1, from_ap, false);
+ }
+ 
+ void print_he_capability(const uint8_t *ie, int len)
diff --git a/package/network/utils/iw/patches/106-iw-scan-add-eht-capability-parsing.patch b/package/network/utils/iw/patches/106-iw-scan-add-eht-capability-parsing.patch
new file mode 100644
index 0000000000..ff8a323d34
--- /dev/null
+++ b/package/network/utils/iw/patches/106-iw-scan-add-eht-capability-parsing.patch
@@ -0,0 +1,175 @@
+From a6ad3f11ead18d1812c7d3759991dc22b20d90da Mon Sep 17 00:00:00 2001
+From: Dylan Eskew <dylan.eskew at candelatech.com>
+Date: Wed, 19 Mar 2025 11:39:18 -0700
+Subject: [PATCH] iw: scan: add eht capability parsing
+
+Add ability to print out EHT capabilities from
+AP beacons.
+
+Signed-off-by: Dylan Eskew <dylan.eskew at candelatech.com>
+Link: https://patch.msgid.link/20250319183918.1215853-3-dylan.eskew@candelatech.com
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+ ieee80211.h |  1 +
+ iw.h        |  2 +-
+ link.c      |  5 +++--
+ scan.c      | 34 +++++++++++++++++++++++++++-------
+ 4 files changed, 32 insertions(+), 10 deletions(-)
+
+--- a/ieee80211.h
++++ b/ieee80211.h
+@@ -99,6 +99,7 @@ enum elem_id {
+ enum elem_id_ext {
+ 	EID_EXT_HE_CAPABILITY		= 35,
+ 	EID_EXT_HE_OPERATION		= 36,
++	EID_EXT_EHT_CAPABILITY		= 108,
+ };
+ 
+ #define SUITE(oui, id)  (((oui) << 8) | (id))
+--- a/iw.h
++++ b/iw.h
+@@ -256,7 +256,7 @@ enum print_ie_type {
+ #define BIT(x) (1ULL<<(x))
+ 
+ void print_ies(unsigned char *ie, int ielen, bool unknown,
+-	       enum print_ie_type ptype);
++	       enum print_ie_type ptype, bool from_ap);
+ 
+ void parse_bitrate(struct nlattr *bitrate_attr, char *buf, int buflen);
+ void iw_hexdump(const char *prefix, const __u8 *data, size_t len);
+--- a/link.c
++++ b/link.c
+@@ -93,7 +93,7 @@ static int link_bss_handler(struct nl_ms
+ 			if (bss[NL80211_BSS_INFORMATION_ELEMENTS])
+ 				print_ies(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]),
+ 					  nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]),
+-					  false, PRINT_LINK_MLO_MLD);
++					  false, PRINT_LINK_MLO_MLD, false);
+ 		}
+ 	} else {
+ 		memcpy(result->sta_addr, nla_data(bss[NL80211_BSS_BSSID]), 6);
+@@ -121,7 +121,8 @@ static int link_bss_handler(struct nl_ms
+ 	if (bss[NL80211_BSS_INFORMATION_ELEMENTS])
+ 		print_ies(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]),
+ 			  nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]),
+-			  false, result->mld ? PRINT_LINK_MLO_LINK : PRINT_LINK);
++			  false, result->mld ? PRINT_LINK_MLO_LINK : PRINT_LINK,
++			  false);
+ 
+ 	if (bss[NL80211_BSS_FREQUENCY_OFFSET])
+ 		freq_offset = nla_get_u32(bss[NL80211_BSS_FREQUENCY_OFFSET]);
+--- a/scan.c
++++ b/scan.c
+@@ -555,7 +555,9 @@ static void tab_on_first(bool *first)
+ }
+ 
+ struct ie_context {
++	bool from_ap;
+ 	bool is_vht_cap;
++	const uint8_t *he_cap;
+ };
+ 
+ static void print_ssid(const uint8_t type, uint8_t len, const uint8_t *data,
+@@ -2393,12 +2395,21 @@ static void print_he_oper(const uint8_t
+ 	print_he_operation(data, len);
+ }
+ 
++static void print_eht_capa(const uint8_t type, uint8_t len,
++			   const uint8_t *data, const struct ie_context *ctx)
++{
++	printf("\n");
++	print_eht_capability(data, len, ctx->he_cap, ctx->from_ap);
++}
++
+ static const struct ie_print ext_printers[] = {
+ 	[EID_EXT_HE_CAPABILITY] = { "HE capabilities", print_he_capa, 21, 54, BIT(PRINT_SCAN), },
+ 	[EID_EXT_HE_OPERATION] = { "HE Operation", print_he_oper, 6, 15, BIT(PRINT_SCAN), },
++	[EID_EXT_EHT_CAPABILITY] = { "EHT capabilities", print_eht_capa, 13, 30, BIT(PRINT_SCAN), },
+ };
+ 
+ static void print_extension(unsigned char len, unsigned char *ie,
++			    const struct ie_context *ctx,
+ 			    bool unknown, enum print_ie_type ptype)
+ {
+ 	unsigned char tag;
+@@ -2411,7 +2422,7 @@ static void print_extension(unsigned cha
+ 	tag = ie[0];
+ 	if (tag < ARRAY_SIZE(ext_printers) && ext_printers[tag].name &&
+ 	    ext_printers[tag].flags & BIT(ptype)) {
+-		print_ie(&ext_printers[tag], tag, len - 1, ie + 1, NULL);
++		print_ie(&ext_printers[tag], tag, len - 1, ie + 1, ctx);
+ 		return;
+ 	}
+ 
+@@ -2426,7 +2437,7 @@ static void print_extension(unsigned cha
+ }
+ 
+ static void init_context(struct ie_context *ctx,
+-			 unsigned char *ie, int ielen)
++			 unsigned char *ie, int ielen, bool from_ap)
+ {
+ 	unsigned char *pos = ie;
+ 	int remaining = ielen;
+@@ -2436,11 +2447,20 @@ static void init_context(struct ie_conte
+ 	if (!ie || !ielen)
+ 		return;
+ 
++	ctx->from_ap = from_ap;
++
+ 	while (remaining >= 2 && remaining - 2 >= pos[1]) {
+ 		switch (pos[0]) {
+ 		case EID_VHT_CAPABILITY:
+ 			ctx->is_vht_cap = true;
+ 			break;
++		case EID_EXTENSION:
++			switch (pos[2]) {
++			case EID_EXT_HE_CAPABILITY:
++				ctx->he_cap = pos + 3;
++				break;
++			}
++			break;
+ 		}
+ 
+ 		remaining -= pos[1] + 2;
+@@ -2449,14 +2469,14 @@ static void init_context(struct ie_conte
+ }
+ 
+ void print_ies(unsigned char *ie, int ielen, bool unknown,
+-	       enum print_ie_type ptype)
++	       enum print_ie_type ptype, bool from_ap)
+ {
+ 	struct ie_context ctx;
+ 
+ 	if (!ie)
+ 		return;
+ 
+-	init_context(&ctx, ie, ielen);
++	init_context(&ctx, ie, ielen, from_ap);
+ 
+ 	while (ielen >= 2 && ielen - 2 >= ie[1]) {
+ 		if (ie[0] < ARRAY_SIZE(ieprinters) &&
+@@ -2468,7 +2488,7 @@ void print_ies(unsigned char *ie, int ie
+ 		} else if (ie[0] == 221 /* vendor */) {
+ 			print_vendor(ie[1], ie + 2, unknown, ptype);
+ 		} else if (ie[0] == 255 /* extension */) {
+-			print_extension(ie[1], ie + 2, unknown, ptype);
++			print_extension(ie[1], ie + 2, &ctx, unknown, ptype);
+ 		} else if (unknown) {
+ 			int i;
+ 
+@@ -2673,13 +2693,13 @@ static int print_bss_handler(struct nl_m
+ 			printf("\tInformation elements from Probe Response "
+ 			       "frame:\n");
+ 		print_ies(nla_data(ies), nla_len(ies),
+-			  params->unknown, params->type);
++			  params->unknown, params->type, true);
+ 	}
+ 	if (bss[NL80211_BSS_BEACON_IES] && show--) {
+ 		printf("\tInformation elements from Beacon frame:\n");
+ 		print_ies(nla_data(bss[NL80211_BSS_BEACON_IES]),
+ 			  nla_len(bss[NL80211_BSS_BEACON_IES]),
+-			  params->unknown, params->type);
++			  params->unknown, params->type, true);
+ 	}
+ 
+ 	return NL_SKIP;
diff --git a/package/network/utils/iw/patches/107-iw-fix-EHT-capabilities-on-Big-Endian-platforms.patch b/package/network/utils/iw/patches/107-iw-fix-EHT-capabilities-on-Big-Endian-platforms.patch
new file mode 100644
index 0000000000..d0f15eaec5
--- /dev/null
+++ b/package/network/utils/iw/patches/107-iw-fix-EHT-capabilities-on-Big-Endian-platforms.patch
@@ -0,0 +1,107 @@
+From 59660a349cf35903e951f99bdd8a74df063c912e Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Date: Fri, 2 May 2025 21:44:05 +0200
+Subject: [PATCH] iw: fix EHT capabilities on Big Endian platforms
+
+IE fields are encoded in Little Endian and are not correctly
+printed on Big Endian platforms.
+
+Fixes: 5a71b722270c ("iw: Print local EHT capabilities")
+Signed-off-by: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Link: https://patch.msgid.link/20250502194405.3489240-1-olek2@wp.pl
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+ util.c | 40 +++++++++++++++++++++++++---------------
+ 1 file changed, 25 insertions(+), 15 deletions(-)
+
+--- a/util.c
++++ b/util.c
+@@ -1521,22 +1521,31 @@ static void __print_eht_capa(int band,
+ 	unsigned int i;
+ 	const char *pre = indent ? "\t" : "";
+ 
+-	#define PRINT_EHT_CAP(_var, _idx, _bit, _str) \
++	#define PRINT_EHT_MAC_CAP(_idx, _bit, _str) \
+ 	do { \
+-		if (_var[_idx] & BIT(_bit)) \
++		if (mac_cap[_idx] & BIT(_bit)) \
+ 			printf("%s\t\t\t" _str "\n", pre); \
+ 	} while (0)
+ 
+-	#define PRINT_EHT_CAP_MASK(_var, _idx, _shift, _mask, _str) \
++	#define PRINT_EHT_MAC_CAP_MASK(_idx, _shift, _mask, _str) \
+ 	do { \
+-		if ((_var[_idx] >> _shift) & _mask) \
+-			printf("%s\t\t\t" _str ": %d\n", pre, (_var[_idx] >> _shift) & _mask); \
++		if ((mac_cap[_idx] >> _shift) & _mask) \
++			printf("%s\t\t\t" _str ": %d\n", pre, \
++			       (mac_cap[_idx] >> _shift) & _mask); \
+ 	} while (0)
+ 
+-	#define PRINT_EHT_MAC_CAP(...) PRINT_EHT_CAP(mac_cap, __VA_ARGS__)
+-	#define PRINT_EHT_MAC_CAP_MASK(...) PRINT_EHT_CAP_MASK(mac_cap, __VA_ARGS__)
+-	#define PRINT_EHT_PHY_CAP(...) PRINT_EHT_CAP(phy_cap, __VA_ARGS__)
+-	#define PRINT_EHT_PHY_CAP_MASK(...) PRINT_EHT_CAP_MASK(phy_cap, __VA_ARGS__)
++	#define PRINT_EHT_PHY_CAP(_idx, _bit, _str) \
++	do { \
++		if (le32toh(phy_cap[_idx]) & BIT(_bit)) \
++			printf("%s\t\t\t" _str "\n", pre); \
++	} while (0)
++
++	#define PRINT_EHT_PHY_CAP_MASK(_idx, _shift, _mask, _str) \
++	do { \
++		if ((le32toh(phy_cap[_idx]) >> _shift) & _mask) \
++			printf("%s\t\t\t" _str ": %d\n", pre, \
++			       (le32toh(phy_cap[_idx]) >> _shift) & _mask); \
++	} while (0)
+ 
+ 	printf("%s\t\tEHT MAC Capabilities (0x", pre);
+ 	for (i = 0; i < 2; i++)
+@@ -1610,7 +1619,7 @@ static void __print_eht_capa(int band,
+ 	PRINT_EHT_PHY_CAP(2, 1, "Rx 4096-QAM In Wider Bandwidth DL OFDMA Supported");
+ 
+ 	if (!from_ap &&
+-	    !(he_phy_cap[0] & ((BIT(1) | BIT(2) | BIT(3) | BIT(4)) << 8))) {
++	    !(le16toh(he_phy_cap[0]) & ((BIT(1) | BIT(2) | BIT(3) | BIT(4)) << 8))) {
+ 		static const char * const mcs[] = { "0-7", "8-9", "10-11", "12-13" };
+ 
+ 		printf("%s\t\tEHT-MCS Map (20 Mhz Non-AP STA) (0x", pre);
+@@ -1632,8 +1641,9 @@ static void __print_eht_capa(int band,
+ 		 * If no Channel Width bits are set, but we are an AP, we use
+ 		 * this MCS logic also.
+ 		 */
+-		if (he_phy_cap[0] & ((BIT(1) | BIT(2)) << 8) ||
+-		    (from_ap && !(he_phy_cap[0] & ((BIT(1) | BIT(2) | BIT(3) | BIT(4)) << 8)))) {
++		if (le16toh(he_phy_cap[0]) & ((BIT(1) | BIT(2)) << 8) ||
++		    (from_ap && !(le16toh(he_phy_cap[0]) &
++		    ((BIT(1) | BIT(2) | BIT(3) | BIT(4)) << 8)))) {
+ 			printf("%s\t\tEHT-MCS Map (BW <= 80) (0x", pre);
+ 			for (i = 0; i < 3; i++)
+ 				printf("%02x", ((__u8 *)mcs_set)[i]);
+@@ -1648,7 +1658,7 @@ static void __print_eht_capa(int band,
+ 		}
+ 		mcs_set += 3;
+ 
+-		if (he_phy_cap[0] & (BIT(3) << 8)) {
++		if (le16toh(he_phy_cap[0]) & (BIT(3) << 8)) {
+ 			printf("%s\t\tEHT-MCS Map (BW = 160) (0x", pre);
+ 			for (i = 0; i < 3; i++)
+ 				printf("%02x", ((__u8 *)mcs_set)[i]);
+@@ -1663,7 +1673,7 @@ static void __print_eht_capa(int band,
+ 		}
+ 
+ 		mcs_set += 3;
+-		if (band == NL80211_BAND_6GHZ && (phy_cap[0] & BIT(1))) {
++		if (band == NL80211_BAND_6GHZ && (le32toh(phy_cap[0]) & BIT(1))) {
+ 			printf("%s\t\tEHT-MCS Map (BW = 320) (0x", pre);
+ 			for (i = 0; i < 3; i++)
+ 				printf("%02x", ((__u8 *)mcs_set)[i]);
+@@ -1678,7 +1688,7 @@ static void __print_eht_capa(int band,
+ 		}
+ 	}
+ 
+-	if (ppet && ppet_len && (phy_cap[1] & BIT(11))) {
++	if (ppet && ppet_len && (le32toh(phy_cap[1]) & BIT(11))) {
+ 		printf("%s\t\tEHT PPE Thresholds ", pre);
+ 		for (i = 0; i < ppet_len; i++)
+ 			if (ppet[i])
diff --git a/package/network/utils/iw/patches/108-iw-scan-Add-printing-of-EHT-Operation-Element.patch b/package/network/utils/iw/patches/108-iw-scan-Add-printing-of-EHT-Operation-Element.patch
new file mode 100644
index 0000000000..81b1def031
--- /dev/null
+++ b/package/network/utils/iw/patches/108-iw-scan-Add-printing-of-EHT-Operation-Element.patch
@@ -0,0 +1,131 @@
+From 8ea80d378ce5f727e69493533a666278c6a568a7 Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Date: Fri, 2 May 2025 12:03:53 +0200
+Subject: [PATCH] iw: scan: Add printing of EHT Operation Element
+
+Add ability to print out EHT capabilities from AP beacons.
+
+Signed-off-by: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Link: https://patch.msgid.link/20250502100353.3149470-1-olek2@wp.pl
+[add default case to bandwidth switch]
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+ ieee80211.h |  1 +
+ iw.h        |  1 +
+ scan.c      |  8 +++++++
+ util.c      | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 73 insertions(+)
+
+--- a/ieee80211.h
++++ b/ieee80211.h
+@@ -99,6 +99,7 @@ enum elem_id {
+ enum elem_id_ext {
+ 	EID_EXT_HE_CAPABILITY		= 35,
+ 	EID_EXT_HE_OPERATION		= 36,
++	EID_EXT_EHT_OPERATION		= 106,
+ 	EID_EXT_EHT_CAPABILITY		= 108,
+ };
+ 
+--- a/iw.h
++++ b/iw.h
+@@ -226,6 +226,7 @@ void print_he_operation(const uint8_t *i
+ void print_he_info(struct nlattr *nl_iftype);
+ void print_eht_capability(const uint8_t *ie, int len, const uint8_t *he_cap,
+ 			  bool from_ap);
++void print_eht_operation(const uint8_t *ie, int len);
+ void print_eht_info(struct nlattr *nl_iftype, int band);
+ void print_s1g_capability(const uint8_t *caps);
+ 
+--- a/scan.c
++++ b/scan.c
+@@ -2402,10 +2402,18 @@ static void print_eht_capa(const uint8_t
+ 	print_eht_capability(data, len, ctx->he_cap, ctx->from_ap);
+ }
+ 
++static void print_eht_oper(const uint8_t type, uint8_t len, const uint8_t *data,
++			   const struct ie_context *ctx)
++{
++	printf("\n");
++	print_eht_operation(data, len);
++}
++
+ static const struct ie_print ext_printers[] = {
+ 	[EID_EXT_HE_CAPABILITY] = { "HE capabilities", print_he_capa, 21, 54, BIT(PRINT_SCAN), },
+ 	[EID_EXT_HE_OPERATION] = { "HE Operation", print_he_oper, 6, 15, BIT(PRINT_SCAN), },
+ 	[EID_EXT_EHT_CAPABILITY] = { "EHT capabilities", print_eht_capa, 13, 30, BIT(PRINT_SCAN), },
++	[EID_EXT_EHT_OPERATION] = { "EHT Operation", print_eht_oper, 5, 10, BIT(PRINT_SCAN), },
+ };
+ 
+ static void print_extension(unsigned char len, unsigned char *ie,
+--- a/util.c
++++ b/util.c
+@@ -1917,6 +1917,69 @@ void print_he_operation(const uint8_t *i
+ 	}
+ }
+ 
++void print_eht_operation(const uint8_t *ie, int len)
++{
++	uint8_t oper_parameters = ie[0];
++	uint8_t disabled_subchannel_info_present = oper_parameters & 0x02;
++	uint8_t eht_operation_info_present = oper_parameters & 0x01;
++
++	printf("\t\tEHT Operation Parameters: (0x%02x)\n",
++	       oper_parameters);
++
++	if (oper_parameters & 0x04)
++		printf("\t\t\tEHT Default PE Duration\n");
++
++	if (oper_parameters & 0x08)
++		printf("\t\t\tGroup Addressed BU Indication Limit\n");
++
++	printf("\t\t\tGroup Addressed BU Indication Exponent: 0x%01x\n",
++	       (oper_parameters >> 4 & 3));
++
++	printf("\t\tBasic EHT-MCS And Nss Set: 0x");
++	for (uint8_t i = 0; i < 4; i++)
++		printf("%02x", ie[1 + i]);
++
++	printf("\n");
++
++	if (eht_operation_info_present) {
++		uint8_t offset = 5;
++		const uint8_t control = ie[offset];
++		uint8_t eht_operation_info_len = 3;
++
++		if (disabled_subchannel_info_present)
++			eht_operation_info_len += 2;
++
++		if (len - offset < eht_operation_info_len) {
++			printf("\t\tEHT Operation Info: Invalid\n");
++			return;
++		}
++
++		printf("\t\tEHT Operation Info: 0x");
++		for (uint8_t i = 0; i < eht_operation_info_len; i++)
++			printf("%02x", ie[offset + i]);
++
++		printf("\n");
++		printf("\t\t\tChannel Width: ");
++		switch (control & 0x7) {
++		case 0: printf("20 MHz\n"); break;
++		case 1: printf("40 MHz\n"); break;
++		case 2: printf("80 MHz\n"); break;
++		case 3: printf("160 MHz\n"); break;
++		case 4: printf("320 MHz\n"); break;
++		default: printf("invalid bandwidth (%d)\n", control & 0x7); break;
++		}
++
++		printf("\t\t\tCenter Frequency Segment 0: %hhu\n",
++		       ie[offset + 1]);
++		printf("\t\t\tCenter Frequency Segment 1: %hhu\n",
++		       ie[offset + 2]);
++
++		if (disabled_subchannel_info_present)
++			printf("\t\t\tDisabled Subchannel Bitmap: 0x%02x%02x\n",
++			       ie[offset + 3], ie[offset + 4]);
++	}
++}
++
+ void iw_hexdump(const char *prefix, const __u8 *buf, size_t size)
+ {
+ 	size_t i;
diff --git a/package/network/utils/iw/patches/200-reduce_size.patch b/package/network/utils/iw/patches/200-reduce_size.patch
index dc1cce99a2..40ca57209d 100644
--- a/package/network/utils/iw/patches/200-reduce_size.patch
+++ b/package/network/utils/iw/patches/200-reduce_size.patch
@@ -132,7 +132,7 @@
  {
 --- a/scan.c
 +++ b/scan.c
-@@ -1308,6 +1308,9 @@ static void print_ht_op(const uint8_t ty
+@@ -1309,6 +1309,9 @@ static void print_ht_op(const uint8_t ty
  	printf("\t\t * secondary channel offset: %s\n",
  		ht_secondary_offset[data[1] & 0x3]);
  	printf("\t\t * STA channel width: %s\n", sta_chan_width[(data[1] & 0x4)>>2]);
@@ -142,55 +142,62 @@
  	printf("\t\t * RIFS: %d\n", (data[1] & 0x8)>>3);
  	printf("\t\t * HT protection: %s\n", protection[data[2] & 0x3]);
  	printf("\t\t * non-GF present: %d\n", (data[2] & 0x4) >> 2);
-@@ -1818,30 +1821,31 @@ static void print_ie(const struct ie_pri
+@@ -1808,17 +1811,25 @@ static void print_ie(const struct ie_pri
  static const struct ie_print ieprinters[] = {
- 	[0] = { "SSID", print_ssid, 0, 32,
- 		 BIT(PRINT_SCAN) | BIT(PRINT_LINK) | BIT(PRINT_LINK_MLO_MLD), },
-+	[11] = { "BSS Load", print_bss_load, 5, 5, BIT(PRINT_SCAN), },
-+	[45] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), },
-+	[48] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), },
-+	[61] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), },
-+	[62] = { "Secondary Channel Offset", print_secchan_offs, 1, 1, BIT(PRINT_SCAN), },
-+	[114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
-+	[191] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), },
-+	[192] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), },
+ 	[EID_SSID] = { "SSID", print_ssid, 0, 32,
+ 		       BIT(PRINT_SCAN) | BIT(PRINT_LINK) | BIT(PRINT_LINK_MLO_MLD), },
++	[EID_BSS_LOAD] = { "BSS Load", print_bss_load, 5, 5, BIT(PRINT_SCAN), },
++	[EID_HT_CAPABILITY] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), },
++	[EID_RSN] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), },
++	[EID_HT_OPERATION] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), },
++	[EID_SECONDARY_CH_OFFSET] = { "Secondary Channel Offset",
++				      print_secchan_offs, 1, 1, BIT(PRINT_SCAN), },
++	[EID_MESH_ID] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
++	[EID_VHT_CAPABILITY] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), },
++	[EID_VHT_OPERATION] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), },
 +#ifdef IW_FULL
- 	[1] = { "Supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), },
- 	[3] = { "DS Parameter set", print_ds, 1, 1, BIT(PRINT_SCAN), },
- 	[5] = { "TIM", print_tim, 4, 255, BIT(PRINT_SCAN), },
- 	[6] = { "IBSS ATIM window", print_ibssatim, 2, 2, BIT(PRINT_SCAN), },
- 	[7] = { "Country", print_country, 3, 255, BIT(PRINT_SCAN), },
--	[11] = { "BSS Load", print_bss_load, 5, 5, BIT(PRINT_SCAN), },
- 	[32] = { "Power constraint", print_powerconstraint, 1, 1, BIT(PRINT_SCAN), },
- 	[35] = { "TPC report", print_tpcreport, 2, 2, BIT(PRINT_SCAN), },
- 	[42] = { "ERP", print_erp, 1, 255, BIT(PRINT_SCAN), },
--	[45] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), },
- 	[47] = { "ERP D4.0", print_erp, 1, 255, BIT(PRINT_SCAN), },
- 	[51] = { "AP Channel Report", print_ap_channel_report, 1, 255, BIT(PRINT_SCAN), },
- 	[59] = { "Supported operating classes", print_supp_op_classes, 1, 255, BIT(PRINT_SCAN), },
- 	[66] = { "Measurement Pilot Transmission", print_measurement_pilot_tx, 1, 255, BIT(PRINT_SCAN), },
- 	[74] = { "Overlapping BSS scan params", print_obss_scan_params, 14, 255, BIT(PRINT_SCAN), },
--	[61] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), },
--	[62] = { "Secondary Channel Offset", print_secchan_offs, 1, 1, BIT(PRINT_SCAN), },
--	[191] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), },
--	[192] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), },
--	[48] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), },
- 	[50] = { "Extended supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), },
- 	[70] = { "RM enabled capabilities", print_rm_enabled_capabilities, 5, 5, BIT(PRINT_SCAN), },
- 	[113] = { "MESH Configuration", print_mesh_conf, 7, 7, BIT(PRINT_SCAN), },
--	[114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
- 	[127] = { "Extended capabilities", print_capabilities, 0, 255, BIT(PRINT_SCAN), },
- 	[107] = { "802.11u Interworking", print_interworking, 0, 255, BIT(PRINT_SCAN), },
- 	[108] = { "802.11u Advertisement", print_11u_advert, 0, 255, BIT(PRINT_SCAN), },
-@@ -1850,6 +1854,7 @@ static const struct ie_print ieprinters[
- 	[214] = { "Short beacon interval", print_short_beacon_int, 2, 2, BIT(PRINT_SCAN), },
- 	[217] = { "S1G capabilities", print_s1g_capa, 15, 15, BIT(PRINT_SCAN), },
- 	[232] = { "S1G operation", print_s1g_oper, 6, 6, BIT(PRINT_SCAN), },
+ 	[EID_SUPP_RATES] = { "Supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), },
+ 	[EID_DS_PARAMS] = { "DS Parameter set", print_ds, 1, 1, BIT(PRINT_SCAN), },
+ 	[EID_TIM] = { "TIM", print_tim, 4, 255, BIT(PRINT_SCAN), },
+ 	[EID_IBSS_TIM_PARAMS] = { "IBSS ATIM window", print_ibssatim, 2, 2, BIT(PRINT_SCAN), },
+ 	[EID_COUNTRY] = { "Country", print_country, 3, 255, BIT(PRINT_SCAN), },
+-	[EID_BSS_LOAD] = { "BSS Load", print_bss_load, 5, 5, BIT(PRINT_SCAN), },
+ 	[EID_POWER_CONSTRAINT] = { "Power constraint", print_powerconstraint,
+ 				   1, 1, BIT(PRINT_SCAN), },
+ 	[EID_TPC_REPORT] = { "TPC report", print_tpcreport, 2, 2, BIT(PRINT_SCAN), },
+ 	[EID_ERP_INFO] = { "ERP", print_erp, 1, 255, BIT(PRINT_SCAN), },
+-	[EID_HT_CAPABILITY] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), },
+ 	[EID_ERP_D4_0] = { "ERP D4.0", print_erp, 1, 255, BIT(PRINT_SCAN), },
+ 	[EID_AP_CHAN_REPORT] = { "AP Channel Report", print_ap_channel_report,
+ 				 1, 255, BIT(PRINT_SCAN), },
+@@ -1828,18 +1839,11 @@ static const struct ie_print ieprinters[
+ 				       print_measurement_pilot_tx, 1, 255, BIT(PRINT_SCAN), },
+ 	[EID_OVERLAP_BSS_SCAN_PARAM] = { "Overlapping BSS scan params",
+ 					 print_obss_scan_params, 14, 255, BIT(PRINT_SCAN), },
+-	[EID_HT_OPERATION] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), },
+-	[EID_SECONDARY_CH_OFFSET] = { "Secondary Channel Offset",
+-				      print_secchan_offs, 1, 1, BIT(PRINT_SCAN), },
+-	[EID_VHT_CAPABILITY] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), },
+-	[EID_VHT_OPERATION] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), },
+-	[EID_RSN] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), },
+ 	[EID_EXT_SUPP_RATES] = { "Extended supported rates", print_supprates,
+ 				 0, 255, BIT(PRINT_SCAN), },
+ 	[EID_RM_ENABLED_CAPABILITIES] = { "RM enabled capabilities",
+ 					  print_rm_enabled_capabilities, 5, 5, BIT(PRINT_SCAN), },
+ 	[EID_MESH_CONFIG] = { "MESH Configuration", print_mesh_conf, 7, 7, BIT(PRINT_SCAN), },
+-	[EID_MESH_ID] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
+ 	[EID_EXT_CAPABILITY] = { "Extended capabilities", print_capabilities,
+ 				 0, 255, BIT(PRINT_SCAN), },
+ 	[EID_INTERWORKING] = { "802.11u Interworking", print_interworking,
+@@ -1854,6 +1858,7 @@ static const struct ie_print ieprinters[
+ 					print_short_beacon_int, 2, 2, BIT(PRINT_SCAN), },
+ 	[EID_S1G_CAPABILITY] = { "S1G capabilities", print_s1g_capa, 15, 15, BIT(PRINT_SCAN), },
+ 	[EID_S1G_OPERATION] = { "S1G operation", print_s1g_oper, 6, 6, BIT(PRINT_SCAN), },
 +#endif
  };
  
  static void print_wifi_wpa(const uint8_t type, uint8_t len, const uint8_t *data,
-@@ -2185,8 +2190,10 @@ static void print_wifi_wps(const uint8_t
+@@ -2189,8 +2194,10 @@ static void print_wifi_wps(const uint8_t
  
  static const struct ie_print wifiprinters[] = {
  	[1] = { "WPA", print_wifi_wpa, 2, 255, BIT(PRINT_SCAN), },
@@ -201,7 +208,7 @@
  };
  
  static inline void print_p2p(const uint8_t type, uint8_t len,
-@@ -2349,6 +2356,10 @@ static void print_vendor(unsigned char l
+@@ -2353,6 +2360,10 @@ static void print_vendor(unsigned char l
  		return;
  	}
  
@@ -212,7 +219,7 @@
  	if (len >= 4 && memcmp(data, wfa_oui, 3) == 0) {
  		if (data[3] < ARRAY_SIZE(wfa_printers) &&
  		    wfa_printers[data[3]].name &&
-@@ -2491,6 +2502,7 @@ static void print_capa_non_dmg(__u16 cap
+@@ -2544,6 +2555,7 @@ static void print_capa_non_dmg(__u16 cap
  		printf(" ESS");
  	if (capa & WLAN_CAPABILITY_IBSS)
  		printf(" IBSS");
@@ -220,7 +227,7 @@
  	if (capa & WLAN_CAPABILITY_CF_POLLABLE)
  		printf(" CfPollable");
  	if (capa & WLAN_CAPABILITY_CF_POLL_REQUEST)
-@@ -2519,6 +2531,7 @@ static void print_capa_non_dmg(__u16 cap
+@@ -2572,6 +2584,7 @@ static void print_capa_non_dmg(__u16 cap
  		printf(" DelayedBACK");
  	if (capa & WLAN_CAPABILITY_IMM_BACK)
  		printf(" ImmediateBACK");
@@ -228,7 +235,7 @@
  }
  
  static int print_bss_handler(struct nl_msg *msg, void *arg)
-@@ -2609,8 +2622,10 @@ static int print_bss_handler(struct nl_m
+@@ -2662,8 +2675,10 @@ static int print_bss_handler(struct nl_m
  		else
  			printf("\tfreq: %d\n", freq);
  
@@ -239,7 +246,7 @@
  	}
  	if (bss[NL80211_BSS_BEACON_INTERVAL])
  		printf("\tbeacon interval: %d TUs\n",
-@@ -2804,6 +2819,7 @@ static int handle_stop_sched_scan(struct
+@@ -2857,6 +2872,7 @@ static int handle_stop_sched_scan(struct
  	return 0;
  }
  
@@ -247,7 +254,7 @@
  COMMAND(scan, sched_start,
  	SCHED_SCAN_OPTIONS,
  	NL80211_CMD_START_SCHED_SCAN, 0, CIB_NETDEV, handle_start_sched_scan,
-@@ -2814,3 +2830,4 @@ COMMAND(scan, sched_start,
+@@ -2867,3 +2883,4 @@ COMMAND(scan, sched_start,
  COMMAND(scan, sched_stop, "",
  	NL80211_CMD_STOP_SCHED_SCAN, 0, CIB_NETDEV, handle_stop_sched_scan,
  	"Stop an ongoing scheduled scan.");




More information about the lede-commits mailing list