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

[Description]
d34487c3 [MAC80211][WiFi6][mt76][Add mt7981 mt7916 mt7915 fw_wm_info support]
327eaf76 [MAC80211][wifi7][Release][Update WiFi7 Filogic680/660 Firmware]
fa03d7ea [MAC80211][WiFi6][hostapd][Fix 2/6G channel switch fail issue]
c0bf67d9 [MAC80211][misc][Add Filogic 880 Non-MLO SDK Release]
e5d03217 [MAC80211][WiFi6][Rebase Patches][Refactor set_offchan_ctrl]
6cad79ae [MAC80211][WiFi6][hostapd][Add support for DFS channel switch with CSA sent]
cde50012 [MAC80211][WiFi6][core][Add DFS channel CSA flow]
0142fd16 [MAC80211][WiFi6][mt76][Add post channel switch callback for DFS channel switch support]
cb3f4c58 [MAC80211][WiFi6][mt76][Update Connac2 CSI Feature]
1b66ac4c [MAC80211][WiFi6][mt76][Refactor precal loading and binfile mode to align upstream]
0ece467b [MAC80211][WiFi6][mt76][Fix scs feature calltrace issue]
1dca03f1 [MAC80211][WiFi6/7][Misc][Change group mgmt cipher setting to align group cipher]
0aa52762 [MAC80211][WiFi6][mt76][Fix muru_onoff as all enabled by default]
c3e5f505 [MAC80211][WiFi6][hostapd][Fix mu_onoff was overwritten with unexpected values]
7090eabe [MAC80211][WiFi6/7][core][Add tx_burst option in wireless configuration file for Kite]
669d3071 [MAC80211][WiFi6][mt76][rebase patches]
c5d6b3e7 [mac80211][mt76][Fix patch fail]
55ef4059 [MAC80211][WiFi6][mt76][Fix TxS ACK is incorrectly reported]
e166eae1 [MAC80211][WiFi6][Misc][Add Filogic 820 Build]
118ffd7e [mac80211][wifi6][mt76][Fix crash caused by per-BSS counter updating]
68015098 [MAC80211][WiFi7][mt76][Add Eagle 2adie TBTC default bin]
eae6e8c0 [MAC80211][WiFi7][mt76][Add Eagle 2adie TBTC support in mt76 Makefile]
cccc8eb9 [MAC80211[WiFi6][hostapd][Fix wds AP interface adding issue]
173fe3b0 [MAC80211][WiFi6][mt76][Add scs feature for connac2 mt76]
1b8af8d9 [MAC80211][WiFi6][mt76][rebase patches]
6dc40325 [MAC80211][WiFi7][misc][fix hostapd udebug init fail]
aa4b39ae [[mt76][csi][mt7915][mt7986] update csi feature]
7d458da2 [MAC80211][WiFi6][hostapd][Auto Channel Selection channel time issue]
f0b5502f [MAC80211][WiFi7][misc][fix build error]
b63c9cf6 [MAC80211][WiFi6/7][misc][fix ucode and backport 6.5 patch fail]
ce056dc7 [mac80211][wifi6][mt76][Add variant support for Cheetah MT76]
c5ae3f9c [MAC80211][WiFi6/7][Misc][Add country setting consistent check before enable AP.]
d57d9c5a [mac80211][misc][wifi6/7][Update libubox to the latest version]
be7dbf21 [mac80211][misc][wifi7][Revert libubox to 20230523 to prevent build fail]
ae9b4428 [MAC80211][WiFi6][mt76][Add cal free data support]
52fd5d80 [MAC80211][WiFi7][Misc][Adjust MU EDCA timer in mac80211.sh]
66c649de [mac80211][hostapd][netifd][Revert udebug for build pass]
136c7f11 [MAC80211][hostapd][wifi7][Fix build fail]
8911e727 [MAC80211][WiFi6][hostapd][Auto Channel Selection issue and patch sync]
75161456 [MAC80211][WiFi7][mt76][Fix issue for testmode bit in eagle defaut bin]
4dc2d646 [MAC80211][WiFi6][mt76][Fix cheetah 5G ibf issue]
d4561158 [MAC80211][WiFi6][Misc][Add Filogic 820 Build]
2e5a1997 [MAC80211][WiFi6][hostapd][Backport hostapd ACS patches and some ACS fixes]
b0305b6e [MAC80211][WiFi6/7][Misc][Add 6g band default enable mbo IE]

[Release-log]

Change-Id: I872b422c1fc56ebd3a1cff3252cb403a2015eabe
diff --git a/recipes-wifi/hostapd/files/patches/bp-0001-ACS-Extract-bw40-80-160-freqs-out-of-acs_usable_bwXX.patch b/recipes-wifi/hostapd/files/patches/bp-0001-ACS-Extract-bw40-80-160-freqs-out-of-acs_usable_bwXX.patch
new file mode 100644
index 0000000..be0bc74
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/bp-0001-ACS-Extract-bw40-80-160-freqs-out-of-acs_usable_bwXX.patch
@@ -0,0 +1,172 @@
+From 8df5520f49796e4e292de6895aa0bc518978b377 Mon Sep 17 00:00:00 2001
+From: Nicolas Escande <nico.escande@gmail.com>
+Date: Wed, 27 Apr 2022 15:36:59 +0200
+Subject: [PATCH 01/50] ACS: Extract bw40/80/160 freqs out of
+ acs_usable_bwXXX_chan()
+
+This extracts the 3 lists of allowed channels for 40/80/160 MHz
+bandwidth out of their respective functions. It also adds for each
+segment the frequency of the segment's last channel and the index of the
+segment's "center" channel.
+
+This is preparative work to allow selecting a channel which is not the
+first of its segment for 40/80/160 MHz. In addition, this adds the 5 GHz
+160 MHz channel defined for 5735-5895 MHz (channels 149-177).
+
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+---
+ src/ap/acs.c | 107 ++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 63 insertions(+), 44 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 4a0a4c7..60c90e9 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -241,6 +241,57 @@
+  * [1] http://en.wikipedia.org/wiki/Near_and_far_field
+  */
+ 
++enum bw_type {
++	ACS_BW40,
++	ACS_BW80,
++	ACS_BW160,
++};
++
++struct bw_item {
++	int first;
++	int last;
++	int center_chan;
++};
++
++static const struct bw_item bw_40[] = {
++	{ 5180, 5200, 38 }, { 5220, 5240, 46 }, { 5260, 5280, 54 },
++	{ 5300, 5320, 62 }, { 5500, 5520, 102 }, { 5540, 5560, 110 },
++	{ 5580, 5600, 110 }, { 5620, 5640, 126}, { 5660, 5680, 134 },
++	{ 5700, 5720, 142 }, { 5745, 5765, 151 }, { 5785, 5805, 159 },
++	{ 5825, 5845, 167 }, { 5865, 5885, 175 },
++	{ 5955, 5975, 3 }, { 5995, 6015, 11 }, { 6035, 6055, 19 },
++	{ 6075, 6095, 27 }, { 6115, 6135, 35 }, { 6155, 6175, 43 },
++	{ 6195, 6215, 51 }, { 6235, 6255, 59 }, { 6275, 6295, 67 },
++	{ 6315, 6335, 75 }, { 6355, 6375, 83 }, { 6395, 6415, 91 },
++	{ 6435, 6455, 99 }, { 6475, 6495, 107 }, { 6515, 6535, 115 },
++	{ 6555, 6575, 123 }, { 6595, 6615, 131 }, { 6635, 6655, 139 },
++	{ 6675, 6695, 147 }, { 6715, 6735, 155 }, { 6755, 6775, 163 },
++	{ 6795, 6815, 171 }, { 6835, 6855, 179 }, { 6875, 6895, 187 },
++	{ 6915, 6935, 195 }, { 6955, 6975, 203 }, { 6995, 7015, 211 },
++	{ 7035, 7055, 219 }, { 7075, 7095, 227}, { -1, -1, -1 }
++};
++static const struct bw_item bw_80[] = {
++	{ 5180, 5240, 42 }, { 5260, 5320, 58 }, { 5500, 5560, 106 },
++	{ 5580, 5640, 122 }, { 5660, 5720, 138 }, { 5745, 5805, 155 },
++	{ 5825, 5885, 171},
++	{ 5955, 6015, 7 }, { 6035, 6095, 23 }, { 6115, 6175, 39 },
++	{ 6195, 6255, 55 }, { 6275, 6335, 71 }, { 6355, 6415, 87 },
++	{ 6435, 6495, 103 }, { 6515, 6575, 119 }, { 6595, 6655, 135 },
++	{ 6675, 6735, 151 }, { 6755, 6815, 167 }, { 6835, 6895, 183 },
++	{ 6915, 6975, 199 }, { 6995, 7055, 215 }, { -1, -1, -1 }
++};
++static const struct bw_item bw_160[] = {
++	{ 5180, 5320, 50 }, { 5500, 5640, 114 }, { 5745, 5885, 163 },
++	{ 5955, 6095, 15 }, { 6115, 6255, 47 }, { 6275, 6415, 79 },
++	{ 6435, 6575, 111 }, { 6595, 6735, 143 },
++	{ 6755, 6895, 175 }, { 6915, 7055, 207 }, { -1, -1, -1 }
++};
++static const struct bw_item *bw_desc[] = {
++	[ACS_BW40] = bw_40,
++	[ACS_BW80] = bw_80,
++	[ACS_BW160] = bw_160,
++};
++
+ 
+ static int acs_request_scan(struct hostapd_iface *iface);
+ static int acs_survey_is_sufficient(struct freq_survey *survey);
+@@ -370,50 +421,18 @@ acs_survey_chan_interference_factor(struct hostapd_iface *iface,
+ }
+ 
+ 
+-static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan)
++static bool acs_usable_bw_chan(const struct hostapd_channel_data *chan,
++			       enum bw_type bw)
+ {
+-	const int allowed[] = { 5180, 5220, 5260, 5300, 5500, 5540, 5580, 5620,
+-				5660, 5745, 5785, 4920, 4960, 5955, 5995, 6035,
+-				6075, 6115, 6155, 6195, 6235, 6275, 6315, 6355,
+-				6395, 6435, 6475, 6515, 6555, 6595, 6635, 6675,
+-				6715, 6755, 6795, 6835, 6875, 6915, 6955, 6995,
+-				7035, 7075 };
+-	unsigned int i;
+-
+-	for (i = 0; i < ARRAY_SIZE(allowed); i++)
+-		if (chan->freq == allowed[i])
+-			return 1;
+-
+-	return 0;
+-}
+-
+-
+-static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan)
+-{
+-	const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955, 6035,
+-				6115, 6195, 6275, 6355, 6435, 6515, 6595, 6675,
+-				6755, 6835, 6915, 6995 };
+-	unsigned int i;
+-
+-	for (i = 0; i < ARRAY_SIZE(allowed); i++)
+-		if (chan->freq == allowed[i])
+-			return 1;
+-
+-	return 0;
+-}
+-
+-
+-static int acs_usable_bw160_chan(const struct hostapd_channel_data *chan)
+-{
+-	const int allowed[] = { 5180, 5500, 5955, 6115, 6275, 6435, 6595, 6755,
+-				6915 };
+-	unsigned int i;
++	unsigned int i = 0;
+ 
+-	for (i = 0; i < ARRAY_SIZE(allowed); i++)
+-		if (chan->freq == allowed[i])
+-			return 1;
++	while (bw_desc[bw][i].first != -1) {
++		if (chan->freq == bw_desc[bw][i].first)
++			return true;
++		i++;
++	}
+ 
+-	return 0;
++	return false;
+ }
+ 
+ 
+@@ -705,7 +724,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		    ((iface->conf->ieee80211n &&
+ 		      iface->conf->secondary_channel) ||
+ 		     is_6ghz_freq(chan->freq)) &&
+-		    !acs_usable_bw40_chan(chan)) {
++		    !acs_usable_bw_chan(chan, ACS_BW40)) {
+ 			wpa_printf(MSG_DEBUG,
+ 				   "ACS: Channel %d: not allowed as primary channel for 40 MHz bandwidth",
+ 				   chan->chan);
+@@ -716,7 +735,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		    (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) {
+ 			if (hostapd_get_oper_chwidth(iface->conf) ==
+ 			    CONF_OPER_CHWIDTH_80MHZ &&
+-			    !acs_usable_bw80_chan(chan)) {
++			    !acs_usable_bw_chan(chan, ACS_BW80)) {
+ 				wpa_printf(MSG_DEBUG,
+ 					   "ACS: Channel %d: not allowed as primary channel for 80 MHz bandwidth",
+ 					   chan->chan);
+@@ -725,7 +744,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 
+ 			if (hostapd_get_oper_chwidth(iface->conf) ==
+ 			    CONF_OPER_CHWIDTH_160MHZ &&
+-			    !acs_usable_bw160_chan(chan)) {
++			    !acs_usable_bw_chan(chan, ACS_BW160)) {
+ 				wpa_printf(MSG_DEBUG,
+ 					   "ACS: Channel %d: not allowed as primary channel for 160 MHz bandwidth",
+ 					   chan->chan);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/bp-0002-ACS-Introduce-acs_get_bw_center_chan.patch b/recipes-wifi/hostapd/files/patches/bp-0002-ACS-Introduce-acs_get_bw_center_chan.patch
new file mode 100644
index 0000000..15e8c98
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/bp-0002-ACS-Introduce-acs_get_bw_center_chan.patch
@@ -0,0 +1,87 @@
+From 3e2fa0f4ab02538c66e61058749272565d94d111 Mon Sep 17 00:00:00 2001
+From: Nicolas Escande <nico.escande@gmail.com>
+Date: Wed, 27 Apr 2022 15:37:00 +0200
+Subject: [PATCH 02/50] ACS: Introduce acs_get_bw_center_chan()
+
+When using 40/80/160 MHz bandwidth, instead of computing the index of
+the segment center freq based on the selected channel, lets look it up
+in the bw_desc[] table.
+
+This is preparative work to allow selecting a primary channel which is
+not the first of the segment.
+
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+---
+ src/ap/acs.c | 33 +++++++++++++++++++++++++++------
+ 1 file changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 60c90e9..511200d 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -436,6 +436,21 @@ static bool acs_usable_bw_chan(const struct hostapd_channel_data *chan,
+ }
+ 
+ 
++static int acs_get_bw_center_chan(int freq, enum bw_type bw)
++{
++	unsigned int i = 0;
++
++	while (bw_desc[bw][i].first != -1) {
++		if (freq >= bw_desc[bw][i].first &&
++		    freq <= bw_desc[bw][i].last)
++			return bw_desc[bw][i].center_chan;
++		i++;
++	}
++
++	return 0;
++}
++
++
+ static int acs_survey_is_sufficient(struct freq_survey *survey)
+ {
+ 	if (!(survey->filled & SURVEY_HAS_NF)) {
+@@ -936,19 +951,26 @@ bw_selected:
+ 
+ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+ {
+-	int offset;
++	int center;
+ 
+ 	wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
+ 
+ 	switch (hostapd_get_oper_chwidth(iface->conf)) {
+ 	case CONF_OPER_CHWIDTH_USE_HT:
+-		offset = 2 * iface->conf->secondary_channel;
++		if (iface->conf->secondary_channel &&
++		    iface->freq >= 2400 && iface->freq < 2500)
++			center = iface->conf->channel +
++				2 * iface->conf->secondary_channel;
++		else if (iface->conf->secondary_channel)
++			center = acs_get_bw_center_chan(iface->freq, ACS_BW40);
++		else
++			center = iface->conf->channel;
+ 		break;
+ 	case CONF_OPER_CHWIDTH_80MHZ:
+-		offset = 6;
++		center = acs_get_bw_center_chan(iface->freq, ACS_BW80);
+ 		break;
+ 	case CONF_OPER_CHWIDTH_160MHZ:
+-		offset = 14;
++		center = acs_get_bw_center_chan(iface->freq, ACS_BW160);
+ 		break;
+ 	default:
+ 		/* TODO: How can this be calculated? Adjust
+@@ -958,8 +980,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+ 		return;
+ 	}
+ 
+-	hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
+-					     iface->conf->channel + offset);
++	hostapd_set_oper_centr_freq_seg0_idx(iface->conf, center);
+ }
+ 
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/bp-0003-ACS-introduce-acs_adjust_secondary.patch b/recipes-wifi/hostapd/files/patches/bp-0003-ACS-introduce-acs_adjust_secondary.patch
new file mode 100644
index 0000000..b4ac1f0
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/bp-0003-ACS-introduce-acs_adjust_secondary.patch
@@ -0,0 +1,92 @@
+From 03dd213b918218fec270e781d284ec394fb63ef1 Mon Sep 17 00:00:00 2001
+From: Nicolas Escande <nico.escande@gmail.com>
+Date: Wed, 27 Apr 2022 15:37:01 +0200
+Subject: [PATCH 03/50] ACS: introduce acs_adjust_secondary
+
+When using 40/80/160 MHz bandwidth on the 5 GHz or 6 GHz band, enforce
+the secondary channel to be the other channel of the corresponding 40
+MHz segment.
+
+Even if this is useless for now, this is preparatory work to allow ACS
+to select a primary channel which is not the first of its segment.
+
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+---
+ src/ap/acs.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 45 insertions(+), 1 deletion(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 511200d..78d1feb 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -634,6 +634,26 @@ acs_find_chan_mode(struct hostapd_hw_modes *mode, int freq)
+ }
+ 
+ 
++static enum hostapd_hw_mode
++acs_find_mode(struct hostapd_iface *iface, int freq)
++{
++	int i;
++	struct hostapd_hw_modes *mode;
++	struct hostapd_channel_data *chan;
++
++	for (i = 0; i < iface->num_hw_features; i++) {
++		mode = &iface->hw_features[i];
++		if (!hostapd_hw_skip_mode(iface, mode)) {
++			chan = acs_find_chan_mode(mode, freq);
++			if (chan)
++				return mode->mode;
++		}
++	}
++
++	return HOSTAPD_MODE_IEEE80211ANY;
++}
++
++
+ static struct hostapd_channel_data *
+ acs_find_chan(struct hostapd_iface *iface, int freq)
+ {
+@@ -949,6 +969,28 @@ bw_selected:
+ }
+ 
+ 
++static void acs_adjust_secondary(struct hostapd_iface *iface)
++{
++	unsigned int i;
++
++	/* When working with bandwidth over 20 MHz on the 5 GHz or 6 GHz band,
++	 * ACS can return a secondary channel which is not the first channel of
++	 * the segment and we need to adjust. */
++	if (!iface->conf->secondary_channel ||
++	    acs_find_mode(iface, iface->freq) != HOSTAPD_MODE_IEEE80211A)
++		return;
++
++	wpa_printf(MSG_DEBUG, "ACS: Adjusting HT/VHT/HE secondary frequency");
++
++	for (i = 0; bw_desc[ACS_BW40][i].first != -1; i++) {
++		if (iface->freq == bw_desc[ACS_BW40][i].first)
++			iface->conf->secondary_channel = 1;
++		else if (iface->freq == bw_desc[ACS_BW40][i].last)
++			iface->conf->secondary_channel = -1;
++	}
++}
++
++
+ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+ {
+ 	int center;
+@@ -1036,8 +1078,10 @@ static void acs_study(struct hostapd_iface *iface)
+ 	iface->conf->channel = ideal_chan->chan;
+ 	iface->freq = ideal_chan->freq;
+ 
+-	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax)
++	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
++		acs_adjust_secondary(iface);
+ 		acs_adjust_center_freq(iface);
++	}
+ 
+ 	err = 0;
+ fail:
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/bp-0004-ACS-Allow-selecting-a-better-channel-when-using-40-8.patch b/recipes-wifi/hostapd/files/patches/bp-0004-ACS-Allow-selecting-a-better-channel-when-using-40-8.patch
new file mode 100644
index 0000000..8da5856
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/bp-0004-ACS-Allow-selecting-a-better-channel-when-using-40-8.patch
@@ -0,0 +1,78 @@
+From a615aa302064919791f3912a5cf1a908390414df Mon Sep 17 00:00:00 2001
+From: Nicolas Escande <nico.escande@gmail.com>
+Date: Wed, 27 Apr 2022 15:37:02 +0200
+Subject: [PATCH 04/50] ACS: Allow selecting a better channel when using
+ 40/80/160 MHz
+
+When considering a channel for a bandwidth of 40/80/160 MHZ on the 5 GHz
+or 6 GHz band, allow selecting one of the other channels in the segment
+instead of the first one. This is done only if the other channel's
+interference_factor is lower than the first one's.
+
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+---
+ src/ap/acs.c | 25 +++++++++++++++++++++++--
+ 1 file changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 78d1feb..130e135 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -712,7 +712,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			 struct hostapd_channel_data **ideal_chan,
+ 			 long double *ideal_factor)
+ {
+-	struct hostapd_channel_data *chan, *adj_chan = NULL;
++	struct hostapd_channel_data *chan, *adj_chan = NULL, *best;
+ 	long double factor;
+ 	int i, j;
+ 	unsigned int k;
+@@ -720,8 +720,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 	for (i = 0; i < mode->num_channels; i++) {
+ 		double total_weight;
+ 		struct acs_bias *bias, tmp_bias;
++		bool update_best = true;
+ 
+-		chan = &mode->channels[i];
++		best = chan = &mode->channels[i];
+ 
+ 		/* Since in the current ACS implementation the first channel is
+ 		 * always a primary channel, skip channels not available as
+@@ -807,7 +808,15 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			if (acs_usable_chan(adj_chan)) {
+ 				factor += adj_chan->interference_factor;
+ 				total_weight += 1;
++			} else {
++				update_best = false;
+ 			}
++
++			/* find the best channel in this segment */
++			if (update_best &&
++			    adj_chan->interference_factor <
++			    best->interference_factor)
++				best = adj_chan;
+ 		}
+ 
+ 		if (j != n_chans) {
+@@ -816,6 +825,18 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			continue;
+ 		}
+ 
++		/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
++		 * crowded primary channel if one was found in the segment */
++		if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
++		    chan != best) {
++			wpa_printf(MSG_DEBUG,
++				   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
++				   best->chan, chan->chan,
++				   chan->interference_factor,
++				   best->interference_factor);
++			chan = best;
++		}
++
+ 		/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
+ 		 * channel interference factor. */
+ 		if (is_24ghz_mode(mode->mode)) {
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch b/recipes-wifi/hostapd/files/patches/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
index b3f4138..af6eaa5 100644
--- a/recipes-wifi/hostapd/files/patches/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
+++ b/recipes-wifi/hostapd/files/patches/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
@@ -1,11 +1,11 @@
-From 53a7b7af61b75ea0e3f9d12d3d6302cf40941a8a Mon Sep 17 00:00:00 2001
+From adc0d43ecd5ad2f8932c7a25c6b0e1dea336aef8 Mon Sep 17 00:00:00 2001
 From: TomLiu <tomml.liu@mediatek.com>
 Date: Tue, 9 Aug 2022 10:23:44 -0700
-Subject: [PATCH 06/37] hostapd: mtk: Add hostapd MU SET/GET control
+Subject: [PATCH] hostapd: mtk: Add hostapd MU SET/GET control
 
 ---
  hostapd/config_file.c             |   9 +++
- hostapd/ctrl_iface.c              |  62 +++++++++++++++++
+ hostapd/ctrl_iface.c              |  66 ++++++++++++++++++
  hostapd/hostapd_cli.c             |  18 +++++
  src/ap/ap_config.c                |   1 +
  src/ap/ap_config.h                |   1 +
@@ -17,7 +17,7 @@
  src/drivers/driver_nl80211.c      | 110 ++++++++++++++++++++++++++++++
  src/drivers/driver_nl80211.h      |   1 +
  src/drivers/driver_nl80211_capa.c |   3 +
- 13 files changed, 251 insertions(+)
+ 13 files changed, 255 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
 index b5024cc..62e8b33 100644
@@ -40,10 +40,10 @@
  	} else if (os_strcmp(buf, "max_listen_interval") == 0) {
  		bss->max_listen_interval = atoi(pos);
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 9c70d54..c72f336 100644
+index 9c70d54..894c47a 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3441,6 +3441,63 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
+@@ -3441,6 +3441,67 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
  }
  
  
@@ -93,6 +93,10 @@
 +	pos = buf;
 +	end = buf + buflen;
 +
++	if (hapd->iface->state != HAPD_IFACE_ENABLED)
++		return os_snprintf(pos, end - pos, "Not allowed to get_mu when current state is %s\n",
++				   hostapd_state_text(hapd->iface->state));
++
 +	if (hostapd_drv_mu_dump(hapd, &mu_onoff) == 0) {
 +		hapd->iconf->mu_onoff = mu_onoff;
 +		return os_snprintf(pos, end - pos, "[hostapd_cli] = UL MU-MIMO: %d, DL MU-MIMO: %d, UL OFDMA: %d, DL OFDMA: %d\n",
@@ -107,7 +111,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -3993,6 +4050,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -3993,6 +4054,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  	} else if (os_strncmp(buf, "GET_EDCCA ", 10) == 0) {
  		reply_len = hostapd_ctrl_iface_get_edcca(hapd, buf+10, reply,
  							  reply_size);
@@ -156,7 +160,7 @@
  	{ "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_config.c b/src/ap/ap_config.c
-index 344585a..1b0e990 100644
+index 344585a..9e5a2ec 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -280,6 +280,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -446,5 +450,5 @@
  			}
  
 -- 
-2.39.0
+2.18.0
 
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch b/recipes-wifi/hostapd/files/patches/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
index aa72f2a..03793bb 100644
--- a/recipes-wifi/hostapd/files/patches/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
+++ b/recipes-wifi/hostapd/files/patches/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
@@ -1,7 +1,7 @@
-From 9b82b5966b57403f389759b6dfb8318dd862b480 Mon Sep 17 00:00:00 2001
+From 8b9963570219d1ba217da21d02fa193ee8aef4ae Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 16 Dec 2022 03:57:11 +0800
-Subject: [PATCH 12/35] hostapd: mtk: Add amsdu set get ctrl
+Subject: [PATCH] hostapd: mtk: Add amsdu set get ctrl
 
 ---
  hostapd/config_file.c             |   9 +++
@@ -40,10 +40,10 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 37a1b2a..61c9e80 100644
+index fcbc4ae..8ed56e4 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3612,6 +3612,30 @@ hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
+@@ -3542,6 +3542,30 @@ hostapd_ctrl_iface_set_dfs_detect_mode(struct hostapd_data *hapd, char *value,
  }
  
  
@@ -74,10 +74,10 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4176,6 +4200,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4104,6 +4128,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 	} else if (os_strncmp(buf, "DFS_DETECT_MODE ", 16) == 0) {
+ 		reply_len = hostapd_ctrl_iface_set_dfs_detect_mode(hapd, buf + 16,
  								   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, "GET_AMSDU", 9) == 0) {
 +		reply_len = hostapd_ctrl_iface_get_amsdu(hapd, reply, reply_size);
  	} else {
@@ -111,7 +111,7 @@
  };
  
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index df90814..24fc0f5 100644
+index c47418a..b351edb 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -299,6 +299,7 @@ struct hostapd_config * hostapd_config_defaults(void)
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0022-hostapd-mtk-Add-available-color-bitmap.patch b/recipes-wifi/hostapd/files/patches/mtk-0022-hostapd-mtk-Add-available-color-bitmap.patch
index 1b23579..6f4425f 100644
--- a/recipes-wifi/hostapd/files/patches/mtk-0022-hostapd-mtk-Add-available-color-bitmap.patch
+++ b/recipes-wifi/hostapd/files/patches/mtk-0022-hostapd-mtk-Add-available-color-bitmap.patch
@@ -1,7 +1,7 @@
-From 9b40b6ccf6fd2f4463b389df46d38610001df04e Mon Sep 17 00:00:00 2001
+From 2e7919e5e52fefa14a48e77fd739ef05371a26c9 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Thu, 26 Jan 2023 09:16:00 +0800
-Subject: [PATCH 22/35] hostapd: mtk: Add available color bitmap
+Subject: [PATCH] hostapd: mtk: Add available color bitmap
 
 Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 ---
@@ -17,10 +17,10 @@
  9 files changed, 192 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 9ba6992..e1e9270 100644
+index 2b7ac96..549c93a 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3645,6 +3645,76 @@ hostapd_ctrl_iface_get_amsdu(struct hostapd_data *hapd, char *buf,
+@@ -3575,6 +3575,76 @@ hostapd_ctrl_iface_get_amsdu(struct hostapd_data *hapd, char *buf,
  	return ret;
  }
  
@@ -97,8 +97,8 @@
  
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
-@@ -4212,6 +4282,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
+@@ -4140,6 +4210,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 								   reply, reply_size);
  	} else if (os_strncmp(buf, "GET_AMSDU", 9) == 0) {
  		reply_len = hostapd_ctrl_iface_get_amsdu(hapd, reply, reply_size);
 +	} else if (os_strncmp(buf, "GET_BSS_COLOR", 13) == 0) {
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0046-hostapd-mtk-ACS-Fix-2.4GHz-HT40-case-and-channel-swi.patch b/recipes-wifi/hostapd/files/patches/mtk-0046-hostapd-mtk-ACS-Fix-2.4GHz-HT40-case-and-channel-swi.patch
new file mode 100644
index 0000000..d968859
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/mtk-0046-hostapd-mtk-ACS-Fix-2.4GHz-HT40-case-and-channel-swi.patch
@@ -0,0 +1,283 @@
+From 920a20927f1537ae2a6ce9c7123ef189e83cd0a0 Mon Sep 17 00:00:00 2001
+From: Evelyn Tsai <evelyn.tsai@mediatek.com>
+Date: Sat, 11 Nov 2023 11:42:59 +0800
+Subject: [PATCH] hostapd: mtk: ACS: Fix 2.4GHz HT40 case and channel switch
+ fail
+
+Issue#1. Add 2.4G HT40- support
+1. Add 2.4G HT40- support
+2. Fix issue: selected best channel is out of channels
+
+Issue#2. Fix chan_switch to usable DFS channel fail due to ACS
+
+Step and issue:
+1. Enable ACS in hostapd config;
+2. Bootup and then use hostapd_cli cmd switch channel to a DFS channel;
+3. Will do ACS again, and no work on channel specified in step 2.
+
+Root cause:
+When need do DFS-CAC, hostapd will do intf disable, then set the new
+channel into running config settings, and finally enable intf;
+In the test case, new DFS channel is set to runnint config settings, but
+another param "acs" is still 1 (enable), caused the ACS running when
+intf enabled.
+---
+ src/ap/acs.c     | 142 ++++++++++++++++++++++++++---------------------
+ src/ap/hostapd.c |   3 +
+ 2 files changed, 83 insertions(+), 62 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 130e135..65573b9 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -712,10 +712,19 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			 struct hostapd_channel_data **ideal_chan,
+ 			 long double *ideal_factor)
+ {
+-	struct hostapd_channel_data *chan, *adj_chan = NULL, *best;
++	struct hostapd_channel_data *chan, *adj_chan = NULL, *tmp_chan = NULL, *best;
+ 	long double factor;
+ 	int i, j;
+ 	unsigned int k;
++	int ht40_plus = 1, sec_ch_factor = 1;
++
++	if (is_24ghz_mode(mode->mode)) {
++		ht40_plus = (iface->conf->secondary_channel == -1) ? 0 : 1;
++		sec_ch_factor = (iface->conf->secondary_channel == -1) ? -1 : 1;
++	}
++
++	wpa_printf(MSG_INFO, "%s:%d, bw(%u), n_chans(%d), num_channels(%d), sec_ch(%d)",
++		__func__, __LINE__, bw, n_chans, mode->num_channels, iface->conf->secondary_channel);
+ 
+ 	for (i = 0; i < mode->num_channels; i++) {
+ 		double total_weight;
+@@ -723,6 +732,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		bool update_best = true;
+ 
+ 		best = chan = &mode->channels[i];
++		wpa_printf(MSG_INFO,
++			   "ACS: Channel[%d] %d: interference_factor %Lg",
++			   i, chan->chan, chan->interference_factor);
+ 
+ 		/* Since in the current ACS implementation the first channel is
+ 		 * always a primary channel, skip channels not available as
+@@ -747,7 +759,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		if (chan->flag & HOSTAPD_CHAN_INDOOR_ONLY && iface->conf->country[2] == 0x4f)
+ 			continue;
+ 
+-		if (!chan_bw_allowed(chan, bw, 1, 1)) {
++		if (!chan_bw_allowed(chan, bw, ht40_plus, 1)) {
+ 			wpa_printf(MSG_DEBUG,
+ 				   "ACS: Channel %d: BW %u is not supported",
+ 				   chan->chan, bw);
+@@ -789,60 +801,73 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		}
+ 
+ 		factor = 0;
+-		if (acs_usable_chan(chan))
+-			factor = chan->interference_factor;
+-		total_weight = 1;
+-
+-		for (j = 1; j < n_chans; j++) {
+-			adj_chan = acs_find_chan(iface, chan->freq + (j * 20));
+-			if (!adj_chan)
+-				break;
++		total_weight = 0;
+ 
+-			if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
+-				wpa_printf(MSG_DEBUG,
+-					   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
+-					   chan->chan, adj_chan->chan, bw);
+-				break;
+-			}
+-
+-			if (acs_usable_chan(adj_chan)) {
+-				factor += adj_chan->interference_factor;
++		if (!is_24ghz_mode(mode->mode)) {
++			/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
++			 * crowded primary channel if one was found in the segment */
++			if (acs_usable_chan(chan)) {
++				factor += chan->interference_factor;
+ 				total_weight += 1;
+-			} else {
+-				update_best = false;
+ 			}
+ 
+-			/* find the best channel in this segment */
+-			if (update_best &&
+-			    adj_chan->interference_factor <
+-			    best->interference_factor)
+-				best = adj_chan;
+-		}
++			for (j = 1; j < n_chans; j++) {
++				adj_chan = acs_find_chan(iface, chan->freq + j * 20);
++				if (!adj_chan)
++					break;
+ 
+-		if (j != n_chans) {
+-			wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
+-				   chan->chan);
+-			continue;
+-		}
++				if (!is_in_chanlist(iface, adj_chan) || !is_in_freqlist(iface, adj_chan))
++					break;
+ 
+-		/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
+-		 * crowded primary channel if one was found in the segment */
+-		if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
+-		    chan != best) {
+-			wpa_printf(MSG_DEBUG,
+-				   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
+-				   best->chan, chan->chan,
+-				   chan->interference_factor,
+-				   best->interference_factor);
+-			chan = best;
+-		}
++				if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
++					wpa_printf(MSG_DEBUG,
++						   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
++						   chan->chan, adj_chan->chan, bw);
++					break;
++				}
+ 
+-		/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
+-		 * channel interference factor. */
+-		if (is_24ghz_mode(mode->mode)) {
++				update_best = true;
++				if (acs_usable_chan(adj_chan)) {
++					factor += adj_chan->interference_factor;
++					total_weight += 1;
++				} else {
++					update_best = false;
++				}
++
++				/* find the best channel in this segment */
++				if (update_best &&
++					adj_chan->interference_factor < best->interference_factor)
++					best = adj_chan;
++			}
++
++			if (j != n_chans) {
++				wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
++					   chan->chan);
++				continue;
++			}
++
++			if (chan != best) {
++				wpa_printf(MSG_INFO,
++					   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
++					   best->chan, chan->chan,
++					   chan->interference_factor,
++					   best->interference_factor);
++				chan = best;
++			}
++		} else {
+ 			for (j = 0; j < n_chans; j++) {
++				/* Will set primary_channel / secondary_channel(40M case) weight to 1 */
++				tmp_chan = acs_find_chan(iface, chan->freq +
++							 (j * sec_ch_factor * 20));
++				if (tmp_chan && acs_usable_chan(tmp_chan)) {
++					factor += tmp_chan->interference_factor;
++					total_weight += 1;
++				}
++
++				/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent channel
++				interference factor, separately for primary/secondary channel. */
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) - 5);
++							  (j * sec_ch_factor * 20) - 5);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -850,7 +875,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 				}
+ 
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) - 10);
++							  (j * sec_ch_factor * 20) - 10);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_NEXT_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -858,7 +883,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 				}
+ 
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) + 5);
++							 (j * sec_ch_factor * 20) + 5);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -866,7 +891,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 				}
+ 
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) + 10);
++							 (j * sec_ch_factor * 20) + 10);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_NEXT_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -875,7 +900,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			}
+ 		}
+ 
+-		factor /= total_weight;
++		if (total_weight)
++			factor /= total_weight;
+ 
+ 		bias = NULL;
+ 		if (iface->conf->acs_chan_bias) {
+@@ -894,11 +920,11 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 
+ 		if (bias) {
+ 			factor *= bias->bias;
+-			wpa_printf(MSG_DEBUG,
++			wpa_printf(MSG_INFO,
+ 				   "ACS:  * channel %d: total interference = %Lg (%f bias)",
+ 				   chan->chan, factor, bias->bias);
+ 		} else {
+-			wpa_printf(MSG_DEBUG,
++			wpa_printf(MSG_INFO,
+ 				   "ACS:  * channel %d: total interference = %Lg",
+ 				   chan->chan, factor);
+ 		}
+@@ -939,14 +965,6 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
+ 		goto bw_selected;
+ 	}
+ 
+-	/* TODO: HT40- support */
+-
+-	if (iface->conf->ieee80211n &&
+-	    iface->conf->secondary_channel == -1) {
+-		wpa_printf(MSG_ERROR, "ACS: HT40- is not supported yet. Please try HT40+");
+-		return NULL;
+-	}
+-
+ 	if (iface->conf->ieee80211n &&
+ 	    iface->conf->secondary_channel)
+ 		n_chans = 2;
+@@ -981,7 +999,7 @@ bw_selected:
+ 	}
+ 
+ 	if (ideal_chan) {
+-		wpa_printf(MSG_DEBUG, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
++		wpa_printf(MSG_INFO, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
+ 			   ideal_chan->chan, ideal_chan->freq, ideal_factor);
+ 		return ideal_chan;
+ 	}
+diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
+index f2eb638..250c168 100644
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -3895,6 +3895,9 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
+ 
+ 	iface->freq = freq_params->freq;
+ 	iface->conf->channel = freq_params->channel;
++	if (iface->conf->channel != 0) /* If channel not zero, will disable acs. */
++		iface->conf->acs = 0;
++
+ 	iface->conf->secondary_channel = freq_params->sec_channel_offset;
+ 	hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx);
+ 	hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0047-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF_new.patch b/recipes-wifi/hostapd/files/patches/mtk-0047-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF_new.patch
new file mode 100644
index 0000000..1937640
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/mtk-0047-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF_new.patch
@@ -0,0 +1,55 @@
+From 99159b174eb245a7162fe38900971cdff017cf75 Mon Sep 17 00:00:00 2001
+From: Michael Lee <michael-cy.lee@mediatek.com>
+Date: Thu, 13 Jul 2023 13:14:26 +0800
+Subject: [PATCH] hostapd: mtk: Check the bridge after ioctl SIOCBRADDIF failed
+
+If ioctl returns EBUSY on command SIOCBRADDIF, the interface might
+already be bridged by others, and linux_br_add_if should not indicate an
+error in the case.
+
+This patch checks whether the interface is correctly brigded when ioctl
+returns EBUSY.
+
+Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
+---
+ src/drivers/linux_ioctl.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/src/drivers/linux_ioctl.c b/src/drivers/linux_ioctl.c
+index 7edb9df..b8c1af2 100644
+--- a/src/drivers/linux_ioctl.c
++++ b/src/drivers/linux_ioctl.c
+@@ -150,7 +150,8 @@ int linux_br_del(int sock, const char *brname)
+ int linux_br_add_if(int sock, const char *brname, const char *ifname)
+ {
+ 	struct ifreq ifr;
+-	int ifindex;
++	int ifindex, ret;
++	char in_br[IFNAMSIZ];
+ 
+ 	ifindex = if_nametoindex(ifname);
+ 	if (ifindex == 0)
+@@ -164,8 +165,19 @@ int linux_br_add_if(int sock, const char *brname, const char *ifname)
+ 
+ 		wpa_printf(MSG_DEBUG, "Could not add interface %s into bridge "
+ 			   "%s: %s", ifname, brname, strerror(errno));
++
++		/* If ioctl returns -EBUSY when adding interface into bridge,
++		 * the interface might already be added by netifd, so here we
++		 * check whether the interface is currently on the right
++		 * bridge. */
++		if(errno == EBUSY && linux_br_get(in_br, ifname) == 0 &&
++	           os_strcmp(in_br, brname) == 0)
++			ret = 0;
++		else
++			ret = -1;
++
+ 		errno = saved_errno;
+-		return -1;
++		return ret;
+ 	}
+ 
+ 	return 0;
+-- 
+2.25.1
+
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch b/recipes-wifi/hostapd/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch
new file mode 100644
index 0000000..82b66f4
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch
@@ -0,0 +1,135 @@
+From 018d87d5b9b53b3e630032bf2cb7e6eaeae09d71 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
+
+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/ieee802_11.c  |  5 +++++
+ 4 files changed, 24 insertions(+), 28 deletions(-)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index b521a08..0afa6a2 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,
+ 	int dfs_range = 0;
+ 	unsigned int i;
+ 	int bandwidth;
+-	u8 chan;
+ 
+ 	ret = hostapd_parse_csa_settings(pos, &settings);
+ 	if (ret)
+@@ -2809,29 +2808,8 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 			iface, bandwidth, settings.freq_params.center_freq2);
+ 
+ 	if (dfs_range) {
+-		ret = ieee80211_freq_to_chan(settings.freq_params.freq, &chan);
+-		if (ret == NUM_HOSTAPD_MODES) {
+-			wpa_printf(MSG_ERROR,
+-				   "Failed to get channel for (freq=%d, sec_channel_offset=%d, bw=%d)",
+-				   settings.freq_params.freq,
+-				   settings.freq_params.sec_channel_offset,
+-				   settings.freq_params.bandwidth);
+-			return -1;
+-		}
+-
+-		settings.freq_params.channel = chan;
+-
+-		wpa_printf(MSG_DEBUG,
+-			   "DFS/CAC to (channel=%u, freq=%d, sec_channel_offset=%d, bw=%d, center_freq1=%d)",
+-			   settings.freq_params.channel,
+-			   settings.freq_params.freq,
+-			   settings.freq_params.sec_channel_offset,
+-			   settings.freq_params.bandwidth,
+-			   settings.freq_params.center_freq1);
+-
+-		/* Perform CAC and switch channel */
+-		hostapd_switch_channel_fallback(iface, &settings.freq_params);
+-		return 0;
++		settings.cs_count = 5;
++		settings.block_tx = 1;
+ 	}
+ 
+ 	for (i = 0; i < iface->num_bss; i++) {
+diff --git a/src/ap/beacon.c b/src/ap/beacon.c
+index 02f4f87..f9c4924 100644
+--- a/src/ap/beacon.c
++++ b/src/ap/beacon.c
+@@ -2027,6 +2027,11 @@ static int __ieee802_11_set_beacon(struct hostapd_data *hapd)
+ 		return -1;
+ 	}
+ 
++	if (iface->cac_started) {
++		wpa_printf(MSG_DEBUG, "Ignore set beacons during CAC period");
++		return 0;
++	}
++
+ 	hapd->beacon_set_done = 1;
+ 
+ 	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
+--- 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,
+ 			 * another radio.
+ 			 */
+ 			if (iface->state != HAPD_IFACE_ENABLED &&
+-			    hostapd_is_dfs_chan_available(iface)) {
++			    hostapd_is_dfs_chan_available(iface))
+ 				hostapd_setup_interface_complete(iface, 0);
+-				iface->cac_started = 0;
+-			}
++
++			iface->cac_started = 0;
+ 
+ 			/*
+ 			 * 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,
+ 	} 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;
++		/* 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,
+ 	} else {
+ 		/* This is called when the driver indicates that an offloaded
+ 		 * DFS has started CAC. */
+-		hostapd_set_state(iface, HAPD_IFACE_DFS);
++		if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
++			hostapd_set_state(iface, HAPD_IFACE_DFS);
+ 		iface->cac_started = 1;
+ 	}
+ 	/* TODO: How to check CAC time for ETSI weather channels? */
+diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
+index 01ceb79..dd477fd 100644
+--- a/src/ap/ieee802_11.c
++++ b/src/ap/ieee802_11.c
+@@ -6352,6 +6352,11 @@ int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
+ 		return 1;
+ 	}
+ 
++	if (hapd->iface->cac_started) {
++		wpa_printf(MSG_DEBUG, "MGMT: Ignore management frame during CAC");
++		return 1;
++	}
++
+ 	if (stype == WLAN_FC_STYPE_PROBE_REQ) {
+ 		handle_probe_req(hapd, mgmt, len, ssi_signal);
+ 		return 1;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch b/recipes-wifi/hostapd/files/patches/mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch
new file mode 100644
index 0000000..0dbdaca
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch
@@ -0,0 +1,409 @@
+From a0538a9373ec7def76048e020fcb6ecfec53f3db Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 16 Nov 2023 13:18:48 +0800
+Subject: [PATCH] hostapd: mtk: add support for channel switching with csa sent
+ when background radar is enabled
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ hostapd/ctrl_iface.c   |  82 +++++++++++++++++-----
+ src/ap/ctrl_iface_ap.c |   5 +-
+ src/ap/dfs.c           | 156 +++++++++++++++++++++++++++++++++++------
+ src/ap/dfs.h           |   9 ++-
+ 4 files changed, 212 insertions(+), 40 deletions(-)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index 0afa6a2..44903e0 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -2742,11 +2742,12 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 					  char *pos)
+ {
+ #ifdef NEED_AP_MLME
+-	struct csa_settings settings;
++	struct csa_settings settings, background_settings;
+ 	int ret;
+-	int dfs_range = 0;
++	int freq, state;
+ 	unsigned int i;
+-	int bandwidth;
++	int bandwidth, oper_chwidth;
++	bool background_radar, bw_changed, cac_required = false;
+ 
+ 	ret = hostapd_parse_csa_settings(pos, &settings);
+ 	if (ret)
+@@ -2762,21 +2763,28 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 	switch (settings.freq_params.bandwidth) {
+ 	case 40:
+ 		bandwidth = CHAN_WIDTH_40;
++		oper_chwidth = CONF_OPER_CHWIDTH_USE_HT;
+ 		break;
+ 	case 80:
+-		if (settings.freq_params.center_freq2)
++		if (settings.freq_params.center_freq2) {
+ 			bandwidth = CHAN_WIDTH_80P80;
+-		else
++			oper_chwidth = CONF_OPER_CHWIDTH_80P80MHZ;
++		} else {
+ 			bandwidth = CHAN_WIDTH_80;
++			oper_chwidth = CONF_OPER_CHWIDTH_80MHZ;
++		}
+ 		break;
+ 	case 160:
+ 		bandwidth = CHAN_WIDTH_160;
++		oper_chwidth = CONF_OPER_CHWIDTH_160MHZ;
+ 		break;
+ 	case 320:
+ 		bandwidth = CHAN_WIDTH_320;
++		oper_chwidth = CONF_OPER_CHWIDTH_320MHZ;
+ 		break;
+ 	default:
+ 		bandwidth = CHAN_WIDTH_20;
++		oper_chwidth = CONF_OPER_CHWIDTH_USE_HT;
+ 		break;
+ 	}
+ 
+@@ -2797,19 +2805,29 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 	}
+ 
+ 	if (settings.freq_params.center_freq1)
+-		dfs_range += hostapd_is_dfs_overlap(
+-			iface, bandwidth, settings.freq_params.center_freq1);
++		freq = settings.freq_params.center_freq1;
+ 	else
+-		dfs_range += hostapd_is_dfs_overlap(
+-			iface, bandwidth, settings.freq_params.freq);
+-
+-	if (settings.freq_params.center_freq2)
+-		dfs_range += hostapd_is_dfs_overlap(
+-			iface, bandwidth, settings.freq_params.center_freq2);
+-
+-	if (dfs_range) {
+-		settings.cs_count = 5;
+-		settings.block_tx = 1;
++		freq = settings.freq_params.freq;
++
++	bw_changed = oper_chwidth != hostapd_get_oper_chwidth(iface->conf);
++	state = hostapd_dfs_get_target_state(iface, bandwidth, freq,
++					     settings.freq_params.center_freq2);
++	switch (state) {
++	case HOSTAPD_CHAN_DFS_USABLE:
++		cac_required = true;
++		/* fallthrough */
++	case HOSTAPD_CHAN_DFS_AVAILABLE:
++		background_radar = hostapd_dfs_handle_csa(iface, &settings,
++							  &background_settings,
++							  cac_required,
++							  bw_changed);
++		break;
++	case HOSTAPD_CHAN_DFS_UNAVAILABLE:
++		wpa_printf(MSG_INFO,
++			   "chanswitch: target channel is UNAVAILABLE, so stop switching");
++		return -1;
++	default:
++		break;
+ 	}
+ 
+ 	for (i = 0; i < iface->num_bss; i++) {
+@@ -2826,6 +2844,36 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 		}
+ 	}
+ 
++	if (background_radar) {
++		u8 seg0, seg1;
++
++		ieee80211_freq_to_chan(background_settings.freq_params.center_freq1, &seg0);
++		ieee80211_freq_to_chan(background_settings.freq_params.center_freq2, &seg1);
++		ret = hostapd_start_dfs_cac(iface, iface->conf->hw_mode,
++					    background_settings.freq_params.freq,
++					    background_settings.freq_params.channel,
++					    background_settings.freq_params.ht_enabled,
++					    background_settings.freq_params.vht_enabled,
++					    background_settings.freq_params.he_enabled,
++					    background_settings.freq_params.eht_enabled,
++					    background_settings.freq_params.sec_channel_offset,
++					    oper_chwidth, seg0, seg1, true);
++		if (ret) {
++			wpa_printf(MSG_ERROR, "Background radar start dfs cac failed, %d",
++				   ret);
++			iface->radar_background.channel = -1;
++			return -1;
++		}
++
++		/* Cache background radar parameters. */
++		iface->radar_background.channel = background_settings.freq_params.channel;
++		iface->radar_background.secondary_channel =
++			background_settings.freq_params.sec_channel_offset;
++		iface->radar_background.freq = background_settings.freq_params.freq;
++		iface->radar_background.centr_freq_seg0_idx = seg0;
++		iface->radar_background.centr_freq_seg1_idx = seg1;
++	}
++
+ 	return 0;
+ #else /* NEED_AP_MLME */
+ 	return -1;
+diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
+index 86e8729..005c9fa 100644
+--- a/src/ap/ctrl_iface_ap.c
++++ b/src/ap/ctrl_iface_ap.c
+@@ -907,6 +907,7 @@ int hostapd_parse_csa_settings(const char *pos,
+ 			       struct csa_settings *settings)
+ {
+ 	char *end;
++	int ret;
+ 
+ 	os_memset(settings, 0, sizeof(*settings));
+ 	settings->cs_count = strtol(pos, &end, 10);
+@@ -916,7 +917,9 @@ int hostapd_parse_csa_settings(const char *pos,
+ 	}
+ 
+ 	settings->freq_params.freq = atoi(end);
+-	if (settings->freq_params.freq == 0) {
++	ret = ieee80211_freq_to_chan(settings->freq_params.freq,
++				     &settings->freq_params.channel);
++	if (ret == NUM_HOSTAPD_MODES) {
+ 		wpa_printf(MSG_ERROR, "chanswitch: invalid freq provided");
+ 		return -1;
+ 	}
+diff --git a/src/ap/dfs.c b/src/ap/dfs.c
+index 012050c..5108e0a 100644
+--- a/src/ap/dfs.c
++++ b/src/ap/dfs.c
+@@ -248,14 +248,15 @@ static int is_in_chanlist(struct hostapd_iface *iface,
+  */
+ static int dfs_find_channel(struct hostapd_iface *iface,
+ 			    struct hostapd_channel_data **ret_chan,
+-			    int idx, enum dfs_channel_type type)
++			    int n_chans, int idx, enum dfs_channel_type type)
+ {
+ 	struct hostapd_hw_modes *mode;
+ 	struct hostapd_channel_data *chan;
+-	int i, channel_idx = 0, n_chans, n_chans1;
++	int i, channel_idx = 0, n_chans1;
+ 
+ 	mode = iface->current_mode;
+-	n_chans = dfs_get_used_n_chans(iface, &n_chans1);
++	if (!n_chans)
++		n_chans = dfs_get_used_n_chans(iface, &n_chans1);
+ 
+ 	wpa_printf(MSG_DEBUG, "DFS new chan checking %d channels", n_chans);
+ 	for (i = 0; i < mode->num_channels; i++) {
+@@ -548,7 +549,7 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
+ 		return NULL;
+ 
+ 	/* Get the count first */
+-	num_available_chandefs = dfs_find_channel(iface, NULL, 0, type);
++	num_available_chandefs = dfs_find_channel(iface, NULL, 0, 0, type);
+ 	wpa_printf(MSG_DEBUG, "DFS: num_available_chandefs=%d",
+ 		   num_available_chandefs);
+ 	if (num_available_chandefs == 0)
+@@ -569,7 +570,7 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
+ 		return NULL;
+ 
+ 	chan_idx = _rand % num_available_chandefs;
+-	dfs_find_channel(iface, &chan, chan_idx, type);
++	dfs_find_channel(iface, &chan, 0, chan_idx, type);
+ 	if (!chan) {
+ 		wpa_printf(MSG_DEBUG, "DFS: no random channel found");
+ 		return NULL;
+@@ -599,7 +600,7 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
+ 		for (i = 0; i < num_available_chandefs - 1; i++) {
+ 			/* start from chan_idx + 1, end when chan_idx - 1 */
+ 			chan_idx2 = (chan_idx + 1 + i) % num_available_chandefs;
+-			dfs_find_channel(iface, &chan2, chan_idx2, type);
++			dfs_find_channel(iface, &chan2, 0, chan_idx2, type);
+ 			if (chan2 && abs(chan2->chan - chan->chan) > 12) {
+ 				/* two channels are not adjacent */
+ 				sec_chan_idx_80p80 = chan2->chan;
+@@ -1302,6 +1303,9 @@ int hostapd_dfs_pre_cac_expired(struct hostapd_iface *iface, int freq,
+ 	set_dfs_state(iface, freq, ht_enabled, chan_offset, chan_width,
+ 		      cf1, cf2, HOSTAPD_CHAN_DFS_USABLE);
+ 
++	if (dfs_use_radar_background(iface) && iface->radar_background.channel == -1)
++		hostpad_dfs_update_background_chain(iface);
++
+ 	return 0;
+ }
+ 
+@@ -1715,14 +1719,15 @@ int hostapd_handle_dfs_offload(struct hostapd_iface *iface)
+ }
+ 
+ 
+-int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
+-			   int center_freq)
++int hostapd_dfs_get_target_state(struct hostapd_iface *iface, enum chan_width width,
++				 int center_freq, int center_freq2)
+ {
+ 	struct hostapd_channel_data *chan;
+ 	struct hostapd_hw_modes *mode = iface->current_mode;
+-	int half_width;
+-	int res = 0;
++	int half_width, chan_state, state = 0;
++	int upper, lower;
+ 	int i;
++	bool in_range;
+ 
+ 	if (!iface->conf->ieee80211h || !mode ||
+ 	    mode->mode != HOSTAPD_MODE_IEEE80211A)
+@@ -1755,18 +1760,129 @@ int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
+ 		if (!(chan->flag & HOSTAPD_CHAN_RADAR))
+ 			continue;
+ 
+-		if ((chan->flag & HOSTAPD_CHAN_DFS_MASK) ==
+-		    HOSTAPD_CHAN_DFS_AVAILABLE)
+-			continue;
++		upper = chan->freq + half_width;
++		lower = chan->freq - half_width;
++		in_range = (lower < center_freq && center_freq < upper) ||
++			   (center_freq2 && (lower < center_freq2 && center_freq2 < upper));
++		if (in_range) {
++			chan_state = chan->flag & HOSTAPD_CHAN_DFS_MASK;
++			switch (chan_state) {
++			case HOSTAPD_CHAN_DFS_USABLE:
++				state = HOSTAPD_CHAN_DFS_USABLE;
++				break;
++			case HOSTAPD_CHAN_DFS_AVAILABLE:
++				if (state != HOSTAPD_CHAN_DFS_USABLE)
++					state = HOSTAPD_CHAN_DFS_AVAILABLE;
++				break;
++			case HOSTAPD_CHAN_DFS_UNKNOWN:
++				wpa_printf(MSG_WARNING, "chan %d DFS state: UNKNOWN",
++					   chan->freq);
++				/* fallthrough */
++			case HOSTAPD_CHAN_DFS_UNAVAILABLE:
++			default:
++				return HOSTAPD_CHAN_DFS_UNAVAILABLE;
++			}
++		}
++	}
+ 
+-		if (center_freq - chan->freq < half_width &&
+-		    chan->freq - center_freq < half_width)
+-			res++;
++	wpa_printf(MSG_DEBUG, "freq range (%d, %d) has DFS state %d",
++		   center_freq - half_width, center_freq + half_width, state);
++
++	return state;
++}
++
++
++static struct hostapd_channel_data *
++dfs_get_csa_channel(struct hostapd_iface *iface,
++		    int n_chans, int cur_center,
++		    enum dfs_channel_type type)
++{
++	struct hostapd_channel_data *chan;
++	int avail_chan_num;
++	u32 _rand, idx;
++
++	if (os_get_random((u8 *)&_rand, sizeof(_rand)) < 0)
++		return NULL;
++
++	avail_chan_num = dfs_find_channel(iface, NULL, n_chans, 0, type);
++	if (!avail_chan_num)
++		return NULL;
++
++	idx = _rand % avail_chan_num;
++	dfs_find_channel(iface, &chan, n_chans, idx, type);
++	if (cur_center == chan->freq + (n_chans - 1) * 10) {
++		if (avail_chan_num == 1)
++			return NULL;
++
++		/* Get the next channel if the found channel is same as current channel */
++		idx = (idx + 1) % avail_chan_num;
++		dfs_find_channel(iface, &chan, n_chans, idx, type);
+ 	}
+ 
+-	wpa_printf(MSG_DEBUG, "DFS CAC required: (%d, %d): in range: %s",
+-		   center_freq - half_width, center_freq + half_width,
+-		   res ? "yes" : "no");
++	return chan;
++}
+ 
+-	return res;
++
++/*
++ * DFS handler for CSA
++ * 1  - update background radar with the filled setting
++ * 0  - background radar is not enabled / background radar remain at the same channel /
++ *	disable background radar
++ */
++int hostapd_dfs_handle_csa(struct hostapd_iface *iface,
++			   struct csa_settings *settings,
++			   struct csa_settings *background_settings,
++			   bool cac_required, bool bw_changed)
++{
++	struct hostapd_channel_data *chan;
++	struct hostapd_freq_params *freq_params = &settings->freq_params;
++	int center = settings->freq_params.center_freq1;
++	int background_center = 5000 + iface->radar_background.centr_freq_seg0_idx * 5;
++	int n_chans = settings->freq_params.bandwidth / 20;
++	bool update_background = false;
++
++	if (!dfs_use_radar_background(iface)) {
++		settings->cs_count = 5;
++		settings->block_tx = cac_required;
++		return 0;
++	}
++
++	if (!cac_required) {
++		if (!bw_changed && center != background_center)
++			return 0;
++		/* Update background radar due to bw change or channel overlapping */
++		update_background = true;
++	} else {
++		/*
++		* Get available channel for main channel.
++		* If no available channel for main channel, then perform
++		* the CAC of target channel on the main channel, and select
++		* an usable channel for background radar.
++		*/
++		iface->radar_background.temp_ch = 1;
++		chan = dfs_get_csa_channel(iface, n_chans, 0, DFS_AVAILABLE);
++		if (!chan)
++			update_background = true;
++	}
++
++	if (update_background) {
++		chan = dfs_get_csa_channel(iface, n_chans, center, DFS_NO_CAC_YET);
++		if (!chan)
++			goto bkg_disable;
++		freq_params = &background_settings->freq_params;
++		iface->radar_background.temp_ch = 0;
++	}
++
++	memcpy(background_settings, settings, sizeof(*settings));
++	freq_params->freq = chan->freq;
++	freq_params->channel = chan->chan;
++	freq_params->sec_channel_offset = 1;
++	freq_params->center_freq1 = chan->freq + (n_chans - 1) * 10;
++	freq_params->center_freq2 = 0;
++
++	return 1;
++
++bkg_disable:
++	iface->radar_background.channel = -1;
++	return 0;
+ }
+diff --git a/src/ap/dfs.h b/src/ap/dfs.h
+index 1a0791f..0a7c25d 100644
+--- a/src/ap/dfs.h
++++ b/src/ap/dfs.h
+@@ -33,7 +33,12 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
+ 			  int ht_enabled, int chan_offset, int chan_width,
+ 			  int cf1, int cf2);
+ int hostapd_handle_dfs_offload(struct hostapd_iface *iface);
+-int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
+-			   int center_freq);
++int hostapd_dfs_get_target_state(struct hostapd_iface *iface, enum chan_width width,
++				 int center_freq, int center_freq2);
++int hostapd_dfs_handle_csa(struct hostapd_iface *iface,
++			   struct csa_settings *settings,
++			   struct csa_settings *background_settings,
++			   bool cac_required, bool bw_changed);
++
+ 
+ #endif /* DFS_H */
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch b/recipes-wifi/hostapd/files/patches/mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
similarity index 80%
rename from recipes-wifi/hostapd/files/patches/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
rename to recipes-wifi/hostapd/files/patches/mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
index 69f3fa2..bfd66a3 100644
--- a/recipes-wifi/hostapd/files/patches/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
+++ b/recipes-wifi/hostapd/files/patches/mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
@@ -1,7 +1,7 @@
-From b087dbc78f6911b16c9c00ac0a9246a89871225f Mon Sep 17 00:00:00 2001
+From 49f5a5c4430e59dec7dc135773636da2e889ce05 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Feb 2023 14:56:55 +0800
-Subject: [PATCH 11/35] hostapd: mtk: Add DFS offchan channel switch
+Subject: [PATCH 49/49] hostapd: mtk: Add DFS offchan channel switch
 
 Add DFS background chain channel switch command for testing purpose.
 This feature is implemented via hostapd_cli command.
@@ -12,17 +12,17 @@
 ---
  hostapd/ctrl_iface.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
  src/ap/dfs.c         | 25 ++++++---------
- src/ap/dfs.h         | 15 +++++++++
- 3 files changed, 96 insertions(+), 16 deletions(-)
+ src/ap/dfs.h         | 16 +++++++++-
+ 3 files changed, 96 insertions(+), 17 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index fcbc4ae..37a1b2a 100644
+index 328f7c2..97d807a 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3542,6 +3542,76 @@ hostapd_ctrl_iface_set_dfs_detect_mode(struct hostapd_data *hapd, char *value,
+@@ -3951,6 +3951,76 @@ hostapd_ctrl_iface_dump_amnt(struct hostapd_data *hapd, char *cmd,
+ 		return pos - buf;
  }
  
- 
 +static int
 +hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
 +				    char *buf, size_t buflen)
@@ -48,9 +48,9 @@
 +	else
 +		return -1;
 +
-+	num_available_chandefs = dfs_find_channel(iface, NULL, 0, type);
++	num_available_chandefs = dfs_find_channel(iface, NULL, 0, 0, type);
 +	for (i = 0; i < num_available_chandefs; i++) {
-+		dfs_find_channel(iface, &chan, i, type);
++		dfs_find_channel(iface, &chan, 0, i, type);
 +		if (chan->chan == channel) {
 +			chan_found = true;
 +			break;
@@ -96,17 +96,17 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4104,6 +4174,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 	} else if (os_strncmp(buf, "DFS_DETECT_MODE ", 16) == 0) {
- 		reply_len = hostapd_ctrl_iface_set_dfs_detect_mode(hapd, buf + 16,
- 								   reply, reply_size);
+@@ -4529,6 +4599,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 	} else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
+ 		reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
+ 							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 {
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 5cb7799..1c3f678 100644
+index a558d4e..bb5702b 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -19,13 +19,6 @@
@@ -123,20 +123,20 @@
  static struct hostapd_channel_data *
  dfs_downgrade_bandwidth(struct hostapd_iface *iface, int *secondary_channel,
  			u8 *oper_centr_freq_seg0_idx,
-@@ -238,9 +231,9 @@ static int is_in_chanlist(struct hostapd_iface *iface,
+@@ -246,9 +239,9 @@ static int is_in_chanlist(struct hostapd_iface *iface,
   *  - hapd->vht/he_oper_centr_freq_seg0_idx
   *  - hapd->vht/he_oper_centr_freq_seg1_idx
   */
 -static int dfs_find_channel(struct hostapd_iface *iface,
 -			    struct hostapd_channel_data **ret_chan,
--			    int idx, enum dfs_channel_type type)
+-			    int n_chans, int idx, enum dfs_channel_type type)
 +int dfs_find_channel(struct hostapd_iface *iface,
 +		     struct hostapd_channel_data **ret_chan,
-+		     int idx, enum dfs_channel_type type)
++		     int n_chans, int idx, enum dfs_channel_type type)
  {
  	struct hostapd_hw_modes *mode;
  	struct hostapd_channel_data *chan;
-@@ -299,12 +292,12 @@ static int dfs_find_channel(struct hostapd_iface *iface,
+@@ -308,12 +301,12 @@ static int dfs_find_channel(struct hostapd_iface *iface,
  }
  
  
@@ -156,7 +156,7 @@
  	if (!iface->conf->ieee80211ac && !iface->conf->ieee80211ax)
  		return;
 diff --git a/src/ap/dfs.h b/src/ap/dfs.h
-index 606c1b3..c2556d2 100644
+index 0a7c25d..e88ea24 100644
 --- a/src/ap/dfs.h
 +++ b/src/ap/dfs.h
 @@ -9,6 +9,12 @@
@@ -172,13 +172,14 @@
  int hostapd_handle_dfs(struct hostapd_iface *iface);
  
  int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
-@@ -32,5 +38,14 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
- int hostapd_handle_dfs_offload(struct hostapd_iface *iface);
- int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
- 			   int center_freq);
+@@ -39,6 +45,14 @@ int hostapd_dfs_handle_csa(struct hostapd_iface *iface,
+ 			   struct csa_settings *settings,
+ 			   struct csa_settings *background_settings,
+ 			   bool cac_required, bool bw_changed);
+-
 +int dfs_find_channel(struct hostapd_iface *iface,
 +		     struct hostapd_channel_data **ret_chan,
-+		     int idx, enum dfs_channel_type type);
++		     int n_chans, int idx, enum dfs_channel_type type);
 +void dfs_adjust_center_freq(struct hostapd_iface *iface,
 +			    struct hostapd_channel_data *chan,
 +			    int secondary_channel,
diff --git a/recipes-wifi/hostapd/files/patches/patches.inc b/recipes-wifi/hostapd/files/patches/patches.inc
index 9121a2f..0a397fe 100644
--- a/recipes-wifi/hostapd/files/patches/patches.inc
+++ b/recipes-wifi/hostapd/files/patches/patches.inc
@@ -62,6 +62,10 @@
     file://800-acs-don-t-select-indoor-channel-on-outdoor-operation.patch \
     file://990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch \
     file://992-openssl-include-rsa.patch \
+    file://bp-0001-ACS-Extract-bw40-80-160-freqs-out-of-acs_usable_bwXX.patch \
+    file://bp-0002-ACS-Introduce-acs_get_bw_center_chan.patch \
+    file://bp-0003-ACS-introduce-acs_adjust_secondary.patch \
+    file://bp-0004-ACS-Allow-selecting-a-better-channel-when-using-40-8.patch \
     file://mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch \
     file://mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch \
     file://mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch \
@@ -72,7 +76,6 @@
     file://mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch \
     file://mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch \
     file://mtk-0010-hostapd-mtk-Add-DFS-detection-mode.patch \
-    file://mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch \
     file://mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch \
     file://mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch \
     file://mtk-0014-hostapd-mtk-Add-the-broadcast-destination-address-of.patch \
@@ -107,4 +110,9 @@
     file://mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch \
     file://mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch \
     file://mtk-0045-hostapd-mtk-add-log-in-extender-mode.patch \
+    file://mtk-0046-hostapd-mtk-ACS-Fix-2.4GHz-HT40-case-and-channel-swi.patch \
+    file://mtk-0047-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF_new.patch \
+    file://mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch \
+    file://mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch \
+    file://mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch \
     "