summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajeev Kumar <rajekuma@codeaurora.org>2016-08-25 14:51:42 -0700
committerqcabuildsw <qcabuildsw@localhost>2016-09-02 17:22:13 -0700
commit4c42662c10d52c24f09eebe157331a6b0fa144f9 (patch)
tree5d6e285ec96fbef502d3f8619228bb154fbd58ae
parent4dc09db4711ccd3a156aa1bd6f294c400f04594a (diff)
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
-rw-r--r--core/cds/src/cds_api.c1
-rw-r--r--core/hdd/src/wlan_hdd_driver_ops.c7
-rw-r--r--core/wma/inc/wma.h1
-rw-r--r--core/wma/inc/wma_api.h2
-rw-r--r--core/wma/src/wma_features.c44
5 files changed, 55 insertions, 0 deletions
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index acfae2518ce4..93ff8bc6888f 100644
--- a/core/cds/src/cds_api.c
+++ b/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 */
diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c
index 4470ca3e3994..2c58e8e2a533 100644
--- a/core/hdd/src/wlan_hdd_driver_ops.c
+++ b/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);
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index 9fb309ab1a91..238b77083806 100644
--- a/core/wma/inc/wma.h
+++ b/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;
diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h
index 69aba4c84d06..1bc33afb7379 100644
--- a/core/wma/inc/wma_api.h
+++ b/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);
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index dfcd72302f9c..4641d5abaee5 100644
--- a/core/wma/src/wma_features.c
+++ b/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));
@@ -6583,6 +6586,47 @@ void wma_target_suspend_acknowledge(void *context, bool wow_nack)
}
/**
+ * 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
*