Merge aa78ad37ba6cccc11ba9b383fecc9d51403d9e08 on remote branch

Change-Id: I853190015417e6f9ae123989f4980eb4bacaa950
diff --git a/event.c b/event.c
index ad29189..4c37297 100644
--- a/event.c
+++ b/event.c
@@ -893,6 +893,21 @@
 	printf("\n");
 }
 
+static void parse_assoc_comeback(struct nlattr **attrs, int command)
+{
+	__u32 timeout = 0;
+	char macbuf[6 * 3] = "<unset>";
+
+	if (attrs[NL80211_ATTR_MAC])
+		mac_addr_n2a(macbuf, nla_data(attrs[NL80211_ATTR_MAC]));
+
+	if (attrs[NL80211_ATTR_TIMEOUT])
+		timeout = nla_get_u32(attrs[NL80211_ATTR_TIMEOUT]);
+
+	printf("assoc comeback bssid %s timeout %d\n",
+	       macbuf, timeout);
+}
+
 static int print_event(struct nl_msg *msg, void *arg)
 {
 	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
@@ -1277,6 +1292,9 @@
 	case NL80211_CMD_CH_SWITCH_NOTIFY:
 		parse_ch_switch_notify(tb, gnlh->cmd);
 		break;
+	case NL80211_CMD_ASSOC_COMEBACK: /* 147 */
+		parse_assoc_comeback(tb, gnlh->cmd);
+		break;
 	default:
 		printf("unknown event %d (%s)\n",
 		       gnlh->cmd, command_name(gnlh->cmd));
diff --git a/info.c b/info.c
index 3a45b3f..24ae201 100644
--- a/info.c
+++ b/info.c
@@ -170,8 +170,12 @@
 				struct nlattr *nl_iftype;
 				int rem_band;
 
-				nla_for_each_nested(nl_iftype, tb_band[NL80211_BAND_ATTR_IFTYPE_DATA], rem_band)
+				nla_for_each_nested(nl_iftype,
+						    tb_band[NL80211_BAND_ATTR_IFTYPE_DATA],
+						    rem_band) {
 					print_he_info(nl_iftype);
+					print_eht_info(nl_iftype, last_band);
+				}
 			}
 			if (tb_band[NL80211_BAND_ATTR_FREQS]) {
 				if (!band_had_freq) {
@@ -702,6 +706,7 @@
 		ext_feat_print(tb, 4WAY_HANDSHAKE_AP_PSK, "AP mode PSK offload support");
 		ext_feat_print(tb, BSS_COLOR, "BSS coloring support");
 		ext_feat_print(tb, FILS_CRYPTO_OFFLOAD, "FILS crypto offload");
+		ext_feat_print(tb, RADAR_BACKGROUND, "Radar background support");
 	}
 
 	if (tb_msg[NL80211_ATTR_COALESCE_RULE]) {
@@ -712,7 +717,7 @@
 		rule = nla_data(tb_msg[NL80211_ATTR_COALESCE_RULE]);
 		pat = &rule->pat;
 		printf("\t\t * Maximum %u coalesce rules supported\n"
-		       "\t\t * Each rule contains upto %u patterns of %u-%u bytes,\n"
+		       "\t\t * Each rule contains up to %u patterns of %u-%u bytes,\n"
 		       "\t\t   maximum packet offset %u bytes\n"
 		       "\t\t * Maximum supported coalescing delay %u msecs\n",
 			rule->max_rules, pat->max_patterns, pat->min_pattern_len,
diff --git a/interface.c b/interface.c
index 89c95a9..84990c9 100644
--- a/interface.c
+++ b/interface.c
@@ -362,6 +362,8 @@
 		return "5 MHz";
 	case NL80211_CHAN_WIDTH_10:
 		return "10 MHz";
+	case NL80211_CHAN_WIDTH_320:
+		return "320 MHz";
 	default:
 		return "unknown";
 	}
diff --git a/iw.h b/iw.h
index 545fd0e..e712c59 100644
--- a/iw.h
+++ b/iw.h
@@ -220,6 +220,7 @@
 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);
+void print_eht_info(struct nlattr *nl_iftype, int band);
 
 char *channel_width_name(enum nl80211_chan_width width);
 const char *iftype_name(enum nl80211_iftype iftype);
diff --git a/mpath.c b/mpath.c
index a88f89f..2a559c2 100644
--- a/mpath.c
+++ b/mpath.c
@@ -226,7 +226,7 @@
 			     enum id_input id)
 {
 	printf("DEST ADDR         NEXT HOP          IFACE\tSN\tMETRIC\tQLEN\t"
-	       "EXPTIME\t\tDTIM\tDRET\tFLAGS\tHOP_COUNT\tPATH_CHANGE\n");
+	       "EXPTIME\tDTIM\tDRET\tFLAGS\tHOP_COUNT\tPATH_CHANGE\n");
 	register_handler(print_mpath_handler, NULL);
 	return 0;
 }
diff --git a/nl80211.h b/nl80211.h
index 61cab81..0568a79 100644
--- a/nl80211.h
+++ b/nl80211.h
@@ -11,7 +11,7 @@
  * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
  * Copyright 2008 Colin McCabe <colin@cozybit.com>
  * Copyright 2015-2017	Intel Deutschland GmbH
- * Copyright (C) 2018-2021 Intel Corporation
+ * Copyright (C) 2018-2022 Intel Corporation
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -1232,6 +1232,11 @@
  *	&NL80211_ATTR_FILS_NONCES - for FILS Nonces
  *		(STA Nonce 16 bytes followed by AP Nonce 16 bytes)
  *
+ * @NL80211_CMD_ASSOC_COMEBACK: notification about an association
+ *      temporal rejection with comeback. The event includes %NL80211_ATTR_MAC
+ *      to describe the BSSID address of the AP and %NL80211_ATTR_TIMEOUT to
+ *      specify the timeout value.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1474,6 +1479,8 @@
 
 	NL80211_CMD_SET_FILS_AAD,
 
+	NL80211_CMD_ASSOC_COMEBACK,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -2470,7 +2477,9 @@
  *	space supports external authentication. This attribute shall be used
  *	with %NL80211_CMD_CONNECT and %NL80211_CMD_START_AP request. The driver
  *	may offload authentication processing to user space if this capability
- *	is indicated in the respective requests from the user space.
+ *	is indicated in the respective requests from the user space. (This flag
+ *	attribute deprecated for %NL80211_CMD_START_AP, use
+ *	%NL80211_ATTR_AP_SETTINGS_FLAGS)
  *
  * @NL80211_ATTR_NSS: Station's New/updated  RX_NSS value notified using this
  *	u8 attribute. This is used with %NL80211_CMD_STA_OPMODE_CHANGED.
@@ -2639,6 +2648,21 @@
  *	Mandatory parameter for the transmitting interface to enable MBSSID.
  *	Optional for the non-transmitting interfaces.
  *
+ * @NL80211_ATTR_RADAR_BACKGROUND: Configure dedicated offchannel chain
+ *	available for radar/CAC detection on some hw. This chain can't be used
+ *	to transmit or receive frames and it is bounded to a running wdev.
+ *	Background radar/CAC detection allows to avoid the CAC downtime
+ *	switching on a different channel during CAC detection on the selected
+ *	radar channel.
+ *
+ * @NL80211_ATTR_AP_SETTINGS_FLAGS: u32 attribute contains ap settings flags,
+ *	enumerated in &enum nl80211_ap_settings_flags. This attribute shall be
+ *	used with %NL80211_CMD_START_AP request.
+ *
+ * @NL80211_ATTR_EHT_CAPABILITY: EHT Capability information element (from
+ *	association request when used with NL80211_CMD_NEW_STATION). Can be set
+ *	only if %NL80211_STA_FLAG_WME is set.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3145,6 +3169,12 @@
 	NL80211_ATTR_MBSSID_CONFIG,
 	NL80211_ATTR_MBSSID_ELEMS,
 
+	NL80211_ATTR_RADAR_BACKGROUND,
+
+	NL80211_ATTR_AP_SETTINGS_FLAGS,
+
+	NL80211_ATTR_EHT_CAPABILITY,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -3200,6 +3230,8 @@
 #define NL80211_HE_MAX_CAPABILITY_LEN           54
 #define NL80211_MAX_NR_CIPHER_SUITES		5
 #define NL80211_MAX_NR_AKM_SUITES		2
