Эх сурвалжийг харах

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
Jayachandran Sreekumaran 8 жил өмнө
parent
commit
68c952c716

+ 81 - 0
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,
+};
+
+/*
+ * <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))

+ 5 - 1
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

+ 19 - 0
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);
 }
 
 

+ 160 - 32
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;

+ 1 - 0
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;