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

Change-Id: I6c9b7a4323fa7edde47617da6c1e0d8f6e6d5101
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 9aa61fa..445d963 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -163,8 +163,6 @@
 	/* Default to strict CRL checking. */
 	bss->check_crl_strict = 1;
 
-	bss->multi_ap_profile = MULTI_AP_PROFILE_2;
-
 #ifdef CONFIG_TESTING_OPTIONS
 	bss->sae_commit_status = -1;
 	bss->test_assoc_comeback_type = -1;
@@ -559,10 +557,6 @@
 
 	for (i = 0; i < num_servers; i++) {
 		os_free(servers[i].shared_secret);
-		os_free(servers[i].ca_cert);
-		os_free(servers[i].client_cert);
-		os_free(servers[i].private_key);
-		os_free(servers[i].private_key_passwd);
 	}
 	os_free(servers);
 }
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 4f2164d..69db16d 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -800,14 +800,6 @@
 #define BACKHAUL_BSS 1
 #define FRONTHAUL_BSS 2
 	int multi_ap; /* bitmap of BACKHAUL_BSS, FRONTHAUL_BSS */
-	int multi_ap_profile;
-	/* Multi-AP Profile-1 clients not allowed to connect */
-#define PROFILE1_CLIENT_ASSOC_DISALLOW BIT(0)
-	/* Multi-AP Profile-2 clients not allowed to connect */
-#define PROFILE2_CLIENT_ASSOC_DISALLOW BIT(1)
-	unsigned int multi_ap_client_disallow;
-	/* Primary VLAN ID to use in Multi-AP */
-	int multi_ap_vlanid;
 
 #ifdef CONFIG_AIRTIME_POLICY
 	unsigned int airtime_weight;
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index 11fe39c..60d66e4 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -265,8 +265,8 @@
 }
 
 
-bool hostapd_sta_is_link_sta(struct hostapd_data *hapd,
-			     struct sta_info *sta)
+static bool hostapd_sta_is_link_sta(struct hostapd_data *hapd,
+				    struct sta_info *sta)
 {
 #ifdef CONFIG_IEEE80211BE
 	if (ap_sta_is_mld(hapd, sta) &&
@@ -572,33 +572,12 @@
 }
 
 
-#ifdef CONFIG_IEEE80211BE
-int hostapd_if_link_remove(struct hostapd_data *hapd,
-			   enum wpa_driver_if_type type,
-			   const char *ifname, u8 link_id)
-{
-	if (!hapd->driver || !hapd->drv_priv || !hapd->driver->link_remove)
-		return -1;
-
-	return hapd->driver->link_remove(hapd->drv_priv, type, ifname,
-					 hapd->mld_link_id);
-}
-#endif /* CONFIG_IEEE80211BE */
-
-
 int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
 		      const char *ifname)
 {
 	if (hapd->driver == NULL || hapd->drv_priv == NULL ||
 	    hapd->driver->if_remove == NULL)
 		return -1;
-
-#ifdef CONFIG_IEEE80211BE
-	if (hapd->conf->mld_ap)
-		return hostapd_if_link_remove(hapd, type, ifname,
-					      hapd->mld_link_id);
-#endif /* CONFIG_IEEE80211BE */
-
 	return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
 }
 
@@ -650,7 +629,7 @@
 				    &cmode->he_capab[IEEE80211_MODE_AP] : NULL,
 				    cmode ?
 				    &cmode->eht_capab[IEEE80211_MODE_AP] :
-				    NULL, hostapd_get_punct_bitmap(hapd)))
+				    NULL))
 		return -1;
 
 	if (hapd->driver == NULL)
@@ -779,8 +758,6 @@
 struct wpa_scan_results * hostapd_driver_get_scan_results(
 	struct hostapd_data *hapd)
 {
-	if (hapd->driver && hapd->driver->get_scan_results)
-		return hapd->driver->get_scan_results(hapd->drv_priv, NULL);
 	if (hapd->driver && hapd->driver->get_scan_results2)
 		return hapd->driver->get_scan_results2(hapd->drv_priv);
 	return NULL;
@@ -863,7 +840,7 @@
 
 		link_id = hapd->mld_link_id;
 		if (ap_sta_is_mld(hapd, sta))
-			own_addr = hapd->mld->mld_addr;
+			own_addr = hapd->mld_addr;
 	}
 #endif /* CONFIG_IEEE80211BE */
 
@@ -884,7 +861,7 @@
 		struct sta_info *sta = ap_get_sta(hapd, addr);
 
 		if (ap_sta_is_mld(hapd, sta))
-			own_addr = hapd->mld->mld_addr;
+			own_addr = hapd->mld_addr;
 	}
 #endif /* CONFIG_IEEE80211BE */
 
@@ -942,7 +919,7 @@
 		sta = ap_get_sta(hapd, dst);
 
 		if (ap_sta_is_mld(hapd, sta)) {
-			own_addr = hapd->mld->mld_addr;
+			own_addr = hapd->mld_addr;
 			bssid = own_addr;
 		}
 #endif /* CONFIG_IEEE80211BE */
@@ -1000,8 +977,7 @@
 				    center_segment1,
 				    cmode->vht_capab,
 				    &cmode->he_capab[IEEE80211_MODE_AP],
-				    &cmode->eht_capab[IEEE80211_MODE_AP],
-				    hostapd_get_punct_bitmap(hapd))) {
+				    &cmode->eht_capab[IEEE80211_MODE_AP])) {
 		wpa_printf(MSG_ERROR, "Can't set freq params");
 		return -1;
 	}
@@ -1023,8 +999,7 @@
 int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
 			    const u8 *qos_map_set, u8 qos_map_set_len)
 {
-	if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv ||
-	    !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_QOS_MAPPING))
+	if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv)
 		return 0;
 	return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
 					 qos_map_set_len);
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index d7e79c8..331b0ea 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -26,8 +26,6 @@
 			       struct wpabuf *assocresp);
 int hostapd_reset_ap_wps_ie(struct hostapd_data *hapd);
 int hostapd_set_ap_wps_ie(struct hostapd_data *hapd);
-bool hostapd_sta_is_link_sta(struct hostapd_data *hapd,
-			     struct sta_info *sta);
 int hostapd_set_authorized(struct hostapd_data *hapd,
 			   struct sta_info *sta, int authorized);
 int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta);
@@ -61,9 +59,6 @@
 		   const char *bridge, int use_existing);
 int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
 		      const char *ifname);
-int hostapd_if_link_remove(struct hostapd_data *hapd,
-			   enum wpa_driver_if_type type,
-			   const char *ifname, u8 link_id);
 int hostapd_set_ieee8021x(struct hostapd_data *hapd,
 			  struct wpa_bss_params *params);
 int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
@@ -393,15 +388,9 @@
 
 static inline int hostapd_drv_stop_ap(struct hostapd_data *hapd)
 {
-	int link_id = -1;
-
 	if (!hapd->driver || !hapd->driver->stop_ap || !hapd->drv_priv)
 		return 0;
-#ifdef CONFIG_IEEE80211BE
-	if (hapd->conf->mld_ap)
-		link_id = hapd->mld_link_id;
-#endif /* CONFIG_IEEE80211BE */
-	return hapd->driver->stop_ap(hapd->drv_priv, link_id);
+	return hapd->driver->stop_ap(hapd->drv_priv);
 }
 
 static inline int hostapd_drv_channel_info(struct hostapd_data *hapd,
@@ -454,28 +443,15 @@
 #endif /* CONFIG_TESTING_OPTIONS */
 
 #ifdef CONFIG_IEEE80211BE
-
 static inline int hostapd_drv_link_add(struct hostapd_data *hapd,
 				       u8 link_id, const u8 *addr)
 {
 	if (!hapd->driver || !hapd->drv_priv || !hapd->driver->link_add)
 		return -1;
 
-	return hapd->driver->link_add(hapd->drv_priv, link_id, addr, hapd);
+	return hapd->driver->link_add(hapd->drv_priv, link_id, addr);
 
 }
-
-static inline int hostapd_drv_link_sta_remove(struct hostapd_data *hapd,
-					      const u8 *addr)
-{
-	if (!hapd->conf->mld_ap || !hapd->driver || !hapd->drv_priv ||
-	    !hapd->driver->link_sta_remove)
-		return -1;
-
-	return hapd->driver->link_sta_remove(hapd->drv_priv, hapd->mld_link_id,
-					     addr);
-}
-
 #endif /* CONFIG_IEEE80211BE */
 
 #endif /* AP_DRV_OPS */
diff --git a/src/ap/authsrv.c b/src/ap/authsrv.c
index 6ed4d06..1488dcc 100644
--- a/src/ap/authsrv.c
+++ b/src/ap/authsrv.c
@@ -107,20 +107,13 @@
 	struct radius_server_conf srv;
 	struct hostapd_bss_config *conf = hapd->conf;
 
-#ifdef CONFIG_IEEE80211BE
-	if (!hostapd_mld_is_first_bss(hapd)) {
-		struct hostapd_data *first;
-
+	if (hapd->mld_first_bss) {
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Using RADIUS server of the first BSS");
 
-		first = hostapd_mld_get_first_bss(hapd);
-		if (!first)
-			return -1;
-		hapd->radius_srv = first->radius_srv;
+		hapd->radius_srv = hapd->mld_first_bss->radius_srv;
 		return 0;
 	}
-#endif /* CONFIG_IEEE80211BE */
 
 	os_memset(&srv, 0, sizeof(srv));
 	srv.client_file = conf->radius_server_clients;
@@ -256,25 +249,18 @@
 
 int authsrv_init(struct hostapd_data *hapd)
 {
-#ifdef CONFIG_IEEE80211BE
-	if (!hostapd_mld_is_first_bss(hapd)) {
-		struct hostapd_data *first;
-
+	if (hapd->mld_first_bss) {
 		wpa_printf(MSG_DEBUG, "MLD: Using auth_serv of the first BSS");
 
-		first = hostapd_mld_get_first_bss(hapd);
-		if (!first)
-			return -1;
 #ifdef EAP_TLS_FUNCS
-		hapd->ssl_ctx = first->ssl_ctx;
+		hapd->ssl_ctx = hapd->mld_first_bss->ssl_ctx;
 #endif /* EAP_TLS_FUNCS */
-		hapd->eap_cfg = first->eap_cfg;
+		hapd->eap_cfg = hapd->mld_first_bss->eap_cfg;
 #ifdef EAP_SIM_DB
-		hapd->eap_sim_db_priv = first->eap_sim_db_priv;
+		hapd->eap_sim_db_priv = hapd->mld_first_bss->eap_sim_db_priv;
 #endif /* EAP_SIM_DB */
 		return 0;
 	}
-#endif /* CONFIG_IEEE80211BE */
 
 #ifdef EAP_TLS_FUNCS
 	if (hapd->conf->eap_server &&
@@ -390,8 +376,7 @@
 
 void authsrv_deinit(struct hostapd_data *hapd)
 {
-#ifdef CONFIG_IEEE80211BE
-	if (!hostapd_mld_is_first_bss(hapd)) {
+	if (hapd->mld_first_bss) {
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Deinit auth_serv of a non-first BSS");
 
@@ -405,7 +390,6 @@
 #endif /* EAP_TLS_FUNCS */
 		return;
 	}
-#endif /* CONFIG_IEEE80211BE */
 
 #ifdef RADIUS_SERVER
 	radius_server_deinit(hapd->radius_srv);
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 32865f6..e50f0a0 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -960,7 +960,7 @@
 	 * We want to include the AP MLD ID in the response if it was
 	 * included in the request.
 	 */
-	probed_mld_id = mld_id != -1 ? mld_id : hostapd_get_mld_id(hapd);
+	probed_mld_id = mld_id != -1 ? mld_id : hapd->conf->mld_id;
 
 	for_each_mld_link(link, i, j, hapd->iface->interfaces,
 			  probed_mld_id) {
@@ -2616,8 +2616,7 @@
 				    hostapd_get_oper_centr_freq_seg1_idx(iconf),
 				    cmode->vht_capab,
 				    &cmode->he_capab[IEEE80211_MODE_AP],
-				    &cmode->eht_capab[IEEE80211_MODE_AP],
-				    hostapd_get_punct_bitmap(hapd)) == 0)
+				    &cmode->eht_capab[IEEE80211_MODE_AP]) == 0)
 		params.freq = &freq;
 
 	for (i = 0; i < hapd->iface->num_hw_features; i++) {
@@ -2676,7 +2675,8 @@
 			continue;
 
 #ifdef CONFIG_IEEE80211BE
-		if (hostapd_is_ml_partner(hapd, other->bss[0]))
+		if (hapd->conf->mld_ap && other->bss[0]->conf->mld_ap &&
+		    hapd->conf->mld_id == other->bss[0]->conf->mld_id)
 			mld_ap = true;
 #endif /* CONFIG_IEEE80211BE */
 
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index eac0606..5378671 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -348,15 +348,11 @@
 
 	if (sta->supp_op_classes &&
 	    buflen - len > (unsigned) (17 + 2 * sta->supp_op_classes[0])) {
-		res = os_snprintf(buf + len, buflen - len, "supp_op_classes=");
-		if (!os_snprintf_error(buflen - len, res))
-			len += res;
+		len += os_snprintf(buf + len, buflen - len, "supp_op_classes=");
 		len += wpa_snprintf_hex(buf + len, buflen - len,
 					sta->supp_op_classes + 1,
 					sta->supp_op_classes[0]);
-		res = os_snprintf(buf + len, buflen - len, "\n");
-		if (!os_snprintf_error(buflen - len, res))
-			len += res;
+		len += os_snprintf(buf + len, buflen - len, "\n");
 	}
 
 	if (sta->power_capab) {
@@ -368,34 +364,6 @@
 			len += ret;
 	}
 
-#ifdef CONFIG_IEEE80211AX
-	if ((sta->flags & WLAN_STA_HE) && sta->he_capab) {
-		res = os_snprintf(buf + len, buflen - len, "he_capab=");
-		if (!os_snprintf_error(buflen - len, res))
-			len += res;
-		len += wpa_snprintf_hex(buf + len, buflen - len,
-					(const u8 *) sta->he_capab,
-					sta->he_capab_len);
-		res = os_snprintf(buf + len, buflen - len, "\n");
-		if (!os_snprintf_error(buflen - len, res))
-			len += res;
-	}
-#endif /* CONFIG_IEEE80211AX */
-
-#ifdef CONFIG_IEEE80211BE
-	if ((sta->flags & WLAN_STA_EHT) && sta->eht_capab) {
-		res = os_snprintf(buf + len, buflen - len, "eht_capab=");
-		if (!os_snprintf_error(buflen - len, res))
-			len += res;
-		len += wpa_snprintf_hex(buf + len, buflen - len,
-					(const u8 *) sta->eht_capab,
-					sta->eht_capab_len);
-		res = os_snprintf(buf + len, buflen - len, "\n");
-		if (!os_snprintf_error(buflen - len, res))
-			len += res;
-	}
-#endif /* CONFIG_IEEE80211BE */
-
 #ifdef CONFIG_IEEE80211AC
 	if ((sta->flags & WLAN_STA_VHT) && sta->vht_capabilities) {
 		res = os_snprintf(buf + len, buflen - len,
@@ -404,16 +372,6 @@
 					       vht_capabilities_info));
 		if (!os_snprintf_error(buflen - len, res))
 			len += res;
-
-		res = os_snprintf(buf + len, buflen - len, "vht_capab=");
-		if (!os_snprintf_error(buflen - len, res))
-			len += res;
-		len += wpa_snprintf_hex(buf + len, buflen - len,
-					(const u8 *) sta->vht_capabilities,
-					sizeof(*sta->vht_capabilities));
-		res = os_snprintf(buf + len, buflen - len, "\n");
-		if (!os_snprintf_error(buflen - len, res))
-			len += res;
 	}
 #endif /* CONFIG_IEEE80211AC */
 
@@ -428,15 +386,11 @@
 
 	if (sta->ext_capability &&
 	    buflen - len > (unsigned) (11 + 2 * sta->ext_capability[0])) {
-		res = os_snprintf(buf + len, buflen - len, "ext_capab=");
-		if (!os_snprintf_error(buflen - len, res))
-			len += res;
+		len += os_snprintf(buf + len, buflen - len, "ext_capab=");
 		len += wpa_snprintf_hex(buf + len, buflen - len,
 					sta->ext_capability + 1,
 					sta->ext_capability[0]);
-		res = os_snprintf(buf + len, buflen - len, "\n");
-		if (!os_snprintf_error(buflen - len, res))
-			len += res;
+		len += os_snprintf(buf + len, buflen - len, "\n");
 	}
 
 	if (sta->flags & WLAN_STA_WDS && sta->ifname_wds) {
@@ -465,21 +419,6 @@
 			len += ret;
 	}
 
-#ifdef CONFIG_IEEE80211BE
-	if (sta->mld_info.mld_sta) {
-		for (i = 0; i < MAX_NUM_MLD_LINKS; ++i) {
-			if (!sta->mld_info.links[i].valid)
-				continue;
-			ret = os_snprintf(
-				buf + len, buflen - len,
-				"peer_addr[%d]=" MACSTR "\n",
-				i, MAC2STR(sta->mld_info.links[i].peer_addr));
-			if (!os_snprintf_error(buflen - len, ret))
-				len += ret;
-		}
-	}
-#endif /* CONFIG_IEEE80211BE */
-
 	return len;
 }
 
@@ -1027,8 +966,8 @@
 					  "mld_addr[%d]=" MACSTR "\n"
 					  "mld_id[%d]=%d\n"
 					  "mld_link_id[%d]=%d\n",
-					  (int) i, MAC2STR(bss->mld->mld_addr),
-					  (int) i, hostapd_get_mld_id(bss),
+					  (int) i, MAC2STR(bss->mld_addr),
+					  (int) i, bss->conf->mld_id,
 					  (int) i, bss->mld_link_id);
 			if (os_snprintf_error(buflen - len, ret))
 				return len;
diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index af9dc16..5e4c810 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -14,7 +14,6 @@
 #include "common/hw_features_common.h"
 #include "common/wpa_ctrl.h"
 #include "hostapd.h"
-#include "beacon.h"
 #include "ap_drv_ops.h"
 #include "drivers/driver.h"
 #include "dfs.h"
@@ -973,7 +972,6 @@
 	struct csa_settings csa_settings;
 	u8 new_vht_oper_chwidth;
 	unsigned int i;
-	unsigned int num_err = 0;
 
 	wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d", channel);
 	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
@@ -1011,8 +1009,7 @@
 				      oper_centr_freq_seg1_idx,
 				      cmode->vht_capab,
 				      &cmode->he_capab[ieee80211_mode],
-				      &cmode->eht_capab[ieee80211_mode],
-				      hostapd_get_punct_bitmap(iface->bss[0]));
+				      &cmode->eht_capab[ieee80211_mode]);
 
 	if (err) {
 		wpa_printf(MSG_ERROR,
@@ -1024,10 +1021,10 @@
 	for (i = 0; i < iface->num_bss; i++) {
 		err = hostapd_switch_channel(iface->bss[i], &csa_settings);
 		if (err)
-			num_err++;
+			break;
 	}
 
-	if (num_err == iface->num_bss) {
+	if (err) {
 		wpa_printf(MSG_WARNING,
 			   "DFS failed to schedule CSA (%d) - trying fallback",
 			   err);
@@ -1144,23 +1141,14 @@
 			     int cf1, int cf2)
 {
 	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_COMPLETED
-		"success=%d freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d radar_detected=%d",
-		success, freq, ht_enabled, chan_offset, chan_width, cf1, cf2,
-		iface->radar_detected);
+		"success=%d freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
+		success, freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
 
 	if (success) {
 		/* Complete iface/ap configuration */
 		if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
-			/* Complete AP configuration for the first bring up. If
-			 * a radar was detected in this channel, interface setup
-			 * will be handled in
-			 * 1. hostapd_event_ch_switch() if switching to a
-			 *    non-DFS channel
-			 * 2. on next CAC complete event if switching to another
-			 *    DFS channel.
-			 */
-			if (iface->state != HAPD_IFACE_ENABLED &&
-			    !iface->radar_detected)
+			/* Complete AP configuration for the first bring up. */
+			if (iface->state != HAPD_IFACE_ENABLED)
 				hostapd_setup_interface_complete(iface, 0);
 			else
 				iface->cac_started = 0;
@@ -1205,7 +1193,6 @@
 		hostapd_dfs_update_background_chain(iface);
 	}
 
-	iface->radar_detected = false;
 	return 0;
 }
 
@@ -1449,8 +1436,6 @@
 		"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
 		freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
 
-	iface->radar_detected = true;
-
 	/* Proceed only if DFS is not offloaded to the driver */
 	if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
 		return 0;
@@ -1544,17 +1529,9 @@
 		iface->radar_background.cac_started = 1;
 	} else {
 		/* This is called when the driver indicates that an offloaded
-		 * DFS has started CAC. radar_detected might be set for previous
-		 * DFS channel. Clear it for this new CAC process. */
+		 * DFS has started CAC. */
 		hostapd_set_state(iface, HAPD_IFACE_DFS);
 		iface->cac_started = 1;
-
-		/* Clear radar_detected in case it is for the previous
-		 * frequency. Also remove disabled link's information in RNR
-		 * element from other links. */
-		iface->radar_detected = false;
-		if (iface->interfaces && iface->interfaces->count > 1)
-			ieee802_11_set_beacons(iface);
 	}
 	/* TODO: How to check CAC time for ETSI weather channels? */
 	iface->dfs_cac_ms = 60000;
diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c
index d1bffa8..3f89bc2 100644
--- a/src/ap/dpp_hostapd.c
+++ b/src/ap/dpp_hostapd.c
@@ -3941,7 +3941,6 @@
 	eloop_register_timeout(100, 0, hostapd_dpp_push_button_expire,
 			       hapd, NULL);
 
-	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_STATUS "started");
 	return 0;
 }
 
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index b0fcd1c..533cc54 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -517,7 +517,7 @@
 		if (ap_sta_is_mld(hapd, sta)) {
 			wpa_printf(MSG_DEBUG,
 				   "MLD: Set ML info in RSN Authenticator");
-			wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld->mld_addr,
+			wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld_addr,
 					     sta->mld_assoc_link_id,
 					     &sta->mld_info);
 		}
