From f4b84ecaf7980474d05a449c1b1f30b03ad62533 Mon Sep 17 00:00:00 2001 From: Chenming Huang Date: Wed, 13 Mar 2024 15:08:17 +0530 Subject: [PATCH] AP MLD: Track radar detection in offloaded DFS case Add a new flag radar_detected which is used in the following cases when setting up a link on a DFS channel while the interface is not yet enabled: 1. DFS link received CAC start event 2. If no radar detected, link setup succeeeds after CAC end event is received. Else go to 3. 3. Radar detected on this link -> set radar_detected bit 4. CAC end received for the current freq -> Do not setup interface as radar already detected. Clear radar_detected bit. 5. The driver sends channel switch event to switch to another channel a. Switch to another DFS channel -> go to 1 b. Switch to non-DFS channel -> proceed to set up interface Or when receiving a CAC start event when the interface is already set up: 1. DFS link already set up successfully 2. Radar detected on this link -> set radar_detected bit a. Switch to DFS channel a.1. CAC start -> clear radar_detected bit and partner RNR a.2. If radar detected, go to 2. a.3. CAC end -> clear radar_detected bit a.4. Link enabled successfully b. Switch to non-DFS channel b.1 No op and the driver handles this Signed-off-by: Chenming Huang --- src/ap/dfs.c | 31 ++++++++++++++++++++++++++----- src/ap/hostapd.h | 2 ++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/ap/dfs.c b/src/ap/dfs.c index fc2e8d83c..af9dc16f5 100644 --- a/src/ap/dfs.c +++ b/src/ap/dfs.c @@ -14,6 +14,7 @@ #include "common/hw_features_common.h" #include "common/wpa_ctrl.h" #include "hostapd.h" +#include "beacon.h" #include "ap_drv_ops.h" #include "drivers/driver.h" #include "dfs.h" @@ -1143,14 +1144,23 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq, int cf1, int cf2) { wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_COMPLETED - "success=%d freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", - success, freq, ht_enabled, chan_offset, chan_width, cf1, cf2); + "success=%d freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d radar_detected=%d", + success, freq, ht_enabled, chan_offset, chan_width, cf1, cf2, + iface->radar_detected); if (success) { /* Complete iface/ap configuration */ if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) { - /* Complete AP configuration for the first bring up. */ - if (iface->state != HAPD_IFACE_ENABLED) + /* Complete AP configuration for the first bring up. If + * a radar was detected in this channel, interface setup + * will be handled in + * 1. hostapd_event_ch_switch() if switching to a + * non-DFS channel + * 2. on next CAC complete event if switching to another + * DFS channel. + */ + if (iface->state != HAPD_IFACE_ENABLED && + !iface->radar_detected) hostapd_setup_interface_complete(iface, 0); else iface->cac_started = 0; @@ -1195,6 +1205,7 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq, hostapd_dfs_update_background_chain(iface); } + iface->radar_detected = false; return 0; } @@ -1438,6 +1449,8 @@ int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq, "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", freq, ht_enabled, chan_offset, chan_width, cf1, cf2); + iface->radar_detected = true; + /* Proceed only if DFS is not offloaded to the driver */ if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) return 0; @@ -1531,9 +1544,17 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq, iface->radar_background.cac_started = 1; } else { /* This is called when the driver indicates that an offloaded - * DFS has started CAC. */ + * DFS has started CAC. radar_detected might be set for previous + * DFS channel. Clear it for this new CAC process. */ hostapd_set_state(iface, HAPD_IFACE_DFS); iface->cac_started = 1; + + /* Clear radar_detected in case it is for the previous + * frequency. Also remove disabled link's information in RNR + * element from other links. */ + iface->radar_detected = false; + if (iface->interfaces && iface->interfaces->count > 1) + ieee802_11_set_beacons(iface); } /* TODO: How to check CAC time for ETSI weather channels? */ iface->dfs_cac_ms = 60000; diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index bed4c48ca..0c38bb53d 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -602,6 +602,8 @@ struct hostapd_iface { int *basic_rates; int freq; + bool radar_detected; + /* Background radar configuration */ struct { int channel;