소스 검색

qcacld-3.0: Fail PM suspend if target has sent initial wake up

Host is not handling target initial wake up properly which is
leading to resume failure. Fail PM suspend request if target
has sent initial wake up message.

Change-Id: I7ac757dd7968f541935519da0689d7672f72d19b
CRs-Fixed: 1059543
Rajeev Kumar 8 년 전
부모
커밋
4c42662c10
5개의 변경된 파일55개의 추가작업 그리고 0개의 파일을 삭제
  1. 1 0
      core/cds/src/cds_api.c
  2. 7 0
      core/hdd/src/wlan_hdd_driver_ops.c
  3. 1 0
      core/wma/inc/wma.h
  4. 2 0
      core/wma/inc/wma_api.h
  5. 44 0
      core/wma/src/wma_features.c

+ 1 - 0
core/cds/src/cds_api.c

@@ -288,6 +288,7 @@ QDF_STATUS cds_open(void)
 	htcInfo.pContext = ol_ctx;
 	htcInfo.TargetFailure = ol_target_failure;
 	htcInfo.TargetSendSuspendComplete = wma_target_suspend_acknowledge;
+	htcInfo.target_initial_wakeup_cb = wma_handle_initial_wake_up;
 	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
 
 	/* Create HTC */

+ 7 - 0
core/hdd/src/wlan_hdd_driver_ops.c

@@ -562,9 +562,16 @@ static int __wlan_hdd_bus_suspend(pm_message_t state)
 	if (err)
 		goto resume_wma;
 
+	err = wma_is_target_wake_up_received();
+	if (err)
+		goto resume_hif;
+
 	hdd_err("suspend done, status = %d", err);
 	return err;
 
+resume_hif:
+	status = hif_bus_resume(hif_ctx);
+	QDF_BUG(!status);
 resume_wma:
 	status = wma_bus_resume();
 	QDF_BUG(!status);

+ 1 - 0
core/wma/inc/wma.h

@@ -1383,6 +1383,7 @@ typedef struct {
 #endif
 	qdf_wake_lock_t wow_wake_lock;
 	int wow_nack;
+	bool wow_initial_wake_up;
 	qdf_atomic_t is_wow_bus_suspended;
 	qdf_mc_timer_t wma_scan_comp_timer;
 	uint8_t dfs_phyerr_filter_offload;

+ 2 - 0
core/wma/inc/wma_api.h

@@ -145,8 +145,10 @@ QDF_STATUS wma_get_wcnss_software_version(void *p_cds_gctx,
 int wma_runtime_suspend(void);
 int wma_runtime_resume(void);
 int wma_bus_suspend(void);
+int wma_is_target_wake_up_received(void);
 QDF_STATUS wma_suspend_target(WMA_HANDLE handle, int disable_target_intr);
 void wma_target_suspend_acknowledge(void *context, bool wow_nack);
+void wma_handle_initial_wake_up(void);
 int wma_bus_resume(void);
 QDF_STATUS wma_resume_target(WMA_HANDLE handle);
 QDF_STATUS wma_disable_wow_in_fw(WMA_HANDLE handle);

+ 44 - 0
core/wma/src/wma_features.c

@@ -6414,10 +6414,13 @@ int wma_bus_suspend(void)
 int __wma_bus_resume(WMA_HANDLE handle)
 {
 	bool wow_mode = wma_is_wow_mode_selected(handle);
+	tp_wma_handle wma = handle;
 	QDF_STATUS status;
 
 	WMA_LOGE("%s: wow mode %d", __func__, wow_mode);
 
+	wma->wow_initial_wake_up = false;
+
 	if (!wow_mode)
 		return qdf_status_to_os_return(wma_resume_target(handle));
 
@@ -6582,6 +6585,47 @@ void wma_target_suspend_acknowledge(void *context, bool wow_nack)
 					      WIFI_POWER_EVENT_WAKELOCK_WOW);
 }
 
+/**
+ * wma_handle_initial_wake_up() - handle inital wake up
+ *
+ * Return: none
+ */
+void wma_handle_initial_wake_up(void)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: wma is NULL", __func__);
+		return;
+	}
+
+	wma->wow_initial_wake_up = true;
+}
+
+/**
+ * wma_is_target_wake_up_received() - check for initial wake up
+ *
+ * Check if target initial wake up is received and fail PM suspend gracefully
+ *
+ * Return: -EAGAIN if initial wake up is received else 0
+ */
+int wma_is_target_wake_up_received(void)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: wma is NULL", __func__);
+		return -EAGAIN;
+	}
+
+	if (wma->wow_initial_wake_up) {
+		WMA_LOGE("Target initial wake up received try again");
+		return -EAGAIN;
+	} else {
+		return 0;
+	}
+}
+
 /**
  * wma_resume_target() - resume target
  * @handle: wma handle