From 2168aadfa4ac6f1cb0642dccf9bfddb6c87df325 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Wed, 12 Jun 2019 20:51:36 +0530 Subject: [PATCH] qcacld-3.0: Add support to configure avoid acs freq list Currently there is no ini support to configure frequencies which needs to be avoided for the acs channel list which may allow SAP to come up on a channel which is not preferred. For Example there are many legacy clients which supports 2.4GHz but don't support channel 12 and 13 (or does not have the capability to detect country change where channel 12 and 13 is valid). In that case, if SAP comes up on channel 12/13, those legacy clients won't be able to connect to AP. Hence, Add a feature flag and ini to configure the frequency list which can be avoided during acs. Change-Id: Id106b38228f837ba056eb916004dc012e919ddd2 CRs-Fixed: 2472004 --- Kbuild | 3 ++ components/mlme/core/src/wlan_mlme_main.c | 25 +++++++++ components/mlme/dispatcher/inc/cfg_mlme_reg.h | 36 ++++++++++++- .../dispatcher/inc/wlan_mlme_public_struct.h | 7 +++ .../mlme/dispatcher/inc/wlan_mlme_ucfg_api.h | 24 +++++++++ .../mlme/dispatcher/src/wlan_mlme_ucfg_api.c | 28 ++++++++++ configs/default_defconfig | 3 ++ configs/genoa.common | 3 ++ core/hdd/src/wlan_hdd_cfg80211.c | 52 +++++++++++++++++++ 9 files changed, 180 insertions(+), 1 deletion(-) diff --git a/Kbuild b/Kbuild index f85c14afc8e9..4996acece0c6 100644 --- a/Kbuild +++ b/Kbuild @@ -2618,6 +2618,9 @@ cppflags-$(CONFIG_HOST_OPCLASS) += -DHOST_OPCLASS #Flag to enable/disable TARGET_11D_SCAN cppflags-$(CONFIG_TARGET_11D_SCAN) += -DTARGET_11D_SCAN +#Flag to enable/disable avoid acs frequency list feature +cppflags-$(CONFIG_SAP_AVOID_ACS_FREQ_LIST) += -DSAP_AVOID_ACS_FREQ_LIST + #Flag to enable Dynamic Voltage WDCVS (Config Voltage Mode) cppflags-$(CONFIG_WLAN_DYNAMIC_CVM) += -DFEATURE_WLAN_DYNAMIC_CVM diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 0e42dbddffac..a97fa69fc275 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -2252,6 +2252,30 @@ static void mlme_init_mwc_cfg(struct wlan_objmgr_psoc *psoc, } #endif +#ifdef SAP_AVOID_ACS_FREQ_LIST +static void mlme_init_acs_avoid_freq_list(struct wlan_objmgr_psoc *psoc, + struct wlan_mlme_reg *reg) +{ + qdf_size_t avoid_acs_freq_list_num = 0; + uint8_t i; + + qdf_uint16_array_parse(cfg_get(psoc, CFG_SAP_AVOID_ACS_FREQ_LIST), + reg->avoid_acs_freq_list, + CFG_VALID_CHANNEL_LIST_LEN, + &avoid_acs_freq_list_num); + reg->avoid_acs_freq_list_num = avoid_acs_freq_list_num; + + for (i = 0; i < avoid_acs_freq_list_num; i++) + mlme_legacy_debug("avoid_acs_freq %d", + reg->avoid_acs_freq_list[i]); +} +#else +static void mlme_init_acs_avoid_freq_list(struct wlan_objmgr_psoc *psoc, + struct wlan_mlme_reg *reg) +{ +} +#endif + static void mlme_init_reg_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_reg *reg) { @@ -2274,6 +2298,7 @@ static void mlme_init_reg_cfg(struct wlan_objmgr_psoc *psoc, qdf_str_lcopy(reg->country_code, cfg_default(CFG_COUNTRY_CODE), sizeof(reg->country_code)); reg->country_code_len = (uint8_t)sizeof(reg->country_code); + mlme_init_acs_avoid_freq_list(psoc, reg); } static void diff --git a/components/mlme/dispatcher/inc/cfg_mlme_reg.h b/components/mlme/dispatcher/inc/cfg_mlme_reg.h index f7972a130db5..502226923f23 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_reg.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_reg.h @@ -95,6 +95,39 @@ 0, \ "enable/disable ETSI SRD channels in master mode") +#ifdef SAP_AVOID_ACS_FREQ_LIST +#define SAP_AVOID_ACS_FREQ_LIST_DEFAULT "" + +/* + * + * sap_avoid_acs_freq_list - Avoid configured frequencies from acs + * @Default: No frequencies are configured, it means consider all + * the frequencies for acs + * + * This ini is to configure the frequencies which needs to be + * avoided during acs and sap will not come up on these channels + * Ex: sap_avoid_acs_freq_list=2412,2417,2422,2427,2467,2472 + * + * Related: Feature flag SAP_AVOID_ACS_FREQ_LIST + * + * Supported Feature: SAP + * + * Usage: External + * + * + */ + +#define CFG_SAP_AVOID_ACS_FREQ_LIST CFG_INI_STRING( \ + "sap_avoid_acs_freq_list", \ + 0, \ + CFG_VALID_CHANNEL_LIST_STRING_LEN, \ + SAP_AVOID_ACS_FREQ_LIST_DEFAULT, \ + "Avoid configured frequencies during acs") +#define CFG_SAP_AVOID_ACS_FREQ_LIST_ALL CFG(CFG_SAP_AVOID_ACS_FREQ_LIST) +#else +#define CFG_SAP_AVOID_ACS_FREQ_LIST_ALL +#endif + /* * * restart_beaconing_on_chan_avoid_event - control the beaconing entity to move @@ -217,6 +250,7 @@ CFG(CFG_INDOOR_CHANNEL_SUPPORT) \ CFG(CFG_SCAN_11D_INTERVAL) \ CFG(CFG_VALID_CHANNEL_LIST) \ - CFG(CFG_COUNTRY_CODE) + CFG(CFG_COUNTRY_CODE) \ + CFG_SAP_AVOID_ACS_FREQ_LIST_ALL #endif /* CFG_MLME_REG_H__ */ diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 5c9cbe4f1143..ff076f710aff 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -2038,6 +2038,9 @@ struct wlan_mlme_mwc { * @country_code: country code * @country_code_len: country code length * @enable_11d_in_world_mode: Whether to enable 11d scan in world mode or not + * @avoid_acs_freq_list: List of the frequencies which need to be avoided + * during acs + * @avoid_acs_freq_list_num: Number of the frequencies to be avoided during acs */ struct wlan_mlme_reg { uint32_t self_gen_frm_pwr; @@ -2051,6 +2054,10 @@ struct wlan_mlme_reg { uint8_t country_code[CFG_COUNTRY_CODE_LEN + 1]; uint8_t country_code_len; bool enable_11d_in_world_mode; +#ifdef SAP_AVOID_ACS_FREQ_LIST + uint16_t avoid_acs_freq_list[CFG_VALID_CHANNEL_LIST_LEN]; + uint8_t avoid_acs_freq_list_num; +#endif }; /** diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 0a9f6e5393f1..2b4fee3bb87f 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -3660,6 +3660,30 @@ QDF_STATUS ucfg_mlme_get_etsi13_srd_chan_in_master_mode(struct wlan_objmgr_psoc *psoc, bool *value); +#ifdef SAP_AVOID_ACS_FREQ_LIST +/** + * ucfg_mlme_get_acs_avoid_freq_list - get acs avoid frequency list + * @psoc: pointer to psoc object + * @freq_list: Pointer to output freq list + * @freq_list_num: Pointer to the output number of frequencies filled + * in the freq_list + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_acs_avoid_freq_list(struct wlan_objmgr_psoc *psoc, + uint16_t *freq_list, uint8_t *freq_list_num); + +#else +static inline QDF_STATUS +ucfg_mlme_get_acs_avoid_freq_list(struct wlan_objmgr_psoc *psoc, + uint16_t *freq_list, uint8_t *freq_list_num) +{ + *freq_list_num = 0; + return QDF_STATUS_E_INVAL; +} +#endif + /** * ucfg_mlme_get_11d_in_world_mode - get whether 11d is enabled in world mode * in master mode diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c index 93d8a09aa0a9..fd4e376ac58f 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c @@ -1414,6 +1414,34 @@ ucfg_mlme_get_etsi13_srd_chan_in_master_mode(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +#ifdef SAP_AVOID_ACS_FREQ_LIST +QDF_STATUS +ucfg_mlme_get_acs_avoid_freq_list(struct wlan_objmgr_psoc *psoc, + uint16_t *freq_list, uint8_t *freq_list_num) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + qdf_size_t avoid_acs_freq_list_num; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + qdf_uint16_array_parse( + cfg_default(CFG_SAP_AVOID_ACS_FREQ_LIST), + freq_list, CFG_VALID_CHANNEL_LIST_LEN, + &avoid_acs_freq_list_num); + *freq_list_num = avoid_acs_freq_list_num; + + mlme_legacy_err("Failed to get MLME Obj"); + return QDF_STATUS_E_INVAL; + } + + *freq_list_num = mlme_obj->cfg.reg.avoid_acs_freq_list_num; + qdf_mem_copy(freq_list, mlme_obj->cfg.reg.avoid_acs_freq_list, + *freq_list_num * sizeof(uint16_t)); + + return QDF_STATUS_SUCCESS; +} +#endif + QDF_STATUS ucfg_mlme_get_11d_in_world_mode(struct wlan_objmgr_psoc *psoc, bool *value) diff --git a/configs/default_defconfig b/configs/default_defconfig index b06dc789f162..0e9efa581ac2 100644 --- a/configs/default_defconfig +++ b/configs/default_defconfig @@ -656,6 +656,9 @@ CONFIG_LTE_COEX := y #Flag to enable/disable TARGET 11d scan CONFIG_TARGET_11D_SCAN := y +#Flag to enable/disable Avoid acs freq feature +CONFIG_SAP_AVOID_ACS_FREQ_LIST := y + #Flag to enable HOST OPCLASS feature CONFIG_HOST_OPCLASS := y diff --git a/configs/genoa.common b/configs/genoa.common index aa7f0aa814a3..e25b4d5c94e1 100644 --- a/configs/genoa.common +++ b/configs/genoa.common @@ -53,6 +53,9 @@ CONFIG_WLAN_DYNAMIC_CVM := n CONFIG_WLAN_WEXT_SUPPORT_ENABLE := y CONFIG_HOST_11D_SCAN := y +#Flag to enable/disable Avoid acs freq feature +CONFIG_SAP_AVOID_ACS_FREQ_LIST := n + ifeq ($(CONFIG_ARCH_MSM8996), y) CONFIG_CHANNEL_HOPPING_ALL_BANDS := y endif diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 2f168d5b2e39..1753f1a69d2a 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -2529,6 +2529,55 @@ int hdd_start_vendor_acs(struct hdd_adapter *adapter) return status; } +/** + * hdd_avoid_acs_channels() - Avoid acs channels + * @hdd_ctx: Pointer to the hdd context + * @sap_config: Sap config structure pointer + * + * This function avoids channels from the acs corresponding to + * the frequencies configured in the ini sap_avoid_acs_freq_list + * + * Return: None + */ + +#ifdef SAP_AVOID_ACS_FREQ_LIST +static void hdd_avoid_acs_channels(struct hdd_context *hdd_ctx, + struct sap_config *sap_config) +{ + int i, j, ch_cnt = 0; + uint16_t avoid_acs_freq_list[CFG_VALID_CHANNEL_LIST_LEN]; + uint8_t avoid_acs_freq_list_num; + + hdd_enter(); + + ucfg_mlme_get_acs_avoid_freq_list(hdd_ctx->psoc, + avoid_acs_freq_list, + &avoid_acs_freq_list_num); + + for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) { + for (j = 0; j < avoid_acs_freq_list_num; j++) { + if (sap_config->acs_cfg.ch_list[i] == + wlan_reg_freq_to_chan( + hdd_ctx->pdev, + avoid_acs_freq_list[j])) { + hdd_debug("skip channel %d", + sap_config->acs_cfg.ch_list[i]); + break; + } + } + if (j == avoid_acs_freq_list_num) + sap_config->acs_cfg.ch_list[ch_cnt++] = + sap_config->acs_cfg.ch_list[i]; + } + sap_config->acs_cfg.ch_list_count = ch_cnt; +} +#else +static void hdd_avoid_acs_channels(struct hdd_context *hdd_ctx, + struct sap_config *sap_config) +{ +} +#endif + /** * __wlan_hdd_cfg80211_do_acs(): CFG80211 handler function for DO_ACS Vendor CMD * @wiphy: Linux wiphy struct pointer @@ -2762,6 +2811,9 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, } sap_config->acs_cfg.ch_list_count = ch_cnt; } + + hdd_avoid_acs_channels(hdd_ctx, sap_config); + hdd_debug("get pcl for DO_ACS vendor command"); pm_mode =