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