DFS: Introduce hostapd_dfs_request_channel_switch()
This is a preliminary patch to add Channel Switch Announcement for background radar detection. Tested-by: Owen Peng <owen.peng@mediatek.com> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
This commit is contained in:
parent
316a9dc63b
commit
25663241c5
1 changed files with 90 additions and 73 deletions
163
src/ap/dfs.c
163
src/ap/dfs.c
|
@ -943,6 +943,90 @@ int hostapd_is_dfs_chan_available(struct hostapd_iface *iface)
|
|||
}
|
||||
|
||||
|
||||
static int hostapd_dfs_request_channel_switch(struct hostapd_iface *iface,
|
||||
int channel, int freq,
|
||||
int secondary_channel,
|
||||
u8 current_vht_oper_chwidth,
|
||||
u8 oper_centr_freq_seg0_idx,
|
||||
u8 oper_centr_freq_seg1_idx)
|
||||
{
|
||||
struct hostapd_hw_modes *cmode = iface->current_mode;
|
||||
int ieee80211_mode = IEEE80211_MODE_AP, err;
|
||||
struct csa_settings csa_settings;
|
||||
u8 new_vht_oper_chwidth;
|
||||
unsigned int i;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d", channel);
|
||||
wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
|
||||
"freq=%d chan=%d sec_chan=%d", freq, channel,
|
||||
secondary_channel);
|
||||
|
||||
new_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
|
||||
hostapd_set_oper_chwidth(iface->conf, current_vht_oper_chwidth);
|
||||
|
||||
/* Setup CSA request */
|
||||
os_memset(&csa_settings, 0, sizeof(csa_settings));
|
||||
csa_settings.cs_count = 5;
|
||||
csa_settings.block_tx = 1;
|
||||
#ifdef CONFIG_MESH
|
||||
if (iface->mconf)
|
||||
ieee80211_mode = IEEE80211_MODE_MESH;
|
||||
#endif /* CONFIG_MESH */
|
||||
err = hostapd_set_freq_params(&csa_settings.freq_params,
|
||||
iface->conf->hw_mode,
|
||||
freq, channel,
|
||||
iface->conf->enable_edmg,
|
||||
iface->conf->edmg_channel,
|
||||
iface->conf->ieee80211n,
|
||||
iface->conf->ieee80211ac,
|
||||
iface->conf->ieee80211ax,
|
||||
secondary_channel,
|
||||
new_vht_oper_chwidth,
|
||||
oper_centr_freq_seg0_idx,
|
||||
oper_centr_freq_seg1_idx,
|
||||
cmode->vht_capab,
|
||||
&cmode->he_capab[ieee80211_mode]);
|
||||
|
||||
if (err) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"DFS failed to calculate CSA freq params");
|
||||
hostapd_disable_iface(iface);
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 0; i < iface->num_bss; i++) {
|
||||
err = hostapd_switch_channel(iface->bss[i], &csa_settings);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
wpa_printf(MSG_WARNING,
|
||||
"DFS failed to schedule CSA (%d) - trying fallback",
|
||||
err);
|
||||
iface->freq = freq;
|
||||
iface->conf->channel = channel;
|
||||
iface->conf->secondary_channel = secondary_channel;
|
||||
hostapd_set_oper_chwidth(iface->conf, new_vht_oper_chwidth);
|
||||
hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
|
||||
oper_centr_freq_seg0_idx);
|
||||
hostapd_set_oper_centr_freq_seg1_idx(iface->conf,
|
||||
oper_centr_freq_seg1_idx);
|
||||
|
||||
hostapd_disable_iface(iface);
|
||||
hostapd_enable_iface(iface);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Channel configuration will be updated once CSA completes and
|
||||
* ch_switch_notify event is received */
|
||||
wpa_printf(MSG_DEBUG, "DFS waiting channel switch event");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void hostpad_dfs_update_background_chain(struct hostapd_iface *iface)
|
||||
{
|
||||
int sec = 0;
|
||||
|
@ -1195,14 +1279,8 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
|
|||
int secondary_channel;
|
||||
u8 oper_centr_freq_seg0_idx;
|
||||
u8 oper_centr_freq_seg1_idx;
|
||||
u8 new_vht_oper_chwidth;
|
||||
enum dfs_channel_type channel_type = DFS_AVAILABLE;
|
||||
struct csa_settings csa_settings;
|
||||
unsigned int i;
|
||||
int err = 1;
|
||||
struct hostapd_hw_modes *cmode = iface->current_mode;
|
||||
u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
|
||||
int ieee80211_mode = IEEE80211_MODE_AP;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s called (CAC active: %s, CSA active: %s)",
|
||||
__func__, iface->cac_started ? "yes" : "no",
|
||||
|
@ -1265,73 +1343,12 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
|
|||
}
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
|
||||
channel->chan);
|
||||
wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
|
||||
"freq=%d chan=%d sec_chan=%d", channel->freq,
|
||||
channel->chan, secondary_channel);
|
||||
|
||||
new_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
|
||||
hostapd_set_oper_chwidth(iface->conf, current_vht_oper_chwidth);
|
||||
|
||||
/* Setup CSA request */
|
||||
os_memset(&csa_settings, 0, sizeof(csa_settings));
|
||||
csa_settings.cs_count = 5;
|
||||
csa_settings.block_tx = 1;
|
||||
#ifdef CONFIG_MESH
|
||||
if (iface->mconf)
|
||||
ieee80211_mode = IEEE80211_MODE_MESH;
|
||||
#endif /* CONFIG_MESH */
|
||||
err = hostapd_set_freq_params(&csa_settings.freq_params,
|
||||
iface->conf->hw_mode,
|
||||
channel->freq,
|
||||
channel->chan,
|
||||
iface->conf->enable_edmg,
|
||||
iface->conf->edmg_channel,
|
||||
iface->conf->ieee80211n,
|
||||
iface->conf->ieee80211ac,
|
||||
iface->conf->ieee80211ax,
|
||||
secondary_channel,
|
||||
new_vht_oper_chwidth,
|
||||
oper_centr_freq_seg0_idx,
|
||||
oper_centr_freq_seg1_idx,
|
||||
cmode->vht_capab,
|
||||
&cmode->he_capab[ieee80211_mode]);
|
||||
|
||||
if (err) {
|
||||
wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
|
||||
hostapd_disable_iface(iface);
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 0; i < iface->num_bss; i++) {
|
||||
err = hostapd_switch_channel(iface->bss[i], &csa_settings);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
wpa_printf(MSG_WARNING, "DFS failed to schedule CSA (%d) - trying fallback",
|
||||
err);
|
||||
iface->freq = channel->freq;
|
||||
iface->conf->channel = channel->chan;
|
||||
iface->conf->secondary_channel = secondary_channel;
|
||||
hostapd_set_oper_chwidth(iface->conf, new_vht_oper_chwidth);
|
||||
hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
|
||||
oper_centr_freq_seg0_idx);
|
||||
hostapd_set_oper_centr_freq_seg1_idx(iface->conf,
|
||||
oper_centr_freq_seg1_idx);
|
||||
|
||||
hostapd_disable_iface(iface);
|
||||
hostapd_enable_iface(iface);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Channel configuration will be updated once CSA completes and
|
||||
* ch_switch_notify event is received */
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DFS waiting channel switch event");
|
||||
return 0;
|
||||
return hostapd_dfs_request_channel_switch(iface, channel->chan,
|
||||
channel->freq,
|
||||
secondary_channel,
|
||||
current_vht_oper_chwidth,
|
||||
oper_centr_freq_seg0_idx,
|
||||
oper_centr_freq_seg1_idx);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue