qcacld-3.0: Send DBS Scan selection policy command to WMI

This change address sending DBS Scan selection policy command
to WMI.

Change-Id: I0117845ac28e3ca8977eefc09b738a79181b4115
CRs-Fixed: 2029280
diff --git a/core/cds/inc/cds_utils.h b/core/cds/inc/cds_utils.h
index 63699f0..cb3f6f4 100644
--- a/core/cds/inc/cds_utils.h
+++ b/core/cds/inc/cds_utils.h
@@ -68,6 +68,9 @@
 
 #define INVALID_SCAN_ID        0xFFFFFFFF
 
+#define CDS_DBS_SCAN_CLIENTS_MAX           (7)
+#define CDS_DBS_SCAN_PARAM_PER_CLIENT      (3)
+
 #define cds_log(level, args...) QDF_TRACE(QDF_MODULE_ID_QDF, level, ## args)
 #define cds_logfl(level, format, args...) cds_log(level, FL(format), ## args)
 
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index b1c36b5..160bc11 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -60,8 +60,6 @@
 #define IPADDR_STRING_LENGTH   (16)
 #endif
 
-#define CFG_DBS_SCAN_CLIENTS_MAX           (7)
-#define CFG_DBS_SCAN_PARAM_PER_CLIENT      (3)
 #define CFG_DBS_SCAN_PARAM_LENGTH          (42)
 
 /* Number of items that can be configured */
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 54f7061..220e513 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -2421,6 +2421,17 @@
 void hdd_unregister_notifiers(hdd_context_t *hdd_ctx);
 
 /**
+ * hdd_dbs_scan_selection_init() - initialization for DBS scan selection config
+ * @hdd_ctx: HDD context
+ *
+ * This function sends the DBS scan selection config configuration to the
+ * firmware via WMA
+ *
+ * Return: 0 - success, < 0 - failure
+ */
+int hdd_dbs_scan_selection_init(hdd_context_t *hdd_ctx);
+
+/**
  * hdd_start_complete()- complete the start event
  * @ret: return value for complete event.
  *
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 85422b4..58cb8ea 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -8699,6 +8699,62 @@
 	return 0;
 }
 
+int hdd_dbs_scan_selection_init(hdd_context_t *hdd_ctx)
+{
+	QDF_STATUS status;
+	struct wmi_dbs_scan_sel_params dbs_scan_params;
+	uint32_t i = 0;
+	uint8_t count = 0, numentries = 0;
+	uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
+				* CDS_DBS_SCAN_CLIENTS_MAX];
+
+	/* check if DBS is enabled or supported */
+	if ((hdd_ctx->config->dual_mac_feature_disable)
+	    || (!policy_mgr_is_hw_dbs_capable(hdd_ctx->hdd_psoc)))
+		return -EINVAL;
+
+	hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
+			       dbs_scan_config, &numentries,
+			       (CDS_DBS_SCAN_PARAM_PER_CLIENT
+				* CDS_DBS_SCAN_CLIENTS_MAX));
+
+	hdd_info("numentries %hu", numentries);
+	if (!numentries) {
+		hdd_info("Donot send scan_selection_config");
+		return 0;
+	}
+
+	/* hdd_set_fw_log_params */
+	dbs_scan_params.num_clients = 0;
+	while (count < (numentries - 2)) {
+		dbs_scan_params.module_id[i] = dbs_scan_config[count];
+		dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
+		dbs_scan_params.num_non_dbs_scans[i] =
+			dbs_scan_config[count + 2];
+		dbs_scan_params.num_clients++;
+		hdd_debug("module:%d NDS:%d NNDS:%d",
+			  dbs_scan_params.module_id[i],
+			  dbs_scan_params.num_dbs_scans[i],
+			  dbs_scan_params.num_non_dbs_scans[i]);
+		count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
+		i++;
+	}
+
+	dbs_scan_params.pdev_id = 0;
+
+	hdd_debug("clients:%d pdev:%d",
+		  dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
+
+	status = sme_set_dbs_scan_selection_config(hdd_ctx->hHal,
+						   &dbs_scan_params);
+	hdd_debug("Sending DBS Scan Selection Configuration to fw");
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Failed to send DBS Scan selection configuration!");
+		return -EAGAIN;
+	}
+	return 0;
+}
+
 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
 /**
  * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
@@ -8774,6 +8830,9 @@
 	if (hdd_adaptive_dwelltime_init(hdd_ctx))
 		hdd_err("Unable to send adaptive dwelltime setting to FW");
 
+	if (hdd_dbs_scan_selection_init(hdd_ctx))
+		hdd_err("Unable to send DBS scan selection setting to FW");
+
 	ret = hdd_init_thermal_info(hdd_ctx);
 	if (ret) {
 		hdd_err("Error while initializing thermal information");
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
index 0109c52..b828da5 100644
--- a/core/mac/src/include/sir_params.h
+++ b/core/mac/src/include/sir_params.h
@@ -642,6 +642,7 @@
 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
 #define SIR_HAL_LL_STATS_EXT_SET_THRESHOLD  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 378)
 #endif
+#define SIR_HAL_SET_DBS_SCAN_SEL_PARAMS     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 379)
 
 #define SIR_HAL_MSG_TYPES_END               (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 
diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
index e0c1423..5744ae9 100644
--- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
+++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
@@ -701,6 +701,7 @@
 		CASE_RETURN_STRING(WMA_SET_WISA_PARAMS);
 		CASE_RETURN_STRING(WMA_SET_WOW_PULSE_CMD);
 		CASE_RETURN_STRING(WMA_SET_PER_ROAM_CONFIG_CMD);
+		CASE_RETURN_STRING(WMA_SET_DBS_SCAN_SEL_CONF_PARAMS);
 	default:
 		return (uint8_t *) "UNKNOWN";
 		break;
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index 7a01fb0..7d48850 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -1486,6 +1486,18 @@
 				enum scan_reject_states *reason));
 
 /**
+ * sme_set_dbs_scan_selection_config() - Update DBS scan selection
+ * configuration
+ * @hal: The handle returned by macOpen
+ * @params: wmi_dbs_scan_sel_params config
+ *
+ * Return: QDF_STATUS if DBS scan selection update
+ * configuration success else failure status
+ */
+QDF_STATUS sme_set_dbs_scan_selection_config(tHalHandle hal,
+		struct wmi_dbs_scan_sel_params *params);
+
+/**
  * sme_store_pdev() - store pdev
  * @hal - MAC global handle
  * @pdev - pdev ptr
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index 2e8dc8e..90a7eb4 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -16069,6 +16069,44 @@
 	return status;
 }
 
+QDF_STATUS sme_set_dbs_scan_selection_config(tHalHandle hal,
+		struct wmi_dbs_scan_sel_params *params)
+{
+	struct scheduler_msg message = {0};
+	QDF_STATUS status;
+	struct wmi_dbs_scan_sel_params *dbs_scan_params;
+	uint32_t i;
+
+	if (0 == params->num_clients) {
+		sme_err("Num of clients is 0");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dbs_scan_params = qdf_mem_malloc(sizeof(*dbs_scan_params));
+	if (!dbs_scan_params) {
+		sme_err("fail to alloc dbs_scan_params");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	dbs_scan_params->num_clients = params->num_clients;
+	dbs_scan_params->pdev_id = params->pdev_id;
+	for (i = 0; i < params->num_clients; i++) {
+		dbs_scan_params->module_id[i] = params->module_id[i];
+		dbs_scan_params->num_dbs_scans[i] = params->num_dbs_scans[i];
+		dbs_scan_params->num_non_dbs_scans[i] =
+			params->num_non_dbs_scans[i];
+	}
+	message.type = WMA_SET_DBS_SCAN_SEL_CONF_PARAMS;
+	message.bodyptr = dbs_scan_params;
+	status = scheduler_post_msg(QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Not able to post msg to WMA!");
+		qdf_mem_free(dbs_scan_params);
+	}
+
+	return status;
+}
+
 void sme_store_pdev(tHalHandle hal, struct wlan_objmgr_pdev *pdev)
 {
 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h
index 23ddd79..4085af7 100644
--- a/core/wma/inc/wma_api.h
+++ b/core/wma/inc/wma_api.h
@@ -181,6 +181,17 @@
 				struct beacon_filter_param *filter_params);
 QDF_STATUS wma_send_adapt_dwelltime_params(WMA_HANDLE handle,
 			struct adaptive_dwelltime_params *dwelltime_params);
+
+/**
+ * wma_send_dbs_scan_selection_params() - send DBS scan selection configuration
+ * params to firmware
+ * @handle: wma handler
+ * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
+ */
+QDF_STATUS wma_send_dbs_scan_selection_params(WMA_HANDLE handle,
+			struct wmi_dbs_scan_sel_params *dbs_scan_params);
 #ifdef FEATURE_GREEN_AP
 void wma_setup_egap_support(struct wma_tgt_cfg *tgt_cfg, WMA_HANDLE handle);
 void wma_register_egap_event_handle(WMA_HANDLE handle);
diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h
index 1190b73..12098c5 100644
--- a/core/wma/inc/wma_types.h
+++ b/core/wma/inc/wma_types.h
@@ -468,6 +468,8 @@
 #define WMA_ENCRYPT_DECRYPT_MSG              SIR_HAL_ENCRYPT_DECRYPT_MSG
 #define WMA_POWER_DEBUG_STATS_REQ            SIR_HAL_POWER_DEBUG_STATS_REQ
 
+#define WMA_SET_DBS_SCAN_SEL_CONF_PARAMS     SIR_HAL_SET_DBS_SCAN_SEL_PARAMS
+
 #define WMA_SET_WOW_PULSE_CMD                SIR_HAL_SET_WOW_PULSE_CMD
 
 #define WMA_SET_PER_ROAM_CONFIG_CMD          SIR_HAL_SET_PER_ROAM_CONFIG_CMD
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index 5bfa03d..cc463df 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -866,6 +866,20 @@
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS wma_send_dbs_scan_selection_params(WMA_HANDLE handle,
+			struct wmi_dbs_scan_sel_params *dbs_scan_params)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	int32_t err;
+
+	err = wmi_unified_send_dbs_scan_sel_params_cmd(wma_handle->
+					wmi_handle, dbs_scan_params);
+	if (err)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 #ifdef FEATURE_GREEN_AP
 
 /**
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index f72c189..4b7a53f 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -4715,6 +4715,9 @@
 	else
 		wma_handle->wlan_resource_config.use_pdev_id = false;
 
+	wma_handle->wlan_resource_config.max_num_dbs_scan_duty_cycle =
+		CDS_DBS_SCAN_CLIENTS_MAX;
+
 	/* register the Enhanced Green AP event handler */
 	wma_register_egap_event_handle(wma_handle);
 
@@ -7063,6 +7066,11 @@
 			(struct wow_pulse_mode *)msg->bodyptr);
 		qdf_mem_free(msg->bodyptr);
 		break;
+	case WMA_SET_DBS_SCAN_SEL_CONF_PARAMS:
+		wma_send_dbs_scan_selection_params(wma_handle,
+			(struct wmi_dbs_scan_sel_params *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
 	default:
 		WMA_LOGE("Unhandled WMA message of type %d", msg->type);
 		if (msg->bodyptr)