[rdkb][common][bsp][Refactor and sync wifi from openwrt]

[Description]
a05cc330 [MAC80211][WiFi6][mt76][rebase patches]
4bd6fb05 [MAC80211][WiFi6][mt76][Support spatial reuse debug commands]
f59fb1fe [MAC80211][WiFi7][misc][Add wifi-scripts packages]
52ac14cd [MAC80211][WiFi6][hostapd][Fix DFS radar trigger issue during first setup CAC]
7e33638a [MAC80211][WiFi6][Rebase Patches][Fix patch fail on mt76-2024-02-04]
b81d400b [MAC80211][Rebase Patches][Add support for WMM PBC configuration]
6e1f46b8 [MAC80211][WiFi6][mt76][Add support for WMM PBC configuration]
4a12d531 [mac80211][wifi6][mt76][Remove revert patch and add sanity check]
46c5e65d [mac80211][wifi6][mt76][Fix tx statistics]
d9b7c50d [MAC80211][WiFi6][mt76][Fix patch fail]
c8c49a13 [MAC80211][WiFi6][mt76][Add no_beacon vendor command for cert]
620200d9 [MAC80211][WiFi6][mt76][Remove redundant argument in add_beacon function]
f5fe56a6 [MAC80211][WiFi6][hostapd][New support for single BSS operations]
ff6e20a8 [MAC80211][WiFi6][hostapd][ACS: remove chan/freq list check when scan request and factor calculation]
3f25a0e5 [MAC80211][WiFi6][mt76][Fix bug in VoW DebugFS command]
33cb7faf [MAC80211][WiFi6][core][Sync wifi7 cert SQC fix to wifi6]
3a1c492a [MAC80211][WiFi6][core][Add support for scan dwell time customization]
7e7a47e4 [mac80211][wifi6][mt76][Fix patch fail]
5fc4c9d6 [MAC80211][misc][Fix external build fail of MAC80211]
b5d42444 [mac80211][wifi6][mt76][add support for realtime Rx rate updates]
638298f6 [mac80211][WiFi7][misc][Fix patch fail]
5c710bc2 [MAC80211][WiFi6][mt76][Add efuse content dump for cal free data verification]

[Release-log]

Change-Id: Ia86a987807efb6f1ef119e2e46232ce08afca96e
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch
index 82b66f4..4e24ba6 100644
--- a/recipes-wifi/wpa-supplicant/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch
@@ -1,19 +1,19 @@
-From 018d87d5b9b53b3e630032bf2cb7e6eaeae09d71 Mon Sep 17 00:00:00 2001
+From 22adaf9edb6e4e60dbe5c7cc8366c08b8141571f Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 15 Nov 2023 15:06:00 +0800
-Subject: [PATCH 47/49] hostapd: mtk: add support for channel switching to dfs
- with csa sent
+Subject: [PATCH] hostapd: mtk: add support for channel switching to dfs with
+ csa sent
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
  hostapd/ctrl_iface.c | 26 ++------------------------
  src/ap/beacon.c      |  5 +++++
- src/ap/dfs.c         | 16 ++++++++++++----
+ src/ap/dfs.c         | 18 ++++++++++++++----
  src/ap/ieee802_11.c  |  5 +++++
- 4 files changed, 24 insertions(+), 28 deletions(-)
+ 4 files changed, 26 insertions(+), 28 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index b521a08..0afa6a2 100644
+index b0117e5..96b593a 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -2747,7 +2747,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
@@ -73,7 +73,7 @@
  
  	if (ieee802_11_build_ap_params(hapd, &params) < 0)
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 80d3605..012050c 100644
+index 80d3605..d490032 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -1255,10 +1255,10 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
@@ -90,21 +90,23 @@
  
  			/*
  			 * When background radar is enabled but the CAC completion
-@@ -1272,6 +1272,13 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
+@@ -1272,6 +1272,15 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
  	} else if (hostapd_dfs_is_background_event(iface, freq)) {
  		iface->radar_background.cac_started = 0;
  		hostpad_dfs_update_background_chain(iface);
 +	} else {
 +		int i;
 +
-+		iface->cac_started = 0;
++		/* If interface is already setup, clear cac_started flag to avoid re-setup */
++		if (iface->state == HAPD_IFACE_ENABLED)
++			iface->cac_started = 0;
 +		/* Clear all CSA flags once channel switch to DFS channel fails */
 +		for (i = 0; i < iface->num_bss; i++)
 +			iface->bss[i]->csa_in_progress = 0;
  	}
  
  	return 0;
