]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP MLD: Track radar detection in offloaded DFS case
authorChenming Huang <quic_chenhuan@quicinc.com>
Wed, 13 Mar 2024 09:38:17 +0000 (15:08 +0530)
committerJouni Malinen <j@w1.fi>
Mon, 15 Apr 2024 08:38:56 +0000 (11:38 +0300)
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 <quic_chenhuan@quicinc.com>
src/ap/dfs.c
src/ap/hostapd.h

index fc2e8d83cda7e36438517dc8cc936037ea22c3e9..af9dc16f5987c128244d67209b2f6abd4f46cca1 100644 (file)
@@ -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;
index bed4c48ca32f92d750a62703a106bff020f22fda..0c38bb53df5a1c2b500cb1fa3204a9b1b3ab18b6 100644 (file)
@@ -602,6 +602,8 @@ struct hostapd_iface {
        int *basic_rates;
        int freq;
 
+       bool radar_detected;
+
        /* Background radar configuration */
        struct {
                int channel;