summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKe Huang <keh@codeaurora.org>2019-03-12 16:48:23 +0800
committerKe Huang <keh@codeaurora.org>2019-03-13 15:34:42 +0800
commitfda5831cba8db3240fc40dde69eaaffe2e10cdb4 (patch)
tree3dad15aa114123d2720208dfbd8d63f8143fe43a
parent84da5137cb897a47e961e08d95a2655ef35de145 (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.h29
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg.c12
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c17
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c8
-rw-r--r--CORE/SERVICES/BMI/ol_fw.c31
-rw-r--r--CORE/SERVICES/BMI/ol_fw.h15
-rw-r--r--CORE/VOSS/inc/vos_cnss.h19
-rw-r--r--Kbuild4
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))
diff --git a/Kbuild b/Kbuild
index d2d2b91a3fac..299049fd8684 100644
--- a/Kbuild
+++ b/Kbuild
@@ -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