DFS: Mark channels required DFS based on reg-domain info from the driver
Mark a channel as required DFS based on regulatory information received from the driver/kernel rather than deciding based on hardcoded boundaries on the frequency. Previously few channels were being marked as requiring DFS even though they were non-DFS in a particular country. If the driver does not provide channel list information, fall back to the previously used frequency-based determination. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
0f7fc6b98d
commit
d239ab3962
6 changed files with 37 additions and 12 deletions
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue