Revert "[wpa_supplicant] cumilative patch from commit 4b755c967"

Revert submission 26533062-Supplicant_merge_June24

Reason for revert: https://b.corp.google.com/issues/349780869

Reverted changes: /q/submissionid:26533062-Supplicant_merge_June24
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:88611417f21e6329aadf8f0e300392dd3738e804)
Merged-In: I6c9b7a4323fa7edde47617da6c1e0d8f6e6d5101
Change-Id: I6c9b7a4323fa7edde47617da6c1e0d8f6e6d5101
diff --git a/wpa_supplicant/Android.bp b/wpa_supplicant/Android.bp
index 347ff39..e6ba165 100644
--- a/wpa_supplicant/Android.bp
+++ b/wpa_supplicant/Android.bp
@@ -331,7 +331,6 @@
         "src/common/sae.c",
         "src/common/sae_pk.c",
         "src/common/wpa_common.c",
-        "src/common/ptksa_cache.c",
         "src/crypto/aes-ctr.c",
         "src/crypto/aes-encblock.c",
         "src/crypto/aes-siv.c",
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 952d1be..bdb19f9 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -139,8 +139,6 @@
 OBJS += src/utils/bitfield.c
 OBJS += src/utils/ip_addr.c
 OBJS += src/utils/crc32.c
-OBJS += src/common/ptksa_cache.c
-OBJS += src/rsn_supp/pmksa_cache.c
 OBJS += twt.c
 OBJS_p = wpa_passphrase.c
 OBJS_p += src/utils/common.c
@@ -381,6 +379,7 @@
 ifndef CONFIG_NO_WPA
 OBJS += src/rsn_supp/wpa.c
 OBJS += src/rsn_supp/preauth.c
+OBJS += src/rsn_supp/pmksa_cache.c
 OBJS += src/rsn_supp/wpa_ie.c
 OBJS += src/common/wpa_common.c
 NEED_AES=y
@@ -433,8 +432,8 @@
 NEED_HMAC_SHA384_KDF=y
 NEED_SHA256=y
 NEED_SHA384=y
+OBJS += src/common/ptksa_cache.c
 OBJS += src/pasn/pasn_initiator.c
-OBJS += src/pasn/pasn_common.c
 OBJS += pasn_supplicant.c
 endif
 
@@ -1847,9 +1846,8 @@
 
 PASNOBJS += src/common/ptksa_cache.c
 
-PASNOBJS += src/rsn_supp/pmksa_cache.c
-
 ifndef CONFIG_NO_WPA
+PASNOBJS += src/rsn_supp/pmksa_cache.c
 PASNOBJS += src/rsn_supp/wpa_ie.c
 endif
 
@@ -1935,7 +1933,6 @@
 
 PASNOBJS += src/pasn/pasn_initiator.c
 PASNOBJS += src/pasn/pasn_responder.c
-PASNOBJS += src/pasn/pasn_common.c
 
 ########################
 
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 8bec178..93fc338 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -112,8 +112,6 @@
 OBJS += ../src/utils/bitfield.o
 OBJS += ../src/utils/ip_addr.o
 OBJS += ../src/utils/crc32.o
-OBJS += ../src/common/ptksa_cache.o
-OBJS += ../src/rsn_supp/pmksa_cache.o
 OBJS += twt.o
 OBJS_p = wpa_passphrase.o
 OBJS_p += ../src/utils/common.o
@@ -376,6 +374,7 @@
 ifndef CONFIG_NO_WPA
 OBJS += ../src/rsn_supp/wpa.o
 OBJS += ../src/rsn_supp/preauth.o
+OBJS += ../src/rsn_supp/pmksa_cache.o
 OBJS += ../src/rsn_supp/wpa_ie.o
 OBJS += ../src/common/wpa_common.o
 NEED_AES=y
@@ -436,8 +435,8 @@
 NEED_HMAC_SHA384_KDF=y
 NEED_SHA256=y
 NEED_SHA384=y
+OBJS += ../src/common/ptksa_cache.o
 OBJS += ../src/pasn/pasn_initiator.o
-OBJS += ../src/pasn/pasn_common.o
 OBJS += pasn_supplicant.o
 endif
 
@@ -1188,10 +1187,6 @@
 CFLAGS += -DCONFIG_TLSV12
 endif
 
-ifdef CONFIG_RADIUS_TLS
-TLS_FUNCS=y
-endif
-
 ifeq ($(CONFIG_TLS), wolfssl)
 ifdef TLS_FUNCS
 CFLAGS += -DWOLFSSL_DER_LOAD
@@ -1930,9 +1925,6 @@
 OBJS_t := $(OBJS) $(OBJS_l2) eapol_test.o
 OBJS_t += ../src/radius/radius_client.o
 OBJS_t += ../src/radius/radius.o
-ifdef CONFIG_RADIUS_TLS
-CFLAGS += -DCONFIG_RADIUS_TLS
-endif
 OBJS_t2 := $(OBJS) $(OBJS_l2) preauth_test.o
 
 OBJS_nfc := $(OBJS) $(OBJS_l2) nfc_pw_token.o
@@ -2227,9 +2219,9 @@
 endif
 
 LIBPASNSO += ../src/common/ptksa_cache.c
-LIBPASNSO += ../src/rsn_supp/pmksa_cache.c
 
 ifndef CONFIG_NO_WPA
+LIBPASNSO += ../src/rsn_supp/pmksa_cache.c
 LIBPASNSO += ../src/rsn_supp/wpa_ie.c
 endif
 
@@ -2324,7 +2316,6 @@
 
 LIBPASNSO += ../src/pasn/pasn_initiator.c
 LIBPASNSO += ../src/pasn/pasn_responder.c
-LIBPASNSO += ../src/pasn/pasn_common.c
 
 libpasn.so: $(LIBPASNSO)
 	@$(E) "  CC  $@ ($^)"
diff --git a/wpa_supplicant/aidl/supplicant.cpp b/wpa_supplicant/aidl/supplicant.cpp
index ae1943f..1589dd2 100644
--- a/wpa_supplicant/aidl/supplicant.cpp
+++ b/wpa_supplicant/aidl/supplicant.cpp
@@ -413,7 +413,7 @@
 		// Request the current scan results from the driver and update
 		// the local BSS list wpa_s->bss. This is to avoid a full scan
 		// while processing the connect request on newly created interface.
-		wpa_supplicant_update_scan_results(wpa_s, NULL);
+		wpa_supplicant_update_scan_results(wpa_s);
 	}
 	// The supplicant core creates a corresponding aidl object via
 	// AidlManager when |wpa_supplicant_add_iface| is called.
@@ -472,7 +472,7 @@
 		// Request the current scan results from the driver and update
 		// the local BSS list wpa_s->bss. This is to avoid a full scan
 		// while processing the connect request on newly created interface.
-		wpa_supplicant_update_scan_results(wpa_s, NULL);
+		wpa_supplicant_update_scan_results(wpa_s);
 	}
 	// The supplicant core creates a corresponding aidl object via
 	// AidlManager when |wpa_supplicant_add_iface| is called.
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 69a0e5e..000914a 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -440,14 +440,9 @@
 		}
 	}
 
-#ifdef CONFIG_P2P
-	if (ssid->p2p_group && wpa_s->p2p_go_no_pri_sec_switch) {
+	if (wpa_s->p2p_go_no_pri_sec_switch) {
 		conf->no_pri_sec_switch = 1;
-		return 0;
-	}
-#endif /* CONFIG_P2P */
-
-	if (conf->secondary_channel) {
+	} else if (conf->secondary_channel) {
 		struct wpa_supplicant *iface;
 
 		for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
@@ -873,8 +868,7 @@
 
 
 static void ap_sta_authorized_cb(void *ctx, const u8 *mac_addr,
-				 int authorized, const u8 *p2p_dev_addr,
-				 const u8 *ip)
+				 int authorized, const u8 *p2p_dev_addr, const u8 *ip)
 {
 	wpas_notify_sta_authorized(ctx, mac_addr, authorized, p2p_dev_addr, ip);
 }
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 2890353..22b694c 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -400,11 +400,6 @@
 	if (bss == wpa_s->ml_connect_probe_bss)
 		return 1;
 
-#ifdef CONFIG_WNM
-	if (bss == wpa_s->wnm_target_bss)
-		return 1;
-#endif /* CONFIG_WNM */
-
 	if (wpa_s->current_bss &&
 	    (bss->ssid_len != wpa_s->current_bss->ssid_len ||
 	     os_memcmp(bss->ssid, wpa_s->current_bss->ssid,
@@ -419,7 +414,10 @@
 	if (!wpa_s->valid_links)
 		return 0;
 
-	for_each_link(wpa_s->valid_links, i) {
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+		if (!(wpa_s->valid_links & BIT(i)))
+			continue;
+
 		if (ether_addr_equal(bss->bssid, wpa_s->links[i].bssid))
 			return 1;
 	}
@@ -1515,6 +1513,9 @@
 	for (i = 0; i < count; i++) {
 		u8 bss_params;
 
+		if (bss->n_mld_links >= MAX_NUM_MLD_LINKS)
+			return;
+
 		if (end - pos < ap_info->tbtt_info_len)
 			break;
 
@@ -1522,8 +1523,6 @@
 		mld_params = pos + mld_params_offset;
 
 		link_id = *(mld_params + 1) & EHT_ML_LINK_ID_MSK;
-		if (link_id >= MAX_NUM_MLD_LINKS)
-			return;
 
 		if (*mld_params != mbssid_idx) {
 			wpa_printf(MSG_DEBUG,
@@ -1547,12 +1546,13 @@
 					   wpa_s, neigh_bss->bssid)) {
 				struct mld_link *l;
 
-				bss->valid_links |= BIT(link_id);
-				l = &bss->mld_links[link_id];
+				l = &bss->mld_links[bss->n_mld_links];
+				l->link_id = link_id;
 				os_memcpy(l->bssid, pos + 1, ETH_ALEN);
 				l->freq = neigh_bss->freq;
 				l->disabled = mld_params[2] &
 					RNR_TBTT_INFO_MLD_PARAM2_LINK_DISABLED;
+				bss->n_mld_links++;
 			}
 		}
 
@@ -1678,15 +1678,15 @@
 		os_memcpy(ap_mld_addr, ml_basic_common_info->mld_addr,
 			  ETH_ALEN);
 
+	bss->n_mld_links = 0;
+	l = &bss->mld_links[bss->n_mld_links];
 	link_id = ml_basic_common_info->variable[0] & EHT_ML_LINK_ID_MSK;
-
-	bss->mld_link_id = link_id;
-	seen = bss->valid_links = BIT(link_id);
-
-	l = &bss->mld_links[link_id];
+	l->link_id = link_id;
 	os_memcpy(l->bssid, bss->bssid, ETH_ALEN);
 	l->freq = bss->freq;
 
+	seen = BIT(link_id);
+	bss->n_mld_links++;
 
 	/*
 	 * The AP MLD ID in the RNR corresponds to the MBSSID index, see
@@ -1736,12 +1736,13 @@
 		}
 	}
 
-	wpa_printf(MSG_DEBUG, "MLD: valid_links=%04hx (unresolved: 0x%04hx)",
-		   bss->valid_links, missing);
+	wpa_printf(MSG_DEBUG, "MLD: n_mld_links=%u (unresolved: 0x%04hx)",
+		   bss->n_mld_links, missing);
 
-	for_each_link(bss->valid_links, i) {
+	for (i = 0; i < bss->n_mld_links; i++) {
 		wpa_printf(MSG_DEBUG, "MLD: link=%u, bssid=" MACSTR,
-			   i, MAC2STR(bss->mld_links[i].bssid));
+			   bss->mld_links[i].link_id,
+			   MAC2STR(bss->mld_links[i].bssid));
 	}
 
 	if (missing_links)
diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h
index cc04963..c06c20a 100644
--- a/wpa_supplicant/bss.h
+++ b/wpa_supplicant/bss.h
@@ -126,12 +126,11 @@
 	size_t beacon_ie_len;
 	/** MLD address of the AP */
 	u8 mld_addr[ETH_ALEN];
-	/** Link ID of this affiliated AP of the AP MLD */
-	u8 mld_link_id;
 
 	/** An array of MLD links */
-	u16 valid_links;
+	u8 n_mld_links;
 	struct mld_link {
+		u8 link_id;
 		u8 bssid[ETH_ALEN];
 		int freq;
 
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index c949bab..8c0db68 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -197,10 +197,9 @@
 #endif /* NO_CONFIG_WRITE */
 
 
-static int wpa_config_parse_int_impl(const struct parse_data *data,
-				     struct wpa_ssid *ssid,
-				     int line, const char *value,
-				     bool check_range)
+static int wpa_config_parse_int(const struct parse_data *data,
+				struct wpa_ssid *ssid,
+				int line, const char *value)
 {
 	int val, *dst;
 	char *end;
@@ -213,46 +212,31 @@
 		return -1;
 	}
 
-	if (check_range && val < (long) data->param3) {
-		wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
-			   "min_value=%ld)", line, data->name, val,
-			   (long) data->param3);
-		return -1;
-	}
-
-	if (check_range && val > (long) data->param4) {
-		wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
-			   "max_value=%ld)", line, data->name, val,
-			   (long) data->param4);
-		return -1;
-	}
-
 	if (*dst == val)
 		return 1;
-
 	*dst = val;
 	wpa_printf(MSG_MSGDUMP, "%s=%d (0x%x)", data->name, *dst, *dst);
 
+	if (data->param3 && *dst < (long) data->param3) {
+		wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
+			   "min_value=%ld)", line, data->name, *dst,
+			   (long) data->param3);
+		*dst = (long) data->param3;
+		return -1;
+	}
+
+	if (data->param4 && *dst > (long) data->param4) {
+		wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
+			   "max_value=%ld)", line, data->name, *dst,
+			   (long) data->param4);
+		*dst = (long) data->param4;
+		return -1;
+	}
+
 	return 0;
 }
 
 
-static int wpa_config_parse_int(const struct parse_data *data,
-				struct wpa_ssid *ssid,
-				int line, const char *value)
-{
-	return wpa_config_parse_int_impl(data, ssid, line, value, false);
-}
-
-
-static int wpa_config_parse_int_range(const struct parse_data *data,
-				      struct wpa_ssid *ssid,
-				      int line, const char *value)
-{
-	return wpa_config_parse_int_impl(data, ssid, line, value, true);
-}
-
-
 #ifndef NO_CONFIG_WRITE
 static char * wpa_config_write_int(const struct parse_data *data,
 				   struct wpa_ssid *ssid)
@@ -2473,14 +2457,7 @@
 #define INTe(f, m) _INTe(f, m), NULL, NULL, 0
 
 /* INT_RANGE: Define an integer variable with allowed value range */
-#ifdef NO_CONFIG_WRITE
-#define INT_RANGE(f, min, max) #f, wpa_config_parse_int_range, OFFSET(f), \
-	(void *) 0, (void *) (min), (void *) (max), 0
-#else /* NO_CONFIG_WRITE */
-#define INT_RANGE(f, min, max) #f, wpa_config_parse_int_range, \
-	wpa_config_write_int, OFFSET(f),	       \
-	(void *) 0, (void *) (min), (void *) (max), 0
-#endif /* NO_CONFIG_WRITE */
+#define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0
 
 /* FUNC: Define a configuration variable that uses a custom function for
  * parsing and writing the value. */
@@ -2675,7 +2652,7 @@
 #endif /* CONFIG_P2P */
 #ifdef CONFIG_HT_OVERRIDES
 	{ INT_RANGE(disable_ht, 0, 1) },
-	{ INT_RANGE(disable_ht40, 0, 1) },
+	{ INT_RANGE(disable_ht40, -1, 1) },
 	{ INT_RANGE(disable_sgi, 0, 1) },
 	{ INT_RANGE(disable_ldpc, 0, 1) },
 	{ INT_RANGE(ht40_intolerant, 0, 1) },
@@ -2748,8 +2725,6 @@
 	{ INT_RANGE(owe_ptk_workaround, 0, 1) },
 	{ INT_RANGE(multi_ap_backhaul_sta, 0, 1) },
 	{ INT_RANGE(ft_eap_pmksa_caching, 0, 1) },
-	{ INT_RANGE(multi_ap_profile, MULTI_AP_PROFILE_1,
-		    MULTI_AP_PROFILE_MAX) },
 	{ INT_RANGE(beacon_prot, 0, 1) },
 	{ INT_RANGE(transition_disable, 0, 255) },
 	{ INT_RANGE(sae_pk, 0, 2) },
@@ -4768,10 +4743,9 @@
 };
 
 
-static int
-wpa_global_config_parse_int_impl(const struct global_parse_data *data,
-				 struct wpa_config *config, int line,
-				 const char *pos, bool check_range)
+static int wpa_global_config_parse_int(const struct global_parse_data *data,
+				       struct wpa_config *config, int line,
+				       const char *pos)
 {
 	int val, *dst;
 	char *end;
@@ -4784,47 +4758,31 @@
 			   line, pos);
 		return -1;
 	}
-
-	if (check_range && val < (long) data->param2) {
-		wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
-			   "min_value=%ld)", line, data->name, val,
-			   (long) data->param2);
-		return -1;
-	}
-
-	if (check_range && val > (long) data->param3) {
-		wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
-			   "max_value=%ld)", line, data->name, val,
-			   (long) data->param3);
-		return -1;
-	}
-
 	same = *dst == val;
 	*dst = val;
 
 	wpa_printf(MSG_DEBUG, "%s=%d", data->name, *dst);
 
+	if (data->param2 && *dst < (long) data->param2) {
+		wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
+			   "min_value=%ld)", line, data->name, *dst,
+			   (long) data->param2);
+		*dst = (long) data->param2;
+		return -1;
+	}
+
+	if (data->param3 && *dst > (long) data->param3) {
+		wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
+			   "max_value=%ld)", line, data->name, *dst,
+			   (long) data->param3);
+		*dst = (long) data->param3;
+		return -1;
+	}
+
 	return same;
 }
 
 
-static int wpa_global_config_parse_int(const struct global_parse_data *data,
-				       struct wpa_config *config, int line,
-				       const char *pos)
-{
-	return wpa_global_config_parse_int_impl(data, config, line, pos, false);
-}
-
-
-static int
-wpa_global_config_parse_int_range(const struct global_parse_data *data,
-				  struct wpa_config *config, int line,
-				  const char *pos)
-{
-	return wpa_global_config_parse_int_impl(data, config, line, pos, true);
-}
-
-
 static int wpa_global_config_parse_str(const struct global_parse_data *data,
 				       struct wpa_config *config, int line,
 				       const char *pos)
@@ -5388,8 +5346,7 @@
 #define FUNC_NO_VAR(f) #f, wpa_config_process_ ## f, NULL, NULL, NULL, NULL
 #define _INT(f) #f, wpa_global_config_parse_int, wpa_config_get_int, OFFSET(f)
 #define INT(f) _INT(f), NULL, NULL
-#define INT_RANGE(f, min, max) #f, wpa_global_config_parse_int_range, \
-	wpa_config_get_int, OFFSET(f), (void *) min, (void *) max
+#define INT_RANGE(f, min, max) _INT(f), (void *) min, (void *) max
 #define _STR(f) #f, wpa_global_config_parse_str, wpa_config_get_str, OFFSET(f)
 #define STR(f) _STR(f), NULL, NULL
 #define STR_RANGE(f, min, max) _STR(f), (void *) min, (void *) max
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 414ed22..71a64b1 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -850,7 +850,6 @@
 	INT(owe_ptk_workaround);
 	INT(multi_ap_backhaul_sta);
 	INT(ft_eap_pmksa_caching);
-	INT(multi_ap_profile);
 	INT(beacon_prot);
 	INT(transition_disable);
 	INT(sae_pk);
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 2043a80..785acc3 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -1187,11 +1187,6 @@
 	int ft_eap_pmksa_caching;
 
 	/**
-	 * multi_ap_profile - Supported Multi-AP profile
-	 */
-	int multi_ap_profile;
-
-	/**
 	 * beacon_prot - Whether Beacon protection is enabled
 	 *
 	 * This depends on management frame protection (ieee80211w) being
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index d0fda4c..500f4d1 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -902,20 +902,9 @@
 			wpa_config_process_global(wpa_s->conf, cmd, -1);
 		}
 	} else if (os_strcasecmp(cmd, "mbo_cell_capa") == 0) {
-		int val = atoi(value);
-
-		if (val < MBO_CELL_CAPA_AVAILABLE ||
-		    val > MBO_CELL_CAPA_NOT_SUPPORTED)
-			return -1;
-
-		wpas_mbo_update_cell_capa(wpa_s, val);
+		wpas_mbo_update_cell_capa(wpa_s, atoi(value));
 	} else if (os_strcasecmp(cmd, "oce") == 0) {
-		int val = atoi(value);
-
-		if (val < 0 || val > 3)
-			return -1;
-
-		wpa_s->conf->oce = val;
+		wpa_s->conf->oce = atoi(value);
 		if (wpa_s->conf->oce) {
 			if ((wpa_s->conf->oce & OCE_STA) &&
 			    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OCE_STA))
@@ -8861,8 +8850,6 @@
 
 	wpa_s->next_ssid = NULL;
 
-	wnm_btm_reset(wpa_s);
-
 #ifdef CONFIG_INTERWORKING
 #ifdef CONFIG_HS20
 	hs20_cancel_fetch_osu(wpa_s);
@@ -12008,7 +11995,10 @@
 	pos = buf;
 	end = buf + buflen;
 
-	for_each_link(mlo_si.valid_links, i) {
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+		if (!(mlo_si.valid_links & BIT(i)))
+			continue;
+
 		ret = os_snprintf(pos, end - pos,
 				  "LINK_ID=%d\nRSSI=%d\nLINKSPEED=%lu\n"
 				  "NOISE=%d\nFREQUENCY=%u\n",
@@ -12080,7 +12070,10 @@
 	pos = buf;
 	end = buf + buflen;
 
-	for_each_link(wpa_s->valid_links, i) {
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+		if (!(wpa_s->valid_links & BIT(i)))
+			continue;
+
 		ret = os_snprintf(pos, end - pos, "link_id=%d\nfreq=%u\n"
 				  "ap_link_addr=" MACSTR
 				  "\nsta_link_addr=" MACSTR "\n",
diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.c b/wpa_supplicant/dbus/dbus_dict_helpers.c
index 27003eb..fdf7b12 100644
--- a/wpa_supplicant/dbus/dbus_dict_helpers.c
+++ b/wpa_supplicant/dbus/dbus_dict_helpers.c
@@ -706,59 +706,6 @@
 }
 
 
-#define UINT16_ARRAY_CHUNK_SIZE 18
-#define UINT16_ARRAY_ITEM_SIZE (sizeof(dbus_uint16_t))
-
-static dbus_bool_t _wpa_dbus_dict_entry_get_uint16_array(
-	DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry)
-{
-	dbus_uint32_t count = 0;
-	dbus_uint16_t *buffer, *nbuffer;
-
-	entry->uint16array_value = NULL;
-	entry->array_type = DBUS_TYPE_UINT16;
-
-	buffer = os_calloc(UINT16_ARRAY_CHUNK_SIZE, UINT16_ARRAY_ITEM_SIZE);
-	if (!buffer)
-		return FALSE;
-
-	entry->array_len = 0;
-	while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_UINT16) {
-		dbus_uint16_t value;
-
-		if ((count % UINT16_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
-			nbuffer = os_realloc_array(
-				buffer, count + UINT16_ARRAY_CHUNK_SIZE,
-				UINT16_ARRAY_ITEM_SIZE);
-			if (!nbuffer) {
-				os_free(buffer);
-				wpa_printf(MSG_ERROR,
-					   "dbus: %s out of memory trying to retrieve the uint16 array",
-					   __func__);
-				return FALSE;
-			}
-			buffer = nbuffer;
-		}
-
-		dbus_message_iter_get_basic(iter, &value);
-		buffer[count] = value;
-		entry->array_len = ++count;
-		dbus_message_iter_next(iter);
-	}
-	entry->uint16array_value = buffer;
-	wpa_hexdump_key(MSG_MSGDUMP, "dbus: uint16 array contents",
-			entry->bytearray_value, entry->array_len);
-
-	/* Zero-length arrays are valid. */
-	if (entry->array_len == 0) {
-		os_free(entry->uint16array_value);
-		entry->uint16array_value = NULL;
-	}
-
-	return TRUE;
-}
-
-
 #define STR_ARRAY_CHUNK_SIZE 8
 #define STR_ARRAY_ITEM_SIZE (sizeof(char *))
 
@@ -926,10 +873,6 @@
 		success = _wpa_dbus_dict_entry_get_byte_array(&iter_array,
 							      entry);
 		break;
-	case DBUS_TYPE_UINT16:
-		success = _wpa_dbus_dict_entry_get_uint16_array(&iter_array,
-								entry);
-		break;
 	case DBUS_TYPE_STRING:
 		success = _wpa_dbus_dict_entry_get_string_array(&iter_array,
 								array_type,
@@ -1138,9 +1081,6 @@
 		case DBUS_TYPE_BYTE:
 			os_free(entry->bytearray_value);
 			break;
-		case DBUS_TYPE_UINT16:
-			os_free(entry->uint16array_value);
-			break;
 		case DBUS_TYPE_STRING:
 			if (!entry->strarray_value)
 				break;
diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.h b/wpa_supplicant/dbus/dbus_dict_helpers.h
index 1d33689..cc9e26f 100644
--- a/wpa_supplicant/dbus/dbus_dict_helpers.h
+++ b/wpa_supplicant/dbus/dbus_dict_helpers.h
@@ -139,7 +139,6 @@
 		dbus_uint64_t uint64_value;
 		double double_value;
 		char *bytearray_value;
-		dbus_uint16_t *uint16array_value;
 		char **strarray_value;
 		struct wpabuf **binarray_value;
 	};
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 8bd6a9a..00b38ed 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -1023,40 +1023,6 @@
 	dbus_message_unref(msg);
 }
 
-
-void wpas_dbus_signal_anqp_query_done(struct wpa_supplicant *wpa_s,
-				      const u8 *dst, const char *result)
-{
-	struct wpas_dbus_priv *iface;
-	DBusMessage *msg;
-	DBusMessageIter iter;
-	char addr[WPAS_DBUS_OBJECT_PATH_MAX], *bssid;
-
-	os_snprintf(addr, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(dst));
-	bssid = addr;
-
-	iface = wpa_s->global->dbus;
-
-	/* Do nothing if the control interface is not turned on */
-	if (!iface || !wpa_s->dbus_new_path)
-		return;
-
-	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
-				      WPAS_DBUS_NEW_IFACE_INTERFACE,
-				      "ANQPQueryDone");
-	if (!msg)
-		return;
-
-	dbus_message_iter_init_append(msg, &iter);
-
-	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bssid) ||
-	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &result))
-		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
-	else
-		dbus_connection_send(iface->con, msg, NULL);
-	dbus_message_unref(msg);
-}
-
 #endif /* CONFIG_INTERWORKING */
 
 
@@ -2473,9 +2439,6 @@
 	case WPAS_DBUS_BSS_PROP_AGE:
 		prop = "Age";
 		break;
-	case WPAS_DBUS_BSS_PROP_ANQP:
-		prop = "ANQP";
-		break;
 	default:
 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
 			   __func__, property);
@@ -3014,11 +2977,6 @@
 	  NULL,
 	  NULL
 	},
-	{"ANQP", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
-	  wpas_dbus_getter_bss_anqp,
-	  NULL,
-	  NULL,
-	},
 	{ NULL, NULL, NULL, NULL, NULL, NULL }
 };
 
@@ -3758,13 +3716,6 @@
 		  END_ARGS
 	  }
 	},
-	{"ANQPGet", WPAS_DBUS_NEW_IFACE_INTERFACE,
-	  (WPADBusMethodHandler) wpas_dbus_handler_anqp_get,
-	  {
-		  { "args", "a{sv}", ARG_IN },
-		  END_ARGS
-	  },
-	},
 #endif /* CONFIG_INTERWORKING */
 	{ NULL, NULL, NULL, { END_ARGS } }
 };
@@ -4352,13 +4303,6 @@
 		  END_ARGS
 	  }
 	},
-	{"ANQPQueryDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
-	  {
-		  { "addr", "s", ARG_OUT },
-		  { "result", "s", ARG_OUT },
-		  END_ARGS
-	  }
-	},
 #endif /* CONFIG_INTERWORKING */
 #ifdef CONFIG_HS20
 	{ "HS20TermsAndConditions", WPAS_DBUS_NEW_IFACE_INTERFACE,
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index 952bb42..b653f10 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -53,7 +53,6 @@
 	WPAS_DBUS_BSS_PROP_WPS,
 	WPAS_DBUS_BSS_PROP_IES,
 	WPAS_DBUS_BSS_PROP_AGE,
-	WPAS_DBUS_BSS_PROP_ANQP,
 };
 
 enum wpas_dbus_sta_prop {
@@ -280,8 +279,6 @@
 					    int bh, int bss_load,
 					    int conn_capab);
 void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s);
-void wpas_dbus_signal_anqp_query_done(struct wpa_supplicant *wpa_s,
-				      const u8 *dst, const char *result);
 void wpas_dbus_signal_hs20_t_c_acceptance(struct wpa_supplicant *wpa_s,
 					  const char *url);
 
@@ -656,12 +653,6 @@
 }
 
 static inline
-void wpas_dbus_signal_anqp_query_done(struct wpa_supplicant *wpa_s,
-				      const u8 *dst, const char *result)
-{
-}
-
-static inline
 void wpas_dbus_signal_hs20_t_c_acceptance(struct wpa_supplicant *wpa_s,
 					  const char *url)
 {
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 3897d98..6ad49a1 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -1957,7 +1957,6 @@
 
 
 #ifdef CONFIG_INTERWORKING
-
 DBusMessage *
 wpas_dbus_handler_interworking_select(DBusMessage *message,
 				      struct wpa_supplicant *wpa_s)
@@ -1978,111 +1977,6 @@
 
 	return reply;
 }
-
-
-DBusMessage *
-wpas_dbus_handler_anqp_get(DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
-	DBusMessageIter	iter, iter_dict;
-	struct wpa_dbus_dict_entry entry;
-	int ret;
-	u8 dst_addr[ETH_ALEN];
-	bool is_addr_present = false;
-	unsigned int freq = 0;
-#define MAX_ANQP_INFO_ID 100 /* Max info ID count from CLI implementation */
-	u16 id[MAX_ANQP_INFO_ID];
-	size_t num_id = 0;
-	u32 subtypes = 0;
-	u32 mbo_subtypes = 0;
-	size_t i;
-
-	dbus_message_iter_init(message, &iter);
-
-	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
-		return wpas_dbus_error_invalid_args(message, NULL);
-
-	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
-		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
-			return wpas_dbus_error_invalid_args(message, NULL);
-
-		if (os_strcmp(entry.key, "addr") == 0 &&
-		    entry.type == DBUS_TYPE_STRING) {
-			if (hwaddr_aton(entry.str_value, dst_addr)) {
-				wpa_printf(MSG_DEBUG,
-					   "%s[dbus]: Invalid address '%s'",
-					   __func__, entry.str_value);
-				wpa_dbus_dict_entry_clear(&entry);
-				return wpas_dbus_error_invalid_args(
-					message, "invalid address");
-			}
-
-			is_addr_present = true;
-		} else if (os_strcmp(entry.key, "freq") == 0 &&
-			   entry.type == DBUS_TYPE_UINT32) {
-			freq = entry.uint32_value;
-		} else if (os_strcmp(entry.key, "ids") == 0 &&
-			   entry.type == DBUS_TYPE_ARRAY &&
-			   entry.array_type == DBUS_TYPE_UINT16) {
-			for (i = 0; i < entry.array_len &&
-				     num_id < MAX_ANQP_INFO_ID; i++) {
-				id[num_id] = entry.uint16array_value[i];
-				num_id++;
-			}
-		} else if (os_strcmp(entry.key, "hs20_ids") == 0 &&
-			   entry.type == DBUS_TYPE_ARRAY &&
-			   entry.array_type == DBUS_TYPE_BYTE) {
-			for (i = 0; i < entry.array_len; i++) {
-				int num = entry.bytearray_value[i];
-
-				if (num <= 0 || num > 31) {
-					wpa_dbus_dict_entry_clear(&entry);
-					return wpas_dbus_error_invalid_args(
-						message,
-						"invalid HS20 ANQP id");
-				}
-				subtypes |= BIT(num);
-			}
-		} else if (os_strcmp(entry.key, "mbo_ids") == 0 &&
-			   entry.type == DBUS_TYPE_ARRAY &&
-			   entry.array_type == DBUS_TYPE_BYTE) {
-			for (i = 0; i < entry.array_len; i++) {
-				int num = entry.bytearray_value[i];
-
-				if (num <= 0 || num > MAX_MBO_ANQP_SUBTYPE) {
-					wpa_dbus_dict_entry_clear(&entry);
-					return wpas_dbus_error_invalid_args(
-						message, "invalid MBO ANQP id");
-				}
-				mbo_subtypes |= BIT(num);
-			}
-		} else {
-			wpa_dbus_dict_entry_clear(&entry);
-			return wpas_dbus_error_invalid_args(
-				message, "unsupported parameter");
-		}
-
-		wpa_dbus_dict_entry_clear(&entry);
-	}
-
-	if (!is_addr_present) {
-		wpa_printf(MSG_DEBUG,
-			   "%s[dbus]: address not provided", __func__);
-		return wpas_dbus_error_invalid_args(message,
-						    "address not provided");
-	}
-
-	ret = anqp_send_req(wpa_s, dst_addr, freq, id, num_id, subtypes,
-			    mbo_subtypes);
-	if (ret < 0) {
-		wpa_printf(MSG_ERROR, "%s[dbus]: failed to send ANQP request",
-			   __func__);
-		return wpas_dbus_error_unknown_error(
-			message, "error sending ANQP request");
-	}
-
-	return NULL;
-}
-
 #endif /* CONFIG_INTERWORKING */
 
 
@@ -5758,177 +5652,6 @@
 
 
 /**
- * wpas_dbus_getter_bss_anqp - Return all the ANQP fields of a BSS
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "ANQP" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_anqp(
-	const struct wpa_dbus_property_desc *property_desc,
-	DBusMessageIter *iter, DBusError *error, void *user_data)
-{
-	DBusMessageIter iter_dict, variant_iter;
-	struct bss_handler_args *args = user_data;
-	struct wpa_bss *bss;
-	struct wpa_bss_anqp *anqp;
-	struct wpa_bss_anqp_elem *elem;
-
-	bss = get_bss_helper(args, error, __func__);
-	if (!bss)
-		return FALSE;
-
-	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
-					      "a{sv}", &variant_iter) ||
-	    !wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
-		goto nomem;
-
-	anqp = bss->anqp;
-	if (anqp) {
-#ifdef CONFIG_INTERWORKING
-		if (anqp->capability_list &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "CapabilityList",
-			    wpabuf_head(anqp->capability_list),
-			    wpabuf_len(anqp->capability_list)))
-			goto nomem;
-		if (anqp->venue_name &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "VenueName",
-			    wpabuf_head(anqp->venue_name),
-			    wpabuf_len(anqp->venue_name)))
-			goto nomem;
-		if (anqp->network_auth_type &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "NetworkAuthType",
-			    wpabuf_head(anqp->network_auth_type),
-			    wpabuf_len(anqp->network_auth_type)))
-			goto nomem;
-		if (anqp->roaming_consortium &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "RoamingConsortium",
-			    wpabuf_head(anqp->roaming_consortium),
-			    wpabuf_len(anqp->roaming_consortium)))
-			goto nomem;
-		if (anqp->ip_addr_type_availability &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "IPAddrTypeAvailability",
-			    wpabuf_head(anqp->ip_addr_type_availability),
-			    wpabuf_len(anqp->ip_addr_type_availability)))
-			goto nomem;
-		if (anqp->nai_realm &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "NAIRealm",
-			    wpabuf_head(anqp->nai_realm),
-			    wpabuf_len(anqp->nai_realm)))
-			goto nomem;
-		if (anqp->anqp_3gpp &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "3GPP",
-			    wpabuf_head(anqp->anqp_3gpp),
-			    wpabuf_len(anqp->anqp_3gpp)))
-			goto nomem;
-		if (anqp->domain_name &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "DomainName",
-			    wpabuf_head(anqp->domain_name),
-			    wpabuf_len(anqp->domain_name)))
-			goto nomem;
-		if (anqp->fils_realm_info &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "FilsRealmInfo",
-			    wpabuf_head(anqp->fils_realm_info),
-			    wpabuf_len(anqp->fils_realm_info)))
-			goto nomem;
-
-#ifdef CONFIG_HS20
-		if (anqp->hs20_capability_list &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "HS20CapabilityList",
-			    wpabuf_head(anqp->hs20_capability_list),
-			    wpabuf_len(anqp->hs20_capability_list)))
-			goto nomem;
-		if (anqp->hs20_operator_friendly_name &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "HS20OperatorFriendlyName",
-			    wpabuf_head(anqp->hs20_operator_friendly_name),
-			    wpabuf_len(anqp->hs20_operator_friendly_name)))
-			goto nomem;
-		if (anqp->hs20_wan_metrics &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "HS20WanMetrics",
-			    wpabuf_head(anqp->hs20_wan_metrics),
-			    wpabuf_len(anqp->hs20_wan_metrics)))
-			goto nomem;
-		if (anqp->hs20_connection_capability &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "HS20ConnectionCapability",
-			    wpabuf_head(anqp->hs20_connection_capability),
-			    wpabuf_len(anqp->hs20_connection_capability)))
-			goto nomem;
-		if (anqp->hs20_operating_class &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "HS20OperatingClass",
-			    wpabuf_head(anqp->hs20_operating_class),
-			    wpabuf_len(anqp->hs20_operating_class)))
-			goto nomem;
-		if (anqp->hs20_osu_providers_list &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "HS20OSUProvidersList",
-			    wpabuf_head(anqp->hs20_osu_providers_list),
-			    wpabuf_len(anqp->hs20_osu_providers_list)))
-			goto nomem;
-		if (anqp->hs20_operator_icon_metadata &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "HS20OperatorIconMetadata",
-			    wpabuf_head(anqp->hs20_operator_icon_metadata),
-			    wpabuf_len(anqp->hs20_operator_icon_metadata)))
-			goto nomem;
-		if (anqp->hs20_osu_providers_nai_list &&
-		    !wpa_dbus_dict_append_byte_array(
-			    &iter_dict, "HS20OSUProvidersNAIList",
-			    wpabuf_head(anqp->hs20_osu_providers_nai_list),
-			    wpabuf_len(anqp->hs20_osu_providers_nai_list)))
-			goto nomem;
-#endif /* CONFIG_HS20 */
-
-		dl_list_for_each(elem, &anqp->anqp_elems,
-				 struct wpa_bss_anqp_elem, list) {
-			char title[32];
-
-			os_snprintf(title, sizeof(title), "anqp[%u]",
-				    elem->infoid);
-			if (!wpa_dbus_dict_append_byte_array(
-				    &iter_dict, title,
-				    wpabuf_head(elem->payload),
-				    wpabuf_len(elem->payload)))
-				goto nomem;
-
-			os_snprintf(title, sizeof(title),
-				    "protected-anqp-info[%u]", elem->infoid);
-			if (!wpa_dbus_dict_append_bool(
-				    &iter_dict, title,
-				    elem->protected_response))
-				goto nomem;
-		}
-#endif /* CONFIG_INTERWORKING */
-	}
-
-	if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict) ||
-	    !dbus_message_iter_close_container(iter, &variant_iter))
-		goto nomem;
-
-	return TRUE;
-
-nomem:
-	dbus_set_error(error, DBUS_ERROR_NO_MEMORY, "no memory");
-	return FALSE;
-}
-
-
-/**
  * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
  * @iter: Pointer to incoming dbus message iter
  * @error: Location to store error on failure
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index acd6af7..97fa337 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -157,9 +157,6 @@
 wpas_dbus_handler_interworking_select(DBusMessage *message,
 				      struct wpa_supplicant *wpa_s);
 
-DBusMessage *
-wpas_dbus_handler_anqp_get(DBusMessage *message, struct wpa_supplicant *wpa_s);
-
 DECLARE_ACCESSOR(wpas_dbus_getter_capabilities);
 DECLARE_ACCESSOR(wpas_dbus_getter_state);
 DECLARE_ACCESSOR(wpas_dbus_getter_scanning);
@@ -219,7 +216,6 @@
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_wps);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_ies);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_age);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_anqp);
 DECLARE_ACCESSOR(wpas_dbus_getter_enabled);
 DECLARE_ACCESSOR(wpas_dbus_setter_enabled);
 DECLARE_ACCESSOR(wpas_dbus_getter_network_properties);
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index e223450..801e698 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -238,12 +238,6 @@
 		wait_time = wpa_s->dpp_resp_retry_time;
 	else
 		wait_time = 1000;
-	if (wpa_s->dpp_tx_chan_change) {
-		wpa_s->dpp_tx_chan_change = false;
-		if (wait_time > 100)
-			wait_time = 100;
-	}
-
 	wpa_printf(MSG_DEBUG,
 		   "DPP: Schedule retransmission of Authentication Response frame in %u ms",
 		wait_time);
@@ -493,21 +487,6 @@
 }
 
 
-static void wpas_dpp_neg_freq_timeout(void *eloop_ctx, void *timeout_ctx)
-{
-	struct wpa_supplicant *wpa_s = eloop_ctx;
-	struct dpp_authentication *auth = wpa_s->dpp_auth;
-
-	if (!wpa_s->dpp_listen_on_tx_expire || !auth || !auth->neg_freq)
-		return;
-
-	wpa_printf(MSG_DEBUG,
-		   "DPP: Start listen on neg_freq %u MHz based on timeout for TX wait expiration",
-		   auth->neg_freq);
-	wpas_dpp_listen_start(wpa_s, auth->neg_freq);
-}
-
-
 static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
 			       unsigned int freq, const u8 *dst,
 			       const u8 *src, const u8 *bssid,
@@ -626,9 +605,7 @@
 			   wpa_s->dpp_auth->curr_freq,
 			   wpa_s->dpp_auth->neg_freq);
 		offchannel_send_action_done(wpa_s);
-		wpa_s->dpp_listen_on_tx_expire = true;
-		eloop_register_timeout(0, 100000, wpas_dpp_neg_freq_timeout,
-				       wpa_s, NULL);
+		wpas_dpp_listen_start(wpa_s, wpa_s->dpp_auth->neg_freq);
 	}
 
 	if (wpa_s->dpp_auth_ok_on_ack)
@@ -1058,8 +1035,6 @@
 	wpa_s->off_channel_freq = 0;
 	wpa_s->roc_waiting_drv_freq = lwork->freq;
 	wpa_drv_dpp_listen(wpa_s, true);
-	wpa_s->dpp_tx_auth_resp_on_roc_stop = false;
-	wpa_s->dpp_tx_chan_change = false;
 }
 
 
@@ -1159,58 +1134,11 @@
 }
 
 
-static void wpas_dpp_tx_auth_resp(struct wpa_supplicant *wpa_s)
-{
-	struct dpp_authentication *auth = wpa_s->dpp_auth;
-
-	if (!auth)
-		return;
-
-	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
-		MAC2STR(auth->peer_mac_addr), auth->curr_freq,
-		DPP_PA_AUTHENTICATION_RESP);
-	offchannel_send_action(wpa_s, auth->curr_freq,
-			       auth->peer_mac_addr, wpa_s->own_addr, broadcast,
-			       wpabuf_head(auth->resp_msg),
-			       wpabuf_len(auth->resp_msg),
-			       500, wpas_dpp_tx_status, 0);
-}
-
-
-static void wpas_dpp_tx_auth_resp_roc_timeout(void *eloop_ctx,
-					      void *timeout_ctx)
-{
-	struct wpa_supplicant *wpa_s = eloop_ctx;
-	struct dpp_authentication *auth = wpa_s->dpp_auth;
-
-	if (!auth || !wpa_s->dpp_tx_auth_resp_on_roc_stop)
-		return;
-
-	wpa_s->dpp_tx_auth_resp_on_roc_stop = false;
-	wpa_s->dpp_tx_chan_change = true;
-	wpa_printf(MSG_DEBUG,
-		   "DPP: Send postponed Authentication Response on remain-on-channel termination timeout");
-	wpas_dpp_tx_auth_resp(wpa_s);
-}
-
-
 void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
 					  unsigned int freq)
 {
-	wpa_printf(MSG_DEBUG, "DPP: Remain on channel cancel for %u MHz", freq);
 	wpas_dpp_listen_work_done(wpa_s);
 
-	if (wpa_s->dpp_auth && wpa_s->dpp_tx_auth_resp_on_roc_stop) {
-		eloop_cancel_timeout(wpas_dpp_tx_auth_resp_roc_timeout,
-				     wpa_s, NULL);
-		wpa_s->dpp_tx_auth_resp_on_roc_stop = false;
-		wpa_s->dpp_tx_chan_change = true;
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Send postponed Authentication Response on remain-on-channel termination");
-		wpas_dpp_tx_auth_resp(wpa_s);
-		return;
-	}
-
 	if (wpa_s->dpp_auth && wpa_s->dpp_in_response_listen) {
 		unsigned int new_freq;
 
@@ -1328,17 +1256,17 @@
 		wpa_printf(MSG_DEBUG,
 			   "DPP: Stop listen on %u MHz to allow response on the request %u MHz",
 			   wpa_s->dpp_listen_freq, wpa_s->dpp_auth->curr_freq);
-		wpa_s->dpp_tx_auth_resp_on_roc_stop = true;
-		eloop_register_timeout(0, 100000,
-				       wpas_dpp_tx_auth_resp_roc_timeout,
-				       wpa_s, NULL);
 		wpas_dpp_listen_stop(wpa_s);
-		return;
 	}
-	wpa_s->dpp_tx_auth_resp_on_roc_stop = false;
-	wpa_s->dpp_tx_chan_change = false;
 
-	wpas_dpp_tx_auth_resp(wpa_s);
+	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
+		MAC2STR(src), wpa_s->dpp_auth->curr_freq,
+		DPP_PA_AUTHENTICATION_RESP);
+	offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
+			       src, wpa_s->own_addr, broadcast,
+			       wpabuf_head(wpa_s->dpp_auth->resp_msg),
+			       wpabuf_len(wpa_s->dpp_auth->resp_msg),
+			       500, wpas_dpp_tx_status, 0);
 }
 
 
@@ -1347,15 +1275,6 @@
 	struct dpp_authentication *auth = wpa_s->dpp_auth;
 	int freq;
 
-	if (wpa_s->dpp_listen_on_tx_expire && auth && auth->neg_freq) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Start listen on neg_freq %u MHz based on TX wait expiration on the previous channel",
-			   auth->neg_freq);
-		eloop_cancel_timeout(wpas_dpp_neg_freq_timeout, wpa_s, NULL);
-		wpas_dpp_listen_start(wpa_s, auth->neg_freq);
-		return;
-	}
-
 	if (!wpa_s->dpp_gas_server || !auth) {
 		if (auth && auth->waiting_auth_resp &&
 		    eloop_is_timeout_registered(wpas_dpp_drv_wait_timeout,
@@ -4897,8 +4816,6 @@
 	eloop_cancel_timeout(wpas_dpp_gas_initial_resp_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_gas_client_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_drv_wait_timeout, wpa_s, NULL);
-	eloop_cancel_timeout(wpas_dpp_tx_auth_resp_roc_timeout, wpa_s, NULL);
-	eloop_cancel_timeout(wpas_dpp_neg_freq_timeout, wpa_s, NULL);
 #ifdef CONFIG_DPP2
 	eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
@@ -5710,7 +5627,6 @@
 	eloop_register_timeout(100, 0, wpas_dpp_push_button_expire,
 			       wpa_s, NULL);
 
-	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PB_STATUS "started");
 	return 0;
 }
 
@@ -5772,7 +5688,6 @@
 	wpa_s->scan_req = MANUAL_SCAN_REQ;
 	wpa_s->scan_res_handler = wpas_dpp_pb_scan_res_handler;
 	wpa_supplicant_req_scan(wpa_s, 0, 0);
-	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PB_STATUS "started");
 	return 0;
 }
 
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index d01b52b..9a4c235 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -128,7 +128,7 @@
 }
 
 struct wpa_scan_results *
-wpa_drv_get_scan_results(struct wpa_supplicant *wpa_s, const u8 *bssid);
+wpa_drv_get_scan_results2(struct wpa_supplicant *wpa_s);
 
 static inline int wpa_drv_get_bssid(struct wpa_supplicant *wpa_s, u8 *bssid)
 {
@@ -342,6 +342,14 @@
 	return -1;
 }
 
+static inline int wpa_drv_set_ap(struct wpa_supplicant *wpa_s,
+				 struct wpa_driver_ap_params *params)
+{
+	if (wpa_s->driver->set_ap)
+		return wpa_s->driver->set_ap(wpa_s->drv_priv, params);
+	return -1;
+}
+
 static inline int wpa_drv_sta_add(struct wpa_supplicant *wpa_s,
 				  struct hostapd_sta_add_params *params)
 {
diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c
index 95953de..9641062 100644
--- a/wpa_supplicant/eapol_test.c
+++ b/wpa_supplicant/eapol_test.c
@@ -670,10 +670,6 @@
 	wpa_s->eapol = NULL;
 	if (e->radius_conf && e->radius_conf->auth_server) {
 		os_free(e->radius_conf->auth_server->shared_secret);
-		os_free(e->radius_conf->auth_server->ca_cert);
-		os_free(e->radius_conf->auth_server->client_cert);
-		os_free(e->radius_conf->auth_server->private_key);
-		os_free(e->radius_conf->auth_server->private_key_passwd);
 		os_free(e->radius_conf->auth_server);
 	}
 	os_free(e->radius_conf);
@@ -1011,10 +1007,7 @@
 
 static void wpa_init_conf(struct eapol_test_data *e,
 			  struct wpa_supplicant *wpa_s, const char *authsrv,
-			  int port, bool tls, const char *secret,
-			  const char *ca_cert, const char *client_cert,
-			  const char *private_key,
-			  const char *private_key_passwd,
+			  int port, const char *secret,
 			  const char *cli_addr, const char *ifname)
 {
 	struct hostapd_radius_server *as;
@@ -1052,17 +1045,8 @@
 	}
 #endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
 	as->port = port;
-	as->tls = tls;
 	as->shared_secret = (u8 *) os_strdup(secret);
 	as->shared_secret_len = os_strlen(secret);
-	if (ca_cert)
-		as->ca_cert = os_strdup(ca_cert);
-	if (client_cert)
-		as->client_cert = os_strdup(client_cert);
-	if (private_key)
-		as->private_key = os_strdup(private_key);
-	if (private_key_passwd)
-		as->private_key_passwd = os_strdup(private_key_passwd);
 	e->radius_conf->auth_server = as;
 	e->radius_conf->auth_servers = as;
 	e->radius_conf->msg_dumps = 1;
@@ -1272,16 +1256,11 @@
 {
 	printf("usage:\n"
 	       "eapol_test [-enWSv] -c<conf> [-a<AS IP>] [-p<AS port>] "
-	       "[-s<AS secret>] \\\n"
-	       "           [-X<RADIUS protocol> \\\n"
+	       "[-s<AS secret>]\\\n"
 	       "           [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n"
 	       "           [-M<client MAC address>] [-o<server cert file] \\\n"
 	       "           [-N<attr spec>] [-R<PC/SC reader>] "
 	       "[-P<PC/SC PIN>] \\\n"
-#ifdef CONFIG_RADIUS_TLS
-	       "           [-j<CA cert>] [-J<client cert>] \\\n"
-	       "[-k<private key] [-K<private key passwd>] \\\n"
-#endif /* CONFIG_RADIUS_TLS */
 	       "           [-A<client IP>] [-i<ifname>] [-T<ctrl_iface>]\n"
 	       "eapol_test scard\n"
 	       "eapol_test sim <PIN> <num triplets> [debug]\n"
@@ -1290,11 +1269,10 @@
 	       "  -c<conf> = configuration file\n"
 	       "  -a<AS IP> = IP address of the authentication server, "
 	       "default 127.0.0.1\n"
-	       "  -p<AS port> = Port of the authentication server,\n"
-	       "                default 1812 for RADIUS/UDP and 2083 for RADIUS/TLS\n"
-	       "  -s<AS secret> = shared secret with the authentication server,\n"
-	       "                  default 'radius' for RADIUS/UDP and 'radsec' for RADIUS/TLS\n"
-	       "  -X<RADIUS protocol> = RADIUS protocol to use: UDP (default) or TLS\n"
+	       "  -p<AS port> = UDP port of the authentication server, "
+	       "default 1812\n"
+	       "  -s<AS secret> = shared secret with the authentication "
+	       "server, default 'radius'\n"
 	       "  -A<client IP> = IP address of the client, default: select "
 	       "automatically\n"
 	       "  -r<count> = number of re-authentications\n"
@@ -1332,11 +1310,8 @@
 	struct wpa_supplicant wpa_s;
 	int c, ret = 1, wait_for_monitor = 0, save_config = 0;
 	char *as_addr = "127.0.0.1";
-	int as_port = -1;
-	char *as_secret = NULL;
-	char *ca_cert = NULL, *client_cert = NULL;
-	char *private_key = NULL, *private_key_passwd = NULL;
-	bool tls = false;
+	int as_port = 1812;
+	char *as_secret = "radius";
 	char *cli_addr = NULL;
 	char *conf = NULL;
 	int timeout = 30;
@@ -1359,8 +1334,7 @@
 	wpa_debug_show_keys = 1;
 
 	for (;;) {
-		c = getopt(argc, argv,
-			   "a:A:c:C:ei:j:J:k:K:M:nN:o:p:P:r:R:s:St:T:vWX:");
+		c = getopt(argc, argv, "a:A:c:C:ei:M:nN:o:p:P:r:R:s:St:T:vW");
 		if (c < 0)
 			break;
 		switch (c) {
@@ -1382,20 +1356,6 @@
 		case 'i':
 			ifname = optarg;
 			break;
-#ifdef CONFIG_RADIUS_TLS
-		case 'j':
-			ca_cert = optarg;
-			break;
-		case 'J':
-			client_cert = optarg;
-			break;
-		case 'k':
-			private_key = optarg;
-			break;
-		case 'K':
-			private_key_passwd = optarg;
-			break;
-#endif /* CONFIG_RADIUS_TLS */
 		case 'M':
 			if (hwaddr_aton(optarg, eapol_test.own_addr)) {
 				usage();
@@ -1446,16 +1406,6 @@
 		case 'W':
 			wait_for_monitor++;
 			break;
-		case 'X':
-			if (os_strcmp(optarg, "UDP") == 0) {
-				tls = false;
-			} else if (os_strcmp(optarg, "TLS") == 0) {
-				tls = true;
-			} else {
-				usage();
-				return -1;
-			}
-			break;
 		case 'N':
 			p1 = os_zalloc(sizeof(*p1));
 			if (p1 == NULL)
@@ -1490,11 +1440,6 @@
 		}
 	}
 
-	if (!as_secret)
-		as_secret = tls ? "radsec" : "radius";
-	if (as_port < 0)
-		as_port = tls ? 2083 : 1812;
-
 	if (argc > optind && os_strcmp(argv[optind], "scard") == 0) {
 		return scard_test(&eapol_test);
 	}
@@ -1544,8 +1489,7 @@
 		wpa_s.conf->pcsc_reader = os_strdup(eapol_test.pcsc_reader);
 	}
 
-	wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, tls, as_secret,
-		      ca_cert, client_cert, private_key, private_key_passwd,
+	wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, as_secret,
 		      cli_addr, ifname);
 	wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s);
 	if (wpa_s.ctrl_iface == NULL) {
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index ff18543..bc45579 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -164,7 +164,7 @@
 	struct wpa_bss *bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
 
 	if (!bss) {
-		wpa_supplicant_update_scan_results(wpa_s, bssid);
+		wpa_supplicant_update_scan_results(wpa_s);
 
 		/* Get the BSS from the new scan results */
 		bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
@@ -183,7 +183,7 @@
 	struct wpa_bss *bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
 
 	if (!bss) {
-		wpa_supplicant_update_scan_results(wpa_s, bssid);
+		wpa_supplicant_update_scan_results(wpa_s);
 		bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
 	}
 
@@ -1156,18 +1156,19 @@
 
 
 static bool wpas_valid_ml_bss(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
+
 {
 	u16 removed_links;
 
 	if (wpa_bss_parse_basic_ml_element(wpa_s, bss, NULL, NULL, NULL, NULL))
 		return true;
 
-	if (!bss->valid_links)
+	if (bss->n_mld_links == 0)
 		return true;
 
 	/* Check if the current BSS is going to be removed */
 	removed_links = wpa_bss_parse_reconf_ml_element(wpa_s, bss);
-	if (BIT(bss->mld_link_id) & removed_links)
+	if (BIT(bss->mld_links[0].link_id) & removed_links)
 		return false;
 
 	return true;
@@ -1696,11 +1697,13 @@
 		return NULL;
 	}
 
+#ifdef CONFIG_WNM
 	if (wnm_is_bss_excluded(wpa_s, bss)) {
 		if (debug_print)
 			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - BSSID excluded");
 		return NULL;
 	}
+#endif /* CONFIG_WNM */
 
 	for (ssid = group; ssid; ssid = only_first_ssid ? NULL : ssid->pnext) {
 		if (wpa_scan_res_ok(wpa_s, ssid, match_ssid, match_ssid_len,
@@ -1806,12 +1809,10 @@
 				break;
 		}
 
-		if (!selected &&
-		    (wpa_s->bssid_ignore || wnm_active_bss_trans_mgmt(wpa_s)) &&
+		if (selected == NULL && wpa_s->bssid_ignore &&
 		    !wpa_s->countermeasures) {
 			wpa_dbg(wpa_s, MSG_DEBUG,
 				"No APs found - clear BSSID ignore list and try again");
-			wnm_btm_reset(wpa_s);
 			wpa_bssid_ignore_clear(wpa_s);
 			wpa_s->bssid_ignore_cleared = true;
 		} else if (selected == NULL)
@@ -2408,7 +2409,7 @@
 
 	scan_res = wpa_supplicant_get_scan_results(wpa_s,
 						   data ? &data->scan_info :
-						   NULL, 1, NULL);
+						   NULL, 1);
 	if (scan_res == NULL) {
 		if (wpa_s->conf->ap_scan == 2 || ap ||
 		    wpa_s->scan_res_handler == scan_only_handler)
@@ -2497,7 +2498,7 @@
 		return 0;
 	}
 
-	if (wnm_scan_process(wpa_s, false) > 0)
+	if (wnm_scan_process(wpa_s, 1) > 0)
 		goto scan_work_done;
 
 	if (sme_proc_obss_scan(wpa_s) > 0)
@@ -2940,6 +2941,8 @@
 }
 
 
+#ifdef CONFIG_INTERWORKING
+
 static int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map,
 			    size_t len)
 {
@@ -2972,6 +2975,8 @@
 	}
 }
 
+#endif /* CONFIG_INTERWORKING */
+
 
 static void wpa_supplicant_set_4addr_mode(struct wpa_supplicant *wpa_s)
 {
@@ -2997,24 +3002,25 @@
 					const u8 *ies, size_t ies_len)
 {
 	struct ieee802_11_elems elems;
-	struct multi_ap_params multi_ap;
-	u16 status;
+	const u8 *map_sub_elem, *pos;
+	size_t len;
 
 	wpa_s->multi_ap_ie = 0;
 
 	if (!ies ||
 	    ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed ||
-	    !elems.multi_ap)
+	    !elems.multi_ap || elems.multi_ap_len < 7)
 		return;
 
-	status = check_multi_ap_ie(elems.multi_ap + 4, elems.multi_ap_len - 4,
-				   &multi_ap);
-	if (status != WLAN_STATUS_SUCCESS)
+	pos = elems.multi_ap + 4;
+	len = elems.multi_ap_len - 4;
+
+	map_sub_elem = get_ie(pos, len, MULTI_AP_SUB_ELEM_TYPE);
+	if (!map_sub_elem || map_sub_elem[1] < 1)
 		return;
 
-	wpa_s->multi_ap_backhaul = !!(multi_ap.capability &
-				      MULTI_AP_BACKHAUL_BSS);
-	wpa_s->multi_ap_fronthaul = !!(multi_ap.capability &
+	wpa_s->multi_ap_backhaul = !!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS);
+	wpa_s->multi_ap_fronthaul = !!(map_sub_elem[2] &
 				       MULTI_AP_FRONTHAUL_BSS);
 	wpa_s->multi_ap_ie = 1;
 }
@@ -3353,8 +3359,10 @@
 		wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
 				       data->assoc_info.resp_ies_len);
 #endif /* CONFIG_WNM */
+#ifdef CONFIG_INTERWORKING
 		interworking_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
 						data->assoc_info.resp_ies_len);
+#endif /* CONFIG_INTERWORKING */
 		if (wpa_s->hw_capab == CAPAB_VHT &&
 		    get_ie(data->assoc_info.resp_ies,
 			   data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP))
@@ -3710,21 +3718,12 @@
 	if (wpa_found || rsn_found)
 		wpa_s->ap_ies_from_associnfo = 1;
 
-	if (wpa_s->assoc_freq && data->assoc_info.freq) {
-		struct wpa_bss *bss;
-		unsigned int freq = 0;
-
-		if (bssid_known) {
-			bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
-			if (bss)
-				freq = bss->freq;
-		}
-		if (freq != data->assoc_info.freq) {
-			wpa_printf(MSG_DEBUG,
-				   "Operating frequency changed from %u to %u MHz",
-				   wpa_s->assoc_freq, data->assoc_info.freq);
-			wpa_supplicant_update_scan_results(wpa_s, bssid);
-		}
+	if (wpa_s->assoc_freq && data->assoc_info.freq &&
+	    wpa_s->assoc_freq != data->assoc_info.freq) {
+		wpa_printf(MSG_DEBUG, "Operating frequency changed from "
+			   "%u to %u MHz",
+			   wpa_s->assoc_freq, data->assoc_info.freq);
+		wpa_supplicant_update_scan_results(wpa_s);
 	}
 
 	wpa_s->assoc_freq = data->assoc_info.freq;
@@ -4078,7 +4077,10 @@
 		if (!mlo.valid_links)
 			return 0;
 
-		for_each_link(mlo.valid_links, i) {
+		for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+			if (!(mlo.valid_links & BIT(i)))
+				continue;
+
 			if (!ether_addr_equal(wpa_s->links[i].addr,
 					      mlo.links[i].addr) ||
 			    !ether_addr_equal(wpa_s->links[i].bssid,
@@ -4096,7 +4098,10 @@
 	wpa_s->valid_links = mlo.valid_links;
 	wpa_s->mlo_assoc_link_id = mlo.assoc_link_id;
 	os_memcpy(wpa_s->ap_mld_addr, mlo.ap_mld_addr, ETH_ALEN);
-	for_each_link(wpa_s->valid_links, i) {
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+		if (!(wpa_s->valid_links & BIT(i)))
+			continue;
+
 		os_memcpy(wpa_s->links[i].addr, mlo.links[i].addr, ETH_ALEN);
 		os_memcpy(wpa_s->links[i].bssid, mlo.links[i].bssid, ETH_ALEN);
 		wpa_s->links[i].freq = mlo.links[i].freq;
@@ -4129,13 +4134,15 @@
 	wpa_mlo.valid_links = drv_mlo.valid_links;
 	wpa_mlo.req_links = drv_mlo.req_links;
 
-	for_each_link(drv_mlo.req_links, i) {
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
 		struct wpa_bss *bss;
 
+		if (!(drv_mlo.req_links & BIT(i)))
+			continue;
+
 		bss = wpa_supplicant_get_new_bss(wpa_s, drv_mlo.links[i].bssid);
 		if (!bss) {
-			wpa_supplicant_update_scan_results(
-				wpa_s, drv_mlo.links[i].bssid);
+			wpa_supplicant_update_scan_results(wpa_s);
 			bss = wpa_supplicant_get_new_bss(
 				wpa_s, drv_mlo.links[i].bssid);
 		}
@@ -6014,10 +6021,13 @@
 	pos += res;
 
 	if (!info->default_map) {
-		for_each_link(info->valid_links, i) {
+		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);
@@ -6297,13 +6307,6 @@
 			" type=%d stype=%d",
 			MAC2STR(data->tx_status.dst),
 			data->tx_status.type, data->tx_status.stype);
-#ifdef CONFIG_WNM
-		if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
-		    data->tx_status.stype == WLAN_FC_STYPE_ACTION &&
-		    wnm_btm_resp_tx_status(wpa_s, data->tx_status.data,
-					   data->tx_status.data_len) == 0)
-			break;
-#endif /* CONFIG_WNM */
 #ifdef CONFIG_PASN
 		if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
 		    data->tx_status.stype == WLAN_FC_STYPE_AUTH &&
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index 5676f38..498cc98 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -2820,7 +2820,7 @@
 	struct wpa_bss *bss;
 	int res;
 
-	bss = wpa_bss_get_bssid_latest(wpa_s, dst);
+	bss = wpa_bss_get_bssid(wpa_s, dst);
 	if (!bss && !freq) {
 		wpa_printf(MSG_WARNING,
 			   "ANQP: Cannot send query without BSS freq info");
@@ -3175,7 +3175,7 @@
 		}
 	}
 	if (bss == NULL)
-		bss = wpa_bss_get_bssid_latest(wpa_s, dst);
+		bss = wpa_bss_get_bssid(wpa_s, dst);
 
 	pos = wpabuf_head(resp);
 	end = pos + wpabuf_len(resp);
@@ -3206,12 +3206,12 @@
 	}
 
 out_parse_done:
-	if (bss)
-		wpas_notify_bss_anqp_changed(wpa_s, bss->id);
 #ifdef CONFIG_HS20
 	hs20_notify_parse_done(wpa_s);
 #endif /* CONFIG_HS20 */
 out:
+	wpa_msg(wpa_s, MSG_INFO, ANQP_QUERY_DONE "addr=" MACSTR " result=%s",
+		MAC2STR(dst), anqp_result);
 	wpas_notify_anqp_query_done(wpa_s, dst, anqp_result, bss ? bss->anqp : NULL);
 }
 
@@ -3290,7 +3290,7 @@
 	u8 query_resp_len_limit = 0;
 
 	freq = wpa_s->assoc_freq;
-	bss = wpa_bss_get_bssid_latest(wpa_s, dst);
+	bss = wpa_bss_get_bssid(wpa_s, dst);
 	if (bss)
 		freq = bss->freq;
 	if (freq <= 0)
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index 85c1ea8..486fc6a 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -231,7 +231,7 @@
 		    hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
 		    hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
 		    ifmsh->conf->vht_capab,
-		    he_capab, NULL, 0)) {
+		    he_capab, NULL)) {
 		wpa_printf(MSG_ERROR, "Error updating mesh frequency params");
 		wpa_supplicant_mesh_deinit(wpa_s, true);
 		return -1;
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index c930651..6f162f2 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -627,15 +627,6 @@
 }
 
 
-void wpas_notify_bss_anqp_changed(struct wpa_supplicant *wpa_s, unsigned int id)
-{
-	if (wpa_s->p2p_mgmt)
-		return;
-
-	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_ANQP, id);
-}
-
-
 void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name)
 {
 	if (wpa_s->p2p_mgmt)
@@ -944,8 +935,7 @@
 				const u8 *p2p_dev_addr, const u8 *ip)
 {
 	if (authorized)
-		wpas_notify_ap_sta_authorized(wpa_s, mac_addr, p2p_dev_addr,
-					      ip);
+		wpas_notify_ap_sta_authorized(wpa_s, mac_addr, p2p_dev_addr, ip);
 	else
 		wpas_notify_ap_sta_deauthorized(wpa_s, mac_addr, p2p_dev_addr);
 }
@@ -1067,14 +1057,11 @@
 				 const char *result,
 				 const struct wpa_bss_anqp *anqp)
 {
-	wpa_msg(wpa_s, MSG_INFO, ANQP_QUERY_DONE "addr=" MACSTR " result=%s",
-		MAC2STR(bssid), result);
 #ifdef CONFIG_INTERWORKING
 	if (!wpa_s || !bssid || !anqp)
 		return;
 
 	wpas_aidl_notify_anqp_query_done(wpa_s, bssid, result, anqp);
-	wpas_dbus_signal_anqp_query_done(wpa_s, bssid, result);
 #endif /* CONFIG_INTERWORKING */
 }
 
@@ -1372,7 +1359,6 @@
 	wpas_dbus_signal_interworking_select_done(wpa_s);
 }
 
-
 #endif /* CONFIG_INTERWORKING */
 
 void wpas_notify_eap_method_selected(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index a584884..d4656ad 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -89,8 +89,6 @@
 void wpas_notify_bss_rates_changed(struct wpa_supplicant *wpa_s,
 				   unsigned int id);
 void wpas_notify_bss_seen(struct wpa_supplicant *wpa_s, unsigned int id);
-void wpas_notify_bss_anqp_changed(struct wpa_supplicant *wpa_s,
-				  unsigned int id);
 void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name);
 void wpas_notify_blob_removed(struct wpa_supplicant *wpa_s, const char *name);
 
diff --git a/wpa_supplicant/op_classes.c b/wpa_supplicant/op_classes.c
index ff11d20..b4ad3ca 100644
--- a/wpa_supplicant/op_classes.c
+++ b/wpa_supplicant/op_classes.c
@@ -22,12 +22,13 @@
 				       unsigned int *flags)
 {
 	int i;
-	bool is_6ghz = is_6ghz_op_class(op_class);
+	bool is_6ghz = op_class >= 131 && op_class <= 136;
 
 	for (i = 0; i < mode->num_channels; i++) {
 		bool chan_is_6ghz;
 
-		chan_is_6ghz = is_6ghz_freq(mode->channels[i].freq);
+		chan_is_6ghz = mode->channels[i].freq >= 5935 &&
+			mode->channels[i].freq <= 7115;
 		if (is_6ghz == chan_is_6ghz && mode->channels[i].chan == chan)
 			break;
 	}
@@ -186,69 +187,6 @@
 }
 
 
-static int get_center_320mhz(struct hostapd_hw_modes *mode, u8 channel,
-			     const u8 *center_channels, size_t num_chan)
-{
-	unsigned int i;
-
-	if (mode->mode != HOSTAPD_MODE_IEEE80211A || !mode->is_6ghz)
-		return 0;
-
-	for (i = 0; i < num_chan; i++) {
-		/*
-		* In 320 MHz, the bandwidth "spans" 60 channels (e.g., 65-125),
-		* so the center channel is 30 channels away from the start/end.
-		*/
-		if (channel >= center_channels[i] - 30 &&
-		    channel <= center_channels[i] + 30)
-			return center_channels[i];
-	}
-
-	return 0;
-}
-
-
-static enum chan_allowed verify_320mhz(struct hostapd_hw_modes *mode,
-				       u8 op_class, u8 channel)
-{
-	u8 center_chan;
-	unsigned int i;
-	bool no_ir = false;
-	const u8 *center_channels;
-	size_t num_chan;
-	const u8 center_channels_6ghz[] = { 31, 63, 95, 127, 159, 191 };
-
-	center_channels = center_channels_6ghz;
-	num_chan = ARRAY_SIZE(center_channels_6ghz);
-
-	center_chan = get_center_320mhz(mode, channel, center_channels,
-					num_chan);
-	if (!center_chan)
-		return NOT_ALLOWED;
-
-	/* Check all the channels are available */
-	for (i = 0; i < 16; i++) {
-		unsigned int flags;
-		u8 adj_chan = center_chan - 30 + i * 4;
-
-		if (allow_channel(mode, op_class, adj_chan, &flags) ==
-		    NOT_ALLOWED)
-			return NOT_ALLOWED;
-
-		if (!(flags & HOSTAPD_CHAN_EHT_320MHZ_SUBCHANNEL))
-			return NOT_ALLOWED;
-
-		if (flags & HOSTAPD_CHAN_NO_IR)
-			no_ir = true;
-	}
-
-	if (no_ir)
-		return NO_IR;
-
-	return ALLOWED;
-}
-
-
 enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 op_class,
 				 u8 channel, u8 bw)
 {
@@ -290,13 +228,6 @@
 		 * result and use only the 80 MHz specific version.
 		 */
 		res2 = res = verify_80mhz(mode, op_class, channel);
-	} else if (bw == BW320) {
-		/*
-		 * channel is a center channel and as such, not necessarily a
-		 * valid 20 MHz channels. Override earlier allow_channel()
-		 * result and use only the 320 MHz specific version.
-		 */
-		res2= res = verify_320mhz(mode, op_class, channel);
 	}
 
 	if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
@@ -320,7 +251,6 @@
 	int z;
 	int freq2 = 0;
 	int freq5 = 0;
-	bool freq6 = false;
 
 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op_class->mode,
 			is_6ghz_op_class(op_class->op_class));
@@ -335,9 +265,7 @@
 
 			if (f == 0)
 				break; /* end of list */
-			if (is_6ghz_freq(f))
-				freq6 = true;
-			else if (f > 4000 && f < 6000)
+			if (f > 4000 && f < 6000)
 				freq5 = 1;
 			else if (f > 2400 && f < 2500)
 				freq2 = 1;
@@ -346,11 +274,8 @@
 		/* No frequencies specified, can use anything hardware supports.
 		 */
 		freq2 = freq5 = 1;
-		freq6 = true;
 	}
 
-	if (is_6ghz_op_class(op_class->op_class) && !freq6)
-		return 0;
 	if (op_class->op_class >= 115 && op_class->op_class <= 130 && !freq5)
 		return 0;
 	if (op_class->op_class >= 81 && op_class->op_class <= 84 && !freq2)
@@ -528,7 +453,6 @@
 	u8 op, current, chan;
 	u8 *ie_len;
 	size_t res;
-	bool op128 = false, op130 = false, op133 = false, op135 = false;
 
 	/*
 	 * Determine the current operating class correct mode based on
@@ -556,50 +480,8 @@
 	wpabuf_put_u8(buf, current);
 
 	for (op = 0; global_op_class[op].op_class; op++) {
-		bool supp;
-		u8 op_class = global_op_class[op].op_class;
-
-		supp = wpas_op_class_supported(wpa_s, ssid,
-					       &global_op_class[op]);
-		if (!supp)
-			continue;
-		switch (op_class) {
-		case 128:
-			op128 = true;
-			break;
-		case 130:
-			op130 = true;
-			break;
-		case 133:
-			op133 = true;
-			break;
-		case 135:
-			op135 = true;
-			break;
-		}
-		if (is_80plus_op_class(op_class))
-			continue;
-
-		/* Add a 1-octet operating class to the Operating Class field */
-		wpabuf_put_u8(buf, global_op_class[op].op_class);
-	}
-
-	/* Add the 2-octet operating classes (i.e., 80+80 MHz cases), if any */
-	if ((op128 && op130) || (op133 && op135)) {
-		/* Operating Class Duple Sequence field */
-
-		/* Zero Delimiter */
-		wpabuf_put_u8(buf, 0);
-
-		/* Operating Class Duple List */
-		if (op128 && op130) {
-			wpabuf_put_u8(buf, 130);
-			wpabuf_put_u8(buf, 128);
-		}
-		if (op133 && op135) {
-			wpabuf_put_u8(buf, 135);
-			wpabuf_put_u8(buf, 133);
-		}
+		if (wpas_op_class_supported(wpa_s, ssid, &global_op_class[op]))
+			wpabuf_put_u8(buf, global_op_class[op].op_class);
 	}
 
 	*ie_len = wpabuf_len(buf) - 2;
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 9c20ee5..3c121c8 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -1103,8 +1103,6 @@
 
 	os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
 
-	wpa_s->p2p_go_no_pri_sec_switch = 0;
-
 	return 0;
 }
 
@@ -7005,8 +7003,7 @@
 			return -1;
 	}
 
-	if (wpas_p2p_init_go_params(wpa_s, &params, selected_freq,
-				    vht_center_freq2,
+	if (wpas_p2p_init_go_params(wpa_s, &params, selected_freq, vht_center_freq2,
 				    ht40, vht, max_oper_chwidth, he, edmg,
 				    NULL))
 		return -1;
@@ -7100,7 +7097,7 @@
 	 * fetch time on the same radio so it reflects the actual time the last
 	 * scan result event occurred.
 	 */
-	wpa_supplicant_update_scan_results(wpa_s, go_bssid);
+	wpa_supplicant_update_scan_results(wpa_s);
 	dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
 			 radio_list) {
 		if (ifs == wpa_s)
diff --git a/wpa_supplicant/pasn_supplicant.c b/wpa_supplicant/pasn_supplicant.c
index 1bb38f7..2e65cf0 100644
--- a/wpa_supplicant/pasn_supplicant.c
+++ b/wpa_supplicant/pasn_supplicant.c
@@ -166,7 +166,7 @@
 
 	bss = wpa_bss_get_bssid(wpa_s, peer_addr);
 	if (!bss) {
-		wpa_supplicant_update_scan_results(wpa_s, peer_addr);
+		wpa_supplicant_update_scan_results(wpa_s);
 		bss = wpa_bss_get_bssid(wpa_s, peer_addr);
 		if (!bss) {
 			wpa_printf(MSG_DEBUG, "PASN: BSS not found");
@@ -560,10 +560,9 @@
 		derive_kdk = wpa_s->conf->force_kdk_derivation;
 #endif /* CONFIG_TESTING_OPTIONS */
 	if (derive_kdk)
-		pasn_enable_kdk_derivation(pasn);
+		pasn->kdk_len = WPA_KDK_MAX_LEN;
 	else
-		pasn_disable_kdk_derivation(pasn);
-
+		pasn->kdk_len = 0;
 	wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", pasn->kdk_len);
 
 	if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_STA) &&
@@ -583,8 +582,9 @@
 		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
 	if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_STA)
 		capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
-	pasn_set_rsnxe_caps(pasn, capab);
-	pasn_register_callbacks(pasn, wpa_s, wpas_pasn_send_mlme, NULL);
+	pasn->rsnxe_capab = capab;
+	pasn->send_mgmt = wpas_pasn_send_mlme;
+
 	ssid = wpa_config_get_network(wpa_s->conf, awork->network_id);
 
 #ifdef CONFIG_SAE
@@ -594,7 +594,7 @@
 				   "PASN: No network profile found for SAE");
 			goto fail;
 		}
-		pasn_set_pt(pasn, wpas_pasn_sae_derive_pt(ssid, awork->group));
+		pasn->pt = wpas_pasn_sae_derive_pt(ssid, awork->group);
 		if (!pasn->pt) {
 			wpa_printf(MSG_DEBUG, "PASN: Failed to derive PT");
 			goto fail;
@@ -629,7 +629,8 @@
 	}
 #endif /* CONFIG_FILS */
 
-	pasn_set_initiator_pmksa(pasn, wpa_sm_get_pmksa_cache(wpa_s->wpa));
+	pasn->cb_ctx = wpa_s;
+	pasn->pmksa = wpa_sm_get_pmksa_cache(wpa_s->wpa);
 
 	if (wpa_key_mgmt_ft(awork->akmp)) {
 #ifdef CONFIG_IEEE80211R
@@ -752,8 +753,7 @@
 
 	wpa_printf(MSG_DEBUG, "PASN: Stopping authentication");
 
-	wpas_pasn_auth_status(wpa_s, pasn->peer_addr, pasn_get_akmp(pasn),
-			      pasn_get_cipher(pasn),
+	wpas_pasn_auth_status(wpa_s, pasn->peer_addr, pasn->akmp, pasn->cipher,
 			      pasn->status, pasn->comeback,
 			      pasn->comeback_after);
 
@@ -765,8 +765,8 @@
 				     struct pasn_data *pasn,
 				     struct wpa_pasn_params_data *params)
 {
-	int akmp = pasn_get_akmp(pasn);
-	int cipher = pasn_get_cipher(pasn);
+	int akmp = pasn->akmp;
+	int cipher = pasn->cipher;
 	u16 group = pasn->group;
 	u8 own_addr[ETH_ALEN];
 	u8 peer_addr[ETH_ALEN];
@@ -806,22 +806,20 @@
 	if (!wpa_s->pasn_auth_work)
 		return -2;
 
-	pasn_register_callbacks(pasn, wpa_s, wpas_pasn_send_mlme, NULL);
+	pasn->cb_ctx = wpa_s;
 	ret = wpa_pasn_auth_rx(pasn, (const u8 *) mgmt, len, &pasn_data);
 	if (ret == 0) {
 		ptksa_cache_add(wpa_s->ptksa, pasn->own_addr, pasn->peer_addr,
-				pasn_get_cipher(pasn),
-				dot11RSNAConfigPMKLifetime,
-				pasn_get_ptk(pasn),
+				pasn->cipher, dot11RSNAConfigPMKLifetime,
+				&pasn->ptk,
 				wpa_s->pasn_params ? wpas_pasn_deauth_cb : NULL,
-				wpa_s->pasn_params ? wpa_s : NULL,
-				pasn_get_akmp(pasn));
+				wpa_s->pasn_params ? wpa_s : NULL, pasn->akmp);
 
 		if (pasn->pmksa_entry)
 			wpa_sm_set_cur_pmksa(wpa_s->wpa, pasn->pmksa_entry);
 	}
 
-	forced_memzero(pasn_get_ptk(pasn), sizeof(pasn->ptk));
+	forced_memzero(&pasn->ptk, sizeof(pasn->ptk));
 
 	if (ret == -1) {
 		wpas_pasn_auth_stop(wpa_s);
@@ -911,8 +909,7 @@
 	}
 
 	wpas_pasn_set_keys_from_cache(wpa_s, pasn->own_addr, pasn->peer_addr,
-				      pasn_get_cipher(pasn),
-				      pasn_get_akmp(pasn));
+				      pasn->cipher, pasn->akmp);
 	wpas_pasn_auth_stop(wpa_s);
 	wpas_pasn_auth_work_done(wpa_s, PASN_STATUS_SUCCESS);
 
diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c
index 2ec4310..7ce854b 100644
--- a/wpa_supplicant/rrm.c
+++ b/wpa_supplicant/rrm.c
@@ -515,8 +515,6 @@
 		num_primary_channels = 4;
 	else if (op->bw == BW160)
 		num_primary_channels = 8;
-	else if (op->bw == BW320)
-		num_primary_channels = 16;
 	else
 		num_primary_channels = 1;
 
@@ -563,7 +561,6 @@
 	u8 channels_80mhz_6ghz[] = { 7, 23, 39, 55, 71, 87, 103, 119, 135, 151,
 				     167, 183, 199, 215 };
 	u8 channels_160mhz_6ghz[] = { 15, 47, 79, 111, 143, 175, 207 };
-	u8 channels_320mhz_6ghz[] = { 31, 63, 95, 127, 159, 191 };
 	const u8 *channels = NULL;
 	size_t num_chan = 0;
 	bool is_6ghz = is_6ghz_op_class(op->op_class);
@@ -582,9 +579,6 @@
 			channels_160mhz_5ghz;
 		num_chan =  is_6ghz ? ARRAY_SIZE(channels_160mhz_6ghz) :
 			ARRAY_SIZE(channels_160mhz_5ghz);
-	} else if (op->bw == BW320) {
-		channels = channels_320mhz_6ghz;
-		num_chan = ARRAY_SIZE(channels_320mhz_6ghz);
 	}
 
 	return wpas_add_channels(op, mode, channels, num_chan);
@@ -1526,7 +1520,10 @@
 	if (!wpa_s->valid_links)
 		return ether_addr_equal(wpa_s->current_bss->bssid, bssid);
 
-	for_each_link(wpa_s->valid_links, i) {
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+		if (!(wpa_s->valid_links & BIT(i)))
+			continue;
+
 		if (ether_addr_equal(wpa_s->links[i].bssid, bssid))
 			return true;
 	}
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index ccd694b..6e6f05d 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -698,7 +698,10 @@
 	else
 		wpa_printf(MSG_DEBUG, "MLD: Probing links 0x%04x", links);
 
-	for_each_link(links, link_id) {
+	for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
+		if (!(links & BIT(link_id)))
+			continue;
+
 		wpabuf_put_u8(extra_ie, EHT_ML_SUB_ELEM_PER_STA_PROFILE);
 
 		/* Subelement length includes only the control */
@@ -2603,8 +2606,8 @@
 }
 
 
-static void filter_scan_res(struct wpa_supplicant *wpa_s,
-			    struct wpa_scan_results *res)
+void filter_scan_res(struct wpa_supplicant *wpa_s,
+		     struct wpa_scan_results *res)
 {
 	size_t i, j;
 
@@ -3166,7 +3169,6 @@
  * @wpa_s: Pointer to wpa_supplicant data
  * @info: Information about what was scanned or %NULL if not available
  * @new_scan: Whether a new scan was performed
- * @bssid: Return BSS entries only for a single BSSID, %NULL for all
  * Returns: Scan results, %NULL on failure
  *
  * This function request the current scan results from the driver and updates
@@ -3175,14 +3177,13 @@
  */
 struct wpa_scan_results *
 wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
-				struct scan_info *info, int new_scan,
-				const u8 *bssid)
+				struct scan_info *info, int new_scan)
 {
 	struct wpa_scan_results *scan_res;
 	size_t i;
 	int (*compar)(const void *, const void *) = wpa_scan_result_compar;
 
-	scan_res = wpa_drv_get_scan_results(wpa_s, bssid);
+	scan_res = wpa_drv_get_scan_results2(wpa_s);
 	if (scan_res == NULL) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results");
 		return NULL;
@@ -3240,7 +3241,6 @@
 /**
  * wpa_supplicant_update_scan_results - Update scan results from the driver
  * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: Update BSS entries only for a single BSSID, %NULL for all
  * Returns: 0 on success, -1 on failure
  *
  * This function updates the BSS table within wpa_supplicant based on the
@@ -3250,11 +3250,10 @@
  * needed information to complete the connection (e.g., to perform validation
  * steps in 4-way handshake).
  */
-int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s,
-				       const u8 *bssid)
+int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s)
 {
 	struct wpa_scan_results *scan_res;
-	scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0, bssid);
+	scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
 	if (scan_res == NULL)
 		return -1;
 	wpa_scan_results_free(scan_res);
@@ -3351,7 +3350,6 @@
 	params->duration = src->duration;
 	params->duration_mandatory = src->duration_mandatory;
 	params->oce_scan = src->oce_scan;
-	params->link_id = src->link_id;
 
 	if (src->sched_scan_plans_num > 0) {
 		params->sched_scan_plans =
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index d4c06c1..8402e74 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -54,10 +54,8 @@
 				bool default_ies, bool next);
 struct wpa_scan_results *
 wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
-				struct scan_info *info, int new_scan,
-				const u8 *bssid);
-int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s,
-				       const u8 *bssid);
+				struct scan_info *info, int new_scan);
+int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s);
 const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie);
 const u8 * wpa_scan_get_ml_ie(const struct wpa_scan_res *res, u8 type);
 const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
@@ -88,6 +86,8 @@
 int wpas_mac_addr_rand_scan_get_mask(struct wpa_supplicant *wpa_s,
 				     unsigned int type, u8 *mask);
 int wpas_abort_ongoing_scan(struct wpa_supplicant *wpa_s);
+void filter_scan_res(struct wpa_supplicant *wpa_s,
+		     struct wpa_scan_results *res);
 void scan_snr(struct wpa_scan_res *res);
 void scan_est_throughput(struct wpa_supplicant *wpa_s,
 			 struct wpa_scan_res *res);
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index be0bc0d..b8f7c65 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -182,7 +182,7 @@
 	if (!bss) {
 		wpa_printf(MSG_DEBUG,
 			   "SAE: BSS not available, update scan result to get BSS");
-		wpa_supplicant_update_scan_results(wpa_s, bssid);
+		wpa_supplicant_update_scan_results(wpa_s);
 		bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
 	}
 	if (bss) {
@@ -405,7 +405,10 @@
 		return bss;
 
 	if (!is_zero_ether_addr(wpa_s->conf->mld_connect_bssid_pref)) {
-		for_each_link(wpa_s->valid_links, i) {
+		for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+			if (!(wpa_s->valid_links & BIT(i)))
+				continue;
+
 			if (wpa_s->mlo_assoc_link_id == i)
 				continue;
 
@@ -436,7 +439,10 @@
 		return bss;
 	}
 
-	for_each_link(wpa_s->valid_links, i) {
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+		if (!(wpa_s->valid_links & BIT(i)))
+			continue;
+
 		if (wpa_s->mlo_assoc_link_id == i)
 			continue;
 
@@ -517,23 +523,21 @@
 static void wpas_sme_set_mlo_links(struct wpa_supplicant *wpa_s,
 				   struct wpa_bss *bss)
 {
-	u8 i;
+	int i;
 
 	wpa_s->valid_links = 0;
-	wpa_s->mlo_assoc_link_id = bss->mld_link_id;
 
-	for_each_link(bss->valid_links, i) {
+	for (i = 0; i < bss->n_mld_links; i++) {
+		u8 link_id = bss->mld_links[i].link_id;
 		const u8 *bssid = bss->mld_links[i].bssid;
 
-		wpa_s->valid_links |= BIT(i);
-		os_memcpy(wpa_s->links[i].bssid, bssid, ETH_ALEN);
-		wpa_s->links[i].freq = bss->mld_links[i].freq;
-		wpa_s->links[i].disabled = bss->mld_links[i].disabled;
-
-		if (bss->mld_link_id == i)
-			wpa_s->links[i].bss = bss;
-		else
-			wpa_s->links[i].bss = wpa_bss_get_bssid(wpa_s, bssid);
+		if (i == 0)
+			wpa_s->mlo_assoc_link_id = link_id;
+		wpa_s->valid_links |= BIT(link_id);
+		os_memcpy(wpa_s->links[link_id].bssid, bssid, ETH_ALEN);
+		wpa_s->links[link_id].freq = bss->mld_links[i].freq;
+		wpa_s->links[link_id].bss = wpa_bss_get_bssid(wpa_s, bssid);
+		wpa_s->links[link_id].disabled = bss->mld_links[i].disabled;
 	}
 }
 
@@ -574,7 +578,7 @@
 	if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO) &&
 	    !wpa_bss_parse_basic_ml_element(wpa_s, bss, wpa_s->ap_mld_addr,
 					    NULL, ssid, NULL) &&
-	    bss->valid_links) {
+	    bss->n_mld_links) {
 		wpa_printf(MSG_DEBUG, "MLD: In authentication");
 		wpas_sme_set_mlo_links(wpa_s, bss);
 
@@ -2412,16 +2416,12 @@
 
 	if (ssid && ssid->multi_ap_backhaul_sta) {
 		size_t multi_ap_ie_len;
-		struct multi_ap_params multi_ap = { 0 };
-
-		multi_ap.capability = MULTI_AP_BACKHAUL_STA;
-		multi_ap.profile = ssid->multi_ap_profile;
 
 		multi_ap_ie_len = add_multi_ap_ie(
 			wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
 			sizeof(wpa_s->sme.assoc_req_ie) -
 			wpa_s->sme.assoc_req_ie_len,
-			&multi_ap);
+			MULTI_AP_BACKHAUL_STA);
 		if (multi_ap_ie_len == 0) {
 			wpa_printf(MSG_ERROR,
 				   "Multi-AP: Failed to build Multi-AP IE");
@@ -2601,7 +2601,10 @@
 		params.mld_params.mld_addr = wpa_s->ap_mld_addr;
 		params.mld_params.valid_links = wpa_s->valid_links;
 		params.mld_params.assoc_link_id = wpa_s->mlo_assoc_link_id;
-		for_each_link(wpa_s->valid_links, i) {
+		for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+			if (!(wpa_s->valid_links & BIT(i)))
+				continue;
+
 			params.mld_params.mld_links[i].bssid =
 				wpa_s->links[i].bssid;
 			params.mld_params.mld_links[i].freq =
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index ea79ae6..775e75b 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -418,7 +418,7 @@
 }
 
 
-void wnm_btm_reset(struct wpa_supplicant *wpa_s)
+void wnm_deallocate_memory(struct wpa_supplicant *wpa_s)
 {
 	int i;
 
@@ -431,17 +431,8 @@
 	os_free(wpa_s->wnm_neighbor_report_elements);
 	wpa_s->wnm_neighbor_report_elements = NULL;
 
-	wpa_s->wnm_cand_valid_until.sec = 0;
-	wpa_s->wnm_cand_valid_until.usec = 0;
-
-	wpa_s->wnm_mode = 0;
-	wpa_s->wnm_dialog_token = 0;
-	wpa_s->wnm_reply = 0;
-
-#ifdef CONFIG_MBO
-	wpa_s->wnm_mbo_trans_reason_present = 0;
-	wpa_s->wnm_mbo_transition_reason = 0;
-#endif /* CONFIG_MBO */
+	wpabuf_free(wpa_s->coloc_intf_elems);
+	wpa_s->coloc_intf_elems = NULL;
 }
 
 
@@ -790,11 +781,22 @@
 			}
 		}
 
-		/*
-		 * TODO: Could consider allowing transition to another ESS if
-		 * PMF was enabled for the association.
-		 */
-		if (!wpa_scan_res_match(wpa_s, 0, target, wpa_s->current_ssid,
+		if (bss->ssid_len != target->ssid_len ||
+		    os_memcmp(bss->ssid, target->ssid, bss->ssid_len) != 0) {
+			/*
+			 * TODO: Could consider allowing transition to another
+			 * ESS if PMF was enabled for the association.
+			 */
+			wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
+				   " (pref %d) in different ESS",
+				   MAC2STR(nei->bssid),
+				   nei->preference_present ? nei->preference :
+				   -1);
+			continue;
+		}
+
+		if (wpa_s->current_ssid &&
+		    !wpa_scan_res_match(wpa_s, 0, target, wpa_s->current_ssid,
 					1, 0)) {
 			wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
 				   " (pref %d) does not match the current network profile",
@@ -804,6 +806,14 @@
 			continue;
 		}
 
+		if (wpa_is_bss_tmp_disallowed(wpa_s, target)) {
+			wpa_printf(MSG_DEBUG,
+				   "MBO: Candidate BSS " MACSTR
+				   " retry delay is not over yet",
+				   MAC2STR(nei->bssid));
+			continue;
+		}
+
 		if (target->level < bss->level && target->level < -80) {
 			wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
 				   " (pref %d) does not have sufficient signal level (%d)",
@@ -1035,8 +1045,8 @@
 
 #define BTM_RESP_MIN_SIZE	5 + ETH_ALEN
 
-static int wnm_send_bss_transition_mgmt_resp(
-	struct wpa_supplicant *wpa_s,
+static void wnm_send_bss_transition_mgmt_resp(
+	struct wpa_supplicant *wpa_s, u8 dialog_token,
 	enum bss_trans_mgmt_status_code status,
 	enum mbo_transition_reject_reason reason,
 	u8 delay, const u8 *target_bssid)
@@ -1044,24 +1054,21 @@
 	struct wpabuf *buf;
 	int res;
 
-	wpa_s->wnm_reply = 0;
-
 	wpa_printf(MSG_DEBUG,
 		   "WNM: Send BSS Transition Management Response to " MACSTR
 		   " dialog_token=%u status=%u reason=%u delay=%d",
-		   MAC2STR(wpa_s->bssid), wpa_s->wnm_dialog_token, status,
-		   reason, delay);
+		   MAC2STR(wpa_s->bssid), dialog_token, status, reason, delay);
 	if (!wpa_s->current_bss) {
 		wpa_printf(MSG_DEBUG,
 			   "WNM: Current BSS not known - drop response");
-		return -1;
+		return;
 	}
 
 	buf = wpabuf_alloc(BTM_RESP_MIN_SIZE);
 	if (!buf) {
 		wpa_printf(MSG_DEBUG,
 			   "WNM: Failed to allocate memory for BTM response");
-		return -1;
+		return;
 	}
 
 	wpa_s->bss_tm_status = status;
@@ -1069,7 +1076,7 @@
 
 	wpabuf_put_u8(buf, WLAN_ACTION_WNM);
 	wpabuf_put_u8(buf, WNM_BSS_TRANS_MGMT_RESP);
-	wpabuf_put_u8(buf, wpa_s->wnm_dialog_token);
+	wpabuf_put_u8(buf, dialog_token);
 	wpabuf_put_u8(buf, status);
 	wpabuf_put_u8(buf, delay);
 	if (target_bssid) {
@@ -1083,7 +1090,7 @@
 		wpabuf_put_data(buf, "\0\0\0\0\0\0", ETH_ALEN);
 	}
 
-	if (status == WNM_BSS_TM_ACCEPT && target_bssid)
+	if (status == WNM_BSS_TM_ACCEPT && !wpa_s->wnm_link_removal)
 		wnm_add_cand_list(wpa_s, &buf);
 
 #ifdef CONFIG_MBO
@@ -1099,7 +1106,7 @@
 				wpabuf_free(buf);
 				wpa_printf(MSG_DEBUG,
 					   "WNM: Failed to allocate memory for MBO IE");
-				return -1;
+				return;
 			}
 
 			wpabuf_put_data(buf, mbo, ret);
@@ -1116,8 +1123,6 @@
 	}
 
 	wpabuf_free(buf);
-
-	return res;
 }
 
 
@@ -1135,24 +1140,19 @@
 
 	/* Send the BSS Management Response - Accept */
 	if (wpa_s->wnm_reply) {
-		wpa_s->wnm_target_bss = bss;
+		wpa_s->wnm_reply = 0;
 		wpa_printf(MSG_DEBUG,
 			   "WNM: Sending successful BSS Transition Management Response");
-
-		/* This function will be called again from the TX handler to
-		 * start the actual reassociation after this response has been
-		 * delivered to the current AP. */
-		if (wnm_send_bss_transition_mgmt_resp(
-			    wpa_s, WNM_BSS_TM_ACCEPT,
-			    MBO_TRANSITION_REJECT_REASON_UNSPECIFIED, 0,
-			    bss->bssid) >= 0)
-			return;
+		wnm_send_bss_transition_mgmt_resp(
+			wpa_s, wpa_s->wnm_dialog_token, WNM_BSS_TM_ACCEPT,
+			MBO_TRANSITION_REJECT_REASON_UNSPECIFIED, 0,
+			bss->bssid);
 	}
 
 	if (bss == wpa_s->current_bss) {
 		wpa_printf(MSG_DEBUG,
 			   "WNM: Already associated with the preferred candidate");
-		wnm_btm_reset(wpa_s);
+		wnm_deallocate_memory(wpa_s);
 		return;
 	}
 
@@ -1168,10 +1168,11 @@
 	 */
 	if (!already_connecting && radio_work_pending(wpa_s, "sme-connect"))
 		wpa_s->bss_trans_mgmt_in_progress = true;
+	wnm_deallocate_memory(wpa_s);
 }
 
 
-int wnm_scan_process(struct wpa_supplicant *wpa_s, bool pre_scan_check)
+int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail)
 {
 	struct wpa_bss *bss;
 	struct wpa_ssid *ssid = wpa_s->current_ssid;
@@ -1179,51 +1180,27 @@
 	enum mbo_transition_reject_reason reason =
 		MBO_TRANSITION_REJECT_REASON_UNSPECIFIED;
 
-	if (!wpa_s->wnm_dialog_token)
+	if (!wpa_s->wnm_neighbor_report_elements)
 		return 0;
 
 	wpa_dbg(wpa_s, MSG_DEBUG,
 		"WNM: Process scan results for BSS Transition Management");
-	if (!pre_scan_check &&
-	    os_reltime_initialized(&wpa_s->wnm_cand_valid_until) &&
-	    os_reltime_before(&wpa_s->wnm_cand_valid_until,
+	if (os_reltime_before(&wpa_s->wnm_cand_valid_until,
 			      &wpa_s->scan_trigger_time)) {
 		wpa_printf(MSG_DEBUG, "WNM: Previously stored BSS transition candidate list is not valid anymore - drop it");
-		goto send_bss_resp_fail;
+		wnm_deallocate_memory(wpa_s);
+		return 0;
+	}
+
+	if (!wpa_s->current_bss ||
+	    !ether_addr_equal(wpa_s->wnm_cand_from_bss,
+			      wpa_s->current_bss->bssid)) {
+		wpa_printf(MSG_DEBUG, "WNM: Stored BSS transition candidate list not from the current BSS - ignore it");
+		return 0;
 	}
 
 	/* Compare the Neighbor Report and scan results */
 	bss = compare_scan_neighbor_results(wpa_s, 0, &reason);
-
-	/*
-	 * If this is a pre-scan check, returning 0 will trigger a scan and
-	 * another call. In that case, reject "bad" candidates in the hope of
-	 * finding a better candidate after scanning.
-	 *
-	 * Use a simple heuristic to check whether the selection is reasonable
-	 * or a scan is a good idea. For that, we need to have found a
-	 * candidate BSS (which might be the current one), it is up-to-date,
-	 * and we don't want to immediately roam back again.
-	 */
-	if (pre_scan_check) {
-		struct os_reltime age;
-
-		if (!bss)
-			return 0;
-
-		os_reltime_age(&bss->last_update, &age);
-		if (age.sec >= 10)
-			return 0;
-
-#ifndef CONFIG_NO_ROAMING
-		if (wpa_s->current_bss && bss != wpa_s->current_bss &&
-		    wpa_supplicant_need_to_roam_within_ess(wpa_s,
-							   wpa_s->current_bss,
-							   bss))
-			return 0;
-#endif /* CONFIG_NO_ROAMING */
-	}
-
 	if (!bss) {
 		wpa_printf(MSG_DEBUG, "WNM: No BSS transition candidate match found");
 		status = WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES;
@@ -1235,13 +1212,18 @@
 	return 1;
 
 send_bss_resp_fail:
+	if (!reply_on_fail)
+		return 0;
+
 	/* Send reject response for all the failures */
 
-	if (wpa_s->wnm_reply)
-		wnm_send_bss_transition_mgmt_resp(wpa_s, status, reason,
-						  0, NULL);
-
-	wnm_btm_reset(wpa_s);
+	if (wpa_s->wnm_reply) {
+		wpa_s->wnm_reply = 0;
+		wnm_send_bss_transition_mgmt_resp(wpa_s,
+						  wpa_s->wnm_dialog_token,
+						  status, reason, 0, NULL);
+	}
+	wnm_deallocate_memory(wpa_s);
 
 	return 0;
 }
@@ -1348,10 +1330,6 @@
 		struct neighbor_report *nei;
 
 		nei = &wpa_s->wnm_neighbor_report_elements[i];
-
-		if (nei->preference_present && nei->preference == 0)
-			continue;
-
 		if (nei->freq <= 0) {
 			wpa_printf(MSG_DEBUG,
 				   "WNM: Unknown neighbor operating frequency for "
@@ -1376,6 +1354,79 @@
 }
 
 
+static int wnm_fetch_scan_results(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_scan_results *scan_res;
+	struct wpa_bss *bss;
+	struct wpa_ssid *ssid = wpa_s->current_ssid;
+	u8 i, found = 0;
+	size_t j;
+
+	wpa_dbg(wpa_s, MSG_DEBUG,
+		"WNM: Fetch current scan results from the driver for checking transition candidates");
+	scan_res = wpa_drv_get_scan_results2(wpa_s);
+	if (!scan_res) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "WNM: Failed to get scan results");
+		return 0;
+	}
+
+	if (scan_res->fetch_time.sec == 0)
+		os_get_reltime(&scan_res->fetch_time);
+
+	filter_scan_res(wpa_s, scan_res);
+
+	for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
+		struct neighbor_report *nei;
+
+		nei = &wpa_s->wnm_neighbor_report_elements[i];
+		if (nei->preference_present && nei->preference == 0)
+			continue;
+
+		for (j = 0; j < scan_res->num; j++) {
+			struct wpa_scan_res *res;
+			const u8 *ssid_ie;
+
+			res = scan_res->res[j];
+			if (!ether_addr_equal(nei->bssid, res->bssid) ||
+			    res->age > WNM_SCAN_RESULT_AGE * 1000)
+				continue;
+			bss = wpa_s->current_bss;
+			ssid_ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
+			if (bss && ssid_ie && ssid_ie[1] &&
+			    (bss->ssid_len != ssid_ie[1] ||
+			     os_memcmp(bss->ssid, ssid_ie + 2,
+				       bss->ssid_len) != 0))
+				continue; /* Skip entries for other ESSs */
+
+			/* Potential candidate found */
+			found = 1;
+			scan_snr(res);
+			scan_est_throughput(wpa_s, res);
+			wpa_bss_update_scan_res(wpa_s, res,
+						&scan_res->fetch_time);
+		}
+	}
+
+	wpa_scan_results_free(scan_res);
+	if (!found) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"WNM: No transition candidate matches existing scan results");
+		return 0;
+	}
+
+	bss = compare_scan_neighbor_results(wpa_s, WNM_SCAN_RESULT_AGE, NULL);
+	if (!bss) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"WNM: Comparison of scan results against transition candidates did not find matches");
+		return 0;
+	}
+
+	/* Associate to the network */
+	wnm_bss_tm_connect(wpa_s, bss, ssid, 0);
+	return 1;
+}
+
+
 static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
 					     const u8 *pos, const u8 *end,
 					     int reply)
@@ -1394,6 +1445,8 @@
 		return;
 
 #ifdef CONFIG_MBO
+	wpa_s->wnm_mbo_trans_reason_present = 0;
+	wpa_s->wnm_mbo_transition_reason = 0;
 	wpa_s->wnm_mbo_cell_pref_present = 0;
 	wpa_s->wnm_mbo_cell_preference = 0;
 	wpa_s->wnm_mbo_assoc_retry_delay_present = 0;
@@ -1405,8 +1458,6 @@
 	else
 		beacon_int = 100; /* best guess */
 
-	wnm_btm_reset(wpa_s);
-
 	wpa_s->wnm_dialog_token = pos[0];
 	wpa_s->wnm_mode = pos[1];
 	wpa_s->wnm_dissoc_timer = WPA_GET_LE16(pos + 2);
@@ -1426,7 +1477,8 @@
 			   "WNM: Testing - reject BSS Transition Management Request: reject_btm_req_reason=%d",
 			   wpa_s->reject_btm_req_reason);
 		wnm_send_bss_transition_mgmt_resp(
-			wpa_s, wpa_s->reject_btm_req_reason,
+			wpa_s, wpa_s->wnm_dialog_token,
+			wpa_s->reject_btm_req_reason,
 			MBO_TRANSITION_REJECT_REASON_UNSPECIFIED, 0, NULL);
 		return;
 	}
@@ -1489,34 +1541,15 @@
 	 * set to 1, and the BSS Termination Included field is set to 1, only
 	 * one of the links is removed and the other links remain associated.
 	 * Ignore the Disassociation Imminent field in such a case.
-	 *
-	 * TODO: We should check if the AP has more than one link.
-	 * TODO: We should pass the RX link and use that
 	 */
-	if (disassoc_imminent && wpa_s->valid_links &&
+	if (disassoc_imminent &&
+	    (wpa_s->valid_links & (wpa_s->valid_links - 1)) != 0 &&
 	    (wpa_s->wnm_mode & WNM_BSS_TM_REQ_LINK_REMOVAL_IMMINENT) &&
 	    (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED)) {
-		/* If we still have a link, then just accept the request */
-		if (wpa_s->valid_links & (wpa_s->valid_links - 1)) {
-			wpa_printf(MSG_INFO,
-				   "WNM: BTM request for a single MLO link - ignore disassociation imminent since other links remain associated");
-			disassoc_imminent = false;
-
-			wnm_send_bss_transition_mgmt_resp(
-				wpa_s, WNM_BSS_TM_ACCEPT, 0, 0, NULL);
-
-			return;
-		}
-
-		/* The last link is being removed (which must be the assoc link)
-		 */
+		wpa_printf(MSG_INFO,
+			   "WNM: BTM request for a single MLO link - ignore disassociation imminent since other links remain associated");
+		disassoc_imminent = false;
 		wpa_s->wnm_link_removal = true;
-		os_memcpy(wpa_s->wnm_dissoc_addr,
-			  wpa_s->links[wpa_s->mlo_assoc_link_id].bssid,
-			  ETH_ALEN);
-	} else {
-		os_memcpy(wpa_s->wnm_dissoc_addr, wpa_s->valid_links ?
-			  wpa_s->ap_mld_addr : wpa_s->bssid, ETH_ALEN);
 	}
 
 	if (disassoc_imminent) {
@@ -1533,6 +1566,7 @@
 		unsigned int valid_ms;
 
 		wpa_msg(wpa_s, MSG_INFO, "WNM: Preferred List Available");
+		wnm_deallocate_memory(wpa_s);
 		wpa_s->wnm_neighbor_report_elements = os_calloc(
 			WNM_MAX_NEIGHBOR_REPORT,
 			sizeof(struct neighbor_report));
@@ -1580,7 +1614,8 @@
 			wpa_printf(MSG_DEBUG,
 				   "WNM: Candidate list included bit is set, but no candidates found");
 			wnm_send_bss_transition_mgmt_resp(
-				wpa_s, WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES,
+				wpa_s, wpa_s->wnm_dialog_token,
+				WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES,
 				MBO_TRANSITION_REJECT_REASON_UNSPECIFIED, 0,
 				NULL);
 			return;
@@ -1590,7 +1625,8 @@
 			wpa_printf(MSG_DEBUG,
 				   "WNM: Configuration prevents roaming (BSSID set)");
 			wnm_send_bss_transition_mgmt_resp(
-				wpa_s, WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES,
+				wpa_s, wpa_s->wnm_dialog_token,
+				WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES,
 				MBO_TRANSITION_REJECT_REASON_UNSPECIFIED, 0,
 				NULL);
 			return;
@@ -1607,21 +1643,35 @@
 		wpa_s->wnm_cand_valid_until.sec +=
 			wpa_s->wnm_cand_valid_until.usec / 1000000;
 		wpa_s->wnm_cand_valid_until.usec %= 1000000;
+		os_memcpy(wpa_s->wnm_cand_from_bss, wpa_s->bssid, ETH_ALEN);
 
 		/*
-		* Try fetching the latest scan results from the kernel.
-		* This can help in finding more up-to-date information should
-		* the driver have done some internal scanning operations after
-		* the last scan result update in wpa_supplicant.
-		*
-		* It is not a new scan, this does not update the last_scan
-		* timestamp nor will it expire old BSSs.
-		*/
-		wpa_supplicant_update_scan_results(wpa_s, NULL);
-		if (wnm_scan_process(wpa_s, true) > 0)
+		 * Fetch the latest scan results from the kernel and check for
+		 * candidates based on those results first. This can help in
+		 * finding more up-to-date information should the driver has
+		 * done some internal scanning operations after the last scan
+		 * result update in wpa_supplicant.
+		 */
+		if (wnm_fetch_scan_results(wpa_s) > 0)
 			return;
-		wpa_printf(MSG_DEBUG,
-			   "WNM: No valid match in previous scan results - try a new scan");
+
+		/*
+		 * Try to use previously received scan results, if they are
+		 * recent enough to use for a connection.
+		 */
+		if (wpa_s->last_scan_res_used > 0) {
+			struct os_reltime now;
+
+			os_get_reltime(&now);
+			if (!os_reltime_expired(&now, &wpa_s->last_scan, 10)) {
+				wpa_printf(MSG_DEBUG,
+					   "WNM: Try to use recent scan results");
+				if (wnm_scan_process(wpa_s, 0) > 0)
+					return;
+				wpa_printf(MSG_DEBUG,
+					   "WNM: No match in previous scan results - try a new scan");
+			}
+		}
 
 		wnm_set_scan_freqs(wpa_s);
 		if (wpa_s->wnm_num_neighbor_report == 1) {
@@ -1644,45 +1694,12 @@
 			status = WNM_BSS_TM_REJECT_UNSPECIFIED;
 		}
 		wnm_send_bss_transition_mgmt_resp(
-			wpa_s, status,
+			wpa_s, wpa_s->wnm_dialog_token, status,
 			MBO_TRANSITION_REJECT_REASON_UNSPECIFIED, 0, NULL);
 	}
 }
 
 
-int wnm_btm_resp_tx_status(struct wpa_supplicant *wpa_s, const u8 *data,
-			   size_t data_len)
-{
-	const struct ieee80211_mgmt *frame =
-		(const struct ieee80211_mgmt *) data;
-
-	if (data_len <
-	    IEEE80211_HDRLEN + sizeof(frame->u.action.u.bss_tm_resp) ||
-	    frame->u.action.category != WLAN_ACTION_WNM ||
-	    frame->u.action.u.bss_tm_resp.action != WNM_BSS_TRANS_MGMT_RESP ||
-	    frame->u.action.u.bss_tm_resp.status_code != WNM_BSS_TM_ACCEPT)
-		return -1;
-
-	/*
-	 * If disassoc imminent bit was set in the request, the response may
-	 * indicate accept even if no candidate was found, so bail out here.
-	 */
-	if (!wpa_s->wnm_target_bss) {
-		wpa_printf(MSG_DEBUG, "WNM: Target BSS is not set");
-		return 0;
-	}
-
-	if (!wpa_s->current_ssid)
-		return 0;
-
-	wnm_bss_tm_connect(wpa_s, wpa_s->wnm_target_bss, wpa_s->current_ssid,
-			   0);
-
-	wpa_s->wnm_target_bss = NULL;
-	return 0;
-}
-
-
 #define BTM_QUERY_MIN_SIZE	4
 
 int wnm_send_bss_transition_mgmt_query(struct wpa_supplicant *wpa_s,
@@ -2035,14 +2052,14 @@
 void wnm_set_coloc_intf_elems(struct wpa_supplicant *wpa_s,
 			      struct wpabuf *elems)
 {
+	wpabuf_free(wpa_s->coloc_intf_elems);
 	if (elems && wpabuf_len(elems) == 0) {
 		wpabuf_free(elems);
 		elems = NULL;
 	}
+	wpa_s->coloc_intf_elems = elems;
 
-	/* NOTE: The elements are not stored as they are only send out once */
-
-	if (wpa_s->conf->coloc_intf_reporting && elems &&
+	if (wpa_s->conf->coloc_intf_reporting && wpa_s->coloc_intf_elems &&
 	    wpa_s->coloc_intf_dialog_token &&
 	    (wpa_s->coloc_intf_auto_report == 1 ||
 	     wpa_s->coloc_intf_auto_report == 3)) {
@@ -2051,10 +2068,8 @@
 		 */
 		wnm_send_coloc_intf_report(wpa_s,
 					   wpa_s->coloc_intf_dialog_token,
-					   elems);
+					   wpa_s->coloc_intf_elems);
 	}
-
-	wpabuf_free(elems);
 }
 
 
@@ -2067,6 +2082,8 @@
 
 bool wnm_is_bss_excluded(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
 {
+	unsigned int i;
+
 	if (!(wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT))
 		return false;
 
@@ -2074,14 +2091,26 @@
 	 * In case disassociation imminent is set, do no try to use a BSS to
 	 * which we are connected.
 	 */
-	if (wpa_s->wnm_link_removal ||
-	    !(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO) ||
-	    is_zero_ether_addr(bss->mld_addr)) {
-		if (ether_addr_equal(bss->bssid, wpa_s->wnm_dissoc_addr))
+
+	if (wpa_s->current_bss &&
+	    ether_addr_equal(wpa_s->current_bss->bssid, bss->bssid)) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"WNM: Disassociation imminent: current BSS");
+		return true;
+	}
+
+	if (!wpa_s->valid_links)
+		return false;
+
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+		if (!(wpa_s->valid_links & BIT(i)))
+			continue;
+
+		if (ether_addr_equal(wpa_s->links[i].bssid, bss->bssid)) {
+			wpa_dbg(wpa_s, MSG_DEBUG,
+				"WNM: MLD: Disassociation imminent: current link");
 			return true;
-	} else {
-		if (ether_addr_equal(bss->mld_addr, wpa_s->wnm_dissoc_addr))
-			return true;
+		}
 	}
 
 	return false;
diff --git a/wpa_supplicant/wnm_sta.h b/wpa_supplicant/wnm_sta.h
index 235a838..2a473db 100644
--- a/wpa_supplicant/wnm_sta.h
+++ b/wpa_supplicant/wnm_sta.h
@@ -65,28 +65,19 @@
 				       const char *btm_candidates,
 				       int cand_list);
 
+void wnm_deallocate_memory(struct wpa_supplicant *wpa_s);
 int wnm_send_coloc_intf_report(struct wpa_supplicant *wpa_s, u8 dialog_token,
 			       const struct wpabuf *elems);
 void wnm_set_coloc_intf_elems(struct wpa_supplicant *wpa_s,
 			      struct wpabuf *elems);
+bool wnm_is_bss_excluded(struct wpa_supplicant *wpa_s, struct wpa_bss *bss);
 
-int wnm_btm_resp_tx_status(struct wpa_supplicant *wpa_s, const u8 *data,
-			   size_t data_len);
 
 #ifdef CONFIG_WNM
 
-int wnm_scan_process(struct wpa_supplicant *wpa_s, bool pre_scan_check);
+int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail);
 void wnm_clear_coloc_intf_reporting(struct wpa_supplicant *wpa_s);
 
-bool wnm_is_bss_excluded(struct wpa_supplicant *wpa_s, struct wpa_bss *bss);
-
-void wnm_btm_reset(struct wpa_supplicant *wpa_s);
-
-static inline bool wnm_active_bss_trans_mgmt(struct wpa_supplicant *wpa_s)
-{
-	return !!wpa_s->wnm_dialog_token;
-}
-
 #else /* CONFIG_WNM */
 
 static inline int wnm_scan_process(struct wpa_supplicant *wpa_s,
@@ -99,21 +90,6 @@
 {
 }
 
-static inline bool
-wnm_is_bss_excluded(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
-{
-	return false;
-}
-
-static inline void wnm_btm_reset(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline bool wnm_active_bss_trans_mgmt(struct wpa_supplicant *wpa_s)
-{
-	return false;
-}
-
 #endif /* CONFIG_WNM */
 
 #endif /* WNM_STA_H */
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 60f8562..b1334e2 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -5129,7 +5129,7 @@
 
 	eloop_register_signal_terminate(wpa_cli_terminate, NULL);
 
-	if (!ctrl_ifname && !global)
+	if (ctrl_ifname == NULL)
 		ctrl_ifname = wpa_cli_get_default_ifname();
 
 	if (reconnect && action_file && ctrl_ifname) {
diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c
index 88f3f2a..31a9af6 100644
--- a/wpa_supplicant/wpa_priv.c
+++ b/wpa_supplicant/wpa_priv.c
@@ -187,10 +187,7 @@
 	int val;
 	size_t i;
 
-	if (iface->driver->get_scan_results)
-		res = iface->driver->get_scan_results(iface->drv_priv, NULL);
-	else
-		res = iface->driver->get_scan_results2(iface->drv_priv);
+	res = iface->driver->get_scan_results2(iface->drv_priv);
 	if (res == NULL)
 		goto fail;
 
@@ -234,7 +231,7 @@
 	if (iface->drv_priv == NULL)
 		return;
 
-	if (iface->driver->get_scan_results || iface->driver->get_scan_results2)
+	if (iface->driver->get_scan_results2)
 		wpa_priv_get_scan_results2(iface, from, fromlen);
 	else
 		sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, fromlen);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 3fde0a8..a851024 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -678,7 +678,9 @@
 	wpa_s->disallow_aps_ssid = NULL;
 
 	wnm_bss_keep_alive_deinit(wpa_s);
-	wnm_btm_reset(wpa_s);
+#ifdef CONFIG_WNM
+	wnm_deallocate_memory(wpa_s);
+#endif /* CONFIG_WNM */
 
 	ext_password_deinit(wpa_s->ext_pw);
 	wpa_s->ext_pw = NULL;
@@ -892,7 +894,7 @@
 			struct wpa_scan_results *scan_res;
 			wpa_s->bgscan_ssid = wpa_s->current_ssid;
 			scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
-								   0, NULL);
+								   0);
 			if (scan_res) {
 				bgscan_notify_scan(wpa_s, scan_res);
 				wpa_scan_results_free(scan_res);
@@ -1079,10 +1081,6 @@
 	if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
 		wpa_supplicant_start_autoscan(wpa_s);
 
-	if (state == WPA_COMPLETED || state == WPA_INTERFACE_DISABLED ||
-	    state == WPA_INACTIVE)
-		wnm_btm_reset(wpa_s);
-
 #ifndef CONFIG_NO_WMM_AC
 	if (old_state >= WPA_ASSOCIATED && wpa_s->wpa_state < WPA_ASSOCIATED)
 		wmm_ac_notify_disassoc(wpa_s);
@@ -2524,7 +2522,6 @@
 #endif /* CONFIG_NO_WMM_AC */
 #ifdef CONFIG_WNM
 	wpa_s->wnm_mode = 0;
-	wpa_s->wnm_target_bss = NULL;
 #endif /* CONFIG_WNM */
 	wpa_s->reassoc_same_bss = 0;
 	wpa_s->reassoc_same_ess = 0;
@@ -2922,8 +2919,7 @@
 	if (obss_scan) {
 		struct wpa_scan_results *scan_res;
 
-		scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0,
-							   NULL);
+		scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
 		if (scan_res == NULL) {
 			/* Back to HT20 */
 			freq->sec_channel_offset = 0;
@@ -3087,7 +3083,7 @@
 				    freq->sec_channel_offset,
 				    chwidth, seg0, seg1, vht_caps,
 				    &mode->he_capab[ieee80211_mode],
-				    &mode->eht_capab[ieee80211_mode], 0) != 0)
+				    &mode->eht_capab[ieee80211_mode]) != 0)
 		return false;
 
 	*freq = vht_freq;
@@ -3835,14 +3831,10 @@
 
 	if (ssid->multi_ap_backhaul_sta) {
 		size_t multi_ap_ie_len;
-		struct multi_ap_params multi_ap = { 0 };
-
-		multi_ap.capability = MULTI_AP_BACKHAUL_STA;
-		multi_ap.profile = ssid->multi_ap_profile;
 
 		multi_ap_ie_len = add_multi_ap_ie(wpa_ie + wpa_ie_len,
 						  max_wpa_ie_len - wpa_ie_len,
-						  &multi_ap);
+						  MULTI_AP_BACKHAUL_STA);
 		if (multi_ap_ie_len == 0) {
 			wpa_printf(MSG_ERROR,
 				   "Multi-AP: Failed to build Multi-AP IE");
@@ -9181,7 +9173,8 @@
 		if (modes[i].mode != mode ||
 		    !modes[i].num_channels || !modes[i].channels)
 			continue;
-		if (is_6ghz == modes[i].is_6ghz)
+		if ((!is_6ghz && !is_6ghz_freq(modes[i].channels[0].freq)) ||
+		    (is_6ghz && is_6ghz_freq(modes[i].channels[0].freq)))
 			return &modes[i];
 	}
 
@@ -9420,21 +9413,17 @@
 
 
 struct wpa_scan_results *
-wpa_drv_get_scan_results(struct wpa_supplicant *wpa_s, const u8 *bssid)
+wpa_drv_get_scan_results2(struct wpa_supplicant *wpa_s)
 {
 	struct wpa_scan_results *scan_res;
 #ifdef CONFIG_TESTING_OPTIONS
 	size_t idx;
 #endif /* CONFIG_TESTING_OPTIONS */
 
-	if (wpa_s->driver->get_scan_results)
-		scan_res = wpa_s->driver->get_scan_results(wpa_s->drv_priv,
-							   bssid);
-	else if (wpa_s->driver->get_scan_results2)
-		scan_res = wpa_s->driver->get_scan_results2(wpa_s->drv_priv);
-	else
+	if (!wpa_s->driver->get_scan_results2)
 		return NULL;
 
+	scan_res = wpa_s->driver->get_scan_results2(wpa_s->drv_priv);
 
 #ifdef CONFIG_TESTING_OPTIONS
 	for (idx = 0; scan_res && idx < scan_res->num; idx++) {
@@ -9472,7 +9461,10 @@
 	if (!wpa_s->valid_links)
 		return false;
 
-	for_each_link(wpa_s->valid_links, i) {
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+		if (!(wpa_s->valid_links & BIT(i)))
+			continue;
+
 		if (ether_addr_equal(wpa_s->links[i].bssid, addr))
 			return true;
 	}
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 89c5d03..d689441 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -1717,12 +1717,6 @@
 # support Multi-AP, and sets 4-address mode if it does. Thus, the netdev can be
 # added to a bridge to allow forwarding frames over this backhaul link.
 
-# Multi-AP Profile
-# Indicate the supported Multi-AP profile
-# 1 = Supports Multi-AP profile 1 as defined in Wi-Fi EasyMesh specification
-# 2 = Supports Multi-AP profile 2 as defined in Wi-Fi EasyMesh specification
-#multi_ap_profile=2
-
 ##### Fast Session Transfer (FST) support #####################################
 #
 # The options in this section are only available when the build configuration
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 0fea5cc..3a5f61c 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1327,14 +1327,14 @@
 	u8 wnm_num_neighbor_report;
 	u8 wnm_mode;
 	bool wnm_link_removal;
-	u8 wnm_dissoc_addr[ETH_ALEN];
 	u16 wnm_dissoc_timer;
 	u8 wnm_bss_termination_duration[12];
 	struct neighbor_report *wnm_neighbor_report_elements;
 	struct os_reltime wnm_cand_valid_until;
-	struct wpa_bss *wnm_target_bss;
+	u8 wnm_cand_from_bss[ETH_ALEN];
 	enum bss_trans_mgmt_status_code bss_tm_status;
 	bool bss_trans_mgmt_in_progress;
+	struct wpabuf *coloc_intf_elems;
 	u8 coloc_intf_dialog_token;
 	u8 coloc_intf_auto_report;
 	u8 coloc_intf_timeout;
@@ -1500,9 +1500,6 @@
 	int dpp_netrole;
 	int dpp_auth_ok_on_ack;
 	int dpp_in_response_listen;
-	bool dpp_tx_auth_resp_on_roc_stop;
-	bool dpp_tx_chan_change;
-	bool dpp_listen_on_tx_expire;
 	int dpp_gas_client;
 	int dpp_gas_server;
 	int dpp_gas_dialog_token;
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 2fea640..111680c 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -465,7 +465,7 @@
 
 	/* No WPA/RSN IE found in the cached scan results. Try to get updated
 	 * scan results from the driver. */
-	if (wpa_supplicant_update_scan_results(wpa_s, wpa_s->bssid) < 0)
+	if (wpa_supplicant_update_scan_results(wpa_s) < 0)
 		return -1;
 
 	return wpa_get_beacon_ie(wpa_s);
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index f103237..81e11e7 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -1208,19 +1208,14 @@
 		}
 	}
 #endif /* CONFIG_P2P */
-	if (multi_ap_backhaul_sta)
-		os_snprintf(phase1, sizeof(phase1), "pbc=1 multi_ap=%d",
-			    multi_ap_backhaul_sta);
-	else
-		os_snprintf(phase1, sizeof(phase1), "pbc=1");
+	os_snprintf(phase1, sizeof(phase1), "pbc=1%s",
+		    multi_ap_backhaul_sta ? " multi_ap=1" : "");
 	if (wpa_config_set_quoted(ssid, "phase1", phase1) < 0)
 		return -1;
 	if (wpa_s->wps_fragment_size)
 		ssid->eap.fragment_size = wpa_s->wps_fragment_size;
-	if (multi_ap_backhaul_sta) {
+	if (multi_ap_backhaul_sta)
 		ssid->multi_ap_backhaul_sta = 1;
-		ssid->multi_ap_profile = multi_ap_backhaul_sta;
-	}
 	wpa_s->supp_pbc_active = true;
 	wpa_s->wps_overlap = false;
 	wpa_supplicant_wps_event(wpa_s, WPS_EV_PBC_ACTIVE, NULL);