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 <quic_chenhuan@quicinc.com>
This commit is contained in:
parent
aaf879ef20
commit
f4b84ecaf7
2 changed files with 28 additions and 5 deletions
31
src/ap/dfs.c
31
src/ap/dfs.c
|
@ -14,6 +14,7 @@
|
||||||
#include "common/hw_features_common.h"
|
#include "common/hw_features_common.h"
|
||||||
#include "common/wpa_ctrl.h"
|
#include "common/wpa_ctrl.h"
|
||||||
#include "hostapd.h"
|
#include "hostapd.h"
|
||||||
|
#include "beacon.h"
|
||||||
#include "ap_drv_ops.h"
|
#include "ap_drv_ops.h"
|
||||||
#include "drivers/driver.h"
|
#include "drivers/driver.h"
|
||||||
#include "dfs.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)
|
int cf1, int cf2)
|
||||||
{
|
{
|
||||||
wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_COMPLETED
|
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=%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);
|
success, freq, ht_enabled, chan_offset, chan_width, cf1, cf2,
|
||||||
|
iface->radar_detected);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
/* Complete iface/ap configuration */
|
/* Complete iface/ap configuration */
|
||||||
if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
|
if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
|
||||||
/* Complete AP configuration for the first bring up. */
|
/* Complete AP configuration for the first bring up. If
|
||||||
if (iface->state != HAPD_IFACE_ENABLED)
|
* 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);
|
hostapd_setup_interface_complete(iface, 0);
|
||||||
else
|
else
|
||||||
iface->cac_started = 0;
|
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);
|
hostapd_dfs_update_background_chain(iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iface->radar_detected = false;
|
||||||
return 0;
|
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=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
|
||||||
freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
|
freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
|
||||||
|
|
||||||
|
iface->radar_detected = true;
|
||||||
|
|
||||||
/* Proceed only if DFS is not offloaded to the driver */
|
/* Proceed only if DFS is not offloaded to the driver */
|
||||||
if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
|
if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1531,9 +1544,17 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
|
||||||
iface->radar_background.cac_started = 1;
|
iface->radar_background.cac_started = 1;
|
||||||
} else {
|
} else {
|
||||||
/* This is called when the driver indicates that an offloaded
|
/* 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);
|
hostapd_set_state(iface, HAPD_IFACE_DFS);
|
||||||
iface->cac_started = 1;
|
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? */
|
/* TODO: How to check CAC time for ETSI weather channels? */
|
||||||
iface->dfs_cac_ms = 60000;
|
iface->dfs_cac_ms = 60000;
|
||||||
|
|
|
@ -602,6 +602,8 @@ struct hostapd_iface {
|
||||||
int *basic_rates;
|
int *basic_rates;
|
||||||
int freq;
|
int freq;
|
||||||
|
|
||||||
|
bool radar_detected;
|
||||||
|
|
||||||
/* Background radar configuration */
|
/* Background radar configuration */
|
||||||
struct {
|
struct {
|
||||||
int channel;
|
int channel;
|
||||||
|
|
Loading…
Reference in a new issue