+#define NL80211_EHT_MIN_CAPABILITY_LEN          13
+#define NL80211_EHT_MAX_CAPABILITY_LEN          51
 
 #define NL80211_MIN_REMAIN_ON_CHANNEL_TIME	10
 
@@ -3227,7 +3259,7 @@
  *	and therefore can't be created in the normal ways, use the
  *	%NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE
  *	commands to create and destroy one
- * @NL80211_IF_TYPE_OCB: Outside Context of a BSS
+ * @NL80211_IFTYPE_OCB: Outside Context of a BSS
  *	This mode corresponds to the MIB variable dot11OCBActivated=true
  * @NL80211_IFTYPE_NAN: NAN device interface type (not a netdev)
  * @NL80211_IFTYPE_MAX: highest interface type number currently defined
@@ -3369,6 +3401,56 @@
 };
 
 /**
+ * enum nl80211_eht_gi - EHT guard interval
+ * @NL80211_RATE_INFO_EHT_GI_0_8: 0.8 usec
+ * @NL80211_RATE_INFO_EHT_GI_1_6: 1.6 usec
+ * @NL80211_RATE_INFO_EHT_GI_3_2: 3.2 usec
+ */
+enum nl80211_eht_gi {
+	NL80211_RATE_INFO_EHT_GI_0_8,
+	NL80211_RATE_INFO_EHT_GI_1_6,
+	NL80211_RATE_INFO_EHT_GI_3_2,
+};
+
+/**
+ * enum nl80211_eht_ru_alloc - EHT RU allocation values
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_26: 26-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_52: 52-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_52P26: 52+26-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_106: 106-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_106P26: 106+26 tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_242: 242-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_484: 484-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_484P242: 484+242 tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_996: 996-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_996P484: 996+484 tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_996P484P242: 996+484+242 tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_2x996: 2x996-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_2x996P484: 2x996+484 tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_3x996: 3x996-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_3x996P484: 3x996+484 tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_4x996: 4x996-tone RU allocation
+ */
+enum nl80211_eht_ru_alloc {
+	NL80211_RATE_INFO_EHT_RU_ALLOC_26,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_52,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_52P26,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_106,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_106P26,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_242,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_484,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_484P242,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_996,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_996P484,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_996P484P242,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_2x996,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_2x996P484,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_3x996,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_3x996P484,
+	NL80211_RATE_INFO_EHT_RU_ALLOC_4x996,
+};
+
+/**
  * enum nl80211_rate_info - bitrate information
  *
  * These attribute types are used with %NL80211_STA_INFO_TXRATE
@@ -3407,6 +3489,13 @@
  * @NL80211_RATE_INFO_HE_DCM: HE DCM value (u8, 0/1)
  * @NL80211_RATE_INFO_RU_ALLOC: HE RU allocation, if not present then
  *	non-OFDMA was used (u8, see &enum nl80211_he_ru_alloc)
+ * @NL80211_RATE_INFO_320_MHZ_WIDTH: 320 MHz bitrate
+ * @NL80211_RATE_INFO_EHT_MCS: EHT MCS index (u8, 0-15)
+ * @NL80211_RATE_INFO_EHT_NSS: EHT NSS value (u8, 1-8)
+ * @NL80211_RATE_INFO_EHT_GI: EHT guard interval identifier
+ *	(u8, see &enum nl80211_eht_gi)
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC: EHT RU allocation, if not present then
+ *	non-OFDMA was used (u8, see &enum nl80211_eht_ru_alloc)
  * @__NL80211_RATE_INFO_AFTER_LAST: internal use
  */
 enum nl80211_rate_info {
@@ -3428,6 +3517,11 @@
 	NL80211_RATE_INFO_HE_GI,
 	NL80211_RATE_INFO_HE_DCM,
 	NL80211_RATE_INFO_HE_RU_ALLOC,
+	NL80211_RATE_INFO_320_MHZ_WIDTH,
+	NL80211_RATE_INFO_EHT_MCS,
+	NL80211_RATE_INFO_EHT_NSS,
+	NL80211_RATE_INFO_EHT_GI,
+	NL80211_RATE_INFO_EHT_RU_ALLOC,
 
 	/* keep last */
 	__NL80211_RATE_INFO_AFTER_LAST,
@@ -3738,13 +3832,20 @@
  *     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_VENDOR_ELEMS: vendor element capabilities that are
  *	advertised on this band/for this iftype (binary)
+ * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC: EHT MAC capabilities as in EHT
+ *	capabilities element
+ * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY: EHT PHY capabilities as in EHT
+ *	capabilities element
+ * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET: EHT supported NSS/MCS as in EHT
+ *	capabilities element
+ * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE: EHT PPE thresholds information as
+ *	defined in EHT capabilities element
  * @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use
+ * @NL80211_BAND_IFTYPE_ATTR_MAX: highest band attribute currently defined
  */
 enum nl80211_band_iftype_attr {
 	__NL80211_BAND_IFTYPE_ATTR_INVALID,
@@ -3756,6 +3857,10 @@
 	NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
 	NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
 	NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS,
+	NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC,
+	NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY,
+	NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET,
+	NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE,
 
 	/* keep last */
 	__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST,
@@ -3900,6 +4005,10 @@
  *	on this channel in current regulatory domain.
  * @NL80211_FREQUENCY_ATTR_16MHZ: 16 MHz operation is allowed
  *	on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_NO_320MHZ: any 320 MHz channel using this channel
+ *	as the primary or any of the secondary channels isn't possible
+ * @NL80211_FREQUENCY_ATTR_NO_EHT: EHT operation is not allowed on this channel
+ *	in current regulatory domain.
  * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
  *	currently defined
  * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
@@ -3936,6 +4045,8 @@
 	NL80211_FREQUENCY_ATTR_4MHZ,
 	NL80211_FREQUENCY_ATTR_8MHZ,
 	NL80211_FREQUENCY_ATTR_16MHZ,
+	NL80211_FREQUENCY_ATTR_NO_320MHZ,
+	NL80211_FREQUENCY_ATTR_NO_EHT,
 
 	/* keep last */
 	__NL80211_FREQUENCY_ATTR_AFTER_LAST,
@@ -4134,6 +4245,7 @@
  * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed
  * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed
  * @NL80211_RRF_NO_HE: HE operation not allowed
+ * @NL80211_RRF_NO_320MHZ: 320MHz operation not allowed
  */
 enum nl80211_reg_rule_flags {
 	NL80211_RRF_NO_OFDM		= 1<<0,
@@ -4152,6 +4264,7 @@
 	NL80211_RRF_NO_80MHZ		= 1<<15,
 	NL80211_RRF_NO_160MHZ		= 1<<16,
 	NL80211_RRF_NO_HE		= 1<<17,
+	NL80211_RRF_NO_320MHZ		= 1<<18,
 };
 
 #define NL80211_RRF_PASSIVE_SCAN	NL80211_RRF_NO_IR
@@ -4649,6 +4762,8 @@
  * @NL80211_CHAN_WIDTH_4: 4 MHz OFDM channel
  * @NL80211_CHAN_WIDTH_8: 8 MHz OFDM channel
  * @NL80211_CHAN_WIDTH_16: 16 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_320: 320 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
+ *	attribute must be provided as well
  */
 enum nl80211_chan_width {
 	NL80211_CHAN_WIDTH_20_NOHT,
@@ -4664,6 +4779,7 @@
 	NL80211_CHAN_WIDTH_4,
 	NL80211_CHAN_WIDTH_8,
 	NL80211_CHAN_WIDTH_16,
+	NL80211_CHAN_WIDTH_320,
 };
 
 /**
@@ -5555,7 +5671,7 @@
  *	=> allows 8 of AP/GO that can have BI gcd >= min gcd
  *
  *	numbers = [ #{STA} <= 2 ], channels = 2, max = 2
- *	=> allows two STAs on different channels
+ *	=> allows two STAs on the same or on different channels
  *
  *	numbers = [ #{STA} <= 1, #{P2P-client,P2P-GO} <= 3 ], max = 4
  *	=> allows a STA plus three P2P interfaces
@@ -5600,7 +5716,7 @@
  * @NL80211_PLINK_ESTAB: mesh peer link is established
  * @NL80211_PLINK_HOLDING: mesh peer link is being closed or cancelled
  * @NL80211_PLINK_BLOCKED: all frames transmitted from this mesh
- *	plink are discarded
+ *	plink are discarded, except for authentication frames
  * @NUM_NL80211_PLINK_STATES: number of peer link states
  * @MAX_NL80211_PLINK_STATES: highest numerical value of plink states
  */
@@ -5737,13 +5853,15 @@
 	NL80211_TDLS_DISABLE_LINK,
 };
 
-/*
+/**
  * enum nl80211_ap_sme_features - device-integrated AP features
- * Reserved for future use, no bits are defined in
- * NL80211_ATTR_DEVICE_AP_SME yet.
-enum nl80211_ap_sme_features {
-};
+ * @NL80211_AP_SME_SA_QUERY_OFFLOAD: SA Query procedures offloaded to driver
+ *	when user space indicates support for SA Query procedures offload during
+ *	"start ap" with %NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT.
  */
+enum nl80211_ap_sme_features {
+	NL80211_AP_SME_SA_QUERY_OFFLOAD		= 1 << 0,
+};
 
 /**
  * enum nl80211_feature_flags - device/driver features
@@ -6051,6 +6169,9 @@
  *	frames. Userspace has to share FILS AAD details to the driver by using
  *	@NL80211_CMD_SET_FILS_AAD.
  *
+ * @NL80211_EXT_FEATURE_RADAR_BACKGROUND: Device supports background radar/CAC
+ *	detection.
+ *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
  */
@@ -6117,6 +6238,7 @@
 	NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
 	NL80211_EXT_FEATURE_BSS_COLOR,
 	NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD,
+	NL80211_EXT_FEATURE_RADAR_BACKGROUND,
 
 	/* add new features before the definition below */
 	NUM_NL80211_EXT_FEATURES,
@@ -7462,4 +7584,20 @@
 	NL80211_MBSSID_CONFIG_ATTR_MAX = __NL80211_MBSSID_CONFIG_ATTR_LAST - 1,
 };
 
