diff --git a/src/ap/dfs.c b/src/ap/dfs.c index 5a0d7814b..993dd19c2 100644 --- a/src/ap/dfs.c +++ b/src/ap/dfs.c @@ -1111,7 +1111,8 @@ int hostapd_handle_dfs_offload(struct hostapd_iface *iface) return 1; } - if (ieee80211_is_dfs(iface->freq)) { + if (ieee80211_is_dfs(iface->freq, iface->hw_features, + iface->num_hw_features)) { wpa_printf(MSG_DEBUG, "%s: freq %d MHz requires DFS", __func__, iface->freq); return 0; diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index 61f886238..c5fd15e06 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -791,7 +791,8 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx; hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx; - is_dfs = ieee80211_is_dfs(freq); + is_dfs = ieee80211_is_dfs(freq, hapd->iface->hw_features, + hapd->iface->num_hw_features); if (hapd->csa_in_progress && freq == hapd->cs_freq_params.freq) { diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index d29c60188..dcae84ce0 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -11,6 +11,7 @@ #include "common.h" #include "defs.h" #include "wpa_common.h" +#include "drivers/driver.h" #include "qca-vendor.h" #include "ieee802_11_defs.h" #include "ieee802_11_common.h" @@ -1178,10 +1179,24 @@ int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan) } -int ieee80211_is_dfs(int freq) +int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes, + u16 num_modes) { - /* TODO: this could be more accurate to better cover all domains */ - return (freq >= 5260 && freq <= 5320) || (freq >= 5500 && freq <= 5700); + int i, j; + + if (!modes || !num_modes) + return (freq >= 5260 && freq <= 5320) || + (freq >= 5500 && freq <= 5700); + + for (i = 0; i < num_modes; i++) { + for (j = 0; j < modes[i].num_channels; j++) { + if (modes[i].channels[j].freq == freq && + (modes[i].channels[j].flag & HOSTAPD_CHAN_RADAR)) + return 1; + } + } + + return 0; } diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h index bbb916b1f..5b0893bba 100644 --- a/src/common/ieee802_11_common.h +++ b/src/common/ieee802_11_common.h @@ -11,6 +11,8 @@ #include "defs.h" +struct hostapd_hw_modes; + #define MAX_NOF_MB_IES_SUPPORTED 5 struct mb_ies_info { @@ -156,7 +158,8 @@ int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan); enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq, int sec_channel, int vht, u8 *op_class, u8 *channel); -int ieee80211_is_dfs(int freq); +int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes, + u16 num_modes); enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht); int supp_rates_11b_only(struct ieee802_11_elems *elems); diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 9e4fc1c54..ce17e5729 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -256,7 +256,8 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_ACS */ - if (ieee80211_is_dfs(ssid->frequency) && wpa_s->conf->country[0]) { + if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes, + wpa_s->hw.num_modes) && wpa_s->conf->country[0]) { conf->ieee80211h = 1; conf->ieee80211d = 1; conf->country[0] = wpa_s->conf->country[0]; @@ -719,7 +720,8 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s, else params.uapsd = -1; - if (ieee80211_is_dfs(params.freq.freq)) + if (ieee80211_is_dfs(params.freq.freq, wpa_s->hw.modes, + wpa_s->hw.num_modes)) params.freq.freq = 0; /* set channel after CAC */ if (params.p2p) diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index afad16f03..6ae3adb83 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -5204,7 +5204,8 @@ static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq, ret = p2p_supported_freq_cli(wpa_s->global->p2p, freq); if (!ret) { if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) && - ieee80211_is_dfs(freq)) { + ieee80211_is_dfs(freq, wpa_s->hw.modes, + wpa_s->hw.num_modes)) { /* * If freq is a DFS channel and DFS is offloaded * to the driver, allow P2P GO to use it. @@ -5692,7 +5693,8 @@ static int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq) if (freq > 0 && !p2p_supported_freq_go(wpa_s->global->p2p, freq)) { if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) && - ieee80211_is_dfs(freq)) { + ieee80211_is_dfs(freq, wpa_s->hw.modes, + wpa_s->hw.num_modes)) { /* * If freq is a DFS channel and DFS is offloaded to the * driver, allow P2P GO to use it. @@ -5856,7 +5858,8 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, } if (!p2p_supported_freq_go(wpa_s->global->p2p, freq)) { if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) && - ieee80211_is_dfs(freq)) { + ieee80211_is_dfs(freq, wpa_s->hw.modes, + wpa_s->hw.num_modes)) { /* * If freq is a DFS channel and DFS is offloaded * to the driver, allow P2P GO to use it. @@ -9087,7 +9090,7 @@ static void wpas_p2p_consider_moving_one_go(struct wpa_supplicant *wpa_s, freq = wpa_s->current_ssid->frequency; dfs_offload = (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) && - ieee80211_is_dfs(freq); + ieee80211_is_dfs(freq, wpa_s->hw.modes, wpa_s->hw.num_modes); for (i = 0, invalid_freq = 0; i < num; i++) { if (freqs[i].freq == freq) { flags = freqs[i].flags;