@@ -910,54 +910,6 @@
 }
 
 
-static void hostapd_remove_sta(struct hostapd_data *hapd, struct sta_info *sta)
-{
-	ap_sta_set_authorized(hapd, sta, 0);
-	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
-	hostapd_set_sta_flags(hapd, sta);
-	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
-	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
-	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
-	ap_free_sta(hapd, sta);
-}
-
-
-#ifdef CONFIG_IEEE80211BE
-static void hostapd_notif_disassoc_mld(struct hostapd_data *assoc_hapd,
-				       struct sta_info *sta,
-				       const u8 *addr)
-{
-	unsigned int link_id, i;
-	struct hostapd_data *tmp_hapd;
-	struct hapd_interfaces *interfaces = assoc_hapd->iface->interfaces;
-
-	/* Remove STA entry in non-assoc links */
-	for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
-		if (!sta->mld_info.links[link_id].valid)
-			continue;
-
-		for (i = 0; i < interfaces->count; i++) {
-			struct sta_info *tmp_sta;
-
-			tmp_hapd = interfaces->iface[i]->bss[0];
-
-			if (!tmp_hapd->conf->mld_ap ||
-			    assoc_hapd == tmp_hapd ||
-			    assoc_hapd->conf->mld_id != tmp_hapd->conf->mld_id)
-				continue;
-
-			tmp_sta = ap_get_sta(tmp_hapd, addr);
-			if (tmp_sta)
-				ap_free_sta(tmp_hapd, tmp_sta);
-		}
-	}
-
-	/* Remove STA in assoc link */
-	hostapd_remove_sta(assoc_hapd, sta);
-}
-#endif /* CONFIG_IEEE80211BE */
-
-
 void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
 {
 	struct sta_info *sta;
@@ -979,50 +931,6 @@
 		       HOSTAPD_LEVEL_INFO, "disassociated");
 
 	sta = ap_get_sta(hapd, addr);
-#ifdef CONFIG_IEEE80211BE
-	if (hostapd_is_mld_ap(hapd)) {
-		struct hostapd_data *assoc_hapd;
-		unsigned int i;
-
-		if (!sta) {
-			/* Find non-MLO cases from any of the affiliated AP
-			 * links. */
-			for (i = 0; i < hapd->iface->interfaces->count; ++i) {
-				struct hostapd_iface *h =
-					hapd->iface->interfaces->iface[i];
-				struct hostapd_data *h_hapd = h->bss[0];
-				struct hostapd_bss_config *hconf = h_hapd->conf;
-
-				if (!hconf->mld_ap ||
-				    hconf->mld_id != hapd->conf->mld_id)
-					continue;
-
-				sta = ap_get_sta(h_hapd, addr);
-				if (sta) {
-					if (!sta->mld_info.mld_sta) {
-						hapd = h_hapd;
-						goto legacy;
-					}
-					break;
-				}
-			}
-		} else if (!sta->mld_info.mld_sta) {
-			goto legacy;
-		}
-		if (!sta) {
-			wpa_printf(MSG_DEBUG,
-			   "Disassociation notification for unknown STA "
-			   MACSTR, MAC2STR(addr));
-			return;
-		}
-		sta = hostapd_ml_get_assoc_sta(hapd, sta, &assoc_hapd);
-		if (sta)
-			hostapd_notif_disassoc_mld(assoc_hapd, sta, addr);
-		return;
-	}
-
-legacy:
-#endif /* CONFIG_IEEE80211BE */
 	if (sta == NULL) {
 		wpa_printf(MSG_DEBUG,
 			   "Disassociation notification for unknown STA "
@@ -1030,7 +938,13 @@
 		return;
 	}
 
-	hostapd_remove_sta(hapd, sta);
+	ap_sta_set_authorized(hapd, sta, 0);
+	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
+	hostapd_set_sta_flags(hapd, sta);
+	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
+	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
+	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
+	ap_free_sta(hapd, sta);
 }
 
 
@@ -1749,34 +1663,6 @@
 }
 
 
-static struct hostapd_data *
-switch_link_scan(struct hostapd_data *hapd, u64 scan_cookie)
-{
-#ifdef CONFIG_IEEE80211BE
-	if (hapd->conf->mld_ap && scan_cookie != 0) {
-		unsigned int i;
-
-		for (i = 0; i < hapd->iface->interfaces->count; i++) {
-			struct hostapd_iface *h;
-			struct hostapd_data *h_hapd;
-
-			h = hapd->iface->interfaces->iface[i];
-			h_hapd = h->bss[0];
-			if (!hostapd_is_ml_partner(hapd, h_hapd))
-				continue;
-
-			if (h_hapd->scan_cookie == scan_cookie) {
-				h_hapd->scan_cookie = 0;
-				return h_hapd;
-			}
-		}
-	}
-#endif /* CONFIG_IEEE80211BE */
-
-	return hapd;
-}
-
-
 #define HAPD_BROADCAST ((struct hostapd_data *) -1)
 
 static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
@@ -1845,7 +1731,7 @@
 
 #ifdef CONFIG_IEEE80211BE
 	if (hapd->conf->mld_ap &&
-	    ether_addr_equal(hapd->mld->mld_addr, bssid))
+	    ether_addr_equal(hapd->mld_addr, bssid))
 		is_mld = true;
 #endif /* CONFIG_IEEE80211BE */
 
@@ -1917,8 +1803,7 @@
 		hapd = tmp_hapd;
 #ifdef CONFIG_IEEE80211BE
 	} else if (hapd->conf->mld_ap &&
-		   ether_addr_equal(hapd->mld->mld_addr,
-				    get_hdr_bssid(hdr, len))) {
+		   ether_addr_equal(hapd->mld_addr, get_hdr_bssid(hdr, len))) {
 		/* AP MLD address match - use hapd pointer as-is */
 #endif /* CONFIG_IEEE80211BE */
 	} else {
@@ -1993,8 +1878,10 @@
 		struct hostapd_iface *h =
 			hapd->iface->interfaces->iface[i];
 		struct hostapd_data *h_hapd = h->bss[0];
+		struct hostapd_bss_config *hconf = h_hapd->conf;
 
-		if (!hostapd_is_ml_partner(h_hapd, hapd))
+		if (!hconf->mld_ap ||
+		    hconf->mld_id != hapd->conf->mld_id)
 			continue;
 
 		h_hapd = hostapd_find_by_sta(h, src, false);
@@ -2405,29 +2292,8 @@
 		michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
 		break;
 	case EVENT_SCAN_RESULTS:
-#ifdef NEED_AP_MLME
-		if (data)
-			hapd = switch_link_scan(hapd,
-						data->scan_info.scan_cookie);
-#endif /* NEED_AP_MLME */
 		if (hapd->iface->scan_cb)
 			hapd->iface->scan_cb(hapd->iface);
-#ifdef CONFIG_IEEE80211BE
-		if (!hapd->iface->scan_cb && hapd->conf->mld_ap) {
-			/* Other links may be waiting for HT scan result */
-			unsigned int i;
-
-			for (i = 0; i < hapd->iface->interfaces->count; i++) {
-				struct hostapd_iface *h =
-					hapd->iface->interfaces->iface[i];
-				struct hostapd_data *h_hapd = h->bss[0];
-
-				if (hostapd_is_ml_partner(hapd, h_hapd) &&
-				    h_hapd->iface->scan_cb)
-					h_hapd->iface->scan_cb(h_hapd->iface);
-			}
-		}
-#endif /* CONFIG_IEEE80211BE */
 		break;
 	case EVENT_WPS_BUTTON_PUSHED:
 		hostapd_wps_button_pushed(hapd, NULL);
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 56bac45..ddbcabc 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -184,8 +184,6 @@
 		hostapd_set_generic_elem(hapd, (u8 *) "", 0);
 	}
 