+/**
+ * enum nl80211_ap_settings_flags - AP settings flags
+ *
+ * @NL80211_AP_SETTINGS_EXTERNAL_AUTH_SUPPORT: AP supports external
+ *	authentication.
+ * @NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT: Userspace supports SA Query
+ *	procedures offload to driver. If driver advertises
+ *	%NL80211_AP_SME_SA_QUERY_OFFLOAD in AP SME features, userspace shall
+ *	ignore SA Query procedures and validations when this flag is set by
+ *	userspace.
+ */
+enum nl80211_ap_settings_flags {
+	NL80211_AP_SETTINGS_EXTERNAL_AUTH_SUPPORT	= 1 << 0,
+	NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT	= 1 << 1,
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/reg.c b/reg.c
index feb347a..857c995 100644
--- a/reg.c
+++ b/reg.c
@@ -210,6 +210,7 @@
 		PARSE_FLAG(NL80211_RRF_NO_80MHZ, "NO-80MHZ");
 		PARSE_FLAG(NL80211_RRF_NO_160MHZ, "NO-160MHZ");
 		PARSE_FLAG(NL80211_RRF_NO_HE, "NO-HE");
+		PARSE_FLAG(NL80211_RRF_NO_320MHZ, "NO-320MHZ");
 
 		/* Kernels that support NO_IR always turn on both flags */
 		if ((flags & NL80211_RRF_NO_IR) && (flags & __NL80211_RRF_NO_IBSS)) {
diff --git a/station.c b/station.c
index 002cf13..da1feae 100644
--- a/station.c
+++ b/station.c
@@ -239,6 +239,8 @@
 		pos += snprintf(pos, buflen - (pos - buf), " 80P80MHz");
 	if (rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
 		pos += snprintf(pos, buflen - (pos - buf), " 160MHz");
+	if (rinfo[NL80211_RATE_INFO_320_MHZ_WIDTH])
+		pos += snprintf(pos, buflen - (pos - buf), " 320MHz");
 	if (rinfo[NL80211_RATE_INFO_SHORT_GI])
 		pos += snprintf(pos, buflen - (pos - buf), " short GI");
 	if (rinfo[NL80211_RATE_INFO_VHT_NSS])
@@ -259,6 +261,18 @@
 	if (rinfo[NL80211_RATE_INFO_HE_RU_ALLOC])
 		pos += snprintf(pos, buflen - (pos - buf),
 				" HE-RU-ALLOC %d", nla_get_u8(rinfo[NL80211_RATE_INFO_HE_RU_ALLOC]));
+	if (rinfo[NL80211_RATE_INFO_EHT_MCS])
+		pos += snprintf(pos, buflen - (pos - buf),
+				" EHT-MCS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_EHT_MCS]));
+	if (rinfo[NL80211_RATE_INFO_EHT_NSS])
+		pos += snprintf(pos, buflen - (pos - buf),
+				" EHT-NSS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_EHT_NSS]));
+	if (rinfo[NL80211_RATE_INFO_EHT_GI])
+		pos += snprintf(pos, buflen - (pos - buf),
+				" EHT-GI %d", nla_get_u8(rinfo[NL80211_RATE_INFO_EHT_GI]));
+	if (rinfo[NL80211_RATE_INFO_EHT_RU_ALLOC])
+		pos += snprintf(pos, buflen - (pos - buf),
+				" EHT-RU-ALLOC %d", nla_get_u8(rinfo[NL80211_RATE_INFO_EHT_RU_ALLOC]));
 }
 
 static char *get_chain_signal(struct nlattr *attr_list)
diff --git a/util.c b/util.c
index 8ec2be2..faef767 100644
--- a/util.c
+++ b/util.c
@@ -298,6 +298,7 @@
 	[NL80211_CMD_COLOR_CHANGE_ABORTED] = "color_change_aborted",
 	[NL80211_CMD_COLOR_CHANGE_COMPLETED] = "color_change_completed",
 	[NL80211_CMD_SET_FILS_AAD] = "set_fils_aad",
+	[NL80211_CMD_ASSOC_COMEBACK] = "assoc_comeback",
 };
 
 static char cmdbuf[100];
@@ -657,6 +658,7 @@
 	case NL80211_CHAN_WIDTH_40:
 	case NL80211_CHAN_WIDTH_80:
 	case NL80211_CHAN_WIDTH_160:
+	case NL80211_CHAN_WIDTH_320:
 		need_cf1 = true;
 		break;
 	case NL80211_CHAN_WIDTH_1:
@@ -774,6 +776,10 @@
 		  .width = NL80211_CHAN_WIDTH_160,
 		  .freq1_diff = 0,
 		  .chantype = -1 },
+		{ .name = "320MHz",
+		  .width = NL80211_CHAN_WIDTH_320,
+		  .freq1_diff = 0,
+		  .chantype = -1 },
 	};
 	const struct chanmode *chanmode_selected = NULL;
 	unsigned int freq;
@@ -1415,6 +1421,216 @@
 			true);
 }
 
