Skip CAC if the driver switches channel to non-DFS
If an AP is started on a DFS channel (or any channels within its bandwidth require DFS) and DFS is offloaded to the driver, hostapd needs to wait for CAC to complete. But the driver may not do CAC and just switches to a non-DFS channel instead. This would result in a failure to start the AP because hostapd fails to receive a CAC complete event and cannot finish interface setup. Skip CAC and complete AP setup in the channel switch event handler for this case. Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
parent
080afc03d5
commit
b6c38cee93
1 changed files with 16 additions and 4 deletions
|
@ -862,14 +862,16 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
||||||
int finished)
|
int finished)
|
||||||
{
|
{
|
||||||
#ifdef NEED_AP_MLME
|
#ifdef NEED_AP_MLME
|
||||||
int channel, chwidth, is_dfs;
|
int channel, chwidth, is_dfs0, is_dfs;
|
||||||
u8 seg0_idx = 0, seg1_idx = 0;
|
u8 seg0_idx = 0, seg1_idx = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
|
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
|
||||||
HOSTAPD_LEVEL_INFO,
|
HOSTAPD_LEVEL_INFO,
|
||||||
"driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, eht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
|
"driver %s channel switch: iface->freq=%d, freq=%d, ht=%d, vht_ch=0x%x, "
|
||||||
|
"he_ch=0x%x, eht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
|
||||||
finished ? "had" : "starting",
|
finished ? "had" : "starting",
|
||||||
|
hapd->iface->freq,
|
||||||
freq, ht, hapd->iconf->ch_switch_vht_config,
|
freq, ht, hapd->iconf->ch_switch_vht_config,
|
||||||
hapd->iconf->ch_switch_he_config,
|
hapd->iconf->ch_switch_he_config,
|
||||||
hapd->iconf->ch_switch_eht_config, offset,
|
hapd->iconf->ch_switch_eht_config, offset,
|
||||||
|
@ -882,6 +884,8 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if any of configured channels require DFS */
|
||||||
|
is_dfs0 = hostapd_is_dfs_required(hapd->iface);
|
||||||
hapd->iface->freq = freq;
|
hapd->iface->freq = freq;
|
||||||
|
|
||||||
channel = hostapd_hw_get_channel(hapd, freq);
|
channel = hostapd_hw_get_channel(hapd, freq);
|
||||||
|
@ -997,11 +1001,11 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
||||||
hapd->iface->num_hw_features);
|
hapd->iface->num_hw_features);
|
||||||
|
|
||||||
wpa_msg(hapd->msg_ctx, MSG_INFO,
|
wpa_msg(hapd->msg_ctx, MSG_INFO,
|
||||||
"%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d dfs=%d",
|
"%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d is_dfs0=%d dfs=%d",
|
||||||
finished ? WPA_EVENT_CHANNEL_SWITCH :
|
finished ? WPA_EVENT_CHANNEL_SWITCH :
|
||||||
WPA_EVENT_CHANNEL_SWITCH_STARTED,
|
WPA_EVENT_CHANNEL_SWITCH_STARTED,
|
||||||
freq, ht, offset, channel_width_to_string(width),
|
freq, ht, offset, channel_width_to_string(width),
|
||||||
cf1, cf2, is_dfs);
|
cf1, cf2, is_dfs0, is_dfs);
|
||||||
if (!finished)
|
if (!finished)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1013,6 +1017,14 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
||||||
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
|
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
|
||||||
"freq=%d dfs=%d", freq, is_dfs);
|
"freq=%d dfs=%d", freq, is_dfs);
|
||||||
} else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
|
} else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
|
||||||
|
/* Complete AP configuration for the first bring up. */
|
||||||
|
if (is_dfs0 > 0 &&
|
||||||
|
hostapd_is_dfs_required(hapd->iface) <= 0 &&
|
||||||
|
hapd->iface->state != HAPD_IFACE_ENABLED) {
|
||||||
|
/* Fake a CAC start bit to skip setting channel */
|
||||||
|
hapd->iface->cac_started = 1;
|
||||||
|
hostapd_setup_interface_complete(hapd->iface, 0);
|
||||||
|
}
|
||||||
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
|
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
|
||||||
"freq=%d dfs=%d", freq, is_dfs);
|
"freq=%d dfs=%d", freq, is_dfs);
|
||||||
} else if (is_dfs &&
|
} else if (is_dfs &&
|
||||||
|
|
Loading…
Reference in a new issue