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; }; /*