-	hostapd_neighbor_sync_own_report(hapd);
-
 	ieee802_11_set_beacon(hapd);
 	hostapd_update_wps(hapd);
 
@@ -397,6 +395,25 @@
 #endif /* CONFIG_WEP */
 
 
+static void hostapd_clear_drv_priv(struct hostapd_data *hapd)
+{
+	unsigned int i;
+
+	for (i = 0; i < hapd->iface->interfaces->count; i++) {
+		struct hostapd_iface *iface = hapd->iface->interfaces->iface[i];
+
+		if (hapd->iface == iface || !iface)
+			continue;
+
+		if (iface->bss && iface->bss[0] &&
+		    iface->bss[0]->mld_first_bss == hapd)
+			iface->bss[0]->drv_priv = NULL;
+	}
+
+	hapd->drv_priv = NULL;
+}
+
+
 #ifdef CONFIG_IEEE80211BE
 #ifdef CONFIG_TESTING_OPTIONS
 
@@ -418,7 +435,6 @@
 	ieee802_11_set_beacon(hapd);
 
 	if (!hapd->eht_mld_link_removal_count) {
-		hostapd_free_link_stas(hapd);
 		hostapd_disable_iface(hapd->iface);
 		return;
 	}
@@ -480,8 +496,7 @@
 	vlan_deinit(hapd);
 	hostapd_acl_deinit(hapd);
 #ifndef CONFIG_NO_RADIUS
-	if (hostapd_mld_is_first_bss(hapd)) {
-#ifdef CONFIG_IEEE80211BE
+	if (!hapd->mld_first_bss) {
 		struct hapd_interfaces *ifaces = hapd->iface->interfaces;
 		size_t i;
 
@@ -500,7 +515,6 @@
 					h->radius_das = NULL;
 			}
 		}
-#endif /* CONFIG_IEEE80211BE */
 		radius_client_deinit(hapd->radius);
 		radius_das_deinit(hapd->radius_das);
 	}
@@ -534,20 +548,10 @@
 			 * driver wrapper may have removed its internal instance
 			 * and hapd->drv_priv is not valid anymore.
 			 */
-			hapd->drv_priv = NULL;
+			hostapd_clear_drv_priv(hapd);
 		}
 	}
 
-#ifdef CONFIG_IEEE80211BE
-	/* If the interface was not added as well as it is not the first BSS,
-	 * at least the link should be removed here since deinit will take care
-	 * of only the first BSS. */
-	if (hapd->conf->mld_ap && !hapd->interface_added &&
-	    hapd->iface->bss[0] != hapd)
-		hostapd_if_link_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface,
-				       hapd->mld_link_id);
-#endif /* CONFIG_IEEE80211BE */
-
 	wpabuf_free(hapd->time_adv);
 	hapd->time_adv = NULL;
 
@@ -610,41 +614,6 @@
 }
 
 
-/* hostapd_bss_link_deinit - Per-BSS ML cleanup (deinitialization)
- * @hapd: Pointer to BSS data
- *
- * This function is used to unlink the BSS from the AP MLD.
- * If the BSS being removed is the first link, the next link becomes the first
- * link.
- */
-static void hostapd_bss_link_deinit(struct hostapd_data *hapd)
-{
-#ifdef CONFIG_IEEE80211BE
-	if (!hapd->conf || !hapd->conf->mld_ap)
-		return;
-
-	if (!hapd->mld->num_links)
-		return;
-
-	/* If not started, not yet linked to the MLD. However, the first
-	 * BSS is always linked since it is linked during driver_init(), and
-	 * hence, need to remove it from the AP MLD.
-	 */
-	if (!hapd->started && hapd->iface->bss[0] != hapd)
-		return;
-
-	/* The first BSS can also be only linked when at least driver_init() is
-	 * executed. But if previous interface fails, it is not, and hence,
-	 * safe to skip.
-	 */
-	if (hapd->iface->bss[0] == hapd && !hapd->drv_priv)
-		return;
-
-	hostapd_mld_remove_link(hapd);
-#endif /* CONFIG_IEEE80211BE */
-}
-
-
 /**
  * hostapd_cleanup - Per-BSS cleanup (deinitialization)
  * @hapd: Pointer to BSS data
@@ -685,7 +654,6 @@
 void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
 {
 	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
-	eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
 #ifdef NEED_AP_MLME
 	hostapd_stop_setup_timers(iface);
 #endif /* NEED_AP_MLME */
@@ -715,6 +683,7 @@
 static void hostapd_cleanup_iface(struct hostapd_iface *iface)
 {
 	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
+	eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
 	eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
 			     NULL);
 
@@ -1334,7 +1303,7 @@
 	u8 if_addr[ETH_ALEN];
 	int flush_old_stations = 1;
 
-	if (!hostapd_mld_is_first_bss(hapd))
+	if (hapd->mld_first_bss)
 		wpa_printf(MSG_DEBUG,
 			   "MLD: %s: Setting non-first BSS", __func__);
 
@@ -1496,7 +1465,7 @@
 	}
 #endif /* CONFIG_SQLITE */
 
-	if (hostapd_mld_is_first_bss(hapd)) {
+	if (!hapd->mld_first_bss) {
 		hapd->radius = radius_client_init(hapd, conf->radius);
 		if (!hapd->radius) {
 			wpa_printf(MSG_ERROR,
@@ -1529,17 +1498,10 @@
 			}
 		}
 	} else {
-#ifdef CONFIG_IEEE80211BE
-		struct hostapd_data *f_bss;
-
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Using RADIUS client of the first BSS");
-		f_bss = hostapd_mld_get_first_bss(hapd);
-		if (!f_bss)
-			return -1;
-		hapd->radius = f_bss->radius;
-		hapd->radius_das = f_bss->radius_das;
-#endif /* CONFIG_IEEE80211BE */
+		hapd->radius = hapd->mld_first_bss->radius;
+		hapd->radius_das = hapd->mld_first_bss->radius_das;
 	}
 #endif /* CONFIG_NO_RADIUS */
 
@@ -1584,7 +1546,6 @@
 		wpa_printf(MSG_ERROR, "GAS server initialization failed");
 		return -1;
 	}
-#endif /* CONFIG_INTERWORKING */
 
 	if (conf->qos_map_set_len &&
 	    hostapd_drv_set_qos_map(hapd, conf->qos_map_set,
@@ -1592,6 +1553,7 @@
 		wpa_printf(MSG_ERROR, "Failed to initialize QoS Map");
 		return -1;
 	}
+#endif /* CONFIG_INTERWORKING */
 
 	if (conf->bss_load_update_period && bss_load_update_init(hapd)) {
 		wpa_printf(MSG_ERROR, "BSS Load initialization failed");
@@ -1777,7 +1739,6 @@
 static void hostapd_no_ir_cleanup(struct hostapd_data *bss)
 {
 	hostapd_bss_deinit_no_free(bss);
-	hostapd_bss_link_deinit(bss);
 	hostapd_free_hapd_data(bss);
 	hostapd_cleanup_iface_partial(bss->iface);
 }
@@ -2074,11 +2035,10 @@
 	} else {
 		int ret;
 
-		if (iface->conf->acs && !iface->is_ch_switch_dfs) {
+		if (iface->conf->acs) {
 			iface->freq = 0;
 			iface->conf->channel = 0;
 		}
-		iface->is_ch_switch_dfs = false;
 
 		ret = configured_fixed_chan_to_freq(iface);
 		if (ret < 0)
@@ -2837,8 +2797,6 @@
 		hapd->rad_attr_db = NULL;
 	}
 #endif /* CONFIG_SQLITE */
-
-	hostapd_bss_link_deinit(hapd);
 	hostapd_cleanup(hapd);
 }
 
@@ -2877,40 +2835,6 @@
 }
 
 
-#ifdef CONFIG_IEEE80211BE
-
-static void hostapd_mld_ref_inc(struct hostapd_mld *mld)
-{
-	if (!mld)
-		return;
-
-	if (mld->refcount == HOSTAPD_MLD_MAX_REF_COUNT) {
-		wpa_printf(MSG_ERROR, "AP MLD %s: Ref count overflow",
-			   mld->name);
-		return;
-	}
-
-	mld->refcount++;
-}
-
-
-static void hostapd_mld_ref_dec(struct hostapd_mld *mld)
-{
-	if (!mld)
-		return;
-
-	if (!mld->refcount) {
-		wpa_printf(MSG_ERROR, "AP MLD %s: Ref count underflow",
-			   mld->name);
-		return;
-	}
-
-	mld->refcount--;
-}
-
-#endif /* CONFIG_IEEE80211BE */
-
-
 void hostapd_interface_free(struct hostapd_iface *iface)
 {
 	size_t j;
@@ -2918,10 +2842,6 @@
 	for (j = 0; j < iface->num_bss; j++) {
 		if (!iface->bss)
 			break;
-#ifdef CONFIG_IEEE80211BE
-		if (iface->bss[j])
-			hostapd_mld_ref_dec(iface->bss[j]->mld);
-#endif /* CONFIG_IEEE80211BE */
 		wpa_printf(MSG_DEBUG, "%s: free hapd %p",
 			   __func__, iface->bss[j]);
 		os_free(iface->bss[j]);
@@ -2944,157 +2864,6 @@
 }
 
 
-#ifdef CONFIG_IEEE80211BE
-static void hostapd_bss_alloc_link_id(struct hostapd_data *hapd)
-{
-	hapd->mld_link_id = hapd->mld->next_link_id++;
-	wpa_printf(MSG_DEBUG, "AP MLD: %s: Link ID %d assigned.",
-		   hapd->mld->name, hapd->mld_link_id);
-}
-#endif /* CONFIG_IEEE80211BE */
-
-
-static void hostapd_bss_setup_multi_link(struct hostapd_data *hapd,
-					 struct hapd_interfaces *interfaces)
-{
-#ifdef CONFIG_IEEE80211BE
-	struct hostapd_mld *mld, **all_mld;
-	struct hostapd_bss_config *conf;
-	size_t i;
-
-	conf = hapd->conf;
-
-	if (!hapd->iconf || !hapd->iconf->ieee80211be || !conf->mld_ap ||
-	    conf->disable_11be)
-		return;
-
-	for (i = 0; i < interfaces->mld_count; i++) {
-		mld = interfaces->mld[i];
-
-		if (!mld || os_strcmp(conf->iface, mld->name) != 0)
-			continue;
-
-		hapd->mld = mld;
-		hostapd_mld_ref_inc(mld);
-		hostapd_bss_alloc_link_id(hapd);
-		break;
-	}
-
-	if (hapd->mld)
-		return;
-
-	mld = os_zalloc(sizeof(struct hostapd_mld));
-	if (!mld)
-		goto fail;
-
-	os_strlcpy(mld->name, conf->iface, sizeof(conf->iface));
-	dl_list_init(&mld->links);
-
-	wpa_printf(MSG_DEBUG, "AP MLD %s created", mld->name);
-
-	hapd->mld = mld;
-	hostapd_mld_ref_inc(mld);
-	hostapd_bss_alloc_link_id(hapd);
-
-	all_mld = os_realloc_array(interfaces->mld, interfaces->mld_count + 1,
-				   sizeof(struct hostapd_mld *));
-	if (!all_mld)
-		goto fail;
-
-	interfaces->mld = all_mld;
-	interfaces->mld[interfaces->mld_count] = mld;
-	interfaces->mld_count++;
-
-	return;
-fail:
-	if (!mld)
-		return;
-
-	wpa_printf(MSG_DEBUG, "AP MLD %s: free mld %p", mld->name, mld);
-	os_free(mld);
-	hapd->mld = NULL;
-#endif /* CONFIG_IEEE80211BE */
-}
-
-
-static void hostapd_cleanup_unused_mlds(struct hapd_interfaces *interfaces)
-{
-#ifdef CONFIG_IEEE80211BE
-	struct hostapd_mld *mld, **all_mld;
-	size_t i, j, num_mlds;
-	bool forced_remove, remove;
-
-	if (!interfaces->mld)
-		return;
-
-	num_mlds = interfaces->mld_count;
-
-	for (i = 0; i < interfaces->mld_count; i++) {
-		mld = interfaces->mld[i];
-		if (!mld)
-			continue;
-
-		remove = false;
-		forced_remove = false;
-
-		if (!mld->refcount)
-			remove = true;
-
-		/* If MLD is still being referenced but the number of interfaces
-		 * is zero, it is safe to force its deletion. Normally, this
-		 * should not happen but even if it does, let us free the
-		 * memory.
-		 */
-		if (!remove && !interfaces->count)
-			forced_remove = true;
-
-		if (!remove && !forced_remove)
-			continue;
-
-		wpa_printf(MSG_DEBUG, "AP MLD %s: Freed%s", mld->name,
-			   forced_remove ? " (forced)" : "");
-		os_free(mld);
-		interfaces->mld[i] = NULL;
-		num_mlds--;
-	}
-
-	if (!num_mlds) {
-		interfaces->mld_count = 0;
-		os_free(interfaces->mld);
-		interfaces->mld = NULL;
-		return;
-	}
-
-	all_mld = os_zalloc(num_mlds * sizeof(struct hostapd_mld *));
-	if (!all_mld) {
-		wpa_printf(MSG_ERROR,
-			   "AP MLD: Failed to re-allocate the MLDs. Expect issues");
-		return;
-	}
-
-	for (i = 0, j = 0; i < interfaces->mld_count; i++) {
-		mld = interfaces->mld[i];
-		if (!mld)
-			continue;
-
-		all_mld[j++] = mld;
-	}
-
-	/* This should not happen */
-	if (j != num_mlds) {
-		wpa_printf(MSG_DEBUG,
-			   "AP MLD: Some error occurred while reallocating MLDs. Expect issues.");
-		os_free(all_mld);
-		return;
-	}
-
-	os_free(interfaces->mld);
-	interfaces->mld = all_mld;
-	interfaces->mld_count = num_mlds;
-#endif /* CONFIG_IEEE80211BE */
-}
-
-
 /**
  * hostapd_init - Allocate and initialize per-interface data
  * @config_file: Path to the configuration file
@@ -3138,10 +2907,8 @@
 		if (hapd == NULL)
 			goto fail;
 		hapd->msg_ctx = hapd;
-		hostapd_bss_setup_multi_link(hapd, interfaces);
 	}
 
-	hapd_iface->is_ch_switch_dfs = false;
 	return hapd_iface;
 
 fail:
@@ -3261,8 +3028,6 @@
 		iface->conf->last_bss = bss;
 		iface->bss[iface->num_bss] = hapd;
 		hapd->msg_ctx = hapd;
-		hostapd_bss_setup_multi_link(hapd, interfaces);
-
 
 		bss_idx = iface->num_bss++;
 		conf->num_bss--;
@@ -3296,37 +3061,6 @@
 }
 
 
-static void hostapd_cleanup_driver(const struct wpa_driver_ops *driver,
-				   void *drv_priv, struct hostapd_iface *iface)
-{
-#ifdef CONFIG_IEEE80211BE
-	if (!driver || !driver->hapd_deinit || !drv_priv)
-		return;
-
-	/* In case of non-ML operation, de-init. But if ML operation exist,
-	 * even if that's the last BSS in the interface, the driver (drv) could
-	 * be in use for a different AP MLD. Hence, need to check if drv is
-	 * still being used by some other BSS before de-initiallizing. */
-	if (!iface->bss[0]->conf->mld_ap) {
-		driver->hapd_deinit(drv_priv);
-	} else if (hostapd_mld_is_first_bss(iface->bss[0]) &&
-		   driver->is_drv_shared &&
-		   !driver->is_drv_shared(drv_priv, iface->bss[0])) {
-		driver->hapd_deinit(drv_priv);
-	} else if (hostapd_if_link_remove(iface->bss[0],
-					  WPA_IF_AP_BSS,
-					  iface->bss[0]->conf->iface,
-					  iface->bss[0]->mld_link_id)) {
-		wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s",
-			   iface->bss[0]->conf->iface);
-	}
-#else /* CONFIG_IEEE80211BE */
-	driver->hapd_deinit(drv_priv);
-#endif /* CONFIG_IEEE80211BE */
-	iface->bss[0]->drv_priv = NULL;
-}
-
-
 void hostapd_interface_deinit_free(struct hostapd_iface *iface)
 {
 	const struct wpa_driver_ops *driver;
@@ -3343,7 +3077,11 @@
 	hostapd_interface_deinit(iface);
 	wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
 		   __func__, driver, drv_priv);
