qcacld-3.0: Fix unit-test suspend regression
A previous commit failed to propagate WoW enable parameters down to
the Power Management Offload (PMO) component. Propagate WoW enable
parameters to the PMO component to restore unit-test suspend
functionality.
Change-Id: I6531a262a189b416499953bc013efdf64111ac5a
CRs-Fixed: 2020034
diff --git a/core/hdd/inc/wlan_hdd_driver_ops.h b/core/hdd/inc/wlan_hdd_driver_ops.h
index 9daf522..77c9ffd 100644
--- a/core/hdd/inc/wlan_hdd_driver_ops.h
+++ b/core/hdd/inc/wlan_hdd_driver_ops.h
@@ -44,11 +44,9 @@
* This function is called by the platform driver to suspend the
* wlan bus
*
- * @state: state
- *
* Return: QDF_STATUS
*/
-int wlan_hdd_bus_suspend(pm_message_t state);
+int wlan_hdd_bus_suspend(void);
/**
* wlan_hdd_bus_suspend_noirq() - handle .suspend_noirq callback
diff --git a/core/hdd/inc/wlan_hdd_power.h b/core/hdd/inc/wlan_hdd_power.h
index 97e9152..754c906 100644
--- a/core/hdd/inc/wlan_hdd_power.h
+++ b/core/hdd/inc/wlan_hdd_power.h
@@ -324,7 +324,6 @@
#ifdef WLAN_SUSPEND_RESUME_TEST
/**
* wlan_hdd_unit_test_bus_suspend() - suspend the wlan bus
- * @state: state containing the suspend source event
* @wow_params: collection of wow enable override parameters
*
* This function does the same as wlan_hdd_bus_suspend, but additionally passes
@@ -333,8 +332,7 @@
*
* Return: 0 for success or error code
*/
-int wlan_hdd_unit_test_bus_suspend(pm_message_t state,
- struct wow_enable_params wow_params);
+int wlan_hdd_unit_test_bus_suspend(struct wow_enable_params wow_params);
/**
* hdd_wlan_fake_apps_resume() - Resume from unit-test triggered suspend
diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c
index 536cf11..f9033d2 100644
--- a/core/hdd/src/wlan_hdd_driver_ops.c
+++ b/core/hdd/src/wlan_hdd_driver_ops.c
@@ -526,118 +526,178 @@
cds_set_recovery_in_progress(true);
}
+static int hdd_to_pmo_interface_pause(enum wow_interface_pause hdd_pause,
+ enum pmo_wow_interface_pause *pmo_pause)
+{
+ switch (hdd_pause) {
+ case WOW_INTERFACE_PAUSE_DEFAULT:
+ *pmo_pause = PMO_WOW_INTERFACE_PAUSE_DEFAULT;
+ break;
+ case WOW_INTERFACE_PAUSE_ENABLE:
+ *pmo_pause = PMO_WOW_INTERFACE_PAUSE_ENABLE;
+ break;
+ case WOW_INTERFACE_PAUSE_DISABLE:
+ *pmo_pause = PMO_WOW_INTERFACE_PAUSE_DISABLE;
+ break;
+ default:
+ hdd_err("Invalid interface pause: %d", hdd_pause);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int hdd_to_pmo_resume_trigger(enum wow_resume_trigger hdd_trigger,
+ enum pmo_wow_resume_trigger *pmo_trigger)
+{
+ switch (hdd_trigger) {
+ case WOW_RESUME_TRIGGER_DEFAULT:
+ *pmo_trigger = PMO_WOW_RESUME_TRIGGER_DEFAULT;
+ break;
+ case WOW_RESUME_TRIGGER_HTC_WAKEUP:
+ *pmo_trigger = PMO_WOW_RESUME_TRIGGER_HTC_WAKEUP;
+ break;
+ case WOW_RESUME_TRIGGER_GPIO:
+ *pmo_trigger = PMO_WOW_RESUME_TRIGGER_GPIO;
+ break;
+ default:
+ hdd_err("Invalid resume trigger: %d", hdd_trigger);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+hdd_to_pmo_wow_enable_params(struct wow_enable_params *in_params,
+ struct pmo_wow_enable_params *out_params)
+{
+ int err;
+
+ /* unit-test suspend */
+ out_params->is_unit_test = in_params->is_unit_test;
+
+ /* interface pause */
+ err = hdd_to_pmo_interface_pause(in_params->interface_pause,
+ &out_params->interface_pause);
+ if (err)
+ return err;
+
+ /* resume trigger */
+ err = hdd_to_pmo_resume_trigger(in_params->resume_trigger,
+ &out_params->resume_trigger);
+ if (err)
+ return err;
+
+ return 0;
+}
+
/**
* __wlan_hdd_bus_suspend() - handles platform supsend
- * @state: suspend message from the kernel
* @wow_params: collection of wow enable override parameters
*
* Does precondtion validation. Ensures that a subsystem restart isn't in
- * progress. Ensures that no load or unload is in progress.
- * Calls ol_txrx_bus_suspend to ensure the layer is ready for a bus suspend.
- * Calls wma_suspend to configure offloads.
- * Calls hif_suspend to suspend the bus.
+ * progress. Ensures that no load or unload is in progress. Does:
+ * data path suspend
+ * component (pmo) suspend
+ * hif (bus) suspend
*
* Return: 0 for success, -EFAULT for null pointers,
* -EBUSY or -EAGAIN if another opperation is in progress and
* wlan will not be ready to suspend in time.
*/
-static int __wlan_hdd_bus_suspend(pm_message_t state,
- struct wow_enable_params wow_params)
+static int __wlan_hdd_bus_suspend(struct wow_enable_params wow_params)
{
- hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
- void *hif_ctx;
int err;
- int status;
- void *soc = cds_get_context(QDF_MODULE_ID_SOC);
- QDF_STATUS qdf_status;
- struct pmo_wow_enable_params *params = NULL;
+ QDF_STATUS status;
+ hdd_context_t *hdd_ctx;
+ void *hif_ctx;
+ void *soc;
+ struct pmo_wow_enable_params pmo_params;
- hdd_info("starting bus suspend; event:%d", state.event);
+ hdd_info("starting bus suspend");
+ hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
err = wlan_hdd_validate_context(hdd_ctx);
if (err) {
- hdd_err("Invalid hdd context");
- goto done;
+ hdd_err("Invalid hdd context: %d", err);
+ return err;
}
if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
- hdd_info("Driver Module closed; return success");
+ hdd_info("Driver Module closed; skipping suspend");
return 0;
}
hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
- if (NULL == hif_ctx) {
+ if (!hif_ctx) {
hdd_err("Failed to get hif context");
- err = -EINVAL;
- goto done;
+ return -EINVAL;
}
+ err = hdd_to_pmo_wow_enable_params(&wow_params, &pmo_params);
+ if (err) {
+ hdd_err("Invalid WoW enable parameters: %d", err);
+ return err;
+ }
+
+ soc = cds_get_context(QDF_MODULE_ID_SOC);
err = qdf_status_to_os_return(cdp_bus_suspend(soc));
if (err) {
- hdd_err("Failed cdp bus suspend");
- goto done;
+ hdd_err("Failed cdp bus suspend: %d", err);
+ return err;
}
- params = (struct pmo_wow_enable_params *)qdf_mem_malloc(
- sizeof(*params));
- if (!params) {
- hdd_err("params is Null");
- err = -ENOMEM;
- goto done;
- }
- qdf_status = pmo_ucfg_psoc_bus_suspend_req(hdd_ctx->hdd_psoc,
- QDF_SYSTEM_SUSPEND, params);
- err = qdf_status_to_os_return(qdf_status);
+ status = pmo_ucfg_psoc_bus_suspend_req(hdd_ctx->hdd_psoc,
+ QDF_SYSTEM_SUSPEND,
+ &pmo_params);
+ err = qdf_status_to_os_return(status);
if (err) {
- hdd_err("Failed wma bus suspend");
- goto resume_oltxrx;
+ hdd_err("Failed pmo bus suspend: %d", status);
+ goto resume_cdp;
}
err = hif_bus_suspend(hif_ctx);
if (err) {
- hdd_err("Failed hif bus suspend");
- goto resume_wma;
+ hdd_err("Failed hif bus suspend: %d", err);
+ goto resume_pmo;
}
hdd_info("bus suspend succeeded");
- qdf_mem_free(params);
- params = NULL;
return 0;
-resume_wma:
- qdf_status = pmo_ucfg_psoc_bus_resume_req(hdd_ctx->hdd_psoc,
- QDF_SYSTEM_SUSPEND);
- QDF_BUG(!qdf_status);
-resume_oltxrx:
+resume_pmo:
+ status = pmo_ucfg_psoc_bus_resume_req(hdd_ctx->hdd_psoc,
+ QDF_SYSTEM_SUSPEND);
+ QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+
+resume_cdp:
status = cdp_bus_resume(soc);
- QDF_BUG(!status);
-done:
- if (params)
- qdf_mem_free(params);
- hdd_err("suspend failed, status = %d", err);
+ QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+
+ /* return suspend related error code */
return err;
}
-int wlan_hdd_bus_suspend(pm_message_t state)
+int wlan_hdd_bus_suspend(void)
{
int ret;
struct wow_enable_params default_params = {0};
cds_ssr_protect(__func__);
- ret = __wlan_hdd_bus_suspend(state, default_params);
+ ret = __wlan_hdd_bus_suspend(default_params);
cds_ssr_unprotect(__func__);
return ret;
}
#ifdef WLAN_SUSPEND_RESUME_TEST
-int wlan_hdd_unit_test_bus_suspend(pm_message_t state,
- struct wow_enable_params wow_params)
+int wlan_hdd_unit_test_bus_suspend(struct wow_enable_params wow_params)
{
int ret;
cds_ssr_protect(__func__);
- ret = __wlan_hdd_bus_suspend(state, wow_params);
+ ret = __wlan_hdd_bus_suspend(wow_params);
cds_ssr_unprotect(__func__);
return ret;
@@ -1113,11 +1173,11 @@
* Return: 0 on success
*/
static int wlan_hdd_pld_suspend(struct device *dev,
- enum pld_bus_type bus_type,
- pm_message_t state)
+ enum pld_bus_type bus_type,
+ pm_message_t state)
{
- return wlan_hdd_bus_suspend(state);
+ return wlan_hdd_bus_suspend();
}
/**
diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c
index 6e906da..0d7fe8b 100644
--- a/core/hdd/src/wlan_hdd_ioctl.c
+++ b/core/hdd/src/wlan_hdd_ioctl.c
@@ -1910,9 +1910,6 @@
if (hdd_ctx->ext_wow_should_suspend) {
if (hdd_ctx->config->extWowGotoSuspend) {
- pm_message_t state;
-
- state.event = PM_EVENT_SUSPEND;
hdd_info("Received ready to ExtWoW. Going to suspend");
rc = wlan_hdd_cfg80211_suspend_wlan(hdd_ctx->wiphy, NULL);
@@ -1921,7 +1918,7 @@
rc);
return rc;
}
- qdf_ret_status = wlan_hdd_bus_suspend(state);
+ qdf_ret_status = wlan_hdd_bus_suspend();
if (qdf_ret_status != QDF_STATUS_SUCCESS) {
hdd_err("wlan_hdd_suspend failed, status = %d",
qdf_ret_status);
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index c45e0e9..1989764 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -2358,7 +2358,6 @@
{
qdf_device_t qdf_dev;
struct hif_opaque_softc *hif_ctx;
- pm_message_t state;
int i, resume_err, suspend_err;
struct wow_enable_params wow_params = {
.is_unit_test = true,
@@ -2403,8 +2402,7 @@
if (suspend_err)
goto resume_done;
- state.event = PM_EVENT_SUSPEND;
- suspend_err = wlan_hdd_unit_test_bus_suspend(state, wow_params);
+ suspend_err = wlan_hdd_unit_test_bus_suspend(wow_params);
if (suspend_err)
goto cfg80211_resume;