[wpa_supplicant] cumilative patch from commit d3ed34ba

Bug: 289287296
Test: Connect to open, WPA2, WPA3 and passpoint network
Test: Establish P2P connection
Test: Basic SoftAp tests
Test: Regression test (b/289297084)

BYPASS_INCLUSIVE_LANGUAGE_REASON=Merged from open source
d3ed34bac Define a QCA vendor command to configure MLO link id for TDLS
8e16372cf Indicate link reconfiguration with QCA vendor interface
7b9070229 Indicate TID to link mapping changes with QCA vendor interface
4120f9d7a PASN: Introduce configuration option to allow/deny PASN-UNAUTH
fc681995c Increase MAX_NL80211_NOISE_FREQS in survey dump handler for 6 GHz
df2f22faf MLD STA: Use AP MLD address as previous BSSID for reassociation requests
199b44213 MLD STA: Allow auth frames without ML IE for failure status codes
57386a647 Add QCA vendor command to indicate STA MLD setup links removal
527cf095f Add QCA vendor command to notify TID-to-Link mapping changes
a1601aaa6 WPS: Fix multi-ap fronthaul association
288566031 Store pmk_r1_name derived with wpa_ft_local_derive_pmk_r1() properly
e978072ba Do prune_association only after the STA is authorized
a2c09eb95 Define a QCA vendor attribute to update the CTS channel width
e49c3df63 Add a new driver feature flag for enhanced audio experience over WLAN
cc8a09a48 Add vendor attributes for forcing MLO power save and STR TX
c0e12a518 Add vendor attributes for EHT OM control, EMLSR padding delay
386d59e00 Do not disconnect EAPOL-Logoff before authentication
733723220 wpa_supplicant: Skip scan before starting a BSS in AP mode
f45cf609c wpa_supplicant: Fix compiling without IEEE8021X_EAPOL
c62e94d79 Add missing driver entries to wpa_supplicant documentation
9122b60ff DPP: Remove argument requirement for DPP push button command
397d432f6 Add vendor attributes for MLO link active, EMLSR entry/exit
5d285040d Rename VHT elements to match the standard
8f8f68ba6 hostapd: Support channel switch to 320 MHz channels
4d0743d5e Fix file mode bits
d930211bd Select 6 GHz mode correctly for ACS cases
927dbfb45 Fix 40 MHz channel bringup with ACS on the 6 GHz band
8bc84fcee Allow MLO disabled connection to legacy open/WPA2-Personal-only AP MLDs
b9c3b57a9 Update AP RSNE/RSNXE to RSN state machine on driver-selected BSS cases
566ab39a7 tests: KDK derivation based on Secure LTF capability
6972b0fa2 OWE: Update transition mode information on selecting a new BSS
f54ce7433 Fix determining mode for 6 GHz band when using hw_mode=any
5b568b21a Add support to fetch link layer stats per MLO link
6422b0d72 Fix vendor attribute numbering and relocate attribute accordingly
c858a6360 Add a vendor specific roam status of background scan abort
b171c5e4d Update QCA LL_STATS vendor command
6002fe87d SAE: Fix expected AP MLD address info in a debug print
c70405cef MLD STA: Do not fail on unknown IEs in Authentication frames
f8931fcba hostapd: Restore the flow of set beacon and WPA key init
e8912452e Export wpa_supplicant config item 'he' for external configuration
9932ff30c Allowed frequency list configuration for AP operation
07a7bcd7e WMM: Advertise support for 16 PTKSA replay counters for non-AP STA
ac54b6127 nl80211: Support for RNR elements
5d06acefd RNR: Add elements by default for EMA AP
8f1d38419 RNR: Skip interfaces on the same radio for MBSSID
921f82cf1 Sync with wireless-next.git include/uapi/linux/nl80211.h
302d761a8 Add QCA vendor feature flag for allowed frequency list
44c38af04 Add QCA vendor interface to get connected channels utilization
bb4560252 Add QCA vendor attribute to configure list of allowed frequencies for AP

Change-Id: Ibb944a0a4fbb2ac4abdec8fb09ce2dab3b551c27
diff --git a/wpa_supplicant/README b/wpa_supplicant/README
index c643b26..f8da781 100644
--- a/wpa_supplicant/README
+++ b/wpa_supplicant/README
@@ -442,7 +442,9 @@
   nl80211 = Linux nl80211/cfg80211
   wext = Linux wireless extensions (generic)
   wired = wpa_supplicant wired Ethernet driver