-	hostapd_cleanup_driver(driver, drv_priv, iface);
+	if (driver && driver->hapd_deinit && drv_priv) {
+		if (!iface->bss[0]->mld_first_bss)
+			driver->hapd_deinit(drv_priv);
+		hostapd_clear_drv_priv(iface->bss[0]);
+	}
 	hostapd_interface_free(iface);
 }
 
@@ -3356,16 +3094,15 @@
 
 	wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
 		   __func__, driver, drv_priv);
-
-	hostapd_cleanup_driver(driver, drv_priv, hapd_iface);
-
 	if (driver && driver->hapd_deinit && drv_priv) {
+		if (!hapd_iface->bss[0]->mld_first_bss)
+			driver->hapd_deinit(drv_priv);
 		for (j = 0; j < hapd_iface->num_bss; j++) {
 			wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p",
 				   __func__, (int) j,
 				   hapd_iface->bss[j]->drv_priv);
 			if (hapd_iface->bss[j]->drv_priv == drv_priv) {
-				hapd_iface->bss[j]->drv_priv = NULL;
+				hostapd_clear_drv_priv(hapd_iface->bss[j]);
 				hapd_iface->extended_capa = NULL;
 				hapd_iface->extended_capa_mask = NULL;
 				hapd_iface->extended_capa_len = 0;
@@ -3375,22 +3112,6 @@
 }
 
 
-static void hostapd_refresh_all_iface_beacons(struct hostapd_iface *hapd_iface)
-{
-	size_t j;
-
-	if (!hapd_iface->interfaces || hapd_iface->interfaces->count <= 1)
-		return;
-
-	for (j = 0; j < hapd_iface->interfaces->count; j++) {
-		if (hapd_iface->interfaces->iface[j] == hapd_iface)
-			continue;
-
-		ieee802_11_update_beacons(hapd_iface->interfaces->iface[j]);
-	}
-}
-
-
 int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
 {
 	size_t j;
@@ -3429,8 +3150,6 @@
 		return -1;
 	}
 
-	hostapd_refresh_all_iface_beacons(hapd_iface);
-
 	return 0;
 }
 
@@ -3488,6 +3207,31 @@
 		return -1;
 	}
 
+#ifdef CONFIG_IEEE80211BE
+	if (hapd_iface->bss[0]->conf->mld_ap &&
+	    !hapd_iface->bss[0]->mld_first_bss) {
+		/* Do not allow mld_first_bss disabling before other BSSs */
+		for (j = 0; j < hapd_iface->interfaces->count; ++j) {
+			struct hostapd_iface *h_iface =
+				hapd_iface->interfaces->iface[j];
+			struct hostapd_data *h_hapd = h_iface->bss[0];
+			struct hostapd_bss_config *h_conf = h_hapd->conf;
+
+			if (!h_conf->mld_ap ||
+			    h_conf->mld_id !=
+			    hapd_iface->bss[0]->conf->mld_id ||
+			    h_iface == hapd_iface)
+				continue;
+
+			if (h_iface->state != HAPD_IFACE_DISABLED) {
+				wpa_printf(MSG_INFO,
+					   "Do not allow disable mld_first_bss first");
+				return -1;
+			}
+		}
+	}
+#endif /* CONFIG_IEEE80211BE */
+
 	wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
 	driver = hapd_iface->bss[0]->driver;
 	drv_priv = hapd_iface->bss[0]->drv_priv;
@@ -3505,7 +3249,6 @@
 	for (j = 0; j < hapd_iface->num_bss; j++) {
 		struct hostapd_data *hapd = hapd_iface->bss[j];
 		hostapd_bss_deinit_no_free(hapd);
-		hostapd_bss_link_deinit(hapd);
 		hostapd_free_hapd_data(hapd);
 	}
 
@@ -3519,7 +3262,6 @@
 	wpa_printf(MSG_DEBUG, "Interface %s disabled",
 		   hapd_iface->bss[0]->conf->iface);
 	hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED);
-	hostapd_refresh_all_iface_beacons(hapd_iface);
 	return 0;
 }
 
@@ -3628,7 +3370,6 @@
 			return -1;
 		}
 		hapd->msg_ctx = hapd;
-		hostapd_bss_setup_multi_link(hapd, hapd_iface->interfaces);
 	}
 
 	hapd_iface->conf = conf;
@@ -3702,7 +3443,6 @@
 			if (start_ctrl_iface_bss(hapd) < 0 ||
 			    (hapd_iface->state == HAPD_IFACE_ENABLED &&
 			     hostapd_setup_bss(hapd, -1, true))) {
-				hostapd_bss_link_deinit(hapd);
 				hostapd_cleanup(hapd);
 				hapd_iface->bss[hapd_iface->num_bss - 1] = NULL;
 				hapd_iface->conf->num_bss--;
@@ -3711,9 +3451,6 @@
 					   __func__, hapd, hapd->conf->iface);
 				hostapd_config_free_bss(hapd->conf);
 				hapd->conf = NULL;
-#ifdef CONFIG_IEEE80211BE
-				hostapd_mld_ref_dec(hapd->mld);
-#endif /* CONFIG_IEEE80211BE */
 				os_free(hapd);
 				return -1;
 			}
@@ -3803,11 +3540,7 @@
 				wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
 					   __func__, hapd_iface->bss[i],
 					   hapd->conf->iface);
-				hostapd_bss_link_deinit(hapd);
 				hostapd_cleanup(hapd);
-#ifdef CONFIG_IEEE80211BE
-				hostapd_mld_ref_dec(hapd->mld);
-#endif /* CONFIG_IEEE80211BE */
 				os_free(hapd);
 				hapd_iface->bss[i] = NULL;
 			}
@@ -3817,7 +3550,6 @@
 		if (new_iface) {
 			interfaces->count--;
 			interfaces->iface[interfaces->count] = NULL;
-			hostapd_cleanup_unused_mlds(interfaces);
 		}
 		hostapd_cleanup_iface(hapd_iface);
 	}
@@ -3840,9 +3572,6 @@
 			   __func__, hapd, hapd->conf->iface);
 		hostapd_config_free_bss(hapd->conf);
 		hapd->conf = NULL;
-#ifdef CONFIG_IEEE80211BE
-		hostapd_mld_ref_dec(hapd->mld);
-#endif /* CONFIG_IEEE80211BE */
 		os_free(hapd);
 
 		iface->num_bss--;
@@ -3885,8 +3614,6 @@
 				k++;
 			}
 			interfaces->count--;
-			hostapd_cleanup_unused_mlds(interfaces);
-
 			return 0;
 		}
 
@@ -4186,8 +3913,7 @@
 				    mode ? &mode->he_capab[IEEE80211_MODE_AP] :
 				    NULL,
 				    mode ? &mode->eht_capab[IEEE80211_MODE_AP] :
-				    NULL,
-				    hostapd_get_punct_bitmap(hapd)))
+				    NULL))
 		return -1;
 
 	switch (params->bandwidth) {
@@ -4677,7 +4403,6 @@
 
 
 #ifdef CONFIG_IEEE80211BE
-
 struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd,
 					       u8 link_id)
 {
@@ -4686,8 +4411,9 @@
 	for (i = 0; i < hapd->iface->interfaces->count; i++) {
 		struct hostapd_iface *h = hapd->iface->interfaces->iface[i];
 		struct hostapd_data *h_hapd = h->bss[0];
+		struct hostapd_bss_config *hconf = h_hapd->conf;
 
-		if (!hostapd_is_ml_partner(hapd, h_hapd))
+		if (!hconf->mld_ap || hconf->mld_id != hapd->conf->mld_id)
 			continue;
 
 		if (h_hapd->mld_link_id == link_id)
@@ -4696,141 +4422,4 @@
 
 	return NULL;
 }
-
-
-bool hostapd_is_ml_partner(struct hostapd_data *hapd1,
-			   struct hostapd_data *hapd2)
-{
-	if (!hapd1->conf->mld_ap || !hapd2->conf->mld_ap)
-		return false;
-
-	return !os_strcmp(hapd1->conf->iface, hapd2->conf->iface);
-}
-
-
-u8 hostapd_get_mld_id(struct hostapd_data *hapd)
-{
-	if (!hapd->conf->mld_ap)
-		return 255;
-
-	/* MLD ID 0 represents self */
-	return 0;
-
-	/* TODO: MLD ID for Multiple BSS cases */
-}
-
-
-int hostapd_mld_add_link(struct hostapd_data *hapd)
-{
-	struct hostapd_mld *mld = hapd->mld;
-
-	if (!hapd->conf->mld_ap)
-		return 0;
-
-	/* Should not happen */
-	if (!mld)
-		return -1;
-
-	dl_list_add_tail(&mld->links, &hapd->link);
-	mld->num_links++;
-
-	wpa_printf(MSG_DEBUG, "AP MLD %s: Link ID %d added. num_links: %d",
-		   mld->name, hapd->mld_link_id, mld->num_links);
-
-	if (mld->fbss)
-		return 0;
-
-	mld->fbss = hapd;
-	wpa_printf(MSG_DEBUG, "AP MLD %s: First link BSS set to %p",
-		   mld->name, mld->fbss);
-	return 0;
-}
-
-
-int hostapd_mld_remove_link(struct hostapd_data *hapd)
-{
-	struct hostapd_mld *mld = hapd->mld;
-	struct hostapd_data *next_fbss;
-
-	if (!hapd->conf->mld_ap)
-		return 0;
-
-	/* Should not happen */
-	if (!mld)
-		return -1;
-
-	dl_list_del(&hapd->link);
-	mld->num_links--;
-
-	wpa_printf(MSG_DEBUG, "AP MLD %s: Link ID %d removed. num_links: %d",
-		   mld->name, hapd->mld_link_id, mld->num_links);
-
-	if (mld->fbss != hapd)
-		return 0;
-
-	/* If the list is empty, all links are removed */
-	if (dl_list_empty(&mld->links)) {
-		mld->fbss = NULL;
-	} else {
-		next_fbss = dl_list_entry(mld->links.next, struct hostapd_data,
-					  link);
-		mld->fbss = next_fbss;
-	}
-
-	wpa_printf(MSG_DEBUG, "AP MLD %s: First link BSS set to %p",
-		   mld->name, mld->fbss);
-	return 0;
-}
-
-
-bool hostapd_mld_is_first_bss(struct hostapd_data *hapd)
-{
-	struct hostapd_mld *mld = hapd->mld;
-
-	if (!hapd->conf->mld_ap)
-		return true;
-
-	/* Should not happen */
-	if (!mld)
-		return false;
-
-	/* If fbss is not set, it is safe to assume the caller is the first BSS.
-	 */
-	if (!mld->fbss)
-		return true;
-
-	return hapd == mld->fbss;
-}
-
-
-struct hostapd_data * hostapd_mld_get_first_bss(struct hostapd_data *hapd)
-{
-	struct hostapd_mld *mld = hapd->mld;
-
-	if (!hapd->conf->mld_ap)
-		return NULL;
-
-	/* Should not happen */
-	if (!mld)
-		return NULL;
-
-	return mld->fbss;
-}
-
 #endif /* CONFIG_IEEE80211BE */
-
-
-u16 hostapd_get_punct_bitmap(struct hostapd_data *hapd)
-{
-	u16 punct_bitmap = 0;
-
-#ifdef CONFIG_IEEE80211BE
-	punct_bitmap = hapd->iconf->punct_bitmap;
-#ifdef CONFIG_TESTING_OPTIONS
-	if (!punct_bitmap)
-		punct_bitmap = hapd->conf->eht_oper_puncturing_override;
-#endif /* CONFIG_TESTING_OPTIONS */
-#endif /* CONFIG_IEEE80211BE */
-
-	return punct_bitmap;
-}
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index ff29726..bcf980f 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -44,7 +44,6 @@
 #endif /* CONFIG_CTRL_IFACE_UDP */
 
 struct hostapd_iface;
-struct hostapd_mld;
 
 struct hapd_interfaces {
 	int (*reload_config)(struct hostapd_iface *iface);
@@ -94,10 +93,6 @@
        unsigned char ctrl_iface_cookie[CTRL_IFACE_COOKIE_LEN];
 #endif /* CONFIG_CTRL_IFACE_UDP */
 
-#ifdef CONFIG_IEEE80211BE
-	struct hostapd_mld **mld;
-	size_t mld_count;
-#endif /* CONFIG_IEEE80211BE */
 };
 
 enum hostapd_chan_status {
@@ -180,6 +175,12 @@
 	unsigned int reenable_beacon:1;
 
 	u8 own_addr[ETH_ALEN];
+	u8 mld_addr[ETH_ALEN];
+	u8 mld_link_id;
+	/* Used for mld_link_id assignment - valid on the first MLD BSS only */
+	u8 mld_next_link_id;
+
+	struct hostapd_data *mld_first_bss;
 
 	int num_sta; /* number of entries in sta_list */
 	struct sta_info *sta_list; /* STA info list head */
@@ -405,10 +406,8 @@
 	u8 beacon_req_token;
 	u8 lci_req_token;
 	u8 range_req_token;
-	u8 link_measurement_req_token;
 	unsigned int lci_req_active:1;
 	unsigned int range_req_active:1;
-	unsigned int link_mesr_req_active:1;
 
 	int dhcp_sock; /* UDP socket used with the DHCP server */
 
@@ -473,9 +472,6 @@
 
 #ifdef CONFIG_IEEE80211BE
 	u8 eht_mld_bss_param_change;
-	struct hostapd_mld *mld;
-	struct dl_list link;
-	u8 mld_link_id;
 #ifdef CONFIG_TESTING_OPTIONS
 	u8 eht_mld_link_removal_count;
 #endif /* CONFIG_TESTING_OPTIONS */
@@ -484,9 +480,6 @@
 #ifdef CONFIG_NAN_USD
 	struct nan_de *nan_de;
 #endif /* CONFIG_NAN_USD */
-
-	u64 scan_cookie; /* Scan instance identifier for the ongoing HT40 scan
-			  */
 };
 
 
@@ -511,29 +504,6 @@
 	HAPD_IFACE_ENABLED
 };
 
-#ifdef CONFIG_IEEE80211BE
-/**
- * struct hostapd_mld - hostapd per-mld data structure
- */
-struct hostapd_mld {
-	char name[IFNAMSIZ + 1];
-	u8 mld_addr[ETH_ALEN];
-	u8 next_link_id;
-	u8 num_links;
-	/* Number of hostapd_data (hapd) referencing this. num_links cannot be
-	 * used since num_links can go to 0 even when a BSS is disabled and
-	 * when it is re-enabled, the MLD should exist and hence it cannot be
-	 * freed when num_links is 0.
-	 */
-	u8 refcount;
-
-	struct hostapd_data *fbss;
-	struct dl_list links; /* List head of all affiliated links */
-};
-
-#define HOSTAPD_MLD_MAX_REF_COUNT      0xFF
-#endif /* CONFIG_IEEE80211BE */
-
 /**
  * struct hostapd_iface - hostapd per-interface data structure
  */
@@ -581,7 +551,6 @@
 
 	u64 drv_flags;
 	u64 drv_flags2;
-	unsigned int drv_rrm_flags;
 
 	/*
 	 * A bitmap of supported protocols for probe response offload. See
@@ -607,8 +576,6 @@
 	int *basic_rates;
 	int freq;
 
-	bool radar_detected;
-
 	/* Background radar configuration */
 	struct {
 		int channel;
@@ -710,8 +677,6 @@
 
 	/* Configured freq of interface is NO_IR */
 	bool is_no_ir;
-
-	bool is_ch_switch_dfs; /* Channel switch from ACS to DFS */
 };
 
 /* hostapd.c */
@@ -818,17 +783,8 @@
 struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd,
 					       u8 link_id);
 int hostapd_link_remove(struct hostapd_data *hapd, u32 count);
-bool hostapd_is_ml_partner(struct hostapd_data *hapd1,
-			   struct hostapd_data *hapd2);
-u8 hostapd_get_mld_id(struct hostapd_data *hapd);
-int hostapd_mld_add_link(struct hostapd_data *hapd);
-int hostapd_mld_remove_link(struct hostapd_data *hapd);
-struct hostapd_data * hostapd_mld_get_first_bss(struct hostapd_data *hapd);
 
 #ifdef CONFIG_IEEE80211BE
-
-bool hostapd_mld_is_first_bss(struct hostapd_data *hapd);
-
 #define for_each_mld_link(_link, _bss_idx, _iface_idx, _ifaces, _mld_id) \
 	for (_iface_idx = 0;						\
 	     _iface_idx < (_ifaces)->count;				\
@@ -840,21 +796,11 @@
 			for (_link =					\
 			     (_ifaces)->iface[_iface_idx]->bss[_bss_idx]; \
 			    _link && _link->conf->mld_ap &&		\
-				hostapd_get_mld_id(_link) == _mld_id;	\
+				_link->conf->mld_id == _mld_id;		\
 			    _link = NULL)
-
 #else /* CONFIG_IEEE80211BE */
-
-static inline bool hostapd_mld_is_first_bss(struct hostapd_data *hapd)
-{
-	return true;
-}
-
 #define for_each_mld_link(_link, _bss_idx, _iface_idx, _ifaces, _mld_id) \
 	if (false)
-
 #endif /* CONFIG_IEEE80211BE */
 
-u16 hostapd_get_punct_bitmap(struct hostapd_data *hapd);
-
 #endif /* HOSTAPD_H */
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index c455660..596f2f0 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -107,7 +107,9 @@
 		 */
 		orig_mode_valid = true;
 		mode = iface->current_mode->mode;
-		is_6ghz = iface->current_mode->is_6ghz;
+		is_6ghz = mode == HOSTAPD_MODE_IEEE80211A &&
+			iface->current_mode->num_channels > 0 &&
+			is_6ghz_freq(iface->current_mode->channels[0].freq);
 		iface->current_mode = NULL;
 	}
 	hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
@@ -506,12 +508,6 @@
 	else
 		ieee80211n_scan_channels_5g(iface, &params);
 
-	params.link_id = -1;
-#ifdef CONFIG_IEEE80211BE
-	if (iface->bss[0]->conf->mld_ap)
-		params.link_id = iface->bss[0]->mld_link_id;
-#endif /* CONFIG_IEEE80211BE */
-
 	ret = hostapd_driver_scan(iface->bss[0], &params);
 	iface->num_ht40_scan_tries++;
 	os_free(params.freqs);
@@ -527,7 +523,6 @@
 
 	if (ret == 0) {
 		iface->scan_cb = ieee80211n_check_scan;
-		iface->bss[0]->scan_cookie = params.scan_cookie;
 		return;
 	}
 
@@ -563,11 +558,6 @@
 	else
 		ieee80211n_scan_channels_5g(iface, &params);
 
-	params.link_id = -1;
-#ifdef CONFIG_IEEE80211BE
-	if (iface->bss[0]->conf->mld_ap)
-		params.link_id = iface->bss[0]->mld_link_id;
-#endif /* CONFIG_IEEE80211BE */
 	ret = hostapd_driver_scan(iface->bss[0], &params);
 	os_free(params.freqs);
 
@@ -589,7 +579,6 @@
 	}
 
 	iface->scan_cb = ieee80211n_check_scan;
-	iface->bss[0]->scan_cookie = params.scan_cookie;
 	return 1;
 }
 
@@ -1081,7 +1070,9 @@
 		return true;
 
 	if (is_6ghz_op_class(iface->conf->op_class) && iface->freq == 0 &&
-	    !mode->is_6ghz)
+	    (mode->mode != HOSTAPD_MODE_IEEE80211A ||
+	     mode->num_channels == 0 ||
+	     !is_6ghz_freq(mode->channels[0].freq)))
 		return true;
 
 	return false;
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 85a39d5..8b8c1f0 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -88,31 +88,18 @@
 			      struct sta_info *sta, int reassoc);
 
 
-static u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid, size_t len)
+u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid)
 {
-	struct multi_ap_params multi_ap = { 0 };
+	u8 multi_ap_val = 0;
 
 	if (!hapd->conf->multi_ap)
 		return eid;
-
 	if (hapd->conf->multi_ap & BACKHAUL_BSS)
-		multi_ap.capability |= MULTI_AP_BACKHAUL_BSS;
+		multi_ap_val |= MULTI_AP_BACKHAUL_BSS;
 	if (hapd->conf->multi_ap & FRONTHAUL_BSS)
-		multi_ap.capability |= MULTI_AP_FRONTHAUL_BSS;
+		multi_ap_val |= MULTI_AP_FRONTHAUL_BSS;
 
-	if (hapd->conf->multi_ap_client_disallow &
-	    PROFILE1_CLIENT_ASSOC_DISALLOW)
-		multi_ap.capability |=
-			MULTI_AP_PROFILE1_BACKHAUL_STA_DISALLOWED;
-	if (hapd->conf->multi_ap_client_disallow &
-	    PROFILE2_CLIENT_ASSOC_DISALLOW)
-		multi_ap.capability |=
-			MULTI_AP_PROFILE2_BACKHAUL_STA_DISALLOWED;
-
-	multi_ap.profile = hapd->conf->multi_ap_profile;
-	multi_ap.vlanid = hapd->conf->multi_ap_vlanid;
-
-	return eid + add_multi_ap_ie(eid, len, &multi_ap);
+	return eid + add_multi_ap_ie(eid, 9, multi_ap_val);
 }
 
 
@@ -422,7 +409,7 @@
 	 * the addresses.
 	 */
 	if (ap_sta_is_mld(hapd, sta)) {
-		sa = hapd->mld->mld_addr;
+		sa = hapd->mld_addr;
 
 		ml_resp = hostapd_ml_auth_resp(hapd);
 		if (!ml_resp)
@@ -623,7 +610,7 @@
 
 #ifdef CONFIG_IEEE80211BE
 	if (ap_sta_is_mld(hapd, sta))
-		own_addr = hapd->mld->mld_addr;
+		own_addr = hapd->mld_addr;
 #endif /* CONFIG_IEEE80211BE */
 
 	if (sta->sae->tmp) {
@@ -2403,7 +2390,7 @@
 	wpa_hexdump(MSG_DEBUG, "RSN: Generated FILS ANonce",
 		    fils->anonce, FILS_NONCE_LEN);
 
-	ret = fils_rmsk_to_pmk(pasn_get_akmp(pasn), msk, msk_len, fils->nonce,
+	ret = fils_rmsk_to_pmk(pasn->akmp, msk, msk_len, fils->nonce,
 			       fils->anonce, NULL, 0, pmk, &pmk_len);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "FILS: Failed to derive PMK");
@@ -2413,16 +2400,15 @@
 	ret = pasn_pmk_to_ptk(pmk, pmk_len, sta->addr, hapd->own_addr,
 			      wpabuf_head(pasn->secret),
 			      wpabuf_len(pasn->secret),
-			      pasn_get_ptk(sta->pasn), pasn_get_akmp(sta->pasn),
-			      pasn_get_cipher(sta->pasn), sta->pasn->kdk_len);
+			      &sta->pasn->ptk, sta->pasn->akmp,
+			      sta->pasn->cipher, sta->pasn->kdk_len);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to derive PTK");
 		goto fail;
 	}
 
 	if (pasn->secure_ltf) {
-		ret = wpa_ltf_keyseed(pasn_get_ptk(pasn), pasn_get_akmp(pasn),
-				      pasn_get_cipher(pasn));
+		ret = wpa_ltf_keyseed(&pasn->ptk, pasn->akmp, pasn->cipher);
 		if (ret) {
 			wpa_printf(MSG_DEBUG,
 				   "PASN: FILS: Failed to derive LTF keyseed");
@@ -2568,8 +2554,7 @@
 	 * Calculate pending PMKID here so that we do not need to maintain a
 	 * copy of the EAP-Initiate/Reautt message.
 	 */
-	fils_pmkid_erp(pasn_get_akmp(pasn),
-		       wpabuf_head(fils_wd), wpabuf_len(fils_wd),
+	fils_pmkid_erp(pasn->akmp, wpabuf_head(fils_wd), wpabuf_len(fils_wd),
 		       fils->erp_pmkid);
 
 	wpabuf_free(fils_wd);
@@ -2594,35 +2579,32 @@
 {
 	struct pasn_data *pasn = sta->pasn;
 
-	pasn_register_callbacks(pasn, hapd, hapd_pasn_send_mlme, NULL);
-	pasn_set_bssid(pasn, hapd->own_addr);
-	pasn_set_own_addr(pasn, hapd->own_addr);
-	pasn_set_peer_addr(pasn, sta->addr);
-	pasn_set_wpa_key_mgmt(pasn, hapd->conf->wpa_key_mgmt);
-	pasn_set_rsn_pairwise(pasn, hapd->conf->rsn_pairwise);
+	pasn->cb_ctx = hapd;
+	pasn->send_mgmt = hapd_pasn_send_mlme;
 	pasn->pasn_groups = hapd->conf->pasn_groups;
 	pasn->noauth = hapd->conf->pasn_noauth;
-	if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_AP)
-		pasn_enable_kdk_derivation(pasn);
-
+	pasn->wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
+	pasn->rsn_pairwise = hapd->conf->rsn_pairwise;
+	pasn->derive_kdk = hapd->iface->drv_flags2 &
+		WPA_DRIVER_FLAGS2_SEC_LTF_AP;
 #ifdef CONFIG_TESTING_OPTIONS
 	pasn->corrupt_mic = hapd->conf->pasn_corrupt_mic;
 	if (hapd->conf->force_kdk_derivation)
-		pasn_enable_kdk_derivation(pasn);
+		pasn->derive_kdk = true;
 #endif /* CONFIG_TESTING_OPTIONS */
 	pasn->use_anti_clogging = use_anti_clogging(hapd);
-	pasn_set_password(pasn, sae_get_password(hapd, sta, NULL, NULL,
-						 &pasn->pt, NULL));
+	pasn->password = sae_get_password(hapd, sta, NULL, NULL, &pasn->pt,
+					  NULL);
 	pasn->rsn_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &pasn->rsn_ie_len);
-	pasn_set_rsnxe_ie(pasn, hostapd_wpa_ie(hapd, WLAN_EID_RSNX));
+	pasn->rsnxe_ie = hostapd_wpa_ie(hapd, WLAN_EID_RSNX);
 	pasn->disable_pmksa_caching = hapd->conf->disable_pmksa_caching;
-	pasn_set_responder_pmksa(pasn,
-				 wpa_auth_get_pmksa_cache(hapd->wpa_auth));
+	pasn->pmksa = wpa_auth_get_pmksa_cache(hapd->wpa_auth);
 
 	pasn->comeback_after = hapd->conf->pasn_comeback_after;
 	pasn->comeback_idx = hapd->comeback_idx;
 	pasn->comeback_key =  hapd->comeback_key;
 	pasn->comeback_pending_idx = hapd->comeback_pending_idx;
+	os_memcpy(pasn->bssid, hapd->own_addr, ETH_ALEN);
 }
 
 
@@ -2670,7 +2652,6 @@
 	struct wpa_pasn_params_data pasn_params;
 	struct wpabuf *wrapped_data = NULL;
 #endif /* CONFIG_FILS */
-	int akmp;
 
 	if (ieee802_11_parse_elems(mgmt->u.auth.variable,
 				   len - offsetof(struct ieee80211_mgmt,
@@ -2694,12 +2675,10 @@
 		return;
 	}
 
-	pasn_set_akmp(pasn, rsn_data.key_mgmt);
-	pasn_set_cipher(pasn, rsn_data.pairwise_cipher);
+	pasn->akmp = rsn_data.key_mgmt;
+	pasn->cipher = rsn_data.pairwise_cipher;
 
-	akmp = pasn_get_akmp(pasn);
-
-	if (wpa_key_mgmt_ft(akmp) && rsn_data.num_pmkid) {
+	if (wpa_key_mgmt_ft(pasn->akmp) && rsn_data.num_pmkid) {
 #ifdef CONFIG_IEEE80211R_AP
 		pasn->pmk_r1_len = 0;
 		wpa_ft_fetch_pmk_r1(hapd->wpa_auth, sta->addr,
@@ -2710,8 +2689,8 @@
 #endif /* CONFIG_IEEE80211R_AP */
 	}
 #ifdef CONFIG_FILS
-	if (akmp != WPA_KEY_MGMT_FILS_SHA256 &&
-	    akmp != WPA_KEY_MGMT_FILS_SHA384)
+	if (pasn->akmp != WPA_KEY_MGMT_FILS_SHA256 &&
+	    pasn->akmp != WPA_KEY_MGMT_FILS_SHA384)
 		return;
 	if (!elems.pasn_params ||
 	    wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
@@ -2764,7 +2743,7 @@
 			return;
 		}
 
-		sta->pasn = pasn_data_init();
+		sta->pasn = os_zalloc(sizeof(*sta->pasn));
 		if (!sta->pasn) {
 			wpa_printf(MSG_DEBUG,
 				   "PASN: Failed to allocate PASN context");
@@ -2794,14 +2773,13 @@
 		if (handle_auth_pasn_3(sta->pasn, hapd->own_addr,
 				       sta->addr, mgmt, len) == 0) {
 			ptksa_cache_add(hapd->ptksa, hapd->own_addr, sta->addr,
-					pasn_get_cipher(sta->pasn), 43200,
-					pasn_get_ptk(sta->pasn), NULL, NULL,
-					pasn_get_akmp(sta->pasn));
+					sta->pasn->cipher, 43200,
+					&sta->pasn->ptk, NULL, NULL,
+					sta->pasn->akmp);
 
 			pasn_set_keys_from_cache(hapd, hapd->own_addr,
-						 sta->addr,
-						 pasn_get_cipher(sta->pasn),
-						 pasn_get_akmp(sta->pasn));
+						 sta->addr, sta->pasn->cipher,
+						 sta->pasn->akmp);
 		}
 		ap_free_sta(hapd, sta);
 	} else {
@@ -2828,9 +2806,7 @@
 	u16 seq_ctrl;
 	struct radius_sta rad_info;
 	const u8 *dst, *sa, *bssid;
-#ifdef CONFIG_IEEE80211BE
 	bool mld_sta = false;
-#endif /* CONFIG_IEEE80211BE */
 
 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
 		wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
@@ -2948,17 +2924,15 @@
 		goto fail;
 	}
 
-#ifdef CONFIG_IEEE80211BE
 	if (mld_sta &&
 	    (ether_addr_equal(sa, hapd->own_addr) ||
-	     ether_addr_equal(sa, hapd->mld->mld_addr))) {
+	     ether_addr_equal(sa, hapd->mld_addr))) {
 		wpa_printf(MSG_INFO,
 			   "Station " MACSTR " not allowed to authenticate",
 			   MAC2STR(sa));
 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
 		goto fail;
 	}
-#endif /* CONFIG_IEEE80211BE */
 
 	if (hapd->conf->no_auth_if_seen_on) {
 		struct hostapd_data *other;
@@ -3058,6 +3032,15 @@
 				       seq_ctrl);
 			return;
 		}
+#ifdef CONFIG_MESH
+		if ((hapd->conf->mesh & MESH_ENABLED) &&
+		    sta->plink_state == PLINK_BLOCKED) {
+			wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
+				   " is blocked - drop Authentication frame",
+				   MAC2STR(sa));
+			return;
+		}
+#endif /* CONFIG_MESH */
 #ifdef CONFIG_PASN
 		if (auth_alg == WLAN_AUTH_PASN &&
 		    (sta->flags & WLAN_STA_ASSOC)) {
@@ -3095,12 +3078,7 @@
 	}
 
 #ifdef CONFIG_IEEE80211BE
