From da8570f4c954bbd285c19baccc2516c9cfa98247 Mon Sep 17 00:00:00 2001 From: Ankita Bajaj Date: Tue, 26 Nov 2019 11:19:32 +0530 Subject: [PATCH] Allow non-PCS 6 GHz channels to be excluded from ACS Add support to exclude non-PSC 6 GHz channels from the input frequency list to ACS. The new acs_exclude_6ghz_non_psc=1 parameter can be used by 6 GHz only APs. Signed-off-by: Jouni Malinen --- hostapd/config_file.c | 2 ++ hostapd/hostapd.conf | 7 +++++++ src/ap/ap_config.h | 1 + src/ap/ap_drv_ops.c | 4 ++++ src/common/ieee802_11_common.c | 20 ++++++++++++++++++++ src/common/ieee802_11_common.h | 1 + 6 files changed, 35 insertions(+) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index e489ec706..21c9ab288 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -3169,6 +3169,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, return 1; } conf->acs_freq_list_present = 1; + } else if (os_strcmp(buf, "acs_exclude_6ghz_non_psc") == 0) { + conf->acs_exclude_6ghz_non_psc = atoi(pos); } else if (os_strcmp(buf, "beacon_int") == 0) { int val = atoi(pos); /* MIB defines range as 1..65535, but very small values diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 591386311..f71e83e51 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -218,6 +218,13 @@ channel=1 # in cases where the driver supports DFS channels. #acs_exclude_dfs=1 +# Include only preferred scan channels from 6 GHz band for ACS +# This option can be used to include only preferred scan channels in the 6 GHz +# band. This can be useful in particular for devices that operate only a 6 GHz +# BSS without a collocated 2.4/5 GHz BSS. +# Default behavior is to include all PSC and non-PSC channels. +#acs_exclude_6ghz_non_psc=1 + # Beacon interval in kus (1.024 ms) (default: 100; range 15..65535) beacon_int=100 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index a3b9b5d50..83b8aee65 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -886,6 +886,7 @@ struct hostapd_config { u8 acs_freq_list_present; int acs_exclude_dfs; enum hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */ + int acs_exclude_6ghz_non_psc; enum { LONG_PREAMBLE = 0, SHORT_PREAMBLE = 1 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index bcacf8cc3..053e9bcc2 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -869,6 +869,10 @@ static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd, &hapd->iface->conf->acs_ch_list, chan->chan))) continue; + if (is_6ghz_freq(chan->freq) && + hapd->iface->conf->acs_exclude_6ghz_non_psc && + !is_6ghz_psc_frequency(chan->freq)) + continue; if (!(chan->flag & HOSTAPD_CHAN_DISABLED) && !(hapd->iface->conf->acs_exclude_dfs && (chan->flag & HOSTAPD_CHAN_RADAR))) diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index 275c50889..ffcbe414a 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -2069,6 +2069,26 @@ int is_6ghz_op_class(u8 op_class) } +int is_6ghz_psc_frequency(int freq) +{ + int i; + + if (!is_6ghz_freq(freq)) + return 0; + if ((((freq - 5940) / 5) & 0x3) != 0x1) + return 0; + + i = (freq - 5940 + 55) % 80; + if (i == 0) + i = (freq - 5940 + 55) / 80; + + if (i >= 1 && i <= 15) + return 1; + + return 0; +} + + int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, size_t nei_rep_len) { diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h index 275bca6db..984d248f6 100644 --- a/src/common/ieee802_11_common.h +++ b/src/common/ieee802_11_common.h @@ -226,6 +226,7 @@ int oper_class_bw_to_int(const struct oper_class_map *map); int center_idx_to_bw_6ghz(u8 idx); int is_6ghz_freq(int freq); int is_6ghz_op_class(u8 op_class); +int is_6ghz_psc_frequency(int freq); int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, size_t nei_rep_len);