+  macsec_linux = MACsec Ethernet driver for Linux
   roboswitch = wpa_supplicant Broadcom switch driver
+  none = no driver (RADIUS server/WPS ER only)
   bsd = BSD 802.11 support (Atheros, etc.)
   ndis = Windows NDIS driver
 
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index a5d4d81..c843cb0 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2501,6 +2501,7 @@
 	{ FUNC(freq_list) },
 	{ INT_RANGE(ht, 0, 1) },
 	{ INT_RANGE(vht, 0, 1) },
+	{ INT_RANGE(he, 0, 1) },
 	{ INT_RANGE(ht40, -1, 1) },
 	{ INT_RANGE(max_oper_chwidth, CONF_OPER_CHWIDTH_USE_HT,
 		    CONF_OPER_CHWIDTH_80P80MHZ) },
diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
index 898765c..df538e3 100644
--- a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
@@ -274,6 +274,13 @@
       </varlistentry>
 
       <varlistentry>
+	<term>macsec_linux</term>
+	<listitem>
+	  <para>MACsec Ethernet driver for Linux</para>
+	</listitem>
+      </varlistentry>
+
+      <varlistentry>
 	<term>roboswitch</term>
 	<listitem>
 	  <para>wpa_supplicant Broadcom switch driver</para>
@@ -281,6 +288,13 @@
       </varlistentry>
 
       <varlistentry>
+	<term>none</term>
+	<listitem>
+	  <para>no driver (RADIUS server/WPS ER only)</para>
+	</listitem>
+      </varlistentry>
+
+      <varlistentry>
 	<term>bsd</term>
 	<listitem>
 	  <para>BSD 802.11 support (Atheros, etc.).</para>
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 0909961..e83d877 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -60,6 +60,10 @@
 static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
 					      int new_scan, int own_request);
 #endif /* CONFIG_NO_SCAN_PROCESSING */
+#ifdef CONFIG_OWE
+static void owe_trans_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+			   const u8 **ret_ssid, size_t *ret_ssid_len);
+#endif /* CONFIG_OWE */
 
 
 int wpas_temp_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
@@ -187,6 +191,7 @@
 					union wpa_event_data *data)
 {
 	struct wpa_ssid *ssid, *old_ssid;
+	struct wpa_bss *bss;
 	u8 drv_ssid[SSID_MAX_LEN];
 	size_t drv_ssid_len;
 	int res;
@@ -210,6 +215,14 @@
 			return 0; /* current profile still in use */
 
 #ifdef CONFIG_OWE
+		if (wpa_s->current_bss &&
+		    !(wpa_s->current_bss->flags & WPA_BSS_OWE_TRANSITION)) {
+			const u8 *match_ssid;
+			size_t match_ssid_len;
+
+			owe_trans_ssid(wpa_s, wpa_s->current_bss,
+				       &match_ssid, &match_ssid_len);
+		}
 		if ((wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
 		    wpa_s->current_bss &&
 		    (wpa_s->current_bss->flags & WPA_BSS_OWE_TRANSITION) &&
@@ -254,6 +267,7 @@
 
 	wpa_dbg(wpa_s, MSG_DEBUG, "Network configuration found for the "
 		"current AP");
+	bss = wpa_supplicant_update_current_bss(wpa_s, wpa_s->bssid);
 	if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
 		u8 wpa_ie[80];
 		size_t wpa_ie_len = sizeof(wpa_ie);
@@ -263,7 +277,7 @@
 		 * driver indicated the actual values used in the
 		 * (Re)Association Request frame. */
 		skip_default_rsne = data && data->assoc_info.req_ies;
-		if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
+		if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
 					      wpa_ie, &wpa_ie_len,
 					      skip_default_rsne) < 0)
 			wpa_dbg(wpa_s, MSG_DEBUG, "Could not set WPA suites");
@@ -276,8 +290,6 @@
 	old_ssid = wpa_s->current_ssid;
 	wpa_s->current_ssid = ssid;
 
-	wpa_supplicant_update_current_bss(wpa_s, wpa_s->bssid);
-
 	wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
 	wpa_supplicant_initiate_eapol(wpa_s);
 	if (old_ssid != wpa_s->current_ssid)
@@ -611,8 +623,7 @@
 #ifdef CONFIG_WEP
 	int wep_ok;
 #endif /* CONFIG_WEP */
-	bool is_6ghz_bss_or_mld = is_6ghz_freq(bss->freq) ||
-		!is_zero_ether_addr(bss->mld_addr);
+	bool is_6ghz_bss = is_6ghz_freq(bss->freq);
 
 	ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss);
 	if (ret >= 0)
@@ -627,10 +638,10 @@
 #endif /* CONFIG_WEP */
 
 	rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
-	if (is_6ghz_bss_or_mld && !rsn_ie) {
+	if (is_6ghz_bss && !rsn_ie) {
 		if (debug_print)
 			wpa_dbg(wpa_s, MSG_DEBUG,
-				"   skip - 6 GHz/MLD BSS without RSNE");
+				"   skip - 6 GHz BSS without RSNE");
 		return 0;
 	}
 
@@ -648,8 +659,8 @@
 		if (!ie.has_group)
 			ie.group_cipher = wpa_default_rsn_cipher(bss->freq);
 
-		if (is_6ghz_bss_or_mld) {
-			/* WEP and TKIP are not allowed on 6 GHz */
+		if (is_6ghz_bss || !is_zero_ether_addr(bss->mld_addr)) {
+			/* WEP and TKIP are not allowed on 6 GHz/MLD */
 			ie.pairwise_cipher &= ~(WPA_CIPHER_WEP40 |
 						WPA_CIPHER_WEP104 |
 						WPA_CIPHER_TKIP);
@@ -699,12 +710,12 @@
 			break;
 		}
 
-		if (is_6ghz_bss_or_mld) {
+		if (is_6ghz_bss) {
 			/* MFPC must be supported on 6 GHz */
 			if (!(ie.capabilities & WPA_CAPABILITY_MFPC)) {
 				if (debug_print)
 					wpa_dbg(wpa_s, MSG_DEBUG,
-						"   skip RSNE - 6 GHz/MLD without MFPC");
+						"   skip RSNE - 6 GHz without MFPC");
 				break;
 			}
 
@@ -744,10 +755,10 @@
 		return 1;
 	}
 
-	if (is_6ghz_bss_or_mld) {
+	if (is_6ghz_bss) {
 		if (debug_print)
 			wpa_dbg(wpa_s, MSG_DEBUG,
-				"   skip - 6 GHz/MLD BSS without matching RSNE");
+				"   skip - 6 GHz BSS without matching RSNE");
 		return 0;
 	}
 
@@ -1828,6 +1839,7 @@
 			   struct wpa_bss *selected,
 			   struct wpa_ssid *ssid)
 {
+#ifdef IEEE8021X_EAPOL
 	if ((eap_is_wps_pbc_enrollee(&ssid->eap) &&
 	     wpas_wps_partner_link_overlap_detect(wpa_s)) ||
 	    wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
@@ -1850,6 +1862,7 @@
 #endif /* CONFIG_WPS */
 		return -1;
 	}
+#endif /* IEEE8021X_EAPOL */
 
 	wpa_msg(wpa_s, MSG_DEBUG,
 		"Considering connect request: reassociate: %d  selected: "
@@ -3793,7 +3806,13 @@
 	wpas_fst_update_mb_assoc(wpa_s, data);
 
 #ifdef CONFIG_SME
-	os_memcpy(wpa_s->sme.prev_bssid, bssid, ETH_ALEN);
+	/*
+	 * Cache the current AP's BSSID (for non-MLO connection) or MLD address
+	 * (for MLO connection) as the previous BSSID for subsequent
+	 * reassociation requests handled by SME-in-wpa_supplicant.
+	 */
+	os_memcpy(wpa_s->sme.prev_bssid,
+		  wpa_s->valid_links ? wpa_s->ap_mld_addr : bssid, ETH_ALEN);
 	wpa_s->sme.prev_bssid_set = 1;
 	wpa_s->sme.last_unprot_disconnect.sec = 0;
 #endif /* CONFIG_SME */
@@ -5383,6 +5402,97 @@
 }
 
 
+static const char * bitmap_to_str(u8 value, char *buf)
+{
+	char *pos = buf;
+	int i, k = 0;
+
+	for (i = 7; i >= 0; i--)
+		pos[k++] = (value & BIT(i)) ? '1' : '0';
+
+	pos[8] = '\0';
+	return pos;
+}
+
+
+static void wpas_tid_link_map(struct wpa_supplicant *wpa_s,
+			      struct tid_link_map_info *info)
+{
+	char map_info[1000], *pos, *end;
+	int res, i;
+
+	pos = map_info;
+	end = pos + sizeof(map_info);
+	res = os_snprintf(map_info, sizeof(map_info), "default=%d",
+			  info->default_map);
+	if (os_snprintf_error(end - pos, res))
+		return;
+	pos += res;
+
+	if (!info->default_map) {
+		for (i = 0; i < MAX_NUM_MLD_LINKS && end > pos; i++) {
+			char uplink_map_str[9];
+			char downlink_map_str[9];
+
+			if (!(info->valid_links & BIT(i)))
+				continue;
+
+			bitmap_to_str(info->t2lmap[i].uplink, uplink_map_str);
+			bitmap_to_str(info->t2lmap[i].downlink,
+				      downlink_map_str);
+
+			res = os_snprintf(pos, end - pos,
+					  " link_id=%d up_link=%s down_link=%s",
+					  i, uplink_map_str,
+					  downlink_map_str);
+			if (os_snprintf_error(end - pos, res))
+				return;
+			pos += res;
+		}
+	}
+
+	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_T2LM_UPDATE "%s", map_info);
+}
+
+
+static void wpas_link_reconfig(struct wpa_supplicant *wpa_s)
+{
+	u8 bssid[ETH_ALEN];
+
+	if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
+		wpa_printf(MSG_ERROR, "LINK_RECONFIG: Failed to get BSSID");
+		wpa_supplicant_deauthenticate(wpa_s,
+					      WLAN_REASON_DEAUTH_LEAVING);
+		return;
+	}
+
+	if (os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) {
+		os_memcpy(wpa_s->bssid, bssid, ETH_ALEN);
+		wpa_supplicant_update_current_bss(wpa_s, wpa_s->bssid);
+		wpas_notify_bssid_changed(wpa_s);
+	}
+
+	if (wpa_drv_get_mlo_info(wpa_s) < 0) {
+		wpa_printf(MSG_ERROR,
+			   "LINK_RECONFIG: Failed to get MLO connection info");
+		wpa_supplicant_deauthenticate(wpa_s,
+					      WLAN_REASON_DEAUTH_LEAVING);
+		return;
+	}
+
+	if (wpa_sm_set_ml_info(wpa_s)) {
+		wpa_printf(MSG_ERROR,
+			   "LINK_RECONFIG: Failed to set MLO connection info to wpa_sm");
+		wpa_supplicant_deauthenticate(wpa_s,
+					      WLAN_REASON_DEAUTH_LEAVING);
+		return;
+	}
+
+	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_LINK_RECONFIG "valid_links=0x%x",
+		wpa_s->valid_links);
+}
+
+
 void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 			  union wpa_event_data *data)
 {
@@ -5482,6 +5592,9 @@
 		wpas_event_deauth(wpa_s,
 				  data ? &data->deauth_info : NULL);
 		break;
+	case EVENT_LINK_RECONFIG:
+		wpas_link_reconfig(wpa_s);
+		break;
 	case EVENT_MICHAEL_MIC_FAILURE:
 		wpa_supplicant_event_michael_mic_failure(wpa_s, data);
 		break;
@@ -6292,6 +6405,10 @@
 		wpas_dpp_tx_wait_expire(wpa_s);
 #endif /* CONFIG_DPP */
 		break;
+	case EVENT_TID_LINK_MAP:
+		if (data)
+			wpas_tid_link_map(wpa_s, &data->t2l_map_info);
+		break;
 	default:
 		wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
 		break;
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index da6d9db..c9e14d5 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -771,7 +771,7 @@
 #ifdef CONFIG_IEEE80211AC
 	copy_sta_vht_capab(data, sta, elems->vht_capabilities);
 	copy_sta_vht_oper(data, sta, elems->vht_operation);
-	set_sta_vht_opmode(data, sta, elems->vht_opmode_notif);
+	set_sta_vht_opmode(data, sta, elems->opmode_notif);
 #endif /* CONFIG_IEEE80211AC */
 
 #ifdef CONFIG_IEEE80211AX
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index ea4023c..8068f1e 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -378,10 +378,12 @@
 }
 
 
-static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
+static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+			    struct wpa_ssid *ssid)
 {
 	struct wpabuf *mlbuf;
-	const u8 *rnr_ie, *pos;
+	const u8 *rnr_ie, *pos, *rsn_ie;
+	struct wpa_ie_data ie;
 	u8 ml_ie_len, rnr_ie_len;
 	const struct ieee80211_eht_ml *eht_ml;
 	const struct eht_ml_basic_common_info *ml_basic_common_info;
@@ -402,6 +404,26 @@
 		return false;
 	}
 
+	rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+	if (!rsn_ie || wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No RSN element");
+		goto out;
+	}
+
+	if (!(ie.capabilities & WPA_CAPABILITY_MFPC) ||
+	    wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"MLD: No management frame protection");
+		goto out;
+	}
+
+	ie.key_mgmt &= ~(WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK |
+			 WPA_KEY_MGMT_PSK_SHA256);
+	if (!(ie.key_mgmt & ssid->key_mgmt)) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No valid key management");
+		goto out;
+	}
+
 	ml_ie_len = wpabuf_len(mlbuf);
 
 	/* control + common info len + MLD address + MLD link information */
@@ -525,20 +547,28 @@
 {
 	struct ieee802_11_elems elems;
 	const u8 *mld_addr;
+	u16 status_code = data->auth.status_code;
 
 	if (!wpa_s->valid_links)
 		return;
 
 	if (ieee802_11_parse_elems(data->auth.ies + ie_offset,
 				   data->auth.ies_len - ie_offset,
-				   &elems, 0) != ParseOK) {
+				   &elems, 0) == ParseFailed) {
 		wpa_printf(MSG_DEBUG, "MLD: Failed parsing elements");
 		goto out;
 	}
 
 	if (!elems.basic_mle || !elems.basic_mle_len) {
 		wpa_printf(MSG_DEBUG, "MLD: No ML element in authentication");
-		goto out;
+		if (status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ ||
+		    status_code == WLAN_STATUS_SUCCESS ||
+		    status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
+		    status_code == WLAN_STATUS_SAE_PK)
+			goto out;
+		/* Accept missing Multi-Link element in failed authentication
+		 * cases. */
+		return;
 	}
 
 	mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