-	/* Set the non-AP MLD information based on the initial Authentication
-	 * frame. Once the STA entry has been added to the driver, the driver
-	 * will translate addresses in the frame and we need to avoid overriding
-	 * peer_addr based on mgmt->sa which would have been translated to the
-	 * MLD MAC address. */
-	if (!sta->added_unassoc && auth_transaction == 1) {
+	if (auth_transaction == 1) {
 		ap_sta_free_sta_profile(&sta->mld_info);
 		os_memset(&sta->mld_info, 0, sizeof(sta->mld_info));
 
@@ -3272,7 +3250,7 @@
 	  */
 	if (ap_sta_is_mld(hapd, sta)) {
 		dst = sta->addr;
-		bssid = hapd->mld->mld_addr;
+		bssid = hapd->mld_addr;
 	}
 #endif /* CONFIG_IEEE80211BE */
 
@@ -3432,58 +3410,37 @@
 static u16 check_multi_ap(struct hostapd_data *hapd, struct sta_info *sta,
 			  const u8 *multi_ap_ie, size_t multi_ap_len)
 {
-	struct multi_ap_params multi_ap;
-	u16 status;
+	u8 multi_ap_value = 0;
 
 	sta->flags &= ~WLAN_STA_MULTI_AP;
 
 	if (!hapd->conf->multi_ap)
 		return WLAN_STATUS_SUCCESS;
 
-	if (!multi_ap_ie) {
-		if (!(hapd->conf->multi_ap & FRONTHAUL_BSS)) {
+	if (multi_ap_ie) {
+		const u8 *multi_ap_subelem;
+
+		multi_ap_subelem = get_ie(multi_ap_ie + 4,
+					  multi_ap_len - 4,
+					  MULTI_AP_SUB_ELEM_TYPE);
+		if (multi_ap_subelem && multi_ap_subelem[1] == 1) {
+			multi_ap_value = multi_ap_subelem[2];
+		} else {
 			hostapd_logger(hapd, sta->addr,
 				       HOSTAPD_MODULE_IEEE80211,
 				       HOSTAPD_LEVEL_INFO,
-				       "Non-Multi-AP STA tries to associate with backhaul-only BSS");
-			return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
+				       "Multi-AP IE has missing or invalid Multi-AP subelement");
+			return WLAN_STATUS_INVALID_IE;
 		}
-
-		return WLAN_STATUS_SUCCESS;
 	}
 
-	status = check_multi_ap_ie(multi_ap_ie + 4, multi_ap_len - 4,
-				   &multi_ap);
-	if (status != WLAN_STATUS_SUCCESS)
-		return status;
-
-	if (multi_ap.capability && multi_ap.capability != MULTI_AP_BACKHAUL_STA)
+	if (multi_ap_value && multi_ap_value != MULTI_AP_BACKHAUL_STA)
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 			       HOSTAPD_LEVEL_INFO,
 			       "Multi-AP IE with unexpected value 0x%02x",
-			       multi_ap.capability);
+			       multi_ap_value);
 
-	if (multi_ap.profile == MULTI_AP_PROFILE_1 &&
-	    (hapd->conf->multi_ap_client_disallow &
-	     PROFILE1_CLIENT_ASSOC_DISALLOW)) {
-		hostapd_logger(hapd, sta->addr,
-			       HOSTAPD_MODULE_IEEE80211,
-			       HOSTAPD_LEVEL_INFO,
-			       "Multi-AP Profile-1 clients not allowed");
-		return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
-	}
-
-	if (multi_ap.profile >= MULTI_AP_PROFILE_2 &&
-	    (hapd->conf->multi_ap_client_disallow &
-	     PROFILE2_CLIENT_ASSOC_DISALLOW)) {
-		hostapd_logger(hapd, sta->addr,
-			       HOSTAPD_MODULE_IEEE80211,
-			       HOSTAPD_LEVEL_INFO,
-			       "Multi-AP Profile-2 clients not allowed");
-		return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
-	}
-
-	if (!(multi_ap.capability & MULTI_AP_BACKHAUL_STA)) {
+	if (!(multi_ap_value & MULTI_AP_BACKHAUL_STA)) {
 		if (hapd->conf->multi_ap & FRONTHAUL_BSS)
 			return WLAN_STATUS_SUCCESS;
 
@@ -3783,7 +3740,7 @@
 	}
 #ifdef CONFIG_IEEE80211BE
 	if (ap_sta_is_mld(hapd, sta))
-		wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld->mld_addr,
+		wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld_addr,
 				     sta->mld_assoc_link_id, &sta->mld_info);
 #endif /* CONFIG_IEEE80211BE */
 	rsn_ie -= 2;
@@ -4068,7 +4025,7 @@
 				wpa_printf(MSG_DEBUG,
 					   "MLD: Set ML info in RSN Authenticator");
 				wpa_auth_set_ml_info(sta->wpa_sm,
-						     hapd->mld->mld_addr,
+						     hapd->mld_addr,
 						     sta->mld_assoc_link_id,
 						     info);
 			}
@@ -4602,7 +4559,8 @@
 			if (hapd->iface == iface)
 				continue;
 
-			if (hostapd_is_ml_partner(hapd, iface->bss[0]) &&
+			if (iface->bss[0]->conf->mld_ap &&
+			    hapd->conf->mld_id == iface->bss[0]->conf->mld_id &&
 			    i == iface->bss[0]->mld_link_id)
 				break;
 		}
@@ -4829,7 +4787,7 @@
 	 * MLD MAC address.
 	 */
 	if (ap_sta_is_mld(hapd, sta) && allow_mld_addr_trans)
-		sa = hapd->mld->mld_addr;
+		sa = hapd->mld_addr;
 #endif /* CONFIG_IEEE80211BE */
 
 	os_memcpy(reply->da, addr, ETH_ALEN);
@@ -5033,7 +4991,7 @@
 #endif /* CONFIG_WPS */
 
 	if (sta && (sta->flags & WLAN_STA_MULTI_AP))
-		p = hostapd_eid_multi_ap(hapd, p, buf + buflen - p);
+		p = hostapd_eid_multi_ap(hapd, p);
 
 #ifdef CONFIG_P2P
 	if (sta && sta->p2p_ie && hapd->p2p_group) {
@@ -5817,7 +5775,8 @@
 			tmp_hapd =
 				assoc_hapd->iface->interfaces->iface[i]->bss[0];
 
-			if (!hostapd_is_ml_partner(assoc_hapd, tmp_hapd))
+			if (!tmp_hapd->conf->mld_ap ||
+			    assoc_hapd->conf->mld_id != tmp_hapd->conf->mld_id)
 				continue;
 
 			for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
@@ -6247,7 +6206,7 @@
 #endif /* CONFIG_MESH */
 #ifdef CONFIG_IEEE80211BE
 	    !(hapd->conf->mld_ap &&
-	      ether_addr_equal(hapd->mld->mld_addr, mgmt->bssid)) &&
+	      ether_addr_equal(hapd->mld_addr, mgmt->bssid)) &&
 #endif /* CONFIG_IEEE80211BE */
 	    !ether_addr_equal(mgmt->bssid, hapd->own_addr)) {
 		wpa_printf(MSG_INFO, "MGMT: BSSID=" MACSTR " not our address",
@@ -6270,7 +6229,7 @@
 	     stype != WLAN_FC_STYPE_ACTION) &&
 #ifdef CONFIG_IEEE80211BE
 	    !(hapd->conf->mld_ap &&
-	      ether_addr_equal(hapd->mld->mld_addr, mgmt->bssid)) &&
+	      ether_addr_equal(hapd->mld_addr, mgmt->bssid)) &&
 #endif /* CONFIG_IEEE80211BE */
 #ifdef CONFIG_NAN_USD
 	    !ether_addr_equal(mgmt->da, nan_network_id) &&
@@ -6484,7 +6443,8 @@
 			struct hostapd_data *tmp_hapd =
 				hapd->iface->interfaces->iface[i]->bss[0];
 
-			if (!hostapd_is_ml_partner(tmp_hapd, hapd))
+			if (!tmp_hapd->conf->mld_ap ||
+			    hapd->conf->mld_id != tmp_hapd->conf->mld_id)
 				continue;
 
 			for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
@@ -7447,12 +7407,12 @@
 		bool ap_mld = false;
 
 #ifdef CONFIG_IEEE80211BE
-		if (hostapd_is_ml_partner(hapd, iface->bss[0]))
+		if (hapd->conf->mld_ap && iface->bss[0]->conf->mld_ap &&
+		    hapd->conf->mld_id == iface->bss[0]->conf->mld_id)
 			ap_mld = true;
 #endif /* CONFIG_IEEE80211BE */
 
 		if (iface == hapd->iface ||
-		    iface->state != HAPD_IFACE_ENABLED ||
 		    !(is_6ghz_op_class(iface->conf->op_class) || ap_mld))
 			continue;
 
@@ -7620,10 +7580,11 @@
 #ifdef CONFIG_IEEE80211BE
 		u8 param_ch = hapd->eht_mld_bss_param_change;
 
-		if (hostapd_is_ml_partner(bss, reporting_hapd))
+		if (reporting_hapd->conf->mld_ap &&
+		    bss->conf->mld_id == reporting_hapd->conf->mld_id)
 			*eid++ = 0;
 		else
-			*eid++ = hostapd_get_mld_id(hapd);
+			*eid++ = hapd->conf->mld_id;
 
 		*eid++ = hapd->mld_link_id | ((param_ch & 0xF) << 4);
 		*eid = (param_ch >> 4) & 0xF;
@@ -7721,12 +7682,12 @@
 		bool ap_mld = false;
 
 #ifdef CONFIG_IEEE80211BE
-		if (hostapd_is_ml_partner(hapd, iface->bss[0]))
+		if (hapd->conf->mld_ap && iface->bss[0]->conf->mld_ap &&
+		    hapd->conf->mld_id == iface->bss[0]->conf->mld_id)
 			ap_mld = true;
 #endif /* CONFIG_IEEE80211BE */
 
 		if (iface == hapd->iface ||
-		    iface->state != HAPD_IFACE_ENABLED ||
 		    !(is_6ghz_op_class(iface->conf->op_class) || ap_mld))
 			continue;
 
@@ -7793,27 +7754,6 @@
 }
 
 
-static size_t hostapd_mbssid_ext_capa(struct hostapd_data *bss,
-				      struct hostapd_data *tx_bss, u8 *buf)
-{
-	u8 ext_capa_tx[20], *ext_capa_tx_end, ext_capa[20], *ext_capa_end;
-	size_t ext_capa_len, ext_capa_tx_len;
-
-	ext_capa_tx_end = hostapd_eid_ext_capab(tx_bss, ext_capa_tx,
-						true);
-	ext_capa_tx_len = ext_capa_tx_end - ext_capa_tx;
-	ext_capa_end = hostapd_eid_ext_capab(bss, ext_capa, true);
-	ext_capa_len = ext_capa_end - ext_capa;
-	if (ext_capa_tx_len != ext_capa_len ||
-	    os_memcmp(ext_capa_tx, ext_capa, ext_capa_len) != 0) {
-		os_memcpy(buf, ext_capa, ext_capa_len);
-		return ext_capa_len;
-	}
-
-	return 0;
-}
-
-
 static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd,
 					  u32 frame_type, size_t *bss_index,
 					  const u8 *known_bss,
