mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-14 00:24:41 -04:00
qcacld-3.0: Power offload unit test framework enhancements
Recently host power offload suspend/resume has switched to 3 stage process. Enhance power offload unit test framework accordingly, and improve error handling. Change-Id: I8cc1e955fbaca631ee7fd76b0c907d1e68c836bf CRs-Fixed: 1072423
This commit is contained in:
parent
45d62ce21f
commit
9bb2e85aff
5 changed files with 188 additions and 36 deletions
|
|
@ -38,7 +38,9 @@
|
|||
int wlan_hdd_register_driver(void);
|
||||
void wlan_hdd_unregister_driver(void);
|
||||
int wlan_hdd_bus_suspend(pm_message_t state);
|
||||
int wlan_hdd_bus_suspend_noirq(void);
|
||||
int wlan_hdd_bus_resume(void);
|
||||
int wlan_hdd_bus_resume_noirq(void);
|
||||
void hdd_hif_close(void *hif_ctx);
|
||||
int hdd_hif_open(struct device *dev, void *bdev, const hif_bus_id *bid,
|
||||
enum qdf_bus_type bus_type, bool reinit);
|
||||
|
|
|
|||
|
|
@ -200,4 +200,26 @@ void hdd_wlan_suspend_resume_event(uint8_t state) {}
|
|||
#endif /* FEATURE_WLAN_DIAG_SUPPORT */
|
||||
|
||||
|
||||
/*
|
||||
* Unit-test suspend/resume is a testing feature that allows putting firmware
|
||||
* into WoW suspend irrespective of Apps suspend status. It emulates the chain
|
||||
* of events that occur durring normal system-level suspend/resume, such as
|
||||
* initiating all of the suspend/resume stages in the correct order, and
|
||||
* enabling/disabling appropriate copy engine irqs.
|
||||
*/
|
||||
#ifdef WLAN_SUSPEND_RESUME_TEST
|
||||
int hdd_wlan_fake_apps_resume(struct wiphy *wiphy);
|
||||
int hdd_wlan_fake_apps_suspend(struct wiphy *wiphy);
|
||||
#else
|
||||
static inline int hdd_wlan_fake_apps_resume(struct wiphy *wiphy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int hdd_wlan_fake_apps_suspend(struct wiphy *wiphy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* WLAN_SUSPEND_RESUME_TEST */
|
||||
|
||||
#endif /* __WLAN_HDD_POWER_H */
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@
|
|||
#include "cds_concurrency.h"
|
||||
#include "cdp_txrx_flow_ctrl_v2.h"
|
||||
#include "pld_common.h"
|
||||
#include "wlan_hdd_driver_ops.h"
|
||||
|
||||
/* Preprocessor definitions and constants */
|
||||
#define HDD_SSR_BRING_UP_TIME 30000
|
||||
|
|
@ -2349,3 +2350,159 @@ int hdd_set_qpower_config(hdd_context_t *hddctx, hdd_adapter_t *adapter,
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WLAN_SUSPEND_RESUME_TEST
|
||||
/*
|
||||
* On Rome/iHelium there are 12 CE irqs and #2 is the wake irq. This may not be
|
||||
* a valid assumption on future platforms.
|
||||
*/
|
||||
#define CE_IRQ_COUNT 12
|
||||
#define CE_WAKE_IRQ 2
|
||||
static struct wiphy *g_wiphy;
|
||||
|
||||
#define HDD_FA_SUSPENDED_BIT (0)
|
||||
static unsigned long fake_apps_state;
|
||||
|
||||
static int __hdd_wlan_fake_apps_resume(struct wiphy *wiphy);
|
||||
|
||||
/**
|
||||
* hdd_wlan_fake_apps_resume_irq_callback() - Irq callback function for resuming
|
||||
* from unit-test initiated suspend from irq wakeup signal
|
||||
* @val: interrupt val
|
||||
*
|
||||
* Resume wlan after getting very 1st CE interrupt from target
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static void hdd_wlan_fake_apps_resume_irq_callback(uint32_t val)
|
||||
{
|
||||
hdd_info("Trigger unit-test resume WLAN; val: 0x%x", val);
|
||||
|
||||
QDF_BUG(g_wiphy);
|
||||
__hdd_wlan_fake_apps_resume(g_wiphy);
|
||||
g_wiphy = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_wlan_fake_apps_suspend() - Initiate a unit-test triggered suspend
|
||||
* @wiphy: wiphy struct from a validated hdd context
|
||||
*
|
||||
* Return: Zero on success, suspend related non-zero error code on failure
|
||||
*/
|
||||
int hdd_wlan_fake_apps_suspend(struct wiphy *wiphy)
|
||||
{
|
||||
qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
|
||||
struct hif_opaque_softc *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
|
||||
pm_message_t state;
|
||||
int i, resume_err, suspend_err;
|
||||
|
||||
hdd_info("Unit-test suspend WLAN");
|
||||
if (test_and_set_bit(HDD_FA_SUSPENDED_BIT, &fake_apps_state)) {
|
||||
hdd_info("Already unit-test suspended; Nothing to do");
|
||||
return 0;
|
||||
}
|
||||
|
||||
suspend_err = wlan_hdd_cfg80211_suspend_wlan(wiphy, NULL);
|
||||
if (suspend_err)
|
||||
goto resume_done;
|
||||
|
||||
state.event = PM_EVENT_SUSPEND;
|
||||
suspend_err = wlan_hdd_bus_suspend(state);
|
||||
if (suspend_err)
|
||||
goto cfg80211_resume;
|
||||
|
||||
/* simulate kernel disabling irqs */
|
||||
for (i = 0; i < CE_IRQ_COUNT; i++)
|
||||
pld_disable_irq(qdf_dev->dev, i);
|
||||
|
||||
suspend_err = wlan_hdd_bus_suspend_noirq();
|
||||
if (suspend_err)
|
||||
goto enable_irqs_and_bus_resume;
|
||||
|
||||
/* re-enable wake irq */
|
||||
pld_enable_irq(qdf_dev->dev, CE_WAKE_IRQ);
|
||||
|
||||
/* pass wiphy to callback via global variable */
|
||||
g_wiphy = wiphy;
|
||||
hif_fake_apps_suspend(hif_ctx, hdd_wlan_fake_apps_resume_irq_callback);
|
||||
|
||||
return 0;
|
||||
|
||||
enable_irqs_and_bus_resume:
|
||||
/* re-enable irqs */
|
||||
for (i = 0; i < CE_IRQ_COUNT; i++)
|
||||
pld_enable_irq(qdf_dev->dev, i);
|
||||
|
||||
resume_err = wlan_hdd_bus_resume();
|
||||
QDF_BUG(resume_err == 0);
|
||||
|
||||
cfg80211_resume:
|
||||
resume_err = wlan_hdd_cfg80211_resume_wlan(wiphy);
|
||||
QDF_BUG(resume_err == 0);
|
||||
|
||||
resume_done:
|
||||
clear_bit(HDD_FA_SUSPENDED_BIT, &fake_apps_state);
|
||||
hdd_err("Unit-test suspend failed: %d", suspend_err);
|
||||
return suspend_err;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_wlan_fake_apps_resume() - Resume from unit-test triggered suspend
|
||||
* @wiphy: wiphy struct from a validated hdd context
|
||||
*
|
||||
* Return: Zero on success, calls QDF_BUG() on failure
|
||||
*/
|
||||
int hdd_wlan_fake_apps_resume(struct wiphy *wiphy)
|
||||
{
|
||||
struct hif_opaque_softc *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
|
||||
int err;
|
||||
|
||||
hif_fake_apps_resume(hif_ctx);
|
||||
err = __hdd_wlan_fake_apps_resume(wiphy);
|
||||
if (err) {
|
||||
hif_fake_apps_suspend(hif_ctx,
|
||||
hdd_wlan_fake_apps_resume_irq_callback);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* __hdd_wlan_fake_apps_resume() - The core logic for
|
||||
* hdd_wlan_fake_apps_resume() skipping the call to hif_fake_apps_resume(),
|
||||
* which is only need for non-irq resume
|
||||
* @wiphy: wiphy struct from a validated hdd context
|
||||
*
|
||||
* Return: Zero on success, calls QDF_BUG() on failure
|
||||
*/
|
||||
static int __hdd_wlan_fake_apps_resume(struct wiphy *wiphy)
|
||||
{
|
||||
qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
|
||||
int i, resume_err;
|
||||
|
||||
hdd_info("Unit-test resume WLAN");
|
||||
if (!test_and_clear_bit(HDD_FA_SUSPENDED_BIT, &fake_apps_state)) {
|
||||
hdd_info("Not unit-test suspended; Nothing to do");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* disable wake irq */
|
||||
pld_disable_irq(qdf_dev->dev, CE_WAKE_IRQ);
|
||||
|
||||
resume_err = wlan_hdd_bus_resume_noirq();
|
||||
QDF_BUG(resume_err == 0);
|
||||
|
||||
/* simulate kernel enable irqs */
|
||||
for (i = 0; i < CE_IRQ_COUNT; i++)
|
||||
pld_enable_irq(qdf_dev->dev, i);
|
||||
|
||||
resume_err = wlan_hdd_bus_resume();
|
||||
QDF_BUG(resume_err == 0);
|
||||
|
||||
resume_err = wlan_hdd_cfg80211_resume_wlan(wiphy);
|
||||
QDF_BUG(resume_err == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@
|
|||
#ifdef WLAN_SUSPEND_RESUME_TEST
|
||||
#include "wlan_hdd_driver_ops.h"
|
||||
#include "hif.h"
|
||||
#include "pld_common.h"
|
||||
#endif
|
||||
|
||||
#define HDD_FINISH_ULA_TIME_OUT 800
|
||||
|
|
@ -439,10 +440,9 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
|
|||
#define WE_ENABLE_FW_PROFILE 4
|
||||
#define WE_SET_FW_PROFILE_HIST_INTVL 5
|
||||
|
||||
#ifdef WLAN_SUSPEND_RESUME_TEST
|
||||
/* Private sub-ioctl for initiating WoW suspend without Apps suspend */
|
||||
#define WE_SET_WLAN_SUSPEND 6
|
||||
#define WE_SET_WLAN_RESUME 7
|
||||
#endif
|
||||
|
||||
/* (SIOCIWFIRSTPRIV + 29) is currently unused */
|
||||
|
||||
|
|
@ -9782,25 +9782,6 @@ static int wlan_hdd_set_mon_chan(hdd_adapter_t *adapter, uint32_t chan,
|
|||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
#ifdef WLAN_SUSPEND_RESUME_TEST
|
||||
static void *g_wiphy;
|
||||
|
||||
/**
|
||||
* hdd_wlan_trigger_resume() - resume wlan
|
||||
* @val: interrupt val
|
||||
*
|
||||
* Resume wlan after getting very 1st CE interrupt from target
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static void hdd_wlan_trigger_resume(uint32_t val)
|
||||
{
|
||||
hdd_err("Resume WLAN val 0x%x", val);
|
||||
wlan_hdd_bus_resume();
|
||||
wlan_hdd_cfg80211_resume_wlan(g_wiphy);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __iw_set_two_ints_getnone(struct net_device *dev,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
|
|
@ -9810,10 +9791,6 @@ static int __iw_set_two_ints_getnone(struct net_device *dev,
|
|||
int sub_cmd = value[0];
|
||||
int ret;
|
||||
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
|
||||
#ifdef WLAN_SUSPEND_RESUME_TEST
|
||||
pm_message_t state;
|
||||
#endif
|
||||
|
||||
|
||||
ENTER_DEV(dev);
|
||||
|
||||
|
|
@ -9877,21 +9854,12 @@ static int __iw_set_two_ints_getnone(struct net_device *dev,
|
|||
case WE_SET_MON_MODE_CHAN:
|
||||
ret = wlan_hdd_set_mon_chan(pAdapter, value[1], value[2]);
|
||||
break;
|
||||
#ifdef WLAN_SUSPEND_RESUME_TEST
|
||||
case WE_SET_WLAN_SUSPEND:
|
||||
hdd_err("Suspend WLAN");
|
||||
g_wiphy = hdd_ctx->wiphy;
|
||||
state.event = PM_EVENT_SUSPEND;
|
||||
ret = wlan_hdd_cfg80211_suspend_wlan(hdd_ctx->wiphy, NULL);
|
||||
wlan_hdd_bus_suspend(state);
|
||||
hif_fake_apps_suspend(hdd_wlan_trigger_resume);
|
||||
ret = hdd_wlan_fake_apps_suspend(hdd_ctx->wiphy);
|
||||
break;
|
||||
case WE_SET_WLAN_RESUME:
|
||||
hdd_err("Resume WLAN");
|
||||
wlan_hdd_bus_resume();
|
||||
ret = wlan_hdd_cfg80211_resume_wlan(hdd_ctx->wiphy);
|
||||
ret = hdd_wlan_fake_apps_resume(hdd_ctx->wiphy);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
hdd_err("Invalid IOCTL command %d", sub_cmd);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -379,4 +379,7 @@ void *pld_smmu_get_mapping(struct device *dev);
|
|||
int pld_smmu_map(struct device *dev, phys_addr_t paddr,
|
||||
uint32_t *iova_addr, size_t size);
|
||||
unsigned int pld_socinfo_get_serial_number(struct device *dev);
|
||||
|
||||
void pld_enable_irq(struct device *dev, unsigned int ce_id);
|
||||
void pld_disable_irq(struct device *dev, unsigned int ce_id);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue