Преглед на файлове

qcacmn: Add wait for cancel scan on pdev and vdev

Add cancel scan sync api which will wait for scan to be aborted on
pdev or vdev.

Change-Id: Ie02eb981154856cda38ef70f42fdfcf82bb88961
CRs-Fixed: 2038092
Abhishek Singh преди 8 години
родител
ревизия
f95b9e4248

+ 3 - 1
os_if/linux/scan/inc/wlan_cfg80211_scan.h

@@ -216,6 +216,7 @@ int wlan_cfg80211_abort_scan(struct wlan_objmgr_pdev *pdev);
  * @pdev_id: pdev id
  * @vdev_id: vdev id
  * @scan_id: scan id
+ * @sync: if wait for scan complete is required
  *
  * Generic API to abort scans
  *
@@ -224,7 +225,8 @@ int wlan_cfg80211_abort_scan(struct wlan_objmgr_pdev *pdev);
 QDF_STATUS wlan_abort_scan(struct wlan_objmgr_pdev *pdev,
 				   uint32_t pdev_id,
 				   uint32_t vdev_id,
-				   wlan_scan_id scan_id);
+				   wlan_scan_id scan_id,
+				   bool sync);
 
 /**
  * wlan_cfg80211_cleanup_scan_queue() - remove entries in scan queue

+ 9 - 5
os_if/linux/scan/src/wlan_cfg80211_scan.c

@@ -216,7 +216,7 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_pdev *pdev,
 	   SCAN_NOT_IN_PROGRESS) {
 		status = wlan_abort_scan(pdev,
 				wlan_objmgr_pdev_get_pdev_id(pdev),
-				INVAL_VDEV_ID, INVAL_SCAN_ID);
+				INVAL_VDEV_ID, INVAL_SCAN_ID, true);
 		if (QDF_IS_STATUS_ERROR(status)) {
 			cfg80211_err("aborting the existing scan is unsuccessful");
 			wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
@@ -1118,7 +1118,7 @@ static int wlan_get_scanid(struct wlan_objmgr_pdev *pdev,
 
 QDF_STATUS wlan_abort_scan(struct wlan_objmgr_pdev *pdev,
 				   uint32_t pdev_id, uint32_t vdev_id,
-				   wlan_scan_id scan_id)
+				   wlan_scan_id scan_id, bool sync)
 {
 	struct scan_cancel_request *req;
 	struct pdev_osif_priv *osif_ctx;
@@ -1163,7 +1163,11 @@ QDF_STATUS wlan_abort_scan(struct wlan_objmgr_pdev *pdev,
 		req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL;
 	else
 		req->cancel_req.req_type = WLAN_SCAN_CANCEL_VDEV_ALL;
-	status = ucfg_scan_cancel(req);
+
+	if (sync)
+		status = ucfg_scan_cancel_sync(req);
+	else
+		status = ucfg_scan_cancel(req);
 	if (QDF_IS_STATUS_ERROR(status))
 		cfg80211_err("Cancel scan request failed");
 
@@ -1181,7 +1185,7 @@ int wlan_cfg80211_abort_scan(struct wlan_objmgr_pdev *pdev)
 	if (ucfg_scan_get_pdev_status(pdev) !=
 	   SCAN_NOT_IN_PROGRESS)
 		wlan_abort_scan(pdev, pdev_id,
-			INVAL_VDEV_ID, INVAL_SCAN_ID);
+			INVAL_VDEV_ID, INVAL_SCAN_ID, true);
 
 	return 0;
 }
@@ -1211,7 +1215,7 @@ int wlan_vendor_abort_scan(struct wlan_objmgr_pdev *pdev,
 		if (ucfg_scan_get_pdev_status(pdev) !=
 		   SCAN_NOT_IN_PROGRESS)
 			wlan_abort_scan(pdev, pdev_id,
-					INVAL_VDEV_ID, scan_id);
+					INVAL_VDEV_ID, scan_id, true);
 	}
 	return 0;
 }

+ 3 - 0
umac/scan/dispatcher/inc/wlan_scan_public_structs.h

@@ -46,6 +46,9 @@ typedef uint32_t wlan_scan_id;
 #define SCM_BSS_CAP_VALUE_UAPSD 1
 #define SCM_BSS_CAP_VALUE_5GHZ  2
 
+#define SCM_CANCEL_SCAN_WAIT_TIME 50
+#define SCM_CANCEL_SCAN_WAIT_ITERATION 100
+
 #define BURST_SCAN_MAX_NUM_OFFCHANNELS 3
 #define P2P_SCAN_MAX_BURST_DURATION 180
 /* Increase dwell time for P2P search in ms */

+ 13 - 0
umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h

@@ -183,6 +183,19 @@ ucfg_scan_start(struct scan_start_request *req);
 QDF_STATUS
 ucfg_scan_cancel(struct scan_cancel_request *req);
 
+/**
+ * ucfg_scan_cancel_sync() - Public API to stop a scan and wait
+ * till all scan are completed
+ * @req: stop scan request params
+ *
+ * The Public API to stop a scan and wait
+ * till all scan are completed
+ *
+ * Return: 0 for success or error code.
+ */
+QDF_STATUS
+ucfg_scan_cancel_sync(struct scan_cancel_request *req);
+
 /**
  * ucfg_scan_get_result() - The Public API to get scan results
  * @pdev: pdev info

+ 72 - 1
umac/scan/dispatcher/src/wlan_scan_ucfg_api.c

@@ -401,6 +401,77 @@ ucfg_scan_cancel(struct scan_cancel_request *req)
 	return status;
 }
 
+QDF_STATUS
+ucfg_scan_cancel_sync(struct scan_cancel_request *req)
+{
+	QDF_STATUS status;
+	bool cancel_vdev = false, cancel_pdev = false;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_pdev *pdev;
+	uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION;
+	qdf_event_t cancel_scan_event;
+
+	if (!req || !req->vdev) {
+		scm_err("vdev: %p, req: %p", req->vdev, req);
+		if (req)
+			qdf_mem_free(req);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (req->cancel_req.req_type ==
+	   WLAN_SCAN_CANCEL_PDEV_ALL)
+		cancel_pdev = true;
+	else if (req->cancel_req.req_type ==
+	   WLAN_SCAN_CANCEL_VDEV_ALL)
+		cancel_vdev = true;
+
+	vdev = req->vdev;
+	status = ucfg_scan_cancel(req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		scm_err("failed to post to QDF_MODULE_ID_OS_IF");
+		return status;
+	}
+
+	/*
+	 * If cancel req is to cancel all scan of pdev or vdev
+	 * wait untill all scan of pdev or vdev get cancelled
+	 */
+	qdf_event_create(&cancel_scan_event);
+	qdf_event_reset(&cancel_scan_event);
+
+	if (cancel_pdev) {
+		wlan_vdev_obj_lock(vdev);
+		pdev = wlan_vdev_get_pdev(vdev);
+		wlan_vdev_obj_unlock(vdev);
+		while ((ucfg_scan_get_pdev_status(pdev) !=
+		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
+			scm_debug("wait for all pdev scan to get complete");
+				qdf_wait_single_event(&cancel_scan_event,
+					qdf_system_msecs_to_ticks(
+					SCM_CANCEL_SCAN_WAIT_TIME));
+			max_wait_iterations--;
+		}
+	} else if (cancel_vdev) {
+		while ((ucfg_scan_get_vdev_status(vdev) !=
+		     SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
+			scm_debug("wait for all vdev scan to get complete");
+				qdf_wait_single_event(&cancel_scan_event,
+					qdf_system_msecs_to_ticks(
+					SCM_CANCEL_SCAN_WAIT_TIME));
+			max_wait_iterations--;
+		}
+	}
+
+	qdf_event_destroy(&cancel_scan_event);
+
+	if (!max_wait_iterations) {
+		scm_err("Failed to wait for scans to get complete");
+		return QDF_STATUS_E_TIMEOUT;
+	}
+
+	return status;
+}
+
 wlan_scan_requester
 ucfg_scan_register_requester(struct wlan_objmgr_psoc *psoc,
 	uint8_t *name, scan_event_handler event_cb, void *arg)
@@ -896,7 +967,7 @@ ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev)
 
 	if (!pdev) {
 		scm_err("null pdev");
-		return QDF_STATUS_E_NULL_VALUE;
+		return SCAN_NOT_IN_PROGRESS;
 	}
 	status = wlan_serialization_pdev_scan_status(pdev);