@@ -7821,7 +7761,6 @@
 {
 	struct hostapd_data *tx_bss = hostapd_mbssid_get_tx_bss(hapd);
 	size_t len, i;
-	u8 ext_capa[20];
 
 	/* Element ID: 1 octet
 	 * Length: 1 octet
@@ -7867,10 +7806,6 @@
 			if (rsnx)
 				nontx_profile_len += 2 + rsnx[1];
 		}
-
-		nontx_profile_len += hostapd_mbssid_ext_capa(bss, tx_bss,
-							     ext_capa);
-
 		if (!rsn && hostapd_wpa_ie(tx_bss, WLAN_EID_RSN))
 			ie_count++;
 		if (!rsnx && hostapd_wpa_ie(tx_bss, WLAN_EID_RSNX))
@@ -8020,9 +7955,6 @@
 				eid += 2 + rsnx[1];
 			}
 		}
-
-		eid += hostapd_mbssid_ext_capa(bss, tx_bss, eid);
-
 		/* List of Element ID values in increasing order */
 		if (!rsn && hostapd_wpa_ie(tx_bss, WLAN_EID_RSN))
 			non_inherit_ie[ie_count++] = WLAN_EID_RSN;
@@ -8130,4 +8062,73 @@
 	return eid;
 }
 
+
+static void punct_update_legacy_bw_80(u8 bitmap, u8 pri_chan, u8 *seg0)
+{
+	u8 first_chan = *seg0 - 6, sec_chan;
+
+	switch (bitmap) {
+	case 0x6:
+		*seg0 = 0;
+		return;
+	case 0x8:
+	case 0x4:
+	case 0x2:
+	case 0x1:
+	case 0xC:
+	case 0x3:
+		if (pri_chan < *seg0)
+			*seg0 -= 4;
+		else
+			*seg0 += 4;
+		break;
+	}
+
+	if (pri_chan < *seg0)
+		sec_chan = pri_chan + 4;
+	else
+		sec_chan = pri_chan - 4;
+
+	if (bitmap & BIT((sec_chan - first_chan) / 4))
+		*seg0 = 0;
+}
+
+
+static void punct_update_legacy_bw_160(u8 bitmap, u8 pri,
+				       enum oper_chan_width *width, u8 *seg0)
+{
+	if (pri < *seg0) {
+		*seg0 -= 8;
+		if (bitmap & 0x0F) {
+			*width = 0;
+			punct_update_legacy_bw_80(bitmap & 0xF, pri, seg0);
+		}
+	} else {
+		*seg0 += 8;
+		if (bitmap & 0xF0) {
+			*width = 0;
+			punct_update_legacy_bw_80((bitmap & 0xF0) >> 4, pri,
+						  seg0);
+		}
+	}
+}
+
+
+void punct_update_legacy_bw(u16 bitmap, u8 pri, enum oper_chan_width *width,
+			    u8 *seg0, u8 *seg1)
+{
+	if (*width == CONF_OPER_CHWIDTH_80MHZ && (bitmap & 0xF)) {
+		*width = CONF_OPER_CHWIDTH_USE_HT;
+		punct_update_legacy_bw_80(bitmap & 0xF, pri, seg0);
+	}
+
+	if (*width == CONF_OPER_CHWIDTH_160MHZ && (bitmap & 0xFF)) {
+		*width = CONF_OPER_CHWIDTH_80MHZ;
+		*seg1 = 0;
+		punct_update_legacy_bw_160(bitmap & 0xFF, pri, width, seg0);
+	}
+
+	/* TODO: 320 MHz */
+}
+
 #endif /* CONFIG_NATIVE_WINDOWS */
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index a35486d..5fd380a 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -248,6 +248,8 @@
 			u8 **elem_offset,
 			const u8 *known_bss, size_t known_bss_len, u8 *rnr_eid,
 			u8 *rnr_count, u8 **rnr_offset, size_t rnr_len);
+void punct_update_legacy_bw(u16 bitmap, u8 pri_chan,
+			    enum oper_chan_width *width, u8 *seg0, u8 *seg1);
 bool hostapd_is_mld_ap(struct hostapd_data *hapd);
 const char * sae_get_password(struct hostapd_data *hapd,
 			      struct sta_info *sta, const char *rx_id,
diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c
index 638546e..840fc20 100644
--- a/src/ap/ieee802_11_eht.c
+++ b/src/ap/ieee802_11_eht.c
@@ -206,11 +206,19 @@
 	enum oper_chan_width chwidth;
 	size_t elen = 1 + 4;
 	bool eht_oper_info_present;
-	u16 punct_bitmap = hostapd_get_punct_bitmap(hapd);
+	u16 punct_bitmap = conf->punct_bitmap;
 
 	if (!hapd->iface->current_mode)
 		return eid;
 
+#ifdef CONFIG_TESTING_OPTIONS
+	if (!punct_bitmap && hapd->conf->eht_oper_puncturing_override) {
+		wpa_printf(MSG_DEBUG, "EHT: Puncturing mask override=0x%x",
+			   hapd->conf->eht_oper_puncturing_override);
+		punct_bitmap = hapd->conf->eht_oper_puncturing_override;
+	}
+#endif /* CONFIG_TESTING_OPTIONS */
+
 	if (is_6ghz_op_class(conf->op_class))
 		chwidth = op_class_to_ch_width(conf->op_class);
 	else
@@ -450,8 +458,6 @@
 	size_t len, slice_len;
 	u8 link_id;
 	u8 common_info_len;
-	u16 mld_cap;
-	u8 max_simul_links, active_links;
 
 	/*
 	 * As the Multi-Link element can exceed the size of 255 bytes need to
@@ -489,7 +495,7 @@
 	wpabuf_put_u8(buf, common_info_len);
 
 	/* Own MLD MAC Address */
-	wpabuf_put_data(buf, hapd->mld->mld_addr, ETH_ALEN);
+	wpabuf_put_data(buf, hapd->mld_addr, ETH_ALEN);
 
 	/* Own Link ID */
 	wpabuf_put_u8(buf, hapd->mld_link_id);
@@ -501,31 +507,14 @@
 		   hapd->iface->mld_eml_capa);
 	wpabuf_put_le16(buf, hapd->iface->mld_eml_capa);
 
-	mld_cap = hapd->iface->mld_mld_capa;
-	max_simul_links = mld_cap & EHT_ML_MLD_CAPA_MAX_NUM_SIM_LINKS_MASK;
-	active_links = hapd->mld->num_links - 1;
-
-	if (active_links > max_simul_links) {
-		wpa_printf(MSG_ERROR,
-			   "MLD: Error in max simultaneous links, advertised: 0x%x current: 0x%x",
-			   max_simul_links, active_links);
-		active_links = max_simul_links;
-	}
-
-	mld_cap &= ~EHT_ML_MLD_CAPA_MAX_NUM_SIM_LINKS_MASK;
-	mld_cap |= active_links & EHT_ML_MLD_CAPA_MAX_NUM_SIM_LINKS_MASK;
-
-	/* TODO: Advertise T2LM based on driver support as well */
-	mld_cap &= ~EHT_ML_MLD_CAPA_TID_TO_LINK_MAP_NEG_SUPP_MSK;
-
 	wpa_printf(MSG_DEBUG, "MLD: MLD Capabilities and Operations=0x%x",
-		   mld_cap);
-	wpabuf_put_le16(buf, mld_cap);
+		   hapd->iface->mld_mld_capa);
+	wpabuf_put_le16(buf, hapd->iface->mld_mld_capa);
 
 	if (include_mld_id) {
 		wpa_printf(MSG_DEBUG, "MLD: AP MLD ID=0x%x",
-			   hostapd_get_mld_id(hapd));
-		wpabuf_put_u8(buf, hostapd_get_mld_id(hapd));
+			   hapd->conf->mld_id);
+		wpabuf_put_u8(buf, hapd->conf->mld_id);
 	}
 
 	if (!mld_info)
@@ -589,8 +578,7 @@
 		wpabuf_put_le64(buf, 0);
 
 		/* DTIM Info */
-		wpabuf_put_u8(buf, 0); /* DTIM Count */
-		wpabuf_put_u8(buf, link_bss->conf->dtim_period);
+		wpabuf_put_le16(buf, link_bss->conf->dtim_period);
 
 		/* BSS Parameters Change Count */
 		wpabuf_put_u8(buf, hapd->eht_mld_bss_param_change);
@@ -824,7 +812,7 @@
 	wpabuf_put_u8(buf, WLAN_EID_EXT_MULTI_LINK);
 	wpabuf_put_le16(buf, MULTI_LINK_CONTROL_TYPE_BASIC);
 	wpabuf_put_u8(buf, ETH_ALEN + 1);
-	wpabuf_put_data(buf, hapd->mld->mld_addr, ETH_ALEN);
+	wpabuf_put_data(buf, hapd->mld_addr, ETH_ALEN);
 
 	return buf;
 }
@@ -1059,7 +1047,8 @@
 			if (hapd == other_hapd)
 				continue;
 
-			if (hostapd_is_ml_partner(hapd, other_hapd) &&
+			if (other_hapd->conf->mld_ap &&
+			    other_hapd->conf->mld_id == hapd->conf->mld_id &&
 			    link_id == other_hapd->mld_link_id)
 				break;
 		}
diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c
index a2deda6..4b693a7 100644
--- a/src/ap/ieee802_11_he.c
+++ b/src/ap/ieee802_11_he.c
@@ -12,7 +12,6 @@
 #include "utils/common.h"
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
-#include "common/hw_features_common.h"
 #include "hostapd.h"
 #include "ap_config.h"
 #include "beacon.h"
@@ -225,11 +224,10 @@
 		u8 seg0 = hapd->iconf->he_oper_centr_freq_seg0_idx;
 		u8 seg1 = hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf);
 		u8 control;
-#ifdef CONFIG_IEEE80211BE
-		u16 punct_bitmap = hostapd_get_punct_bitmap(hapd);
 
-		if (punct_bitmap) {
-			punct_update_legacy_bw(punct_bitmap,
+#ifdef CONFIG_IEEE80211BE
+		if (hapd->iconf->punct_bitmap) {
+			punct_update_legacy_bw(hapd->iconf->punct_bitmap,
 					       hapd->iconf->channel,
 					       &oper_chwidth, &seg0, &seg1);
 		}
diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c
index 85790c7..0c38483 100644
--- a/src/ap/ieee802_11_shared.c
+++ b/src/ap/ieee802_11_shared.c
@@ -121,7 +121,7 @@
 
 #ifdef CONFIG_IEEE80211BE
 	if (ap_sta_is_mld(hapd, sta))
-		own_addr = hapd->mld->mld_addr;
+		own_addr = hapd->mld_addr;
 #endif /* CONFIG_IEEE80211BE */
 
 	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
@@ -219,7 +219,7 @@
 
 #ifdef CONFIG_IEEE80211BE
 	if (ap_sta_is_mld(hapd, sta))
-		own_addr = hapd->mld->mld_addr;
+		own_addr = hapd->mld_addr;
 #endif /* CONFIG_IEEE80211BE */
 
 	resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
@@ -1138,11 +1138,13 @@
 u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta,
 		    const u8 *ext_capab_ie, size_t ext_capab_ie_len)
 {
+#ifdef CONFIG_INTERWORKING
 	/* check for QoS Map support */
 	if (ext_capab_ie_len >= 5) {
 		if (ext_capab_ie[4] & 0x01)
 			sta->qos_map_enabled = 1;
 	}
+#endif /* CONFIG_INTERWORKING */
 
 	if (ext_capab_ie_len > 0) {
 		sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2));
diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c
index 4dc325c..db615a3 100644
--- a/src/ap/ieee802_11_vht.c
+++ b/src/ap/ieee802_11_vht.c
@@ -12,7 +12,6 @@
 
 #include "utils/common.h"
 #include "common/ieee802_11_defs.h"
-#include "common/hw_features_common.h"
 #include "hostapd.h"
 #include "ap_config.h"
 #include "sta_info.h"
@@ -80,9 +79,6 @@
 		hostapd_get_oper_chwidth(hapd->iconf);
 	u8 seg0 = hapd->iconf->vht_oper_centr_freq_seg0_idx;
 	u8 seg1 = hapd->iconf->vht_oper_centr_freq_seg1_idx;
-#ifdef CONFIG_IEEE80211BE
-	u16 punct_bitmap = hostapd_get_punct_bitmap(hapd);
-#endif /* CONFIG_IEEE80211BE */
 
 	if (is_6ghz_op_class(hapd->iconf->op_class))
 		return eid;
@@ -94,8 +90,8 @@
 	os_memset(oper, 0, sizeof(*oper));
 
 #ifdef CONFIG_IEEE80211BE
-	if (punct_bitmap) {
-		punct_update_legacy_bw(punct_bitmap,
+	if (hapd->iconf->punct_bitmap) {
+		punct_update_legacy_bw(hapd->iconf->punct_bitmap,
 				       hapd->iconf->channel,
 				       &oper_chwidth, &seg0, &seg1);
 	}
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 8e98b65..f13c60a 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -172,7 +172,8 @@
 			struct hostapd_data *tmp_hapd =
 				hapd->iface->interfaces->iface[i]->bss[0];
 
-			if (!hostapd_is_ml_partner(hapd, tmp_hapd))
+			if (!tmp_hapd->conf->mld_ap ||
+			    hapd->conf->mld_id != tmp_hapd->conf->mld_id)
 				continue;
 
 			for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
@@ -2539,20 +2540,13 @@
 	struct eapol_auth_config conf;
 	struct eapol_auth_cb cb;
 
-#ifdef CONFIG_IEEE80211BE
-	if (!hostapd_mld_is_first_bss(hapd)) {
-		struct hostapd_data *first;
-
+	if (hapd->mld_first_bss) {
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Using IEEE 802.1X state machine of the first BSS");
 
-		first = hostapd_mld_get_first_bss(hapd);
-		if (!first)
-			return -1;
-		hapd->eapol_auth = first->eapol_auth;
+		hapd->eapol_auth = hapd->mld_first_bss->eapol_auth;
 		return 0;
 	}
-#endif /* CONFIG_IEEE80211BE */
 
 	dl_list_init(&hapd->erp_keys);
 
@@ -2638,15 +2632,13 @@
 
 void ieee802_1x_deinit(struct hostapd_data *hapd)
 {
-#ifdef CONFIG_IEEE80211BE
-	if (!hostapd_mld_is_first_bss(hapd)) {
+	if (hapd->mld_first_bss) {
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Deinit IEEE 802.1X state machine of a non-first BSS");
 
 		hapd->eapol_auth = NULL;
 		return;
 	}
-#endif /* CONFIG_IEEE80211BE */
 
 #ifdef CONFIG_WEP
 	eloop_cancel_timeout(ieee802_1x_rekey, hapd, NULL);
diff --git a/src/ap/ndisc_snoop.c b/src/ap/ndisc_snoop.c
index bc1eb62..788c12f 100644
--- a/src/ap/ndisc_snoop.c
+++ b/src/ap/ndisc_snoop.c
@@ -61,7 +61,6 @@
 	dl_list_for_each_safe(ip6addr, prev, &sta->ip6addr, struct ip6addr,
 			      list) {
 		hostapd_drv_br_delete_ip_neigh(hapd, 6, (u8 *) &ip6addr->addr);
-		dl_list_del(&ip6addr->list);
 		os_free(ip6addr);
 	}
 }
diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c
index f7a7d83..2a25ae2 100644
--- a/src/ap/neighbor_db.c
+++ b/src/ap/neighbor_db.c
@@ -99,10 +99,7 @@
 	nr->civic = NULL;
 	os_memset(nr->bssid, 0, sizeof(nr->bssid));
 	os_memset(&nr->ssid, 0, sizeof(nr->ssid));
-	os_memset(&nr->lci_date, 0, sizeof(nr->lci_date));
 	nr->stationary = 0;
-	nr->short_ssid = 0;
-	nr->bss_parameters = 0;
 }
 
 
@@ -168,14 +165,6 @@
 }
 
 
-static void hostapd_neighbor_free(struct hostapd_neighbor_entry *nr)
-{
-	hostapd_neighbor_clear_entry(nr);
-	dl_list_del(&nr->list);
-	os_free(nr);
-}
-
-
 int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
 			    const struct wpa_ssid_value *ssid)
 {
@@ -185,7 +174,9 @@
 	if (!nr)
 		return -1;
 
-	hostapd_neighbor_free(nr);
+	hostapd_neighbor_clear_entry(nr);
+	dl_list_del(&nr->list);
+	os_free(nr);
 
 	return 0;
 }
@@ -197,7 +188,9 @@
 
 	dl_list_for_each_safe(nr, prev, &hapd->nr_db,
 			      struct hostapd_neighbor_entry, list) {
-		hostapd_neighbor_free(nr);
+		hostapd_neighbor_clear_entry(nr);
+		dl_list_del(&nr->list);
+		os_free(nr);
 	}
 }
 
@@ -332,35 +325,3 @@
 	wpabuf_free(nr);
 #endif /* NEED_AP_MLME */
 }
