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
This commit is contained in:
Jayachandran Sreekumaran 2017-04-24 12:42:03 +05:30 • committed by snandini
commit 68c952c716
5 changed files with 266 additions and 33 deletions

View file

@ -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,
};
/*
* <ini>
* 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
*
* </ini>
*/
#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,
};
/*
* <ini>
* 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
*
* </ini>
*/
#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))

View file

@ -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

View file

@ -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);
}

View file

@ -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;

View file

@ -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;