qcacmn: Add scan_ctrl_flags_ext to scan command

This change adds scan_ctrl_flags_ext to scan command
to support DBS Scan selection policy.

Change-Id: I71727259c0b5984cfc8fd6157ed0066d3cd9b193
CRs-Fixed: 2061031
diff --git a/umac/scan/core/src/wlan_scan_main.h b/umac/scan/core/src/wlan_scan_main.h
index b92913b..d84982e 100644
--- a/umac/scan/core/src/wlan_scan_main.h
+++ b/umac/scan/core/src/wlan_scan_main.h
@@ -104,6 +104,17 @@
 #define SCAN_MAX_BSS_PDEV 100
 #define SCAN_PRIORITY SCAN_PRIORITY_LOW
 
+/* DBS Scan policy selection ext flags */
+#define SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK  0x00000003
+#define SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT   0
+#define SCAN_DBS_POLICY_DEFAULT             0x0
+#define SCAN_DBS_POLICY_FORCE_NONDBS        0x1
+#define SCAN_DBS_POLICY_IGNORE_DUTY         0x2
+#define SCAN_DBS_POLICY_MAX                 0x3
+/* Minimum number of channels for enabling DBS Scan */
+#define SCAN_MIN_CHAN_DBS_SCAN_THRESHOLD         8
+
+
 /**
  * struct cb_handler - defines scan event handler
  * call back function and arguments
diff --git a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c
index a4c7bc9..bf2e6f8 100644
--- a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c
+++ b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c
@@ -26,12 +26,16 @@
 #include <wlan_objmgr_cmn.h>
 #include <wlan_serialization_api.h>
 #include <wlan_scan_tgt_api.h>
+#include <wlan_reg_services_api.h>
 #include "../../core/src/wlan_scan_main.h"
 #include "../../core/src/wlan_scan_manager.h"
 #include "../../core/src/wlan_scan_cache_db.h"
 #ifdef WLAN_PMO_ENABLE
 #include <wlan_pmo_obj_mgmt_api.h>
 #endif
+#ifdef WLAN_POLICY_MGR_ENABLE
+#include <wlan_policy_mgr_api.h>
+#endif
 
 QDF_STATUS ucfg_scan_register_bcn_cb(struct wlan_objmgr_psoc *psoc,
 	update_beacon_cb cb, enum scan_cb_type type)
@@ -328,6 +332,64 @@
 
 #endif
 
+/**
+ * ucfg_scan_update_dbs_scan_ctrl_ext_flag() - update dbs scan ctrl flags
+ * @req: pointer to scan request
+ *
+ * This function updates the dbs scan ctrl flags.
+ * Non-DBS scan is requested if any of the below case is met:
+ * 1. HW is DBS incapable
+ * 2. Directed scan
+ * 3. Channel list has only few channels
+ * 4. Channel list has single band channels
+ * For remaining cases, dbs scan is requested.
+ *
+ * Return: None
+ */
+static void
+ucfg_scan_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req)
+{
+	uint32_t num_chan;
+	struct wlan_objmgr_psoc *psoc;
+	uint32_t scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS;
+
+	psoc = wlan_vdev_get_psoc(req->vdev);
+
+	/* Resetting the scan_ctrl_flags_ext to 0 */
+	req->scan_req.scan_ctrl_flags_ext = 0;
+
+	if (!policy_mgr_is_hw_dbs_capable(psoc))
+		goto end;
+
+	if (!qdf_is_macaddr_zero(&req->scan_req.bssid_list[0]))
+		goto end;
+
+	num_chan = req->scan_req.num_chan;
+
+	/* num_chan=0 means all channels */
+	if (!num_chan)
+		scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT;
+
+	if (num_chan < SCAN_MIN_CHAN_DBS_SCAN_THRESHOLD)
+		goto end;
+
+	while (num_chan > 1) {
+		if (!WLAN_REG_IS_SAME_BAND_CHANNELS(
+					req->scan_req.chan_list[0],
+					req->scan_req.chan_list[num_chan-1])) {
+			scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT;
+			break;
+		}
+		num_chan--;
+	}
+
+end:
+	req->scan_req.scan_ctrl_flags_ext |=
+		((scan_dbs_policy << SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT)
+		 & SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK);
+	scm_debug("scan_ctrl_flags_ext: 0x%x",
+			req->scan_req.scan_ctrl_flags_ext);
+}
 
 QDF_STATUS
 ucfg_scan_start(struct scan_start_request *req)
@@ -345,6 +407,8 @@
 		req->scan_req.scan_req_id, req->scan_req.scan_id,
 		req->scan_req.vdev_id);
 
+	ucfg_scan_update_dbs_scan_ctrl_ext_flag(req);
+
 	/* Try to get vdev reference. Return if reference could
 	 * not be taken. Reference will be released once scan
 	 * request handling completes along with free of @req.