Quellcode durchsuchen

qcacmn: Add wakelock for enhanced CFR

There is potential risk when starting CFR and resume happens at same
time, so this change adds wake lock for enhanced CFR.

Change-Id: Ifbde12cb73092b7fc4ef517e57051af4ffe7a79f
CRs-Fixed: 2974733
Wu Gao vor 4 Jahren
Ursprung
Commit
0971daad9f

+ 18 - 1
umac/cfr/core/inc/cfr_defs_i.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021 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
@@ -142,4 +142,21 @@ cfr_streamfs_flush(struct pdev_cfr *pa);
  */
 QDF_STATUS cfr_stop_indication(struct wlan_objmgr_vdev *vdev);
 
+#ifdef WLAN_CFR_PM
+/**
+ * cfr_prevent_suspend() - Acquire wake lock and prevent suspend
+ * @pcfr - pointer to pdev_cfr object
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cfr_prevent_suspend(struct pdev_cfr *pcfr);
+
+/**
+ * cfr_allow_suspend() - Release wake lock and allow suspend
+ * @pcfr - pointer to pdev_cfr object
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cfr_allow_suspend(struct pdev_cfr *pcfr);
+#endif
 #endif

+ 92 - 0
umac/cfr/core/src/cfr_common.c

@@ -28,6 +28,9 @@
 #include <wlan_osif_priv.h>
 #include <cfg_ucfg_api.h>
 #include "cfr_cfg.h"
+#ifdef WLAN_CFR_PM
+#include "host_diag_core_event.h"
+#endif
 
 /**
  * wlan_cfr_is_ini_disabled() - Check if cfr feature is disabled
@@ -106,6 +109,53 @@ wlan_cfr_get_dbr_num_entries(struct wlan_objmgr_pdev *pdev)
 	return num_entries;
 }
 
+#ifdef WLAN_CFR_PM
+/**
+ * cfr_wakelock_init(): Create/init wake lock for CFR
+ *
+ * Create/init wake lock for CFR
+ *
+ * Return None
+ */
+static void cfr_wakelock_init(struct pdev_cfr *pcfr)
+{
+	if (!pcfr) {
+		cfr_debug("NULL pa");
+		return;
+	}
+
+	pcfr->is_prevent_suspend = false;
+	qdf_wake_lock_create(&pcfr->wake_lock, "wlan_cfr");
+	qdf_runtime_lock_init(&pcfr->runtime_lock);
+}
+
+/**
+ * cfr_wakelock_deinit(): Destroy/deinit wake lock for CFR
+ *
+ * Destroy/deinit wake lock for CFR
+ *
+ * Return None
+ */
+static void cfr_wakelock_deinit(struct pdev_cfr *pcfr)
+{
+	if (!pcfr) {
+		cfr_debug("NULL pa");
+		return;
+	}
+
+	qdf_runtime_lock_deinit(&pcfr->runtime_lock);
+	qdf_wake_lock_destroy(&pcfr->wake_lock);
+}
+#else
+static inline void cfr_wakelock_init(struct pdev_cfr *pcfr)
+{
+}
+
+static inline void cfr_wakelock_deinit(struct pdev_cfr *pcfr)
+{
+}
+#endif
+
 QDF_STATUS
 wlan_cfr_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg)
 {
@@ -183,6 +233,7 @@ wlan_cfr_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg)
 		pa->lut[idx] = (struct look_up_table *)qdf_mem_malloc(
 			sizeof(struct look_up_table));
 
+	cfr_wakelock_init(pa);
 	wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_UMAC_COMP_CFR,
 					      (void *)pa, QDF_STATUS_SUCCESS);
 
@@ -207,6 +258,7 @@ wlan_cfr_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev, void *arg)
 
 	pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
 	if (pa) {
+		cfr_wakelock_deinit(pa);
 		wlan_objmgr_pdev_component_obj_detach(pdev, WLAN_UMAC_COMP_CFR,
 						      (void *)pa);
 		if (pa->lut) {
@@ -475,3 +527,43 @@ QDF_STATUS cfr_stop_indication(struct wlan_objmgr_vdev *vdev)
 
 	return status;
 }
+
+#ifdef WLAN_CFR_PM
+QDF_STATUS cfr_prevent_suspend(struct pdev_cfr *pcfr)
+{
+	if (!pcfr) {
+		cfr_debug("NULL pcfr");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (pcfr->is_prevent_suspend) {
+		cfr_debug("acquired wake lock");
+		return QDF_STATUS_E_AGAIN;
+	}
+	qdf_wake_lock_acquire(&pcfr->wake_lock,
+			      WIFI_POWER_EVENT_WAKELOCK_CFR);
+	qdf_runtime_pm_prevent_suspend(&pcfr->runtime_lock);
+	pcfr->is_prevent_suspend = true;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS cfr_allow_suspend(struct pdev_cfr *pcfr)
+{
+	if (!pcfr) {
+		cfr_debug("NULL pcfr");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!pcfr->is_prevent_suspend) {
+		cfr_debug("wake lock not acquired");
+		return QDF_STATUS_E_INVAL;
+	}
+	qdf_wake_lock_release(&pcfr->wake_lock,
+			      WIFI_POWER_EVENT_WAKELOCK_CFR);
+	qdf_runtime_pm_allow_suspend(&pcfr->runtime_lock);
+	pcfr->is_prevent_suspend = false;
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif

+ 32 - 0
umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h

@@ -347,5 +347,37 @@ QDF_STATUS ucfg_cfr_rcc_dump_lut(struct wlan_objmgr_vdev *vdev);
  */
 QDF_STATUS ucfg_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev,
 					bool is_subscribe);
+
+#ifdef WLAN_CFR_PM
+/**
+ * ucfg_cfr_suspend() - User space interface to
+ * set suspend status to CFR
+ * @pdev: pointer to pdev_object
+ *
+ * return QDF status
+ */
+QDF_STATUS ucfg_cfr_suspend(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_cfr_resume() - User space interface to
+ * set resume status to CFR
+ * @pdev: pointer to pdev_object
+ *
+ * return QDF status
+ */
+QDF_STATUS ucfg_cfr_resume(struct wlan_objmgr_pdev *pdev);
+#else
+static inline QDF_STATUS
+ucfg_cfr_suspend(struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_cfr_resume(struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif /* end of WLAN_CFR_PM */
 #endif
 #endif

+ 8 - 0
umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h

@@ -558,6 +558,9 @@ struct nl_event_cb {
  * CFR_CAPTURE_METHOD_PROBE_RESPONSE
  * nl_cb: call back to register for nl event for cfr data
  * lut_lock: Lock to protect access to cfr lookup table
+ * is_prevent_suspend: CFR wake lock acquired or not
+ * wake_lock: wake lock for cfr
+ * runtime_lock: runtime lock for cfr
  */
 /*
  * To be extended if we get more capbality info
@@ -606,6 +609,11 @@ struct pdev_cfr {
 	struct unassoc_pool_entry unassoc_pool[MAX_CFR_ENABLED_CLIENTS];
 	struct nl_event_cb nl_cb;
 	qdf_spinlock_t lut_lock;
+#ifdef WLAN_CFR_PM
+	bool is_prevent_suspend;
+	qdf_wake_lock_t wake_lock;
+	qdf_runtime_lock_t runtime_lock;
+#endif
 };
 
 /**

+ 31 - 1
umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c

@@ -1326,6 +1326,37 @@ QDF_STATUS ucfg_cfr_committed_rcc_config(struct wlan_objmgr_vdev *vdev)
 	return status;
 }
 
+#ifdef WLAN_CFR_PM
+QDF_STATUS ucfg_cfr_suspend(struct wlan_objmgr_pdev *pdev)
+{
+	struct pdev_cfr *pcfr;
+
+	pcfr = wlan_objmgr_pdev_get_comp_private_obj(
+				pdev, WLAN_UMAC_COMP_CFR);
+
+	if (!pcfr) {
+		cfr_err("null pcfr");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return cfr_allow_suspend(pcfr);
+}
+
+QDF_STATUS ucfg_cfr_resume(struct wlan_objmgr_pdev *pdev)
+{
+	struct pdev_cfr *pcfr;
+
+	pcfr = wlan_objmgr_pdev_get_comp_private_obj(
+				pdev, WLAN_UMAC_COMP_CFR);
+
+	if (!pcfr) {
+		cfr_err("null pcfr");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return cfr_prevent_suspend(pcfr);
+}
+#endif
 /*
  * This handler is used to enable / disable the capture mode.
  *
@@ -1404,5 +1435,4 @@ QDF_STATUS ucfg_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev,
 	return tgt_cfr_subscribe_ppdu_desc(pdev, is_subscribe);
 }
 #endif
-
 #endif

+ 2 - 0
utils/host_diag_log/inc/host_diag_core_event.h

@@ -942,6 +942,7 @@ enum wifi_connectivity_events {
  * @WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_RESTART: Wakelock for Idle Restart
  * @WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN: Wakelock for Idle Shutdown
  * @WIFI_POWER_EVENT_WAKELOCK_TDLS: Wakelock for TDLS
+ * @WIFI_POWER_EVENT_WAKELOCK_CFR: Wakelock for CFR
  *
  * Indicates the reason for which the wakelock was taken/released
  */
@@ -971,6 +972,7 @@ enum wake_lock_reason {
 	WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_RESTART,
 	WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN,
 	WIFI_POWER_EVENT_WAKELOCK_TDLS,
+	WIFI_POWER_EVENT_WAKELOCK_CFR,
 };
 
 /* The length of interface name should >= IFNAMSIZ */