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
This commit is contained in:
Dustin Brown 2017-03-15 12:19:37 -07:00 committed by Sandeep Puligilla
parent e402d5676c
commit 9ef609b196
5 changed files with 120 additions and 69 deletions

View File

@ -44,11 +44,9 @@ void wlan_hdd_unregister_driver(void);
* 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

View File

@ -324,7 +324,6 @@ void wlan_hdd_inc_suspend_stats(hdd_context_t *hdd_ctx,
#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 @@ void wlan_hdd_inc_suspend_stats(hdd_context_t *hdd_ctx,
*
* 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

View File

@ -526,118 +526,178 @@ static void wlan_hdd_update_status(uint32_t status)
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 @@ static void wlan_hdd_pld_crash_shutdown(struct device *dev,
* 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();
}
/**

View File

@ -1910,9 +1910,6 @@ static int hdd_enable_ext_wow(hdd_adapter_t *adapter,
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 @@ static int hdd_enable_ext_wow(hdd_adapter_t *adapter,
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);

View File

@ -2358,7 +2358,6 @@ int hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev,
{
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 @@ int hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev,
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;