diff options
| author | Ke Huang <keh@codeaurora.org> | 2019-03-12 16:48:23 +0800 |
|---|---|---|
| committer | Ke Huang <keh@codeaurora.org> | 2019-03-13 15:34:42 +0800 |
| commit | fda5831cba8db3240fc40dde69eaaffe2e10cdb4 (patch) | |
| tree | 3dad15aa114123d2720208dfbd8d63f8143fe43a | |
| parent | 84da5137cb897a47e961e08d95a2655ef35de145 (diff) | |
qcacld-2.0: Dynamic Power Control when do Suspend/Resume
1. Add one new solution to turn off/on wlan_vdd 3.3v power
while do suspend/resume. During suspend, it will stop all
active adapter and stop the wlanhost thread; During resume,
and power on wlan_vdd again while do resume, and then reinit
wlanhost driver to download firmware and start all adapter.
2. Export gChangeSleepPowerMode to INI file for user.
3. As gChangeSleepPowerMode=0 means do not change power mode
when do suspend/resume, if gChangeSleepPowerMode=1, the wifi
driver will notify cnss module to turn off/on WLAN_EN
if gChangeSleepPowerMode=2, the wifi driver will notify cnss
module to turn off/on both WLAN_VDD and WLAN_EN.
Change-Id: Iea4b284ca8c5ed1407ea4669c3c65fd7777ba09c
CRs-fixed: 2373073
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_cfg.h | 29 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg.c | 12 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg80211.c | 17 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_main.c | 8 | ||||
| -rw-r--r-- | CORE/SERVICES/BMI/ol_fw.c | 31 | ||||
| -rw-r--r-- | CORE/SERVICES/BMI/ol_fw.h | 15 | ||||
| -rw-r--r-- | CORE/VOSS/inc/vos_cnss.h | 19 | ||||
| -rw-r--r-- | Kbuild | 4 |
8 files changed, 128 insertions, 7 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index d6af7e3aa7cf..102142e51c00 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -5591,6 +5591,31 @@ FG_BTC_BT_INTERVAL_PAGE_P2P_STA_DEFAULT /* * <ini> + * gChangeSleepPowerMode - Change suspend/resume mode. + * @Min: 0 + * @Max: 2 + * @Default: 0 + * + * This ini is used to set WLAN chipset suspend/resume mode + * 0: do not change sleep power mode + * 1: wlan chip reset when do suspend/resume + * 2: wlan chip cut power when suspend + * others: invalid + * + * Related: None + * + * Usage: Internal/External + * + * </ini> + */ + +#define CFG_SLEEP_POWER_MODE_NAME "gChangeSleepPowerMode" +#define CFG_SLEEP_POWER_MODE_MIN (0) +#define CFG_SLEEP_POWER_MODE_MAX (2) +#define CFG_SLEEP_POWER_MODE_DEFAULT (0) + +/* + * <ini> * sae_enabled - Enable/Disable SAE support in driver * @Min: 0 * @Max: 1 @@ -6563,11 +6588,11 @@ struct hdd_config { uint32_t dpd_recalib_cooling_time; uint32_t dpd_recalib_duration_max; bool enable_bcast_probe_rsp; + uint32_t sleep_power_mode; #ifdef WLAN_FEATURE_SAE bool is_sae_enabled; #endif - - bool per_chain_stats_enabled; + bool per_chain_stats_enabled; }; typedef struct hdd_config hdd_config_t; diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index 001c34774f6c..4306a7f9ef50 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -5445,6 +5445,14 @@ REG_TABLE_ENTRY g_registry_table[] = CFG_ENABLE_BCAST_PROBE_RESP_DEFAULT, CFG_ENABLE_BCAST_PROBE_RESP_MIN, CFG_ENABLE_BCAST_PROBE_RESP_MAX), + + REG_VARIABLE(CFG_SLEEP_POWER_MODE_NAME, WLAN_PARAM_Integer, + struct hdd_config, sleep_power_mode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SLEEP_POWER_MODE_DEFAULT, + CFG_SLEEP_POWER_MODE_MIN, + CFG_SLEEP_POWER_MODE_MAX), + #ifdef WLAN_FEATURE_SAE REG_VARIABLE(CFG_IS_SAE_ENABLED_NAME, WLAN_PARAM_Integer, struct hdd_config, is_sae_enabled, @@ -6416,6 +6424,10 @@ void print_hdd_cfg(hdd_context_t *pHddCtx) pHddCtx->cfg_ini->probe_req_ouis); hddLog(LOG2, "Name = [%s] Value = [%u]", + CFG_SLEEP_POWER_MODE_NAME, + pHddCtx->cfg_ini->sleep_power_mode); + + hddLog(LOG2, "Name = [%s] Value = [%u]", CFG_ARP_AC_CATEGORY, pHddCtx->cfg_ini->arp_ac_category); hdd_cfg_print_sae(pHddCtx); diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 45d7c25889c5..fa19cf1c8bc0 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -31265,6 +31265,14 @@ int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy) hdd_context_t *hdd_ctx = wiphy_priv(wiphy); int ret; + if (0 != hdd_ctx->cfg_ini->sleep_power_mode) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: wlan has already been reinited when it is not " + "worked on default sleep power mode, so skip to do " + "wlan cfg80211 resume in this case.", __func__); + return 0; + } + vos_ssr_protect(__func__); ret = __wlan_hdd_cfg80211_resume_wlan(wiphy, false); hdd_system_suspend_state_set(hdd_ctx, false); @@ -31538,6 +31546,15 @@ int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, hdd_context_t *hdd_ctx = wiphy_priv(wiphy); int ret; + if (0 != hdd_ctx->cfg_ini->sleep_power_mode) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: wlan will do shutdown and reinit when suspend " + "and resume if default sleep power mode changed, so " + "skip to do wlan cfg80211 suspend in this case.", + __func__); + return 0; + } + vos_ssr_protect(__func__); ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow, false); hdd_system_suspend_state_set(hdd_ctx, true); diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 3093c7c88e53..668c77ec3079 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -17177,6 +17177,14 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) } #endif + if (0 != vos_set_sleep_power_mode(dev, + pHddCtx->cfg_ini->sleep_power_mode)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: set sleep power mode failed", __func__); + pHddCtx->cfg_ini->sleep_power_mode = 0; + } + ol_set_sleep_power_mode(pHddCtx->cfg_ini->sleep_power_mode); + status = wlan_hdd_reg_init(pHddCtx); if (status != VOS_STATUS_SUCCESS) { hddLog(VOS_TRACE_LEVEL_FATAL, diff --git a/CORE/SERVICES/BMI/ol_fw.c b/CORE/SERVICES/BMI/ol_fw.c index c08a8a7a1871..2b6c884b3010 100644 --- a/CORE/SERVICES/BMI/ol_fw.c +++ b/CORE/SERVICES/BMI/ol_fw.c @@ -63,6 +63,10 @@ static struct hash_fw fw_hash; #endif +#ifdef FEATURE_DYNAMIC_POWER_CONTROL +static uint32_t g_sleep_power_mode = 0; +#endif + #if defined(HIF_PCI) || defined(HIF_SDIO) static u_int32_t refclk_speed_to_hz[] = { 48000000, /* SOC_REFCLK_48_MHZ */ @@ -996,15 +1000,36 @@ release_fw: return status; } +#ifdef FEATURE_DYNAMIC_POWER_CONTROL +void ol_set_sleep_power_mode(uint32_t mode) +{ + g_sleep_power_mode = mode; +} + +uint32_t ol_get_sleep_power_mode(void) +{ + return g_sleep_power_mode; +} +#endif + static int ol_transfer_bin_file(struct ol_softc *scn, ATH_BIN_FILE file, u_int32_t address, bool compressed) { int ret; + bool default_sleep_power_mode_changed = false; + + if (0 != ol_get_sleep_power_mode()) { + default_sleep_power_mode_changed = true; + } - /* Wait until suspend and resume are completed before loading FW */ - vos_lock_pm_sem(); + if (!default_sleep_power_mode_changed) { + /* Wait until suspend and resume are completed before loading FW */ + vos_lock_pm_sem(); + } ret = __ol_transfer_bin_file(scn, file, address, compressed); - vos_release_pm_sem(); + if (!default_sleep_power_mode_changed) { + vos_release_pm_sem(); + } return ret; } diff --git a/CORE/SERVICES/BMI/ol_fw.h b/CORE/SERVICES/BMI/ol_fw.h index 0b28b5ddb54f..bdb49f1fe462 100644 --- a/CORE/SERVICES/BMI/ol_fw.h +++ b/CORE/SERVICES/BMI/ol_fw.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -179,4 +179,17 @@ static inline void ol_target_ready(struct ol_softc *scn, void *cfg_ctx) } #endif +#ifdef FEATURE_DYNAMIC_POWER_CONTROL +void ol_set_sleep_power_mode(uint32_t mode); +uint32_t ol_get_sleep_power_mode(void); +#else +static inline void ol_set_sleep_power_mode(uint32_t mode) +{ +} +static inline uint32_t ol_get_sleep_power_mode(void) +{ + return 0; +} +#endif + #endif /* _OL_FW_H_ */ diff --git a/CORE/VOSS/inc/vos_cnss.h b/CORE/VOSS/inc/vos_cnss.h index 51e1eaf316e4..2a8a0bd834d8 100644 --- a/CORE/VOSS/inc/vos_cnss.h +++ b/CORE/VOSS/inc/vos_cnss.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -249,6 +249,11 @@ static inline enum cnss_cc_src vos_get_cc_source(void) { return CNSS_SOURCE_USER; } + +static inline int vos_set_sleep_power_mode(struct device *dev, int mode) +{ + return 0; +} #else /* END WLAN_OPEN_SOURCE and !CONFIG_CNSS */ static inline void vos_dump_stack (struct task_struct *task) { @@ -579,6 +584,18 @@ static inline int vos_cache_boarddata(unsigned int offset, } #endif +#if defined(CONFIG_CNSS) && defined(FEATURE_DYNAMIC_POWER_CONTROL) +static inline int vos_set_sleep_power_mode(struct device *dev, int mode) +{ + return cnss_common_set_sleep_power_mode(dev, mode); +} +#else +static inline int vos_set_sleep_power_mode(struct device *dev, int mode) +{ + return 0; +} +#endif + #if defined(CONFIG_CNSS) && defined(HIF_SDIO) #include <linux/version.h> #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) @@ -1802,6 +1802,10 @@ ifeq ($(CONFIG_WLAN_WAPI_MODE_11AC_DISABLE), y) CDEFINES += -DWLAN_WAPI_MODE_11AC_DISABLE endif +ifeq ($(CONFIG_WLAN_DYNAMIC_POWER_CONTROL), y) +CDEFINES += -DFEATURE_DYNAMIC_POWER_CONTROL +endif + KBUILD_CPPFLAGS += $(CDEFINES) # Currently, for versions of gcc which support it, the kernel Makefile |