-@@ -1646,7 +1653,8 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
+@@ -1646,7 +1655,8 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
  	} else {
  		/* This is called when the driver indicates that an offloaded
  		 * DFS has started CAC. */
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0050-hostapd-mtk-add-support-for-removeing-the-main-BSS.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0050-hostapd-mtk-add-support-for-removeing-the-main-BSS.patch
new file mode 100644
index 0000000..d6f13f1
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0050-hostapd-mtk-add-support-for-removeing-the-main-BSS.patch
@@ -0,0 +1,284 @@
+From cc04411d78f2569cc235e0f5620b3476091a1af1 Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Thu, 14 Dec 2023 14:42:58 +0800
+Subject: [PATCH 1/2] hostapd: mtk: add support for removeing the main BSS
+
+The first hostapd_data/i802_bss are important to hostapd since many
+operations/events are directly operated on the first BSS.
+(such as iface->bss[0], drv->first_bss, etc)
+
+To remove the main BSS, the 1st and 2nd hostapd_data/i802_bss are
+switched, then the new 2nd hostapd_data/i802_bss are removed as it is
+done to remove BSS other than the first one.
+
+This patch add the new command to remove the BSS (including the first
+one):
+$ hostapd_cli -i global raw REMOVE_BSS <ifname>
+
+Note that if the command is used in OpenWrt, an additional step is
+needed:
+update the "aplist" in /var/state/wireless according to the removed ifname
+Therefore the "wifi" command can work normally.
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ hostapd/ctrl_iface.c         | 14 ++++++
+ src/ap/ap_drv_ops.h          | 10 +++++
+ src/ap/hostapd.c             | 85 +++++++++++++++++++++++++++++++++++-
+ src/ap/hostapd.h             |  1 +
+ src/drivers/driver.h         |  2 +
+ src/drivers/driver_nl80211.c | 43 ++++++++++++++++++
+ 6 files changed, 153 insertions(+), 2 deletions(-)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index 6552bc4..650af3b 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -5028,6 +5028,17 @@ static int hostapd_ctrl_iface_add(struct hapd_interfaces *interfaces,
+ }
+ 
+ 
++static int hostapd_ctrl_bss_remove(struct hapd_interfaces *interfaces,
++				   char *buf)
++{
++	if (hostapd_remove_bss(interfaces, buf) < 0) {
++		wpa_printf(MSG_ERROR, "Removing interface %s failed", buf);
++		return -1;
++	}
++	return 0;
++}
++
++
+ static int hostapd_ctrl_iface_remove(struct hapd_interfaces *interfaces,
+ 				     char *buf)
+ {
+@@ -5444,6 +5455,9 @@ static void hostapd_global_ctrl_iface_receive(int sock, void *eloop_ctx,
+ 	} else if (os_strncmp(buf, "REMOVE ", 7) == 0) {
+ 		if (hostapd_ctrl_iface_remove(interfaces, buf + 7) < 0)
+ 			reply_len = -1;
++	} else if (os_strncmp(buf, "REMOVE_BSS ", 11) == 0) {
++		if (hostapd_ctrl_bss_remove(interfaces, buf + 11) < 0)
++			reply_len = -1;
+ 	} else if (os_strcmp(buf, "ATTACH") == 0) {
+ 		if (hostapd_global_ctrl_iface_attach(interfaces, &from,
+ 						     fromlen, NULL))
+diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
+index 2a89b99..95db664 100644
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -310,6 +310,16 @@ static inline const char * hostapd_drv_get_radio_name(struct hostapd_data *hapd)
+ 	return hapd->driver->get_radio_name(hapd->drv_priv);
+ }
+ 
++static inline int hostapd_drv_move_bss_to_first(struct hostapd_data *hapd,
++						const char *ifname)
++{
++	if (hapd->driver == NULL || hapd->driver->move_bss_to_first == NULL ||
++	    hapd->drv_priv == NULL)
++		return -1;
++
++	return hapd->driver->move_bss_to_first(hapd->drv_priv, ifname);
++}
++
+ static inline int hostapd_drv_switch_channel(struct hostapd_data *hapd,
+ 					     struct csa_settings *settings)
+ {
+diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
+index 250c168..7f58354 100644
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -3297,7 +3297,35 @@ fail:
+ }
+ 
+ 
+-static int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx)
++int hostapd_move_bss_to_first(struct hostapd_iface *iface, int idx)
++{
++	struct hostapd_data *target_hapd, *first_hapd;
++
++	if (idx == 0 || idx >= iface->num_bss)
++		return -1;
++
++	target_hapd = iface->bss[idx];
++	first_hapd = iface->bss[0];
++	if (hostapd_drv_move_bss_to_first(first_hapd, target_hapd->conf->iface))
++		return -1;
++
++	iface->bss[0] = target_hapd;
++	iface->bss[idx] = first_hapd;
++	iface->conf->bss[0] = iface->bss[0]->conf;
++	iface->conf->bss[idx] = iface->bss[idx]->conf;
++
++	first_hapd->interface_added = 1;
++	target_hapd->interface_added = 0;
++
++	if (idx == iface->num_bss - 1)
++		iface->conf->last_bss = iface->bss[idx]->conf;
++
++	return 0;
++}
++
++
++static int hostapd_remove_bss_by_idx(struct hostapd_iface *iface,
++				     unsigned int idx)
+ {
+ 	size_t i;
+ 
+@@ -3331,6 +3359,59 @@ static int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx)
+ }
+ 
+ 
++int hostapd_remove_bss(struct hapd_interfaces *interfaces, char *buf)
++{
++	struct hostapd_iface *hapd_iface;
++	size_t i, j, k = 0;
++	int ret;
++
++	for (i = 0; i < interfaces->count; i++) {
++		hapd_iface = interfaces->iface[i];
++		if (hapd_iface == NULL)
++			return -1;
++
++		if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
++			if (hapd_iface->conf->num_bss == 1) {
++				wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
++				hapd_iface->driver_ap_teardown =
++					!!(hapd_iface->drv_flags &
++					   WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
++
++				hostapd_interface_deinit_free(hapd_iface);
++				k = i;
++				while (k < (interfaces->count - 1)) {
++					interfaces->iface[k] =
++						interfaces->iface[k + 1];
++					k++;
++				}
++				interfaces->count--;
++				return 0;
++			} else {
++				wpa_printf(MSG_INFO, "Switch interface to %s",
++					   hapd_iface->bss[1]->conf->iface);
++
++				ret = hostapd_move_bss_to_first(hapd_iface, 1);
++				if (ret < 0) {
++					wpa_printf(MSG_ERROR,
++						   "Interface switch failed");
++					return ret;
++				}
++			}
++		}
++
++		for (j = 0; j < hapd_iface->conf->num_bss; j++) {
++			if (!os_strcmp(hapd_iface->conf->bss[j]->iface, buf)) {
++				hapd_iface->driver_ap_teardown =
++					!(hapd_iface->drv_flags &
++					  WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
++				return hostapd_remove_bss_by_idx(hapd_iface, j);
++			}
++		}
++	}
++	return -1;
++}
++
++
+ int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf)
+ {
+ 	struct hostapd_iface *hapd_iface;
+@@ -3362,7 +3443,7 @@ int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf)
+ 				hapd_iface->driver_ap_teardown =
+ 					!(hapd_iface->drv_flags &
+ 					  WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
+-				return hostapd_remove_bss(hapd_iface, j);
++				return hostapd_remove_bss_by_idx(hapd_iface, j);
+ 			}
+ 		}
+ 	}
+diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
+index 3b51050..824a24a 100644
+--- a/src/ap/hostapd.h
++++ b/src/ap/hostapd.h
+@@ -701,6 +701,7 @@ void hostapd_bss_deinit_no_free(struct hostapd_data *hapd);
+ void hostapd_free_hapd_data(struct hostapd_data *hapd);
+ void hostapd_cleanup_iface_partial(struct hostapd_iface *iface);
+ int hostapd_add_iface(struct hapd_interfaces *ifaces, char *buf);
++int hostapd_remove_bss(struct hapd_interfaces *ifaces, char *buf);
+ int hostapd_remove_iface(struct hapd_interfaces *ifaces, char *buf);
+ void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator);
+ void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s);
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index 01281a1..ab19794 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -3185,6 +3185,8 @@ struct wpa_driver_ops {
+ 	 */
+ 	void (*hapd_deinit)(void *priv);
+ 
++	int (*move_bss_to_first)(void *priv, const char *ifname);
++
+ 	/**
+ 	 * set_ieee8021x - Enable/disable IEEE 802.1X support (AP only)
+ 	 * @priv: Private driver interface data
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index e744a18..cef502f 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -7986,6 +7986,48 @@ static void i802_deinit(void *priv)
+ 	wpa_driver_nl80211_deinit(bss);
+ }
+ 
++static int i802_move_bss_to_first(void *priv, const char *ifname)
++{
++	struct i802_bss *bss = priv;
++	struct i802_bss *first_bss, *target_bss, *prev_bss, *tmp_bss;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++
++	if (!os_strcmp(bss->ifname, ifname)) {
++		wpa_printf(MSG_ERROR, "nl80211: BSS is already the first one");
++		return -1;
++	}
++
++	prev_bss = drv->first_bss;
++	target_bss = drv->first_bss->next;
++	while (target_bss) {
++		if (!os_strcmp(target_bss->ifname, ifname))
++			break;
++
++		prev_bss = target_bss;
++		target_bss = target_bss->next;
++	}
++
++	if (!target_bss) {
++		wpa_printf(MSG_ERROR, "nl80211: Failed to find the target BSS");
++		return -1;
++	}
++
++	first_bss = drv->first_bss;
++	drv->first_bss = target_bss;
++	prev_bss->next = first_bss;
++
++	tmp_bss = first_bss->next;
++	first_bss->next = target_bss->next;
++	target_bss->next = tmp_bss;
++
++	memcpy(drv->perm_addr, drv->first_bss->addr, ETH_ALEN);
++	drv->ifindex = if_nametoindex(drv->first_bss->ifname);
++	drv->ctx = drv->first_bss->ctx;
++
++	first_bss->added_if = 1;
++	target_bss->added_if = 0;
++	return 0;
++}
+ 
+ static enum nl80211_iftype wpa_driver_nl80211_if_type(
+ 	enum wpa_driver_if_type type)
+@@ -13433,6 +13475,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+ 	.sta_set_airtime_weight = driver_nl80211_sta_set_airtime_weight,
+ 	.hapd_init = i802_init,
+ 	.hapd_deinit = i802_deinit,
++	.move_bss_to_first = i802_move_bss_to_first,
+ 	.set_wds_sta = i802_set_wds_sta,
+ 	.get_seqnum = i802_get_seqnum,
+ 	.flush = i802_flush,
+-- 
+2.25.1
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0051-hostapd-mtk-add-support-for-enable-disable-single-BS.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0051-hostapd-mtk-add-support-for-enable-disable-single-BS.patch
new file mode 100644
index 0000000..dd9795a
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0051-hostapd-mtk-add-support-for-enable-disable-single-BS.patch
@@ -0,0 +1,248 @@
+From be968a6aeea80dca7661e59e0ab5db32341cadb8 Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Mon, 18 Dec 2023 11:35:34 +0800
+Subject: [PATCH 2/2] hostapd: mtk: add support for enable/disable single BSS
+
+Enabling or disabling single BSS mean that the beacon of the BSS is
+enabled or disabled.
+
+When the BSS is disabled, the following statements are true:
+1. the events or packets from the driver are all ignored.
+2. Per radio functions (ex. channel switch, color change) will not
+   execute for the BSS, but are finished by other enabling BSS(es).
+   The changed parameters take effect when the BSS is enabled again.
+3. Enabling the BSS will not reload the configuration. In other word,
+   if the configuration changes during the BSS disabling, the BSS needs
+   to be removed and added again, not just be enabled.
+
+This patch add new commands to enable/disable single BSS:
+$ hostapd_cli -i <ifname> enable_bss
+$ hostapd_cli -i <ifname> disable_bss
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ hostapd/ctrl_iface.c               | 26 ++++++++++++++++++++
+ hostapd/hostapd_cli.c              | 18 ++++++++++++++
+ src/ap/hostapd.c                   | 39 ++++++++++++++++++++++++++++++
+ src/ap/hostapd.h                   |  2 ++
+ src/drivers/driver_nl80211.c       | 11 +++++++++
+ src/drivers/driver_nl80211_event.c |  6 +++++
+ 6 files changed, 102 insertions(+)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index 650af3b..a980c0b 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -1590,6 +1590,16 @@ static int hostapd_ctrl_iface_get(struct hostapd_data *hapd, char *cmd,
+ }
+ 
+ 
++static int hostapd_ctrl_iface_enable_bss(struct hostapd_data *hapd)
++{
++	if (hostapd_enable_bss(hapd) < 0) {
++		wpa_printf(MSG_ERROR, "Enabling of BSS failed");
++		return -1;
++	}
++	return 0;
++}
++
++
+ static int hostapd_ctrl_iface_enable(struct hostapd_iface *iface)
+ {
+ 	if (hostapd_enable_iface(iface) < 0) {
+@@ -1610,6 +1620,16 @@ static int hostapd_ctrl_iface_reload(struct hostapd_iface *iface)
+ }
+ 
+ 
++static int hostapd_ctrl_iface_disable_bss(struct hostapd_data *hapd)
++{
++	if (hostapd_disable_bss(hapd) < 0) {
++		wpa_printf(MSG_ERROR, "Disabling of BSS failed");
++		return -1;
++	}
++	return 0;
++}
++
++
+ static int hostapd_ctrl_iface_disable(struct hostapd_iface *iface)
+ {
+ 	if (hostapd_disable_iface(iface) < 0) {
+@@ -4196,6 +4216,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 	} else if (os_strncmp(buf, "GET ", 4) == 0) {
+ 		reply_len = hostapd_ctrl_iface_get(hapd, buf + 4, reply,
+ 						   reply_size);
++	} else if (os_strncmp(buf, "ENABLE_BSS", 10) == 0) {
++		if (hostapd_ctrl_iface_enable_bss(hapd))
++			reply_len = -1;
+ 	} else if (os_strncmp(buf, "ENABLE", 6) == 0) {
+ 		if (hostapd_ctrl_iface_enable(hapd->iface))
+ 			reply_len = -1;
+@@ -4205,6 +4228,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 	} else if (os_strncmp(buf, "RELOAD", 6) == 0) {
+ 		if (hostapd_ctrl_iface_reload(hapd->iface))
+ 			reply_len = -1;
++	} else if (os_strncmp(buf, "DISABLE_BSS", 11) == 0) {
++		if (hostapd_ctrl_iface_disable_bss(hapd))
++			reply_len = -1;
+ 	} else if (os_strncmp(buf, "DISABLE", 7) == 0) {
+ 		if (hostapd_ctrl_iface_disable(hapd->iface))
+ 			reply_len = -1;
+diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
+index 0c4a176..c8f0566 100644
+--- a/hostapd/hostapd_cli.c
++++ b/hostapd/hostapd_cli.c
+@@ -1215,6 +1215,13 @@ static int hostapd_cli_cmd_enable(struct wpa_ctrl *ctrl, int argc,
+ }
+ 
+ 
++static int hostapd_cli_cmd_enable_bss(struct wpa_ctrl *ctrl, int argc,
++				      char *argv[])
++{
++	return wpa_ctrl_command(ctrl, "ENABLE_BSS");
++}
++
++
+ static int hostapd_cli_cmd_reload(struct wpa_ctrl *ctrl, int argc,
+ 				      char *argv[])
+ {
+@@ -1229,6 +1236,13 @@ static int hostapd_cli_cmd_disable(struct wpa_ctrl *ctrl, int argc,
+ }
+ 
+ 
++static int hostapd_cli_cmd_disable_bss(struct wpa_ctrl *ctrl, int argc,
++				       char *argv[])
++{
++	return wpa_ctrl_command(ctrl, "DISABLE_BSS");
++}
++
++
+ static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
+ 				      char *argv[])
+ {
+@@ -1731,10 +1745,14 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
+ 	  "  = send vendor driver command" },
+ 	{ "enable", hostapd_cli_cmd_enable, NULL,
+ 	  "= enable hostapd on current interface" },
++	{ "enable_bss", hostapd_cli_cmd_enable_bss, NULL,
++	  "= enable hostapd on current BSS" },
+ 	{ "reload", hostapd_cli_cmd_reload, NULL,
+ 	  "= reload configuration for current interface" },
+ 	{ "disable", hostapd_cli_cmd_disable, NULL,
+ 	  "= disable hostapd on current interface" },
++	{ "disable_bss", hostapd_cli_cmd_disable_bss, NULL,
++	  "= disable hostapd on current BSS" },
+ 	{ "update_beacon", hostapd_cli_cmd_update_beacon, NULL,
+ 	  "= update Beacon frame contents\n"},
+ 	{ "erp_flush", hostapd_cli_cmd_erp_flush, NULL,
+diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
+index 7f58354..8b4fc4e 100644
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -3297,6 +3297,42 @@ fail:
+ }
+ 
+ 
++int hostapd_enable_bss(struct hostapd_data *hapd)
++{
++	if (hapd->beacon_set_done)
++		return 0;
++
++	if (hapd->conf->bss_load_update_period && bss_load_update_init(hapd)) {
++		wpa_printf(MSG_ERROR, "BSS Load initialization failed");
++		return -1;
++	}
++	return ieee802_11_set_beacon(hapd);
++}
++
++
++int hostapd_disable_bss(struct hostapd_data *hapd)
++{
++	struct hostapd_iface *iface = hapd->iface;
++	int i, remain_bss = 0;
++
++	if (!hapd->beacon_set_done)
++		return 0;
++
++	for (i = 0; i < iface->num_bss; i++)
++		remain_bss += iface->bss[i]->beacon_set_done ? 1 : 0;
++
++	if (remain_bss == 1) {
++		wpa_printf(MSG_ERROR, "Cannot disable last BSS");
++		return -1;
++	}
++
++	hapd->beacon_set_done = 0;
++	bss_load_update_deinit(hapd);
++	hostapd_bss_deinit_no_free(hapd);
++	return hostapd_drv_stop_ap(hapd);
++}
++
++
+ int hostapd_move_bss_to_first(struct hostapd_iface *iface, int idx)
+ {
+ 	struct hostapd_data *target_hapd, *first_hapd;
+@@ -3905,6 +3941,9 @@ int hostapd_switch_channel(struct hostapd_data *hapd,
+ {
+ 	int ret;
+ 
++	if (!hapd->beacon_set_done)
++		return 0;
++
+ 	if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) {
+ 		wpa_printf(MSG_INFO, "CSA is not supported");
+ 		return -1;
+diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
+index 824a24a..88ff1ca 100644
+--- a/src/ap/hostapd.h
++++ b/src/ap/hostapd.h
+@@ -701,6 +701,8 @@ void hostapd_bss_deinit_no_free(struct hostapd_data *hapd);
+ void hostapd_free_hapd_data(struct hostapd_data *hapd);
+ void hostapd_cleanup_iface_partial(struct hostapd_iface *iface);
+ int hostapd_add_iface(struct hapd_interfaces *ifaces, char *buf);
++int hostapd_enable_bss(struct hostapd_data *hapd);
++int hostapd_disable_bss(struct hostapd_data *hapd);
+ int hostapd_remove_bss(struct hapd_interfaces *ifaces, char *buf);
+ int hostapd_remove_iface(struct hapd_interfaces *ifaces, char *buf);
+ void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator);
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index cef502f..8e8e194 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -4693,6 +4693,17 @@ static int wpa_driver_nl80211_set_ap(void *priv,
+ 	wpa_printf(MSG_DEBUG, "nl80211: dtim_period=%d", params->dtim_period);
+ 	wpa_printf(MSG_DEBUG, "nl80211: ssid=%s",
+ 		   wpa_ssid_txt(params->ssid, params->ssid_len));
++
++	if (!beacon_set) {
++		/* update wdev->preset_chandef in MAC80211 */
++		ret = nl80211_set_channel(bss, params->freq, 1);
++		if (ret) {
++			wpa_printf(MSG_ERROR,
++				   "nl80211: Frequency set failed: %d (%s)",
++				   ret, strerror(-ret));
++		}
++	}
++
+ 	if (!(msg = nl80211_bss_msg(bss, 0, cmd)) ||
+ 	    nla_put(msg, NL80211_ATTR_BEACON_HEAD, params->head_len,
+ 		    params->head) ||
+diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
+index 585d207..6600c9c 100644
+--- a/src/drivers/driver_nl80211_event.c
++++ b/src/drivers/driver_nl80211_event.c
+@@ -1094,6 +1094,12 @@ static void mlme_event(struct i802_bss *bss,
+ 		return;
+ 	}
+ 
++	if (is_ap_interface(drv->nlmode) && !bss->beacon_set) {
++		wpa_printf(MSG_DEBUG,
++			   "nl80211: drop BSS Event due to disabled BSS");
++		return;
++	}
++
+ 	if (frame == NULL) {
+ 		wpa_printf(MSG_DEBUG,
+ 			   "nl80211: MLME event %d (%s) without frame data",
+-- 
+2.25.1
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0052-hostapd-mtk-ACS-remove-chan-freq-list-check-when-sca.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0052-hostapd-mtk-ACS-remove-chan-freq-list-check-when-sca.patch
new file mode 100644
index 0000000..1099ef2
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0052-hostapd-mtk-ACS-remove-chan-freq-list-check-when-sca.patch
@@ -0,0 +1,44 @@
+From 7f442586bbff0c7b6aca157237b442291b90116b Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Tue, 23 Jan 2024 10:52:57 +0800
+Subject: [PATCH] hostapd: mtk: ACS: remove chan/freq list check when scan
+ request and factor calculation
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ src/ap/acs.c | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index e4871921f..089d9c5f4 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -590,12 +590,6 @@ static void acs_survey_mode_interference_factor(
+ 		    iface->conf->acs_exclude_dfs)
+ 			continue;
+ 
+-		if (!is_in_chanlist(iface, chan))
+-			continue;
+-
+-		if (!is_in_freqlist(iface, chan))
+-			continue;
+-
+ 		if (chan->max_tx_power < iface->conf->min_tx_power)
+ 			continue;
+ 
+@@ -1327,12 +1321,6 @@ static int * acs_request_scan_add_freqs(struct hostapd_iface *iface,
+ 		     iface->conf->acs_exclude_dfs))
+ 			continue;
+ 
+-		if (!is_in_chanlist(iface, chan))
+-			continue;
+-
+-		if (!is_in_freqlist(iface, chan))
+-			continue;
+-
+ 		if (chan->max_tx_power < iface->conf->min_tx_power)
+ 			continue;
+ 
+-- 
+2.25.1
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0053-hostapd-mtk-add-no_beacon-vendor-command-for-cert.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0053-hostapd-mtk-add-no_beacon-vendor-command-for-cert.patch
new file mode 100644
index 0000000..e99e2a3
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0053-hostapd-mtk-add-no_beacon-vendor-command-for-cert.patch
@@ -0,0 +1,240 @@
+From e621aacd1eb69668a8e9176b4cd09125394d2fb8 Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
+Date: Wed, 24 Jan 2024 15:15:26 +0800
+Subject: [PATCH] hostapd: mtk: add no_beacon vendor command for cert
+
+Add the vendor command to disable/enable beacon
+
+[Usage]
+hostapd_cli -i <interface> no_beacon <value>
+ <value>
+ 0: enable beacon
+ 1: disable beacon
+---
+ hostapd/ctrl_iface.c              | 18 +++++++++++++++++
+ hostapd/hostapd_cli.c             |  7 +++++++
+ src/ap/ap_drv_ops.c               |  7 +++++++
+ src/ap/ap_drv_ops.h               |  1 +
+ src/common/mtk_vendor.h           | 12 +++++++++++
+ src/drivers/driver.h              |  7 +++++++
+ src/drivers/driver_nl80211.c      | 33 +++++++++++++++++++++++++++++++
+ src/drivers/driver_nl80211.h      |  1 +
+ src/drivers/driver_nl80211_capa.c |  3 +++
+ 9 files changed, 89 insertions(+)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index bacf14c..c662417 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -4034,6 +4034,22 @@ hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
+ 	return os_snprintf(buf, buflen, "OK\n");
+ }
+ 
++static int
++hostapd_ctrl_iface_disable_beacon(struct hostapd_data *hapd, char *value,
++				  char *buf, size_t buflen)
++{
++	int disable_beacon = atoi(value);
++
++	if (disable_beacon < 0) {
++		wpa_printf(MSG_ERROR, "Invalid value for beacon ctrl");
++		return -1;
++	}
++
++	if (hostapd_drv_beacon_ctrl(hapd, !disable_beacon) == 0)
++		return os_snprintf(buf, buflen, "OK\n");
++	else
++		return -1;
++}
+ 
+ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 					      char *buf, char *reply,
+@@ -4615,6 +4631,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 							reply, reply_size);
+ 	} else if (os_strncmp(buf, "SET_OFFCHAN_CTRL", 16) == 0) {
+ 		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
++	} else if (os_strncmp(buf, "NO_BEACON ", 10) == 0) {
++		reply_len = hostapd_ctrl_iface_disable_beacon(hapd, buf + 10, reply, reply_size);
+ 	} else {
+ 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
+ 		reply_len = 16;
+diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
+index 0c4a176..60e963a 100644
+--- a/hostapd/hostapd_cli.c
++++ b/hostapd/hostapd_cli.c
+@@ -1393,6 +1393,11 @@ static int hostapd_cli_cmd_get_mu(struct wpa_ctrl *ctrl, int argc,
+ 	return hostapd_cli_cmd(ctrl, "GET_MU", 0, NULL, NULL);
+ }
+ 
++static int hostapd_cli_cmd_disable_beacon(struct wpa_ctrl *ctrl, int argc,
++					  char *argv[])
++{
++	return hostapd_cli_cmd(ctrl, "NO_BEACON", 1, argc, argv);
++}
+ 
+ #ifdef CONFIG_DPP
+ 
+@@ -1762,6 +1767,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
+ 		"<value> [0-15] bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0)"},
+ 	{ "get_mu", hostapd_cli_cmd_get_mu, NULL,
+ 		" = show mu onoff value in 0-15 bitmap"},
++	{ "no_beacon", hostapd_cli_cmd_disable_beacon, NULL,
++		"<value> 0: Enable beacon, 1: Disable beacon"},
+ #ifdef CONFIG_DPP
+ 	{ "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
+ 	  "report a scanned DPP URI from a QR Code" },
+diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
+index a060f5c..b1f7c92 100644
+--- a/src/ap/ap_drv_ops.c
++++ b/src/ap/ap_drv_ops.c
+@@ -1143,3 +1143,10 @@ int hostapd_drv_amnt_dump(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_dump_
+ 		return 0;
+ 	return hapd->driver->amnt_dump(hapd->drv_priv, amnt_idx, amnt_dump_buf);
+ }
++
++int hostapd_drv_beacon_ctrl(struct hostapd_data *hapd, u8 beacon_mode)
++{
++		if (!hapd->driver || !hapd->driver->beacon_ctrl)
++			return 0;
++		return hapd->driver->beacon_ctrl(hapd->drv_priv, beacon_mode);
++}
+diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
+index 5f11a57..c5fdb00 100644
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -158,6 +158,7 @@ int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
+ 
+ int hostapd_drv_amnt_set(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_sta_mac);
+ int hostapd_drv_amnt_dump(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_dump_buf);
++int hostapd_drv_beacon_ctrl(struct hostapd_data *hapd, u8 beacon_mode);
+ 
+ #include "drivers/driver.h"
+ 
+diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
+index 21e735f..c7ed8e8 100644
+--- a/src/common/mtk_vendor.h
++++ b/src/common/mtk_vendor.h
+@@ -16,6 +16,7 @@ enum mtk_nl80211_vendor_subcmds {
+ 	MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL = 0xc8,
+ 	MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL = 0xc9,
+ 	MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
++	MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL = 0xcd,
+ 	MTK_NL80211_VENDOR_SUBCMD_TXPOWER_CTRL = 0xce,
+ };
+ 
+@@ -253,6 +254,17 @@ enum mtk_vendor_attr_txpower_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_TXPOWER_CTRL - 1
+ };
+ 
++enum mtk_vendor_attr_beacon_ctrl {
++	MTK_VENDOR_ATTR_BEACON_CTRL_UNSPEC,
++
++	MTK_VENDOR_ATTR_BEACON_CTRL_MODE,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_BEACON_CTRL,
++	MTK_VENDOR_ATTR_BEACON_CTRL_MAX =
++		NUM_MTK_VENDOR_ATTRS_BEACON_CTRL - 1
++};
++
+ #define CSI_MAX_COUNT 256
+ #define ETH_ALEN 6
+ 
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index 0e3934e..f420464 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -4749,6 +4749,13 @@ struct wpa_driver_ops {
+ 	 int (*mu_ctrl)(void *priv, u8 mode, u8 val);
+ 	 int (*mu_dump)(void *priv, u8 *mu_onoff);
+ 
++	/**
++	* beacon_ctrl - ctrl on off for beacon
++	* @priv: Private driver interface data
++	*
++	*/
++	int (*beacon_ctrl)(void *priv, u8 beacon_mode);
++
+ 	/**
+ 	 * three_wire_ctrl - set three_wire_ctrl mode
+ 	 * @priv: Private driver interface data
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index c8720bb..a1ce671 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -12565,6 +12565,38 @@ static int nl80211_mu_dump(void *priv, u8 *mu_onoff)
+ }
+ #endif /* CONFIG_IEEE80211AX */
+ 
++static int nl80211_beacon_ctrl(void *priv, u8 beacon_mode)
++{
++	struct i802_bss *bss = priv;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct nl_msg *msg;
++	struct nlattr *data;
++	int ret;
++
++	if (!drv->mtk_beacon_ctrl_vendor_cmd_avail) {
++		wpa_printf(MSG_ERROR,
++			   "nl80211: Driver does not support setting beacon control");
++		return 0;
++	}
++
++	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL) ||
++		!(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
++		nla_put_u8(msg, MTK_VENDOR_ATTR_BEACON_CTRL_MODE, beacon_mode)) {
++		nlmsg_free(msg);
++		return -ENOBUFS;
++	}
++
++	nla_nest_end(msg, data);
++
++	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
++
++	if (ret)
++		wpa_printf(MSG_ERROR, "Failed to set beacon_ctrl. ret=%d (%s)", ret, strerror(-ret));
++
++	return ret;
++}
+ 
+ #ifdef CONFIG_DPP
+ static int nl80211_dpp_listen(void *priv, bool enable)
+@@ -13586,6 +13618,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+ 	.set_4addr_mode = nl80211_set_4addr_mode,
+ 	.mu_ctrl = nl80211_mu_ctrl,
+ 	.mu_dump = nl80211_mu_dump,
++	.beacon_ctrl = nl80211_beacon_ctrl,
+ #ifdef CONFIG_DPP
+ 	.dpp_listen = nl80211_dpp_listen,
+ #endif /* CONFIG_DPP */
+diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
+index 640fdc5..53cf2be 100644
+--- a/src/drivers/driver_nl80211.h
++++ b/src/drivers/driver_nl80211.h
+@@ -190,6 +190,7 @@ struct wpa_driver_nl80211_data {
+ 	unsigned int mtk_rfeatures_vendor_cmd_avail:1;
+ 	unsigned int mtk_amnt_vendor_cmd_avail:1;
+ 	unsigned int mtk_txpower_vendor_cmd_avail:1;
++	unsigned int mtk_beacon_ctrl_vendor_cmd_avail:1;
+ 
+ 	u64 vendor_scan_cookie;
+ 	u64 remain_on_chan_cookie;
+diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
+index 004c452..d13a64c 100644
+--- a/src/drivers/driver_nl80211_capa.c
++++ b/src/drivers/driver_nl80211_capa.c
+@@ -1103,6 +1103,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+ 				case MTK_NL80211_VENDOR_SUBCMD_TXPOWER_CTRL:
+ 					drv->mtk_txpower_vendor_cmd_avail = 1;
+ 					break;
++				case MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL :
++					drv->mtk_beacon_ctrl_vendor_cmd_avail = 1;
++					break;
+ 				}
+ 			}
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches/patches.inc b/recipes-wifi/wpa-supplicant/files/patches/patches.inc
index 5268b34..73393d2 100644
--- a/recipes-wifi/wpa-supplicant/files/patches/patches.inc
+++ b/recipes-wifi/wpa-supplicant/files/patches/patches.inc
@@ -116,5 +116,9 @@
     file://mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch \
     file://mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch \
     file://mtk-0050-hostapd-mtk-Add-txpower-vendor-command.patch \
+    file://mtk-0050-hostapd-mtk-add-support-for-removeing-the-main-BSS.patch \
     file://mtk-0051-hostapd-mtk-Update-Wide-Bandwidth-Channel-Switch-element.patch \
+    file://mtk-0051-hostapd-mtk-add-support-for-enable-disable-single-BS.patch \
+    file://mtk-0052-hostapd-mtk-ACS-remove-chan-freq-list-check-when-sca.patch \
+    file://mtk-0053-hostapd-mtk-add-no_beacon-vendor-command-for-cert.patch \
     "