@@ -604,7 +634,7 @@
 	params.ssid_len = bss->ssid_len;
 	params.p2p = ssid->p2p_group;
 
-	if (wpas_ml_element(wpa_s, bss)) {
+	if (wpas_ml_element(wpa_s, bss, ssid)) {
 		wpa_printf(MSG_DEBUG, "MLD: In authentication");
 		params.mld = true;
 		params.mld_link_id = wpa_s->mlo_assoc_link_id;
@@ -1596,20 +1626,28 @@
 
 
 static int sme_external_ml_auth(struct wpa_supplicant *wpa_s,
-				const u8 *data, size_t len, int ie_offset)
+				const u8 *data, size_t len, int ie_offset,
+				u16 status_code)
 {
 	struct ieee802_11_elems elems;
 	const u8 *mld_addr;
 
 	if (ieee802_11_parse_elems(data + ie_offset, len - ie_offset,
-				   &elems, 0) != ParseOK) {
+				   &elems, 0) == ParseFailed) {
 		wpa_printf(MSG_DEBUG, "MLD: Failed parsing elements");
 		return -1;
 	}
 
 	if (!elems.basic_mle || !elems.basic_mle_len) {
 		wpa_printf(MSG_DEBUG, "MLD: No ML element in authentication");
-		return -1;
+		if (status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ ||
+		    status_code == WLAN_STATUS_SUCCESS ||
+		    status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
+		    status_code == WLAN_STATUS_SAE_PK)
+			return -1;
+		/* Accept missing Multi-Link element in failed authentication
+		 * cases. */
+		return 0;
 	}
 
 	mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
@@ -1623,7 +1661,8 @@
 	if (os_memcmp(wpa_s->sme.ext_auth_ap_mld_addr, mld_addr, ETH_ALEN) !=
 	    0) {
 		wpa_printf(MSG_DEBUG, "MLD: Unexpected MLD address (expected "
-			   MACSTR ")", MAC2STR(wpa_s->ap_mld_addr));
+			   MACSTR ")",
+			   MAC2STR(wpa_s->sme.ext_auth_ap_mld_addr));
 		return -1;
 	}
 