+static void __print_eht_capa(int band,
+			     const __u8 *mac_cap,
+			     const __u32 *phy_cap,
+			     const __u8 *mcs_set, size_t mcs_len,
+			     const __u8 *ppet, size_t ppet_len,
+			     const __u16 *he_phy_cap,
+			     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 { \
+		if (_var[_idx] & BIT(_bit)) \
+			printf("%s\t\t\t" _str "\n", pre); \
+	} while (0)
+
+	#define PRINT_EHT_CAP_MASK(_var, _idx, _shift, _mask, _str) \
+	do { \
+		if ((_var[_idx] >> _shift) & _mask) \
+			printf("%s\t\t\t" _str ": %d\n", pre, (_var[_idx] >> _shift) & _mask); \
+	} while (0)
+
+	#define PRINT_EHT_MAC_CAP(...) PRINT_EHT_CAP(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__)
+
+	printf("%s\t\tEHT MAC Capabilities (0x", pre);
+	for (i = 0; i < 2; i++)
+		printf("%02x", mac_cap[i]);
+	printf("):\n");
+
+	PRINT_EHT_MAC_CAP(0, 0, "NSEP 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");
+
+	printf("%s\t\tEHT PHY Capabilities: (0x", pre);
+	for (i = 0; i < 8; i++)
+		printf("%02x", ((__u8 *)phy_cap)[i]);
+	printf("):\n");
+
+	PRINT_EHT_PHY_CAP(0, 1, "320MHz in 6GHz Supported");
+	PRINT_EHT_PHY_CAP(0, 2, "242-tone RU in BW wider than 20MHz Supported");
+	PRINT_EHT_PHY_CAP(0, 3, "NDP With  EHT-LTF And 3.2 µs GI");
+	PRINT_EHT_PHY_CAP(0, 4, "Partial Bandwidth UL MU-MIMO");
+	PRINT_EHT_PHY_CAP(0, 5, "SU Beamformer");
+	PRINT_EHT_PHY_CAP(0, 6, "SU Beamformee");
+	PRINT_EHT_PHY_CAP_MASK(0, 7, 0x7, "Beamformee SS (80MHz)");
+	PRINT_EHT_PHY_CAP_MASK(0, 10, 0x7, "Beamformee SS (160MHz)");
+	PRINT_EHT_PHY_CAP_MASK(0, 13, 0x7, "Beamformee SS (320MHz)");
+
+	PRINT_EHT_PHY_CAP_MASK(0, 16, 0x7, "Number Of Sounding Dimensions (80MHz)");
+	PRINT_EHT_PHY_CAP_MASK(0, 19, 0x7, "Number Of Sounding Dimensions (160MHz)");
+	PRINT_EHT_PHY_CAP_MASK(0, 22, 0x7, "Number Of Sounding Dimensions (320MHz)");
+	PRINT_EHT_PHY_CAP(0, 25, "Ng = 16 SU Feedback");
+	PRINT_EHT_PHY_CAP(0, 26, "Ng = 16 MU Feedback");
+	PRINT_EHT_PHY_CAP(0, 27, "Codebook size (4, 2) SU Feedback");
+	PRINT_EHT_PHY_CAP(0, 28, "Codebook size (7, 5) MU Feedback");
+	PRINT_EHT_PHY_CAP(0, 29, "Triggered SU Beamforming Feedback");
+	PRINT_EHT_PHY_CAP(0, 30, "Triggered MU Beamforming Partial BW Feedback");
+	PRINT_EHT_PHY_CAP(0, 31, "Triggered CQI Feedback");
+
+	PRINT_EHT_PHY_CAP(1, 0, "Partial Bandwidth DL MU-MIMO");
+	PRINT_EHT_PHY_CAP(1, 1, "PSR-Based SR Support");
+	PRINT_EHT_PHY_CAP(1, 2, "Power Boost Factor Support");
+	PRINT_EHT_PHY_CAP(1, 3, "EHT MU PPDU With 4 EHT-LTF And 0.8 µs GI");
+	PRINT_EHT_PHY_CAP_MASK(1, 4, 0xf, "Max Nc");
+	PRINT_EHT_PHY_CAP(1, 8, "Non-Triggered CQI Feedback");
+
+	PRINT_EHT_PHY_CAP(1, 9, "Tx 1024-QAM And 4096-QAM < 242-tone RU");
+	PRINT_EHT_PHY_CAP(1, 10, "Rx 1024-QAM And 4096-QAM < 242-tone RU");
+	PRINT_EHT_PHY_CAP(1, 11, "PPE Thresholds Present");
+	PRINT_EHT_PHY_CAP_MASK(1, 12, 0x3, "Common Nominal Packet Padding");
+	PRINT_EHT_PHY_CAP_MASK(1, 14, 0x1f, "Maximum Number Of Supported EHT-LTFs");
+	PRINT_EHT_PHY_CAP_MASK(1, 19, 0xf, "Support of MCS 15");
+	PRINT_EHT_PHY_CAP(1, 23, "Support Of EHT DUP In 6 GHz");
+	PRINT_EHT_PHY_CAP(1, 24, "Support For 20MHz Rx NDP With Wider Bandwidth");
+	PRINT_EHT_PHY_CAP(1, 25, "Non-OFDMA UL MU-MIMO (80MHz)");
+	PRINT_EHT_PHY_CAP(1, 26, "Non-OFDMA UL MU-MIMO (160MHz)");
+	PRINT_EHT_PHY_CAP(1, 27, "Non-OFDMA UL MU-MIMO (320MHz)");
+	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)");
+
+	printf("%s\t\tEHT MCS/NSS: (0x", pre);
+	for (i = 0; i < mcs_len; i++)
+		printf("%02x", ((__u8 *)mcs_set)[i]);
+	printf("):\n");
+
+	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);
+	}
+
+	mcs_set += 4;
+	if (he_phy_cap[0] & (BIT(2) << 8)) {
+		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);
+
+	}
+
+	mcs_set += 3;
+	if (he_phy_cap[0] & (BIT(3) << 8)) {
+		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);
+
+	}
+
+	mcs_set += 3;
+	if (band == NL80211_BAND_6GHZ && (phy_cap[0] & BIT(1))) {
+		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);
+
+	}
+
+	if (ppet && ppet_len && (phy_cap[1] & BIT(11))) {
+		printf("%s\t\tEHT PPE Thresholds ", pre);
+		for (i = 0; i < ppet_len; i++)
+			if (ppet[i])
+				printf("0x%02x ", ppet[i]);
+		printf("\n");
+	}
+}
+
+void print_eht_info(struct nlattr *nl_iftype, int band)
+{
+	struct nlattr *tb[NL80211_BAND_IFTYPE_ATTR_MAX + 1];
+	__u8 mac_cap[2] = { 0 };
+	__u32 phy_cap[2] = { 0 };
+	__u8 mcs_set[13] = { 0 };
+	__u8 ppet[31] = { 0 };
+	__u16 he_phy_cap[6] = { 0 };
+	size_t len, mcs_len = 0, ppet_len = 0;
+
+	nla_parse(tb, NL80211_BAND_IFTYPE_ATTR_MAX,
+		  nla_data(nl_iftype), nla_len(nl_iftype), NULL);
+
+	if (!tb[NL80211_BAND_IFTYPE_ATTR_IFTYPES])
+		return;
+
+	printf("\t\tEHT Iftypes: ");
+	print_iftype_line(tb[NL80211_BAND_IFTYPE_ATTR_IFTYPES]);
+	printf("\n");
+
+	if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]) {
+		len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]);
+		if (len > sizeof(mac_cap))
+			len = sizeof(mac_cap);
+		memcpy(mac_cap,
+		       nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]),
+		       len);
+	}
+
+	if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]) {
+		len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]);
+
+		if (len > sizeof(phy_cap))
+			len = sizeof(phy_cap);
+
+		memcpy(phy_cap,
+		       nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]),
+		       len);
+	}
+
+	if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]) {
+		len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]);
+		if (len > sizeof(mcs_set))
+			len = sizeof(mcs_set);
+		memcpy(mcs_set,
+		       nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]),
+		       len);
+
+		// Assume that all parts of the MCS set are present
+		mcs_len = sizeof(mcs_set);
+	}
+
+	if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]) {
+		len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]);
+		if (len > sizeof(ppet))
+			len = sizeof(ppet);
+		memcpy(ppet,
+		       nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]),
+		       len);
+		ppet_len = len;
+	}
+
+	if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]) {
+		len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]);
+
+		if (len > sizeof(he_phy_cap) - 1)
+			len = sizeof(he_phy_cap) - 1;
+		memcpy(&((__u8 *)he_phy_cap)[1],
+		       nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]),
+		       len);
+	}
+
+	__print_eht_capa(band, mac_cap, phy_cap, mcs_set, mcs_len, ppet, ppet_len,
+			 he_phy_cap, true);
+}
+
 void print_he_capability(const uint8_t *ie, int len)
 {
 	const void *mac_cap, *phy_cap, *mcs_set;
@@ -1454,7 +1670,8 @@
 				5955, 6035, 6115, 6195, 6275, 6355,
 				6435, 6515, 6595, 6675, 6755, 6835,
 				6195, 6995 };
-	unsigned int vht160[] = { 5180, 5500 };
+	unsigned int bw160[] = { 5180, 5500, 5955, 6115, 6275, 6435,
+				  6595, 6755, 6915 };
 
 	switch (chanmode->width) {
 	case NL80211_CHAN_WIDTH_80:
@@ -1471,15 +1688,15 @@
 		break;
 	case NL80211_CHAN_WIDTH_160:
 		/* setup center_freq1 */
-		for (j = 0; j < ARRAY_SIZE(vht160); j++) {
-			if (freq >= vht160[j] && freq < vht160[j] + 160)
+		for (j = 0; j < ARRAY_SIZE(bw160); j++) {
+			if (freq >= bw160[j] && freq < bw160[j] + 160)
 				break;
 		}
 
-		if (j == ARRAY_SIZE(vht160))
+		if (j == ARRAY_SIZE(bw160))
 			break;
 
-		cf1 = vht160[j] + 70;
+		cf1 = bw160[j] + 70;
 		break;
 	default:
 		cf1 = freq + chanmode->freq1_diff;