]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DFS: Mark channels required DFS based on reg-domain info from the driver
authormazumdar <mazumdar@codeaurora.org>
Fri, 13 Apr 2018 09:55:40 +0000 (15:25 +0530)
committerJouni Malinen <j@w1.fi>
Mon, 23 Apr 2018 21:35:47 +0000 (00:35 +0300)
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>
src/ap/dfs.c
src/ap/drv_callbacks.c
src/common/ieee802_11_common.c
src/common/ieee802_11_common.h
wpa_supplicant/ap.c
wpa_supplicant/p2p_supplicant.c

index 5a0d7814b79bec3a68850e9a86149e0a57f27b92..993dd19c2cb07df9f838467f92a2f47d4c321ec8 100644 (file)
@@ -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;
index 61f8862380032050756b6f77c746203f0f849462..c5fd15e0620ecf9ba5d678b7cb080edeb7fcd21f 100644 (file)
@@ -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) {
index d29c60188e5b8821a7cac5cb684bca1342078ece..dcae84ce0392b6e6e188bb8e9ce767a6ca1157aa 100644 (file)
@@ -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;
 }
 
 
index bbb916b1f5b792b7a7bc266dc0c898f00eee3ca7..5b0893bba606f1bcfa489b7f3664fdbc1a0fb4cd 100644 (file)
@@ -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);
index 9e4fc1c54063a918423473d3469cd00087edc284..ce17e5729b69ad089e334f12798525bb86e05581 100644 (file)
@@ -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)
index afad16f03fe8b415bfe37b094d23a0d587679b17..6ae3adb83a29fcc3193e9345f8a21ae37b863881 100644 (file)
@@ -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;