@@ -1714,7 +1753,8 @@
 						wpa_s->current_ssid, 2);
 		} else {
 			if (wpa_s->sme.ext_ml_auth &&
-			    sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+			    sme_external_ml_auth(wpa_s, data, len, *ie_offset,
+						 status_code))
 				return -1;
 
 			sme_external_auth_send_sae_commit(
@@ -1741,7 +1781,8 @@
 						wpa_s->current_ssid, 1);
 		} else {
 			if (wpa_s->sme.ext_ml_auth &&
-			    sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+			    sme_external_ml_auth(wpa_s, data, len, *ie_offset,
+						 status_code))
 				return -1;
 
 			sme_external_auth_send_sae_commit(
@@ -1840,7 +1881,8 @@
 						wpa_s->current_ssid, 0);
 		} else {
 			if (wpa_s->sme.ext_ml_auth &&
-			    sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+			    sme_external_ml_auth(wpa_s, data, len, *ie_offset,
+						 status_code))
 				return -1;
 
 			sme_external_auth_send_sae_confirm(wpa_s, sa);
@@ -1856,7 +1898,8 @@
 				      ie_offset) < 0)
 			return -1;
 		if (external && wpa_s->sme.ext_ml_auth &&
-		    sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+		    sme_external_ml_auth(wpa_s, data, len, *ie_offset,
+					 status_code))
 			return -1;
 
 		wpa_s->sme.sae.state = SAE_ACCEPTED;
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index f808ac4..effc7b3 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -1427,7 +1427,7 @@
 	"bssid_accept", "psk", "proto", "key_mgmt",
 	"bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq",
 	"freq_list", "max_oper_chwidth", "ht40", "vht", "vht_center_freq1",
-	"vht_center_freq2", "ht", "edmg",
+	"vht_center_freq2", "ht", "edmg", "he",
 #ifdef IEEE8021X_EAPOL
 	"eap", "identity", "anonymous_identity", "password", "ca_cert",
 	"ca_path", "client_cert", "private_key", "private_key_passwd",
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 287bc9e..71ffa69 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1587,6 +1587,7 @@
 	int sel, proto;
 	enum sae_pwe sae_pwe;
 	const u8 *bss_wpa, *bss_rsn, *bss_rsnx, *bss_osen;
+	bool wmm;
 
 	if (bss) {
 		bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
@@ -1983,6 +1984,22 @@
 		wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_USE_EXT_KEY_ID, 0);
 	}
 
+	/* Mark WMM enabled for any HT/VHT/HE/EHT association to get more
+	 * appropriate advertisement of the supported number of PTKSA receive
+	 * counters. In theory, this could be based on a driver capability, but
+	 * in practice all cases using WMM support at least eight replay
+	 * counters, so use a hardcoded value for now since there is no explicit
+	 * driver capability indication for this.
+	 *
+	 * In addition, claim WMM to be enabled if the AP supports it since it
+	 * is far more likely for any current device to support WMM. */
+	wmm = wpa_s->connection_set &&
+		(wpa_s->connection_ht || wpa_s->connection_vht ||
+		 wpa_s->connection_he || wpa_s->connection_eht);
+	if (!wmm && bss)
+		wmm = wpa_bss_get_vendor_ie(bss, WMM_IE_VENDOR_TYPE);
+	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_WMM_ENABLED, wmm);
+
 	if (!skip_default_rsne) {
 		if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie,
 						    wpa_ie_len)) {
@@ -3975,7 +3992,16 @@
 		return;
 	}
 
-	os_memcpy(prev_bssid, wpa_s->bssid, ETH_ALEN);
+	/*
+	 * Set the current AP's BSSID (for non-MLO connection) or MLD address
+	 * (for MLO connection) as the previous BSSID for reassociation requests
+	 * handled by SME-in-driver. If wpa_supplicant is in disconnected state,
+	 * prev_bssid will be zero as both wpa_s->valid_links and wpa_s->bssid
+	 * will be zero.
+	 */
+	os_memcpy(prev_bssid,
+		  wpa_s->valid_links ? wpa_s->ap_mld_addr : wpa_s->bssid,
+		  ETH_ALEN);
 	os_memset(&params, 0, sizeof(params));
 	wpa_s->reassociate = 0;
 	wpa_s->eap_expected_failure = 0;
@@ -4829,7 +4855,8 @@
 		wpa_s->current_ssid = ssid;
 		eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
 		wpa_s->connect_without_scan =
-			(ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
+			(ssid->mode == WPAS_MODE_MESH ||
+			 ssid->mode == WPAS_MODE_AP) ? ssid : NULL;
 
 		/*
 		 * Don't optimize next scan freqs since a new ESS has been