Kaynağa Gözat

qcacmn: Add support to enable/disable scan with reason code

Adds support to enable/disable scan for psoc/vdev with reason,
so that multiple clients can enable/disable the scan at same time.

Scan will remain disabled till all clients enable it back.

Change-Id: I8d840b24210095accb56ac9a2697ec26e8a5eb17
CRs-Fixed: 2362093
Abhishek Singh 6 yıl önce
ebeveyn
işleme
502095b236

+ 4 - 4
umac/scan/core/src/wlan_scan_main.h

@@ -238,12 +238,12 @@ struct pdev_scan_info {
  * struct scan_vdev_obj - scan vdev obj
  * @pno_match_evt_received: pno match received
  * @pno_in_progress: pno in progress
- * @is_vdev_delete_in_progress: flag to indicate if vdev del is in progress
+ * @scan_disabled: if scan is disabled for this vdev
  */
 struct scan_vdev_obj {
 	bool pno_match_evt_received;
 	bool pno_in_progress;
-	bool is_vdev_delete_in_progress;
+	uint32_t scan_disabled;
 };
 
 /**
@@ -461,7 +461,7 @@ struct scan_cb {
 
 /**
  * struct wlan_scan_obj - scan object definition
- * @enable_scan: if scan is enabled
+ * @scan_disabled: if scan is disabled
  * @scan_db:    scan cache data base
  * @cc_db:      pointer of country code data base
  * @lock:       spin lock
@@ -482,7 +482,7 @@ struct scan_cb {
  *      scan config to event handlers
  */
 struct wlan_scan_obj {
-	bool enable_scan;
+	uint32_t scan_disabled;
 	qdf_spinlock_t lock;
 	qdf_atomic_t scan_ids;
 	struct scan_dbs scan_db[WLAN_UMAC_MAX_PDEVS];

+ 42 - 18
umac/scan/core/src/wlan_scan_manager.c

@@ -367,6 +367,44 @@ scm_scan_serialize_callback(struct wlan_serialization_command *cmd,
 	return status;
 }
 
+bool scm_is_scan_allowed(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_scan_obj *scan_psoc_obj;
+	struct scan_vdev_obj *scan_vdev_obj;
+
+	if (!vdev) {
+		scm_err("vdev is NULL");
+		return false;
+	}
+
+	scan_psoc_obj = wlan_vdev_get_scan_obj(vdev);
+	if (!scan_psoc_obj) {
+		scm_err("Couldn't find scan psoc object");
+		return false;
+	}
+
+	if (scan_psoc_obj->scan_disabled) {
+		scm_err_rl("scan disabled %x, for psoc",
+			   scan_psoc_obj->scan_disabled);
+		return false;
+	}
+
+	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
+	if (!scan_vdev_obj) {
+		scm_err("Couldn't find scan vdev object");
+		return false;
+	}
+
+	if (scan_vdev_obj->scan_disabled) {
+		scm_err_rl("scan disabled %x on vdev_id:%d",
+			   scan_vdev_obj->scan_disabled,
+			   wlan_vdev_get_id(vdev));
+		return false;
+	}
+
+	return true;
+}
+
 QDF_STATUS
 scm_scan_start_req(struct scheduler_msg *msg)
 {
@@ -374,7 +412,6 @@ scm_scan_start_req(struct scheduler_msg *msg)
 	enum wlan_serialization_status ser_cmd_status;
 	struct scan_start_request *req = NULL;
 	struct wlan_scan_obj *scan_obj;
-	struct scan_vdev_obj *scan_vdev_priv_obj;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 	if (!msg) {
@@ -389,29 +426,16 @@ scm_scan_start_req(struct scheduler_msg *msg)
 	}
 
 	req = msg->bodyptr;
-	scan_obj = wlan_vdev_get_scan_obj(req->vdev);
-	if (!scan_obj) {
-		scm_debug("Couldn't find scan object");
-		status = QDF_STATUS_E_NULL_VALUE;
-		goto err;
-	}
 
-	if (!scan_obj->enable_scan) {
+	if (!scm_is_scan_allowed(req->vdev)) {
 		scm_err("scan disabled, rejecting the scan req");
 		status = QDF_STATUS_E_NULL_VALUE;
 		goto err;
 	}
 
-	scan_vdev_priv_obj = wlan_get_vdev_scan_obj(req->vdev);
-	if (!scan_vdev_priv_obj) {
-		scm_debug("Couldn't find scan priv object");
-		status = QDF_STATUS_E_NULL_VALUE;
-		goto err;
-	}
-
-	if (scan_vdev_priv_obj->is_vdev_delete_in_progress) {
-		scm_err("Can't allow scan on vdev_id:%d",
-			wlan_vdev_get_id(req->vdev));
+	scan_obj = wlan_vdev_get_scan_obj(req->vdev);
+	if (!scan_obj) {
+		scm_debug("Couldn't find scan object");
 		status = QDF_STATUS_E_NULL_VALUE;
 		goto err;
 	}

+ 9 - 1
umac/scan/core/src/wlan_scan_manager.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -44,6 +44,14 @@ struct scan_event_listeners {
 	struct cb_handler cb[MAX_SCAN_EVENT_LISTENERS];
 };
 
+/**
+ * scm_is_scan_allowed() - check if scan is allowed
+ * @vdev: vdev for which scan allowed is check
+ *
+ * Return: true if scan is allowed else false
+ */
+bool scm_is_scan_allowed(struct wlan_objmgr_vdev *vdev);
+
 /**
  * scm_scan_start_req() - scan start req core api
  * @msg: scheduler message object containing start scan req params

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

@@ -577,6 +577,19 @@ struct scan_filter {
 	struct qdf_mac_addr bssid_hint;
 };
 
+/**
+ * enum scan_disable_reason - scan enable/disable reason
+ * @REASON_SUSPEND: reason is suspend
+ * @REASON_SYSTEM_DOWN: reason is system going down
+ * @REASON_USER_SPACE: reason is user space initiated
+ * @REASON_VDEV_DOWN: reason is vdev going down
+ */
+enum scan_disable_reason {
+	REASON_SUSPEND  = 0x1,
+	REASON_SYSTEM_DOWN = 0x2,
+	REASON_USER_SPACE = 0x4,
+	REASON_VDEV_DOWN = 0x8,
+};
 
 /**
  * enum scan_priority - scan priority definitions

+ 32 - 22
umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h

@@ -174,21 +174,46 @@ QDF_STATUS
 ucfg_scan_start(struct scan_start_request *req);
 
 /**
- * ucfg_scan_set_enable() - Public API to disable/enable scans
+ * ucfg_scan_set_psoc_enable() - Public API to enable scans for psoc
  * @psoc: psoc on which scans need to be disabled
- * @enable: enable scan if true disable is false
+ * @reason: reason for enable/disabled
  *
  * Return: QDF_STATUS.
  */
-QDF_STATUS ucfg_scan_set_enable(struct wlan_objmgr_psoc *psoc, bool enable);
+QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc,
+				     enum scan_disable_reason reason);
 
 /**
- * ucfg_scan_get_enable() - Public API to get if scan is enabled or disabled
- * @psoc: psoc on which scans status need to be checked
+ * ucfg_scan_psoc_set_disable() - Public API to disable scans for psoc
+ * @psoc: psoc on which scans need to be disabled
+ * @reason: reason for enable/disabled
  *
- * Return: true if enabled else false.
+ * Return: QDF_STATUS.
+ */
+QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc,
+				      enum scan_disable_reason reason);
+
+/**
+ * ucfg_scan_vdev_set_enable() - Public API to enable scans for vdev
+ * @psoc: psoc on which scans need to be disabled
+ * @reason: reason for enable/disabled
+ *
+ * Return: QDF_STATUS.
+ */
+QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev,
+				     enum scan_disable_reason reason);
+
+/**
+ * ucfg_scan_vdev_set_disable() - Public API to disable scans for vdev
+ * @psoc: psoc on which scans need to be disabled
+ * @reason: reason for enable/disabled
+ *
+ * Return: QDF_STATUS.
  */
-bool ucfg_scan_get_enable(struct wlan_objmgr_psoc *psoc);
+QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev,
+				      enum scan_disable_reason reason);
+
+
 
 /**
  * ucfg_scan_set_miracast() - Public API to disable/enable miracast flag
@@ -614,21 +639,6 @@ void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc,
  */
 bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc);
 
-/**
- * ucfg_scan_set_vdev_del_in_progress() - API to mark vdev delete in progress
- * @vdev: pointer to vdev object
- *
- * Return: none
- */
-void ucfg_scan_set_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev);
-/**
- * ucfg_scan_clear_vdev_del_in_progress() - API to reset vdev delete in progress
- * @vdev: pointer to vdev object
- *
- * Return: none
- */
-void ucfg_scan_clear_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev);
-
 /**
  * ucfg_scan_cfg_set_active_dwelltime() - API to set scan active dwelltime
  * @psoc: pointer to psoc object

+ 61 - 47
umac/scan/dispatcher/src/wlan_scan_ucfg_api.c

@@ -879,6 +879,12 @@ ucfg_scan_start(struct scan_start_request *req)
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
+	if (!scm_is_scan_allowed(req->vdev)) {
+		scm_err("scan disabled, rejecting the scan req");
+		scm_scan_free_scan_request_mem(req);
+		return QDF_STATUS_E_AGAIN;
+	}
+
 	scan_obj = wlan_pdev_get_scan_obj(pdev);
 	if (!scan_obj) {
 		scm_err("Failed to get scan object");
@@ -886,12 +892,6 @@ ucfg_scan_start(struct scan_start_request *req)
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
-	if (!scan_obj->enable_scan) {
-		scm_err("scan disabled, rejecting the scan req");
-		scm_scan_free_scan_request_mem(req);
-		return QDF_STATUS_E_AGAIN;
-	}
-
 	scm_debug("reqid: %d, scanid: %d, vdevid: %d",
 		req->scan_req.scan_req_id, req->scan_req.scan_id,
 		req->scan_req.vdev_id);
@@ -932,7 +932,8 @@ ucfg_scan_start(struct scan_start_request *req)
 	return status;
 }
 
-QDF_STATUS ucfg_scan_set_enable(struct wlan_objmgr_psoc *psoc, bool enable)
+QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc,
+				     enum scan_disable_reason reason)
 {
 	struct wlan_scan_obj *scan_obj;
 
@@ -941,24 +942,69 @@ QDF_STATUS ucfg_scan_set_enable(struct wlan_objmgr_psoc *psoc, bool enable)
 		scm_err("Failed to get scan object");
 		return QDF_STATUS_E_NULL_VALUE;
 	}
-	scan_obj->enable_scan = enable;
-	scm_debug("set enable_scan to %d", scan_obj->enable_scan);
+
+	scan_obj->scan_disabled &= ~reason;
+	scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled);
 
 	return QDF_STATUS_SUCCESS;
 }
 
-bool ucfg_scan_get_enable(struct wlan_objmgr_psoc *psoc)
+QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc,
+				      enum scan_disable_reason reason)
 {
 	struct wlan_scan_obj *scan_obj;
 
 	scan_obj = wlan_psoc_get_scan_obj(psoc);
 	if (!scan_obj) {
 		scm_err("Failed to get scan object");
-		return false;
+		return QDF_STATUS_E_NULL_VALUE;
 	}
-	return scan_obj->enable_scan;
+
+	scan_obj->scan_disabled |= reason;
+
+	scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled);
+
+	return QDF_STATUS_SUCCESS;
 }
 
+
+QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev,
+				     enum scan_disable_reason reason)
+{
+	struct scan_vdev_obj *scan_vdev_obj;
+
+	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
+	if (!scan_vdev_obj) {
+		scm_err("null scan_vdev_obj");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	scan_vdev_obj->scan_disabled &= ~reason;
+
+	scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev,
+				      enum scan_disable_reason reason)
+{
+	struct scan_vdev_obj *scan_vdev_obj;
+
+	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
+	if (!scan_vdev_obj) {
+		scm_err("null scan_vdev_obj");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	scan_vdev_obj->scan_disabled |= reason;
+
+	scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
 QDF_STATUS ucfg_scan_set_miracast(
 	struct wlan_objmgr_psoc *psoc, bool enable)
 {
@@ -1359,7 +1405,7 @@ static QDF_STATUS
 wlan_scan_global_init(struct wlan_objmgr_psoc *psoc,
 		      struct wlan_scan_obj *scan_obj)
 {
-	scan_obj->enable_scan = true;
+	scan_obj->scan_disabled = 0;
 	scan_obj->drop_bcn_on_chan_mismatch = true;
 	scan_obj->disable_timeout = false;
 	scan_obj->scan_def.active_dwell =
@@ -1980,7 +2026,7 @@ ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	int i;
 
-	ucfg_scan_set_enable(psoc, false);
+	ucfg_scan_psoc_set_disable(psoc, REASON_SUSPEND);
 	/* Check all pdev */
 	for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) {
 		pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID);
@@ -2002,7 +2048,7 @@ ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
 static QDF_STATUS
 ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
 {
-	ucfg_scan_set_enable(psoc, true);
+	ucfg_scan_psoc_set_enable(psoc, REASON_SUSPEND);
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -2229,38 +2275,6 @@ bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc)
 	return scan_obj->bt_a2dp_enabled;
 }
 
-void ucfg_scan_set_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev)
-{
-	struct scan_vdev_obj *scan_vdev_obj;
-
-	if (!vdev) {
-		scm_err("invalid vdev");
-		return;
-	}
-	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
-	if (!scan_vdev_obj) {
-		scm_err("null scan_vdev_obj");
-		return;
-	}
-	scan_vdev_obj->is_vdev_delete_in_progress = true;
-}
-
-void ucfg_scan_clear_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev)
-{
-	struct scan_vdev_obj *scan_vdev_obj;
-
-	if (!vdev) {
-		scm_err("invalid vdev");
-		return;
-	}
-	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
-	if (!scan_vdev_obj) {
-		scm_err("null scan_vdev_obj");
-		return;
-	}
-	scan_vdev_obj->is_vdev_delete_in_progress = false;
-}
-
 QDF_STATUS
 ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc,
 			       enum scan_config config, uint32_t val)