diff mbox series

[v2,5/5] DFS: switch to background radar channel if available

Message ID 6f18afa3fb1326bab22d199dc4c5007d794f7034.1646594636.git.lorenzo@kernel.org
State Accepted
Headers show
Series introduce background radar detection support | expand

Commit Message

Lorenzo Bianconi March 6, 2022, 7:34 p.m. UTC
On radar detection on the main chain switch to the channel monitored
by the background chain if we have already performed the CAC there.
If a radar pattern is reported on the background chain, just select a
new random channel according to the regulations for monitoring.

Tested-by: Owen Peng <owen.peng@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 src/ap/dfs.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 56 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index b152dc411..796fd348a 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -1263,6 +1263,51 @@  static int hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface)
 	return err;
 }
 
+static int
+hostapd_dfs_background_start_channel_switch(struct hostapd_iface *iface,
+					    int freq)
+{
+	if (!(iface->drv_flags2 & WPA_DRIVER_RADAR_BACKGROUND))
+		return -1; /* Background radar chain not supported. */
+
+	wpa_printf(MSG_DEBUG,
+		   "%s called (background CAC active: %s, CSA active: %s)",
+		   __func__, iface->radar_background.cac_started ? "yes" : "no",
+		   hostapd_csa_in_progress(iface) ? "yes" : "no");
+
+	/* Check if CSA in progress */
+	if (hostapd_csa_in_progress(iface))
+		return 0;
+
+	if (hostapd_dfs_is_background_event(iface, freq)) {
+		/*
+		 * Radar pattern is reported on the background chain.
+		 * Just select a new random channel according to the
+		 * regulations for monitoring.
+		 */
+		hostpad_dfs_update_background_chain(iface);
+		return 0;
+	}
+
+	/*
+	 * If background radar detection is supported and radar channel
+	 * monitored by background chain is available switch to it without
+	 * waiting for the CAC.
+	 */
+	if (iface->radar_background.channel == -1)
+		return -1; /* Background radar chain not available. */
+
+	if (iface->radar_background.cac_started) {
+		/* Background channel not available yet. Perform CAC on the
+		 * main chain.
+		 */
+		iface->radar_background.temp_ch = 1;
+		return -1;
+	}
+
+	return hostapd_dfs_start_channel_switch_background(iface);
+}
+
 static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
 {
 	u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
@@ -1365,15 +1410,19 @@  int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq,
 	if (!res)
 		return 0;
 
-	/* Skip if reported radar event not overlapped our channels */
-	res = dfs_are_channels_overlapped(iface, freq, chan_width, cf1, cf2);
-	if (!res)
-		return 0;
+	if (!hostapd_dfs_is_background_event(iface, freq)) {
+		/* Skip if reported radar event not overlapped our channels */
+		res = dfs_are_channels_overlapped(iface, freq, chan_width,
+						  cf1, cf2);
+		if (!res)
+			return 0;
+	}
 
-	/* radar detected while operating, switch the channel. */
-	res = hostapd_dfs_start_channel_switch(iface);
+	if (hostapd_dfs_background_start_channel_switch(iface, freq))
+		/* radar detected while operating, switch the channel. */
+		return hostapd_dfs_start_channel_switch(iface);
 
-	return res;
+	return 0;
 }