From 68c952c71618eddb527ecc67251eb6e084db0d95 Mon Sep 17 00:00:00 2001 From: Jayachandran Sreekumaran Date: Mon, 24 Apr 2017 12:42:03 +0530 Subject: [PATCH] qcacld-3.0: Add acs config parameter acs_policy A new external acs configuration parameter acs_policy. This parameter indicates the external ACS module whether its mandatory or preferrable to select a channel from the preferred channel list provided by the driver Change-Id: I80925109349c68c95f25ba27d87bd68964c4eb04 CRs-Fixed: 2037034 --- core/hdd/inc/wlan_hdd_cfg.h | 81 +++++++++++++ core/hdd/inc/wlan_hdd_main.h | 6 +- core/hdd/src/wlan_hdd_cfg.c | 19 +++ core/hdd/src/wlan_hdd_cfg80211.c | 192 +++++++++++++++++++++++++------ core/sap/inc/sap_api.h | 1 + 5 files changed, 266 insertions(+), 33 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index ea48a60620e0..37edc42e8691 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -9923,6 +9923,85 @@ enum l1ss_sleep_allowed { #define CFG_FILS_MAX_CHAN_GUARD_TIME_MAX (10) #define CFG_FILS_MAX_CHAN_GUARD_TIME_DEFAULT (0) +/* + * enum hdd_external_acs_policy - External ACS policy + * @HDD_EXTERNAL_ACS_PCL_PREFERRED -Preferable for ACS to select a + * channel with non-zero pcl weight. + * @HDD_EXTERNAL_ACS_PCL_MANDATORY -Mandatory for ACS to select a + * channel with non-zero pcl weight. + * + * enum hdd_external_acs_policy is used to select the ACS policy. + * + */ +enum hdd_external_acs_policy { + HDD_EXTERNAL_ACS_PCL_PREFERRED = 0, + HDD_EXTERNAL_ACS_PCL_MANDATORY = 1, +}; + +/* + * + * external_acs_policy - External ACS policy control + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * Values are per enum hdd_external_acs_policy. + * + * This ini is used to control the external ACS policy. + * + * Related: None + * + * Supported Feature: ACS + * + * Usage: Internal/External + * + * + */ +#define CFG_EXTERNAL_ACS_POLICY "acs_policy" +#define CFG_EXTERNAL_ACS_POLICY_MIN (HDD_EXTERNAL_ACS_PCL_PREFERRED) +#define CFG_EXTERNAL_ACS_POLICY_MAX (HDD_EXTERNAL_ACS_PCL_MANDATORY) +#define CFG_EXTERNAL_ACS_POLICY_DEFAULT (HDD_EXTERNAL_ACS_PCL_PREFERRED) + +/* + * enum hdd_external_acs_policyl - Preferred freq band for external ACS + * @HDD_EXTERNAL_ACS_FREQ_BAND_24GHZ -2.4GHz band + * @HDD_EXTERNAL_ACS_FREQ_BAND_5GHZ -5GHz band + * + * enum hdd_external_acs_freq_band is used to select the freq band for ACS. + * + */ +enum hdd_external_acs_freq_band { + HDD_EXTERNAL_ACS_FREQ_BAND_24GHZ = 0, + HDD_EXTERNAL_ACS_FREQ_BAND_5GHZ = 1, +}; + +/* + * + * external_acs_freq_band - External ACS freq band + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * Values are per enum hdd_external_acs_freq_band. + * + * This ini is used to select the ACS freq band. Currently + * the external ACS module doesn't support channels from + * both the bands. Once multiple band support is added in + * ICM, this ini can be removed + * + * Related: None + * + * Supported Feature: ACS + * + * Usage: Internal/External + * + * + */ +#define CFG_EXTERNAL_ACS_FREQ_BAND "acs_freq_band" +#define CFG_EXTERNAL_ACS_FREQ_BAND_MIN (HDD_EXTERNAL_ACS_FREQ_BAND_24GHZ) +#define CFG_EXTERNAL_ACS_FREQ_BAND_MAX (HDD_EXTERNAL_ACS_FREQ_BAND_5GHZ) +#define CFG_EXTERNAL_ACS_FREQ_BAND_DEFAULT (HDD_EXTERNAL_ACS_FREQ_BAND_24GHZ) + /* * Type declarations */ @@ -10647,6 +10726,8 @@ struct hdd_config { bool qcn_ie_support; bool reg_offload_enabled; uint8_t fils_max_chan_guard_time; + enum hdd_external_acs_policy external_acs_policy; + enum hdd_external_acs_freq_band external_acs_freq_band; }; #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var)) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index d652f030335f..467e62434903 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1620,12 +1620,14 @@ struct hdd_context_s { * struct hdd_vendor_acs_chan_params - vendor acs channel parameters * @channel_count: channel count * @channel_list: pointer to channel list + * @pcl_count: pcl list count * @vendor_pcl_list: pointer to pcl list * @vendor_weight_list: pointer to pcl weight list */ struct hdd_vendor_acs_chan_params { uint32_t channel_count; uint8_t *channel_list; + uint32_t pcl_count; uint8_t *vendor_pcl_list; uint8_t *vendor_weight_list; }; @@ -2250,6 +2252,7 @@ bool hdd_set_connection_in_progress(bool value); * @ap_adapter: adapter * @channel_count: valid channel count * @channel_list: valid channel list + * @band: frequency band * * This API returns valid channel list for SAP after removing nol and * channel which lies outside of configuration. @@ -2258,7 +2261,8 @@ bool hdd_set_connection_in_progress(bool value); */ int wlan_hdd_sap_get_valid_channellist(hdd_adapter_t *adapter, uint32_t *channel_count, - uint8_t *channel_list); + uint8_t *channel_list, + eCsrBand band); /** * wlan_hdd_init_chan_info() - initialize channel info variables * @hdd_ctx: hdd ctx diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index c096627bd306..afd17a95a9ab 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -4318,6 +4318,19 @@ struct reg_table_entry g_registry_table[] = { CFG_FILS_MAX_CHAN_GUARD_TIME_DEFAULT, CFG_FILS_MAX_CHAN_GUARD_TIME_MIN, CFG_FILS_MAX_CHAN_GUARD_TIME_MAX), + REG_VARIABLE(CFG_EXTERNAL_ACS_POLICY, WLAN_PARAM_Integer, + struct hdd_config, external_acs_policy, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTERNAL_ACS_POLICY_DEFAULT, + CFG_EXTERNAL_ACS_POLICY_MIN, + CFG_EXTERNAL_ACS_POLICY_MAX), + + REG_VARIABLE(CFG_EXTERNAL_ACS_FREQ_BAND, WLAN_PARAM_Integer, + struct hdd_config, external_acs_freq_band, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTERNAL_ACS_FREQ_BAND_DEFAULT, + CFG_EXTERNAL_ACS_FREQ_BAND_MIN, + CFG_EXTERNAL_ACS_FREQ_BAND_MAX), }; @@ -5819,6 +5832,12 @@ void hdd_cfg_print(hdd_context_t *pHddCtx) hdd_info("Name = [%s] Value = [%d]", CFG_ARP_AC_CATEGORY, pHddCtx->config->arp_ac_category); + hdd_info("Name = [%s] Value = [%d]", + CFG_EXTERNAL_ACS_POLICY, + pHddCtx->config->external_acs_policy); + hdd_info("Name = [%s] Value = [%d]", + CFG_EXTERNAL_ACS_FREQ_BAND, + pHddCtx->config->external_acs_freq_band); } diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 042d37a7914b..01293e2eda90 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -1437,32 +1437,74 @@ static void hdd_update_vendor_pcl_list(hdd_context_t *hdd_ctx, tsap_Config_t *sap_config) { int i, j; + bool found; - for (i = 0; i < acs_chan_params->channel_count; i++) { - for (j = 0; j < sap_config->acs_cfg.pcl_ch_count; j++) { - if (acs_chan_params->channel_list[i] == + if (HDD_EXTERNAL_ACS_PCL_MANDATORY == + hdd_ctx->config->external_acs_policy) { + /* + * In preferred channels mandatory case, PCL shall + * contain only the preferred channels from the + * application. If those channels are not present + * in the driver PCL, then set the weight to zero + */ + for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) { + acs_chan_params->vendor_pcl_list[i] = + sap_config->acs_cfg.ch_list[i]; + acs_chan_params->vendor_weight_list[i] = 0; + for (j = 0; j < sap_config->acs_cfg.pcl_ch_count; j++) { + if (sap_config->acs_cfg.ch_list[i] == sap_config->acs_cfg.pcl_channels[j]) { + acs_chan_params->vendor_weight_list[i] = + sap_config-> + acs_cfg.pcl_channels_weight_list[j]; + break; + } + } + } + acs_chan_params->pcl_count = sap_config->acs_cfg.ch_list_count; + } else { + /* + * In preferred channels not mandatory case update the + * PCL weight to zero for those channels which are not + * present in the application's preferred channel list for + * ACS + */ + for (i = 0; i < sap_config->acs_cfg.pcl_ch_count; i++) { + found = false; + for (j = 0; j < sap_config->acs_cfg.ch_list_count; + j++) { + if (sap_config->acs_cfg.pcl_channels[i] == + sap_config->acs_cfg.ch_list[j]) { + acs_chan_params->vendor_pcl_list[i] = + sap_config-> + acs_cfg.pcl_channels[i]; + acs_chan_params-> + vendor_weight_list[i] = + sap_config->acs_cfg. + pcl_channels_weight_list[i]; + found = true; + break; + } + } + if (!found) { acs_chan_params->vendor_pcl_list[i] = - sap_config->acs_cfg.pcl_channels[j]; - acs_chan_params->vendor_weight_list[i] = - sap_config->acs_cfg. - pcl_channels_weight_list[j]; - break; - } else { - acs_chan_params->vendor_pcl_list[i] = - acs_chan_params->channel_list[i]; + sap_config->acs_cfg.pcl_channels[i]; acs_chan_params->vendor_weight_list[i] = 0; } } - } - if (hdd_ctx->unsafe_channel_count == 0) - return; - /* Update unsafe channel weight as zero */ - for (i = 0; i < acs_chan_params->channel_count; i++) { - for (j = 0; j < hdd_ctx->unsafe_channel_count; j++) { - if (acs_chan_params->channel_list[i] == + + acs_chan_params->pcl_count = sap_config->acs_cfg.pcl_ch_count; + + if (hdd_ctx->unsafe_channel_count == 0) + return; + /* Update unsafe channel weight as zero */ + for (i = 0; i < acs_chan_params->pcl_count; i++) { + for (j = 0; j < hdd_ctx->unsafe_channel_count; j++) { + if (acs_chan_params->vendor_pcl_list[i] == hdd_ctx->unsafe_channel_list[j]) { - acs_chan_params->vendor_weight_list[i] = 0; + acs_chan_params-> + vendor_weight_list[i] = 0; + } } } } @@ -1497,6 +1539,7 @@ static int hdd_update_reg_chan_info(hdd_adapter_t *adapter, return -ENOMEM; } + sap_config->channel_info_count = channel_count; for (i = 0; i < channel_count; i++) { icv = &sap_config->channel_info[i]; chan = channel_list[i]; @@ -1591,7 +1634,7 @@ hdd_cfg80211_update_channel_info(struct sk_buff *skb, if (!nla_attr) goto fail; - for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) { + for (i = 0; i < sap_config->channel_info_count; i++) { channel = nla_nest_start(skb, i); if (!channel) goto fail; @@ -1687,7 +1730,9 @@ fail: return -EINVAL; } -static void hdd_get_scan_band(tsap_Config_t *sap_config, eCsrBand *band) +static void hdd_get_scan_band(hdd_context_t *hdd_ctx, + tsap_Config_t *sap_config, + eCsrBand *band) { /* Get scan band */ if ((sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211B) || @@ -1701,7 +1746,11 @@ static void hdd_get_scan_band(tsap_Config_t *sap_config, eCsrBand *band) /* Auto is not supported currently */ if (!((*band == eCSR_BAND_24) || (eCSR_BAND_5G == *band))) { hdd_err("invalid band"); - *band = eCSR_BAND_24; + if (HDD_EXTERNAL_ACS_FREQ_BAND_24GHZ == + hdd_ctx->config->external_acs_freq_band) + *band = eCSR_BAND_24; + else + *band = eCSR_BAND_5G; } } @@ -1718,6 +1767,9 @@ void hdd_cfg80211_update_acs_config(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); eCsrBand band = eCSR_BAND_24; eCsrPhyMode phy_mode; + enum qca_wlan_vendor_attr_external_acs_policy acs_policy; + uint32_t i; + if (!hdd_ctx) { hdd_err("HDD context is NULL"); @@ -1727,12 +1779,14 @@ void hdd_cfg80211_update_acs_config(hdd_adapter_t *adapter, ENTER(); sap_config = &adapter->sessionCtx.ap.sapConfig; + hdd_get_scan_band(hdd_ctx, &adapter->sessionCtx.ap.sapConfig, &band); /* Get valid channels for SAP */ wlan_hdd_sap_get_valid_channellist(adapter, - &channel_count, channel_list); + &channel_count, + channel_list, + band); hdd_update_reg_chan_info(adapter, channel_count, channel_list); - hdd_get_scan_band(&adapter->sessionCtx.ap.sapConfig, &band); /* Get phymode */ phy_mode = sme_get_phy_mode(WLAN_HDD_GET_HAL_CTX(adapter)); @@ -1758,6 +1812,33 @@ void hdd_cfg80211_update_acs_config(hdd_adapter_t *adapter, hdd_update_vendor_pcl_list(hdd_ctx, &acs_chan_params, sap_config); + + if (acs_chan_params.channel_count) { + hdd_debug("ACS channel list: len: %d", + acs_chan_params.channel_count); + for (i = 0; i < acs_chan_params.channel_count; i++) + hdd_debug("%d ", acs_chan_params.channel_list[i]); + } + + if (acs_chan_params.pcl_count) { + hdd_debug("ACS PCL list: len: %d", + acs_chan_params.pcl_count); + for (i = 0; i < acs_chan_params.pcl_count; i++) + hdd_debug("channel:%d, weight:%d ", + acs_chan_params. + vendor_pcl_list[i], + acs_chan_params. + vendor_weight_list[i]); + } + + if (HDD_EXTERNAL_ACS_PCL_MANDATORY == + hdd_ctx->config->external_acs_policy) { + acs_policy = + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_MANDATORY; + } else { + acs_policy = + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_PREFERRED; + } /* Update values in NL buffer */ if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_REASON, reason) || @@ -1781,9 +1862,13 @@ void hdd_cfg80211_update_acs_config(hdd_adapter_t *adapter, hdd_err("nla put fail"); goto fail; } - status = hdd_cfg80211_update_pcl(skb, channel_count, - QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PCL, - vendor_pcl_list, vendor_weight_list); + status = + hdd_cfg80211_update_pcl(skb, + acs_chan_params. + pcl_count, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PCL, + vendor_pcl_list, + vendor_weight_list); if (status != 0) goto fail; @@ -1794,6 +1879,13 @@ void hdd_cfg80211_update_acs_config(hdd_adapter_t *adapter, if (status != 0) goto fail; + status = nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_POLICY, + acs_policy); + + if (status != 0) + goto fail; + cfg80211_vendor_event(skb, GFP_KERNEL); return; fail: @@ -2009,6 +2101,17 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, if (QDF_STATUS_SUCCESS != status) hdd_err("Get PCL failed"); + if (sap_config->acs_cfg.pcl_ch_count) { + hdd_debug("ACS config PCL: len: %d", + sap_config->acs_cfg.pcl_ch_count); + for (i = 0; i < sap_config->acs_cfg.pcl_ch_count; i++) + hdd_debug("channel:%d, weight:%d ", + sap_config->acs_cfg. + pcl_channels[i], + sap_config->acs_cfg. + pcl_channels_weight_list[i]); + } + /* ACS override for android */ if (hdd_ctx->config->sap_p2p_11ac_override && ht_enabled && !hdd_ctx->config->sap_force_11n_for_11ac) { @@ -7334,17 +7437,42 @@ static void wlan_hdd_get_chanlist_without_nol(hdd_adapter_t *adapter, int wlan_hdd_sap_get_valid_channellist(hdd_adapter_t *adapter, uint32_t *channel_count, - uint8_t *channel_list) + uint8_t *channel_list, + eCsrBand band) { tsap_Config_t *sap_config; + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + uint8_t tmp_chan_list[QDF_MAX_NUM_CHAN] = {0}; + uint32_t chan_count; + uint8_t i; + QDF_STATUS status; sap_config = &adapter->sessionCtx.ap.sapConfig; - qdf_mem_copy(channel_list, sap_config->acs_cfg.ch_list, - sap_config->acs_cfg.ch_list_count); - *channel_count = sap_config->acs_cfg.ch_list_count; + status = + policy_mgr_get_valid_chans(hdd_ctx->hdd_psoc, + tmp_chan_list, + &chan_count); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Failed to get channel list"); + return -EINVAL; + } + for (i = 0; i < chan_count; i++) { + if (*channel_count < QDF_MAX_NUM_CHAN) { + if ((eCSR_BAND_24 == band) && + (WLAN_REG_IS_24GHZ_CH(tmp_chan_list[i]))) { + channel_list[*channel_count] = tmp_chan_list[i]; + *channel_count += 1; + } else if ((eCSR_BAND_5G == band) && + (WLAN_REG_IS_5GHZ_CH(tmp_chan_list[i]))) { + channel_list[*channel_count] = tmp_chan_list[i]; + *channel_count += 1; + } + } else { + break; + } + } wlan_hdd_get_chanlist_without_nol(adapter, channel_count, channel_list); - if (*channel_count == 0) { hdd_err("no valid channel found"); return -EINVAL; diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index 223cca7b2cb8..987bdd6c7466 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -618,6 +618,7 @@ typedef struct sap_Config { tSirMacRateSet extended_rates; enum sap_acs_dfs_mode acs_dfs_mode; struct hdd_channel_info *channel_info; + uint32_t channel_info_count; bool dfs_cac_offload; } tsap_Config_t;