From 980c1dcd1511cc868cdf8c669d105a2daa6bc17b Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Sun, 22 Sep 2019 13:34:53 +0530 Subject: [PATCH] qcacld-3.0: Normalize the channel weights according to ini Normalize the weights of the frequencies for ACS scan if the user has changed them in the ini. This is done as legacy devices wont be able to scan the newly added 6ghz frequencies, and thus wont be able to associate with the SAP if it starts on 6ghz channels. Change-Id: I2dd2f706c248f5339bde06963540d0874d08b847 CRs-Fixed: 2543007 --- mlme/core/src/wlan_mlme_main.c | 86 +++++++++++++++++++ mlme/dispatcher/inc/cfg_mlme_acs.h | 27 +++++- mlme/dispatcher/inc/wlan_mlme_public_struct.h | 32 +++++++ 3 files changed, 144 insertions(+), 1 deletion(-) diff --git a/mlme/core/src/wlan_mlme_main.c b/mlme/core/src/wlan_mlme_main.c index f7d4889c94..26d907ddf0 100644 --- a/mlme/core/src/wlan_mlme_main.c +++ b/mlme/core/src/wlan_mlme_main.c @@ -1291,6 +1291,90 @@ static void mlme_init_threshold_cfg(struct wlan_objmgr_psoc *psoc, threshold->frag_threshold = cfg_get(psoc, CFG_FRAG_THRESHOLD); } +static bool +mlme_is_freq_present_in_list(struct acs_weight *normalize_weight_chan_list, + uint8_t num_freq, uint32_t freq, uint8_t *index) +{ + uint8_t i; + + for (i = 0; i < num_freq; i++) { + if (normalize_weight_chan_list[i].chan_freq == freq) { + *index = i; + return true; + } + } + + return false; +} + +static void +mlme_acs_parse_weight_list(struct wlan_objmgr_psoc *psoc, + struct wlan_mlme_acs *acs) +{ + char *acs_weight, *str1, *str2 = NULL, *acs_weight_temp, is_range = '-'; + int freq1, freq2, normalize_factor; + uint8_t num_acs_weight = 0, num_acs_weight_range = 0, index = 0; + struct acs_weight *weight_list = acs->normalize_weight_chan; + struct acs_weight_range *range_list = acs->normalize_weight_range; + + if (!qdf_str_len(cfg_get(psoc, CFG_NORMALIZE_ACS_WEIGHT))) + return; + + acs_weight = qdf_mem_malloc(ACS_WEIGHT_MAX_STR_LEN); + + if (!acs_weight) + return; + + qdf_mem_copy(acs_weight, cfg_get(psoc, CFG_NORMALIZE_ACS_WEIGHT), + ACS_WEIGHT_MAX_STR_LEN); + acs_weight_temp = acs_weight; + + while(acs_weight_temp) { + str1 = strsep(&acs_weight_temp, ","); + if (!str1) + goto end; + freq1 = 0; + freq2 = 0; + if (strchr(str1, is_range)) { + str2 = strsep(&str1, "-"); + sscanf(str2, "%d", &freq1); + sscanf(str1, "%d", &freq2); + strsep(&str1, "="); + sscanf(str1, "%d", &normalize_factor); + + if (num_acs_weight_range == MAX_ACS_WEIGHT_RANGE) + continue; + range_list[num_acs_weight_range].normalize_weight = + normalize_factor; + range_list[num_acs_weight_range].start_freq = freq1; + range_list[num_acs_weight_range++].end_freq = freq2; + } else { + sscanf(str1, "%d", &freq1); + strsep(&str1, "="); + sscanf(str1, "%d", &normalize_factor); + if (mlme_is_freq_present_in_list(weight_list, + num_acs_weight, freq1, + &index)) { + weight_list[index].normalize_weight = + normalize_factor; + } else { + if (num_acs_weight == QDF_MAX_NUM_CHAN) + continue; + + weight_list[num_acs_weight].chan_freq = freq1; + weight_list[num_acs_weight++].normalize_weight = + normalize_factor; + } + } + } + + acs->normalize_weight_num_chan = num_acs_weight; + acs->num_weight_range = num_acs_weight_range; + +end: + qdf_mem_free(acs_weight); +} + static void mlme_init_acs_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_acs *acs) { @@ -1304,6 +1388,8 @@ static void mlme_init_acs_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_USER_ACS_DFS_LTE); acs->is_external_acs_policy = cfg_get(psoc, CFG_EXTERNAL_ACS_POLICY); + + mlme_acs_parse_weight_list(psoc, acs); } QDF_STATUS mlme_init_ibss_cfg(struct wlan_objmgr_psoc *psoc, diff --git a/mlme/dispatcher/inc/cfg_mlme_acs.h b/mlme/dispatcher/inc/cfg_mlme_acs.h index eeb412a5ba..405aea11d5 100644 --- a/mlme/dispatcher/inc/cfg_mlme_acs.h +++ b/mlme/dispatcher/inc/cfg_mlme_acs.h @@ -155,11 +155,36 @@ 1, \ "External ACS Policy Control") +#define ACS_WEIGHT_MAX_STR_LEN 500 + +/* + * + * normalize_acs_weight - Used to control the ACS channel weightage. + * + * This ini is used to specify the weight percentage of the channel. Channel + * weights can be controlled by user to prioritize or de-prioritize channels. + * + * Related: ACS + * + * Supported Feature: ACS + * + * Usage: External + * + * + */ +#define CFG_NORMALIZE_ACS_WEIGHT CFG_INI_STRING( \ + "normalize_acs_weight", \ + 0, \ + ACS_WEIGHT_MAX_STR_LEN, \ + "", \ + "Used to specify the channel weights") + #define CFG_ACS_ALL \ CFG(CFG_ACS_WITH_MORE_PARAM) \ CFG(CFG_AUTO_CHANNEL_SELECT_WEIGHT) \ CFG(CFG_USER_AUTO_CHANNEL_SELECTION) \ CFG(CFG_USER_ACS_DFS_LTE) \ - CFG(CFG_EXTERNAL_ACS_POLICY) + CFG(CFG_EXTERNAL_ACS_POLICY) \ + CFG(CFG_NORMALIZE_ACS_WEIGHT) #endif /* __CFG_MLME_ACS_H */ diff --git a/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 543043d784..a34aa65dbc 100644 --- a/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1161,6 +1161,30 @@ struct wlan_mlme_product_details_cfg { char manufacture_product_version[WLAN_CFG_MFR_PRODUCT_VERSION_LEN + 1]; }; +/* + * struct acs_weight - Normalize ACS weight for mentioned channels + * @chan_freq: frequency of the channel + * @normalize_weight: Normalization factor of the frequency + */ +struct acs_weight { + uint32_t chan_freq; + uint8_t normalize_weight; +}; + +/* + * struct acs_weight_range - Normalize ACS weight for mentioned channel range + * @start_freq: frequency of the start channel + * @end_freq: frequency of the end channel + * @normalize_weight: Normalization factor for freq range + */ +struct acs_weight_range { + uint32_t start_freq; + uint32_t end_freq; + uint8_t normalize_weight; +}; + +#define MAX_ACS_WEIGHT_RANGE 10 + /* * struct wlan_mlme_acs - All acs related cfg items * @is_acs_with_more_param - to enable acs with more param @@ -1168,6 +1192,10 @@ struct wlan_mlme_product_details_cfg { * @is_vendor_acs_support - enable application based channel selection * @is_acs_support_for_dfs_ltecoex - enable channel for dfs and lte coex * @is_external_acs_policy - control external policy + * @normalize_weight_chan: Weight factor to be considered in ACS + * @normalize_weight_num_chan: Number of freq items for normalization. + * @normalize_weight_range: Frequency range for weight normalization + * @num_weight_range: num of ranges provided by user */ struct wlan_mlme_acs { bool is_acs_with_more_param; @@ -1175,6 +1203,10 @@ struct wlan_mlme_acs { bool is_vendor_acs_support; bool is_acs_support_for_dfs_ltecoex; bool is_external_acs_policy; + struct acs_weight normalize_weight_chan[QDF_MAX_NUM_CHAN]; + uint16_t normalize_weight_num_chan; + struct acs_weight_range normalize_weight_range[MAX_ACS_WEIGHT_RANGE]; + uint16_t num_weight_range; }; /*