-
-
-static struct hostapd_neighbor_entry *
-hostapd_neighbor_get_diff_short_ssid(struct hostapd_data *hapd, const u8 *bssid)
-{
-	struct hostapd_neighbor_entry *nr;
-
-	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
-			 list) {
-		if (ether_addr_equal(bssid, nr->bssid) &&
-		    nr->short_ssid != hapd->conf->ssid.short_ssid)
-			return nr;
-	}
-	return NULL;
-}
-
-
-int hostapd_neighbor_sync_own_report(struct hostapd_data *hapd)
-{
-	struct hostapd_neighbor_entry *nr;
-
-	nr = hostapd_neighbor_get_diff_short_ssid(hapd, hapd->own_addr);
-	if (!nr)
-		return -1;
-
-	/* Clear old entry due to SSID change */
-	hostapd_neighbor_free(nr);
-
-	hostapd_neighbor_set_own_report(hapd);
-
-	return 0;
-}
diff --git a/src/ap/neighbor_db.h b/src/ap/neighbor_db.h
index 53f7142..992671b 100644
--- a/src/ap/neighbor_db.h
+++ b/src/ap/neighbor_db.h
@@ -20,7 +20,6 @@
 			 const struct wpabuf *civic, int stationary,
 			 u8 bss_parameters);
 void hostapd_neighbor_set_own_report(struct hostapd_data *hapd);
-int hostapd_neighbor_sync_own_report(struct hostapd_data *hapd);
 int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
 			    const struct wpa_ssid_value *ssid);
 void hostapd_free_neighbor_db(struct hostapd_data *hapd);
diff --git a/src/ap/rrm.c b/src/ap/rrm.c
index fbcddf3..f2d5cd1 100644
--- a/src/ap/rrm.c
+++ b/src/ap/rrm.c
@@ -334,53 +334,6 @@
 }
 
 
-static void hostapd_link_mesr_rep_timeout_handler(void *eloop_data,
-						  void *user_ctx)
-{
-	struct hostapd_data *hapd = eloop_data;
-
-	wpa_printf(MSG_DEBUG,
-		   "RRM: Link measurement request (token %u) timed out",
-		   hapd->link_measurement_req_token);
-	hapd->link_mesr_req_active = 0;
-}
-
-
-static void hostapd_handle_link_mesr_report(struct hostapd_data *hapd,
-					    const u8 *buf, size_t len)
-{
-	const struct ieee80211_mgmt *mgmt = (const struct ieee80211_mgmt *) buf;
-	const struct rrm_link_measurement_report *report;
-	const u8 *pos, *end;
-	char report_msg[2 * 8 + 1];
-
-	end = buf + len;
-	pos = mgmt->u.action.u.rrm.variable;
-	report = (const struct rrm_link_measurement_report *) (pos - 1);
-	if (end - (const u8 *) report < (int) sizeof(*report))
-		return;
-
-	if (!hapd->link_mesr_req_active ||
-	    (hapd->link_measurement_req_token != report->dialog_token)) {
-		wpa_printf(MSG_INFO,
-			   "Unexpected Link measurement report, token %u",
-			   report->dialog_token);
-		return;
-	}
-
-	hapd->link_mesr_req_active = 0;
-	eloop_cancel_timeout(hostapd_link_mesr_rep_timeout_handler, hapd, NULL);
-
-	report_msg[0] = '\0';
-	if (wpa_snprintf_hex(report_msg, sizeof(report_msg),
-			     pos, end - pos) < 0)
-		return;
-
-	wpa_msg(hapd->msg_ctx, MSG_INFO, LINK_MSR_RESP_RX MACSTR " %u %s",
-		MAC2STR(mgmt->sa), report->dialog_token, report_msg);
-}
-
-
 void hostapd_handle_radio_measurement(struct hostapd_data *hapd,
 				      const u8 *buf, size_t len)
 {
@@ -403,9 +356,6 @@
 	case WLAN_RRM_NEIGHBOR_REPORT_REQUEST:
 		hostapd_handle_nei_report_req(hapd, buf, len);
 		break;
-	case WLAN_RRM_LINK_MEASUREMENT_REPORT:
-		hostapd_handle_link_mesr_report(hapd, buf, len);
-		break;
 	default:
 		wpa_printf(MSG_DEBUG, "RRM action %u is not supported",
 			   mgmt->u.action.u.rrm.action);
@@ -613,7 +563,6 @@
 	hapd->lci_req_active = 0;
 	eloop_cancel_timeout(hostapd_range_rep_timeout_handler, hapd, NULL);
 	hapd->range_req_active = 0;
-	eloop_cancel_timeout(hostapd_link_mesr_rep_timeout_handler, hapd, NULL);
 }
 
 
@@ -723,73 +672,3 @@
 		" %u ack=%d", MAC2STR(mgmt->da),
 		mgmt->u.action.u.rrm.dialog_token, ok);
 }
-
-
-int hostapd_send_link_measurement_req(struct hostapd_data *hapd, const u8 *addr)
-{
-	struct wpabuf *buf;
-	struct sta_info *sta;
-	int ret;
-
-	wpa_printf(MSG_DEBUG, "Request Link Measurement: dest addr " MACSTR,
-		   MAC2STR(addr));
-
-	if (!(hapd->iface->drv_rrm_flags &
-	      WPA_DRIVER_FLAGS_TX_POWER_INSERTION)) {
-		wpa_printf(MSG_INFO,
-			   "Request Link Measurement: the driver does not support TX power insertion");
-		return -1;
-	}
-
-	sta = ap_get_sta(hapd, addr);
-	if (!sta || !(sta->flags & WLAN_STA_AUTHORIZED)) {
-		wpa_printf(MSG_INFO,
-			   "Request Link Measurement: specied STA is not connected");
-		return -1;
-	}
-
-	if (!(sta->rrm_enabled_capa[0] & WLAN_RRM_CAPS_LINK_MEASUREMENT)) {
-		wpa_printf(MSG_INFO,
-			   "Request Link Measurement: destination STA does not support link measurement");
-		return -1;
-	}
-
-	if (hapd->link_mesr_req_active) {
-		wpa_printf(MSG_DEBUG,
-			   "Request Link Measurement: request already in process - overriding");
-		hapd->link_mesr_req_active = 0;
-		eloop_cancel_timeout(hostapd_link_mesr_rep_timeout_handler,
-				     hapd, NULL);
-	}
-
-	/* Action + Action type + token + Tx Power used + Max Tx Power = 5 */
-	buf = wpabuf_alloc(5);
-	if (!buf)
-		return -1;
-
-	hapd->link_measurement_req_token++;
-	if (!hapd->link_measurement_req_token)
-		hapd->link_measurement_req_token++;
-
-	wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
-	wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REQUEST);
-	wpabuf_put_u8(buf, hapd->link_measurement_req_token);
-	/* NOTE: The driver is expected to fill the Tx Power Used and Max Tx
-	 * Power */
-	wpabuf_put_u8(buf, 0);
-	wpabuf_put_u8(buf, 0);
-
-	ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr,
-				      wpabuf_head(buf), wpabuf_len(buf));
-	wpabuf_free(buf);
-	if (ret < 0)
-		return ret;
-
-	hapd->link_mesr_req_active = 1;
-
-	eloop_register_timeout(HOSTAPD_RRM_REQUEST_TIMEOUT, 0,
-			       hostapd_link_mesr_rep_timeout_handler, hapd,
-			       NULL);
-
-	return hapd->link_measurement_req_token;
-}
diff --git a/src/ap/rrm.h b/src/ap/rrm.h
index 17751e0..02cd522 100644
--- a/src/ap/rrm.h
+++ b/src/ap/rrm.h
@@ -29,7 +29,5 @@
 void hostapd_rrm_beacon_req_tx_status(struct hostapd_data *hapd,
 				      const struct ieee80211_mgmt *mgmt,
 				      size_t len, int ok);
-int hostapd_send_link_measurement_req(struct hostapd_data *hapd,
-				      const u8 *addr);
 
 #endif /* RRM_H */
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 32944ed..2178d65 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -180,26 +180,13 @@
 		sta->pasn->fils.erp_resp = NULL;
 #endif /* CONFIG_FILS */
 
-		pasn_data_deinit(sta->pasn);
+		bin_clear_free(sta->pasn, sizeof(*sta->pasn));
 		sta->pasn = NULL;
 	}
 }
 
 #endif /* CONFIG_PASN */
 
-
-static void __ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
-{
-#ifdef CONFIG_IEEE80211BE
-	if (hostapd_sta_is_link_sta(hapd, sta) &&
-	    !hostapd_drv_link_sta_remove(hapd, sta->addr))
-		return;
-#endif /* CONFIG_IEEE80211BE */
-
-	hostapd_drv_sta_remove(hapd, sta->addr);
-}
-
-
 void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
 {
 	int set_beacon = 0;
@@ -222,7 +209,7 @@
 
 	if (!hapd->iface->driver_ap_teardown &&
 	    !(sta->flags & WLAN_STA_PREAUTH)) {
-		__ap_free_sta(hapd, sta);
+		hostapd_drv_sta_remove(hapd, sta->addr);
 		sta->added_unassoc = 0;
 	}
 
@@ -467,27 +454,6 @@
 }
 
 
-#ifdef CONFIG_IEEE80211BE
-void hostapd_free_link_stas(struct hostapd_data *hapd)
-{
-	struct sta_info *sta, *prev;
-
-	sta = hapd->sta_list;
-	while (sta) {
-		prev = sta;
-		sta = sta->next;
-
-		if (!hostapd_sta_is_link_sta(hapd, prev))
-			continue;
-
-		wpa_printf(MSG_DEBUG, "Removing link station from MLD " MACSTR,
-			   MAC2STR(prev->addr));
-		ap_free_sta(hapd, prev);
-	}
-}
-#endif /* CONFIG_IEEE80211BE */
-
-
 /**
  * ap_handle_timer - Per STA timer handler
  * @eloop_ctx: struct hostapd_data *
@@ -1004,15 +970,16 @@
 	interfaces = assoc_hapd->iface->interfaces;
 
 	for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
-		if (!assoc_sta->mld_info.links[link_id].valid)
-			continue;
-
 		for (i = 0; i < interfaces->count; i++) {
 			struct sta_info *tmp_sta;
 
+			if (!assoc_sta->mld_info.links[link_id].valid)
+				continue;
+
 			tmp_hapd = interfaces->iface[i]->bss[0];
 
-			if (!hostapd_is_ml_partner(tmp_hapd, assoc_hapd))
+			if (!tmp_hapd->conf->mld_ap ||
+			    assoc_hapd->conf->mld_id != tmp_hapd->conf->mld_id)
 				continue;
 
 			for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
@@ -1466,7 +1433,7 @@
 	u8 addr[ETH_ALEN];
 	u8 ip_addr_buf[4];
 #endif /* CONFIG_P2P */
-	const u8 *ip_ptr = NULL;
+	u8 *ip_ptr = NULL;
 
 #ifdef CONFIG_P2P
 	if (hapd->p2p_group == NULL) {
@@ -1764,7 +1731,7 @@
 	unsigned int i, j;
 
 	for_each_mld_link(tmp_hapd, i, j, hapd->iface->interfaces,
-			  hostapd_get_mld_id(hapd)) {
+			  hapd->conf->mld_id) {
 		struct sta_info *tmp_sta;
 
 		if (hapd == tmp_hapd)
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index 153e4a0..b136ff7 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -440,6 +440,4 @@
 
 void ap_sta_free_sta_profile(struct mld_info *info);
 
-void hostapd_free_link_stas(struct hostapd_data *hapd);
-
 #endif /* STA_INFO_H */
diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
index af8ccca..b77e21b 100644
--- a/src/ap/wnm_ap.c
+++ b/src/ap/wnm_ap.c
@@ -51,7 +51,7 @@
 
 #ifdef CONFIG_IEEE80211BE
 	if (hapd->conf->mld_ap && (!sta || ap_sta_is_mld(hapd, sta)))
-		own_addr = hapd->mld->mld_addr;
+		own_addr = hapd->mld_addr;
 #endif /* CONFIG_IEEE80211BE */
 
 	return own_addr;
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 4bf8d79..3002d91 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -3345,7 +3345,10 @@
 	}
 
 	/* Find matching link ID and the MAC address for each link */
-	for_each_link(kde->valid_mlo_links, i) {
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+		if (!(kde->valid_mlo_links & BIT(i)))
+			continue;
+
 		/*
 		 * Each entry should contain the link information and the MAC
 		 * address.
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index 34de45c..b286a77 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -1559,7 +1559,8 @@
 			struct hostapd_iface *iface =
 				hapd->iface->interfaces->iface[j];
 
-			if (!hostapd_is_ml_partner(hapd, iface->bss[0]) ||
+			if (!iface->bss[0]->conf->mld_ap ||
+			    hapd->conf->mld_id != iface->bss[0]->conf->mld_id ||
 			    link_id != iface->bss[0]->mld_link_id ||
 			    !iface->bss[0]->wpa_auth)
 				continue;
@@ -1601,7 +1602,8 @@
 			struct hostapd_iface *iface =
 				hapd->iface->interfaces->iface[j];
 
-			if (!hostapd_is_ml_partner(hapd, iface->bss[0]) ||
+			if (!iface->bss[0]->conf->mld_ap ||
+			    hapd->conf->mld_id != iface->bss[0]->conf->mld_id ||
 			    link_id != iface->bss[0]->mld_link_id ||
 			    !iface->bss[0]->wpa_auth)
 				continue;