[PATCH] hostapd: Fix CSA on 6GHz with bandwidth > 20

Nicolas Escande nico.escande at gmail.com
Thu Mar 5 01:29:10 PST 2026


On 6GHz we do not specify a secondary channel as it is always 0 for that band.

The code however was intended for 2.4/5G and clearly missed an exception for
this band to work when validating bandwidth > 20 MHz. As such switching to a
6GHz channel with a wide bandwidth failed systematically.

As an example a command to start channel switch to 6GHz chan 37 width 320MHz:
	CHAN_SWITCH 8 6135 blocktx he eht bandwidth=320 center_freq1=6265

Signed-off-by: Nicolas Escande <nico.escande at gmail.com>
---
 src/ap/ctrl_iface_ap.c | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index f2093018b939..f6a0f59d80a9 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -1220,8 +1220,9 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
 					  u16 punct_bitmap)
 {
 	u32 start_freq;
+	bool is_6g = is_6ghz_freq(params->freq);
 
-	if (is_6ghz_freq(params->freq)) {
+	if (is_6g) {
 		const int bw_idx[] = { 20, 40, 80, 160, 320 };
 		int idx, bw;
 
@@ -1273,7 +1274,8 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
 			return -1;
 		break;
 	case 40:
-		if (params->center_freq2 || !params->sec_channel_offset)
+		if (params->center_freq2 ||
+		    (!is_6g && !params->sec_channel_offset))
 			return -1;
 
 		if (punct_bitmap)
@@ -1290,12 +1292,17 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
 			if (params->freq - 10 != params->center_freq1)
 				return -1;
 			break;
+		case 0:
+			if (is_6g)
+				break;
+		// fallthrough
 		default:
 			return -1;
 		}
 		break;
 	case 80:
-		if (!params->center_freq1 || !params->sec_channel_offset)
+		if (!params->center_freq1 ||
+		    (!is_6g && !params->sec_channel_offset))
 			return 1;
 
 		switch (params->sec_channel_offset) {
@@ -1309,6 +1316,10 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
 			    params->freq - 30 != params->center_freq1)
 				return -1;
 			break;
+		case 0:
+			if (is_6g)
+				break;
+		// fallthrough
 		default:
 			return -1;
 		}
@@ -1324,7 +1335,7 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
 		break;
 	case 160:
 		if (!params->center_freq1 || params->center_freq2 ||
-		    !params->sec_channel_offset)
+		    (!is_6g && !params->sec_channel_offset))
 			return -1;
 
 		switch (params->sec_channel_offset) {
@@ -1342,13 +1353,17 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
 			    params->freq - 70 != params->center_freq1)
 				return -1;
 			break;
+		case 0:
+			if (is_6g)
+				break;
+		// fallthrough
 		default:
 			return -1;
 		}
 		break;
 	case 320:
 		if (!params->center_freq1 || params->center_freq2 ||
-		    !params->sec_channel_offset)
+		    (!is_6g && !params->sec_channel_offset))
 			return -1;
 
 		switch (params->sec_channel_offset) {
@@ -1374,6 +1389,12 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
 			    params->freq - 150 != params->center_freq1)
 				return -1;
 			break;
+		case 0:
+			if (is_6g)
+				break;
+		// fallthrough
+		default:
+			return -1;
 		}
 		break;
 	default:
-- 
2.53.0




More information about the Hostap mailing list