diff --git a/Kbuild b/Kbuild index 9b49cf0822bf..fff9d744389b 100644 --- a/Kbuild +++ b/Kbuild @@ -269,6 +269,10 @@ ifeq ($(CONFIG_QCACLD_FEATURE_HW_CAPABILITY), y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_hw_capability.o endif +ifeq ($(CONFIG_FW_THERMAL_THROTTLE), y) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_thermal.o +endif + ###### OSIF_SYNC ######## SYNC_DIR := os_if/sync SYNC_INC_DIR := $(SYNC_DIR)/inc @@ -2823,6 +2827,9 @@ cppflags-$(CONFIG_DISABLE_CHANNEL_LIST) += -DDISABLE_CHANNEL_LIST #Flag to enable/disable WIPS feature cppflags-$(CONFIG_WLAN_BCN_RECV_FEATURE) += -DWLAN_BCN_RECV_FEATURE +#Flag to enable/disable thermal mitigation +cppflags-$(CONFIG_FW_THERMAL_THROTTLE) += -DFW_THERMAL_THROTTLE + #Flag to enable/disable LTE COEX support cppflags-$(CONFIG_LTE_COEX) += -DLTE_COEX diff --git a/components/fw_offload/core/inc/wlan_fw_offload_main.h b/components/fw_offload/core/inc/wlan_fw_offload_main.h index 2464e9b5864d..4609b7d1fb4c 100644 --- a/components/fw_offload/core/inc/wlan_fw_offload_main.h +++ b/components/fw_offload/core/inc/wlan_fw_offload_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 - 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012 - 2020 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 @@ -100,7 +100,7 @@ struct wlan_fwol_coex_config { }; #define FWOL_THERMAL_LEVEL_MAX 4 -#define FWOL_THERMAL_THROTTLE_LEVEL_MAX 4 +#define FWOL_THERMAL_THROTTLE_LEVEL_MAX 6 /* * struct wlan_fwol_thermal_temp - Thermal temperature config items * @thermal_temp_min_level: Array of temperature minimum levels @@ -108,6 +108,7 @@ struct wlan_fwol_coex_config { * @thermal_mitigation_enable: Control for Thermal mitigation feature * @throttle_period: Thermal throttle period value * @throttle_dutycycle_level: Array of throttle duty cycle levels + * @thermal_sampling_time: sampling time for thermal mitigation in ms */ struct wlan_fwol_thermal_temp { bool thermal_mitigation_enable; @@ -115,6 +116,7 @@ struct wlan_fwol_thermal_temp { uint16_t thermal_temp_min_level[FWOL_THERMAL_LEVEL_MAX]; uint16_t thermal_temp_max_level[FWOL_THERMAL_LEVEL_MAX]; uint32_t throttle_dutycycle_level[FWOL_THERMAL_THROTTLE_LEVEL_MAX]; + uint16_t thermal_sampling_time; }; /** diff --git a/components/fw_offload/core/src/wlan_fw_offload_main.c b/components/fw_offload/core/src/wlan_fw_offload_main.c index 4010ede8aa19..771781a694fa 100644 --- a/components/fw_offload/core/src/wlan_fw_offload_main.c +++ b/components/fw_offload/core/src/wlan_fw_offload_main.c @@ -132,14 +132,20 @@ fwol_init_thermal_temp_in_cfg(struct wlan_objmgr_psoc *psoc, thermal_temp->thermal_mitigation_enable = cfg_get(psoc, CFG_THERMAL_MITIGATION_ENABLE); thermal_temp->throttle_period = cfg_get(psoc, CFG_THROTTLE_PERIOD); + thermal_temp->thermal_sampling_time = + cfg_get(psoc, CFG_THERMAL_SAMPLING_TIME); thermal_temp->throttle_dutycycle_level[0] = cfg_get(psoc, CFG_THROTTLE_DUTY_CYCLE_LEVEL0); - thermal_temp->throttle_dutycycle_level[1]= + thermal_temp->throttle_dutycycle_level[1] = cfg_get(psoc, CFG_THROTTLE_DUTY_CYCLE_LEVEL1); - thermal_temp->throttle_dutycycle_level[2]= + thermal_temp->throttle_dutycycle_level[2] = cfg_get(psoc, CFG_THROTTLE_DUTY_CYCLE_LEVEL2); - thermal_temp->throttle_dutycycle_level[3]= + thermal_temp->throttle_dutycycle_level[3] = cfg_get(psoc, CFG_THROTTLE_DUTY_CYCLE_LEVEL3); + thermal_temp->throttle_dutycycle_level[4] = + cfg_get(psoc, CFG_THROTTLE_DUTY_CYCLE_LEVEL4); + thermal_temp->throttle_dutycycle_level[5] = + cfg_get(psoc, CFG_THROTTLE_DUTY_CYCLE_LEVEL5); } QDF_STATUS fwol_init_neighbor_report_cfg(struct wlan_objmgr_psoc *psoc, diff --git a/components/fw_offload/dispatcher/inc/cfg_thermal_temp.h b/components/fw_offload/dispatcher/inc/cfg_thermal_temp.h index 54d84a02eb92..e500a107cded 100644 --- a/components/fw_offload/dispatcher/inc/cfg_thermal_temp.h +++ b/components/fw_offload/dispatcher/inc/cfg_thermal_temp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018,2020 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 @@ -234,7 +234,7 @@ * gThrottleDutyCycleLevel1 - Set Thermal mitigation throttle duty cycle level1 * @Min: 0 * @Max: 100 - * @Default: 50 + * @Default: 10 * * Usage: External * @@ -244,7 +244,7 @@ "gThrottleDutyCycleLevel1", \ 0, \ 100, \ - 50, \ + 10, \ CFG_VALUE_OR_DEFAULT, \ "Thermal mitigation throttle duty cycle level1") @@ -253,7 +253,7 @@ * gThrottleDutyCycleLevel2 - Set Thermal mitigation throttle duty cycle level2 * @Min: 0 * @Max: 100 - * @Default: 75 + * @Default: 30 * * Usage: External * @@ -263,7 +263,7 @@ "gThrottleDutyCycleLevel2", \ 0, \ 100, \ - 75, \ + 30, \ CFG_VALUE_OR_DEFAULT, \ "Thermal mitigation throttle duty cycle level2") @@ -272,7 +272,7 @@ * gThrottleDutyCycleLevel3 - Set Thermal mitigation throttle duty cycle level3 * @Min: 0 * @Max: 100 - * @Default: 94 + * @Default: 50 * * Usage: External * @@ -282,10 +282,74 @@ "gThrottleDutyCycleLevel3", \ 0, \ 100, \ - 94, \ + 50, \ CFG_VALUE_OR_DEFAULT, \ "Thermal mitigation throttle duty cycle level3") +/* + * + * gThrottleDutyCycleLevel4 - Set Thermal mitigation throttle duty cycle level4 + * @Min: 0 + * @Max: 100 + * @Default: 70 + * + * This ini will apply the thermal throttle duty cycle value in FW + * Usage: External + * + * + */ +#define CFG_THROTTLE_DUTY_CYCLE_LEVEL4 CFG_INI_UINT( \ + "gThrottleDutyCycleLevel4", \ + 0, \ + 100, \ + 70, \ + CFG_VALUE_OR_DEFAULT, \ + "Thermal mitigation throttle duty cycle level4") + +/* + * + * gThrottleDutyCycleLevel5 - Set Thermal mitigation throttle duty cycle level5 + * @Min: 0 + * @Max: 100 + * @Default: 90 + * + * This ini will apply the thermal throttle duty cycle value in FW + * Usage: External + * + * + */ +#define CFG_THROTTLE_DUTY_CYCLE_LEVEL5 CFG_INI_UINT( \ + "gThrottleDutyCycleLevel5", \ + 0, \ + 100, \ + 90, \ + CFG_VALUE_OR_DEFAULT, \ + "Thermal mitigation throttle duty cycle level5") + +/* + *gThermalSamplingTime - Configure the thermal mitigation sampling time in ms. + * + * @Min: 10 + * @Max: 100 + * @Default: 100 + * + * This ini will control the sampling time that the thermal mitigation in FW + * will consider while applying the duty cycle. + * + * Usage: External + * + * Supported features: Thermal Mitigation + * + * + */ +#define CFG_THERMAL_SAMPLING_TIME CFG_INI_UINT( \ + "gThermalSamplingTime", \ + 10, \ + 100, \ + 100, \ + CFG_VALUE_OR_DEFAULT, \ + "Thermal mitigation sampling time") + #define CFG_THERMAL_TEMP_ALL \ CFG(CFG_THERMAL_TEMP_MIN_LEVEL0) \ CFG(CFG_THERMAL_TEMP_MAX_LEVEL0) \ @@ -300,7 +364,10 @@ CFG(CFG_THROTTLE_DUTY_CYCLE_LEVEL0) \ CFG(CFG_THROTTLE_DUTY_CYCLE_LEVEL1) \ CFG(CFG_THROTTLE_DUTY_CYCLE_LEVEL2) \ - CFG(CFG_THROTTLE_DUTY_CYCLE_LEVEL3) + CFG(CFG_THROTTLE_DUTY_CYCLE_LEVEL3) \ + CFG(CFG_THROTTLE_DUTY_CYCLE_LEVEL4) \ + CFG(CFG_THROTTLE_DUTY_CYCLE_LEVEL5) \ + CFG(CFG_THERMAL_SAMPLING_TIME) #endif diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 527ab5a2aea0..4a82b471a6b8 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -143,6 +143,8 @@ #include "wlan_hdd_oemdata.h" #include "os_if_fwol.h" #include "wlan_hdd_sta_info.h" +#include "sme_api.h" +#include "wlan_hdd_thermal.h" #include #define g_mode_rates_size (12) @@ -3886,6 +3888,11 @@ __wlan_hdd_cfg80211_get_features(struct wiphy *wiphy, wlan_hdd_cfg80211_set_feature(feature_flags, QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY); #endif + + if (wlan_hdd_thermal_config_support()) + wlan_hdd_cfg80211_set_feature(feature_flags, + QCA_WLAN_VENDOR_FEATURE_THERMAL_CONFIG); + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(feature_flags) + NLMSG_HDRLEN); @@ -14183,7 +14190,6 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { WIPHY_VENDOR_CMD_NEED_RUNNING, .doit = wlan_hdd_cfg80211_extscan_get_valid_channels }, - #ifdef WLAN_FEATURE_STATS_EXT { .info.vendor_id = QCA_NL80211_VENDOR_ID, @@ -14797,6 +14803,7 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { FEATURE_COEX_CONFIG_COMMANDS FEATURE_MPTA_HELPER_COMMANDS FEATURE_HW_CAPABILITY_COMMANDS + FEATURE_THERMAL_VENDOR_COMMANDS }; struct hdd_context *hdd_cfg80211_wiphy_alloc(void) diff --git a/core/hdd/src/wlan_hdd_thermal.c b/core/hdd/src/wlan_hdd_thermal.c new file mode 100644 index 000000000000..fb09212f6080 --- /dev/null +++ b/core/hdd/src/wlan_hdd_thermal.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2020 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_hdd_thermal.c + * + * WLAN Host Device Driver implementation for thermal mitigation handling + */ + +#include +#include +#include "wlan_osif_priv.h" +#include "qdf_trace.h" +#include "wlan_hdd_main.h" +#include "osif_sync.h" +#include +#include +#include "sme_api.h" +#include "wlan_hdd_thermal.h" +#include "wlan_hdd_cfg80211.h" +#include +#include "wlan_fwol_ucfg_api.h" + +static const struct nla_policy + wlan_hdd_thermal_mitigation_policy + [QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE] = {.type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL] = { + .type = NLA_U32}, +}; + +/** + * __wlan_hdd_cfg80211_set_thermal_mitigation_policy() - Set the thermal policy + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Length of @data + * + * Return: 0 on success, negative errno on failure + */ +static int +__wlan_hdd_cfg80211_set_thermal_mitigation_policy(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_MAX + 1]; + bool enable = true; + uint32_t dc, dc_off_percent, level, cmd_type; + uint32_t prio = 0, target_temp = 0; + struct wlan_fwol_thermal_temp thermal_temp = {0}; + QDF_STATUS status; + + hdd_enter(); + + if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + hdd_err_rl("Command not allowed in FTM mode"); + return -EPERM; + } + + if (wlan_cfg80211_nla_parse(tb, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_MAX, + (struct nlattr *)data, data_len, + wlan_hdd_thermal_mitigation_policy)) { + hdd_err_rl("Invalid attribute"); + return -EINVAL; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE]) { + hdd_err_rl("attr thermal cmd value failed"); + return -EINVAL; + } + + cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE]); + if (cmd_type != QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL) { + hdd_err_rl("invalid thermal cmd value"); + return -EINVAL; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL]) { + hdd_err_rl("attr thermal throttle set failed"); + return -EINVAL; + } + level = + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL]); + + hdd_debug("thermal mitigation level %d", level); + + status = ucfg_fwol_get_thermal_temp(hdd_ctx->psoc, &thermal_temp); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err_rl("Failed to get fwol thermal obj"); + return qdf_status_to_os_return(status); + } + + switch (level) { + case QCA_WLAN_VENDOR_THERMAL_LEVEL_EMERGENCY: + dc_off_percent = thermal_temp.throttle_dutycycle_level[5]; + break; + case QCA_WLAN_VENDOR_THERMAL_LEVEL_CRITICAL: + dc_off_percent = thermal_temp.throttle_dutycycle_level[4]; + break; + case QCA_WLAN_VENDOR_THERMAL_LEVEL_SEVERE: + dc_off_percent = thermal_temp.throttle_dutycycle_level[3]; + break; + case QCA_WLAN_VENDOR_THERMAL_LEVEL_MODERATE: + dc_off_percent = thermal_temp.throttle_dutycycle_level[2]; + break; + case QCA_WLAN_VENDOR_THERMAL_LEVEL_LIGHT: + dc_off_percent = thermal_temp.throttle_dutycycle_level[1]; + break; + case QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE: + enable = false; + dc_off_percent = thermal_temp.throttle_dutycycle_level[0]; + break; + default: + hdd_debug("Invalid thermal state"); + return -EINVAL; + } + + dc = thermal_temp.thermal_sampling_time; + hdd_debug("dc %d dc_off_per %d", dc, dc_off_percent); + + status = sme_set_thermal_throttle_cfg(hdd_ctx->mac_handle, + enable, + dc, + dc_off_percent, + prio, + target_temp); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err_rl("Failed to set throttle configuration %d", status); + + return qdf_status_to_os_return(status); +} + +/** + * wlan_hdd_cfg80211_set_thermal_mitigation_policy() - set thermal + * mitigation policy + * @wiphy: wiphy pointer + * @wdev: pointer to struct wireless_dev + * @data: pointer to incoming NL vendor data + * @data_len: length of @data + * + * Return: 0 on success; error number otherwise. + */ +int +wlan_hdd_cfg80211_set_thermal_mitigation_policy(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct osif_psoc_sync *psoc_sync; + int errno; + + errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync); + if (errno) + return errno; + + errno = __wlan_hdd_cfg80211_set_thermal_mitigation_policy(wiphy, wdev, + data, + data_len); + + osif_psoc_sync_op_stop(psoc_sync); + + return errno; +} + +bool wlan_hdd_thermal_config_support(void) +{ + return true; +} + diff --git a/core/hdd/src/wlan_hdd_thermal.h b/core/hdd/src/wlan_hdd_thermal.h new file mode 100644 index 000000000000..39b01df01b86 --- /dev/null +++ b/core/hdd/src/wlan_hdd_thermal.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __HDD_THERMAL_H +#define __HDD_THERMAL_H +/** + * DOC: wlan_hdd_thermal.h + * WLAN Host Device Driver thermal mitigation include file + */ + +#include +#include + +#ifdef FW_THERMAL_THROTTLE_SUPPORT + +int +wlan_hdd_cfg80211_set_thermal_mitigation_policy(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +/** + * wlan_hdd_thermal_config_support() - thermal mitigation support + * + * Return: true if thermal mitigation support enabled otherwise false + */ +bool wlan_hdd_thermal_config_support(void); + +#define FEATURE_THERMAL_VENDOR_COMMANDS \ +{ \ + .info.vendor_id = QCA_NL80211_VENDOR_ID, \ + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD, \ + .flags = WIPHY_VENDOR_CMD_NEED_WDEV, \ + .doit = wlan_hdd_cfg80211_set_thermal_mitigation_policy \ +}, +#else +#define FEATURE_THERMAL_VENDOR_COMMANDS + +static inline bool wlan_hdd_thermal_config_support(void) +{ + return false; +} + +#endif /* FEATURE_THERMAL_VENDOR_COMMANDS */ +#endif /* __HDD_THERMAL_H */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 77e2066fec92..72b5a857a932 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -15541,7 +15541,9 @@ QDF_STATUS sme_motion_det_base_line_enable( return qdf_status; } #endif /* WLAN_FEATURE_MOTION_DETECTION */ + #ifdef FW_THERMAL_THROTTLE_SUPPORT + /** * sme_set_thermal_throttle_cfg() - SME API to set the thermal throttle * configuration parameters @@ -15577,6 +15579,7 @@ QDF_STATUS sme_set_thermal_throttle_cfg(mac_handle_t mac_handle, bool enable, therm_cfg_params->levelconf[0].dcoffpercent = dc_off_percent; therm_cfg_params->levelconf[0].priority = prio; therm_cfg_params->levelconf[0].tmplwm = target_temp; + therm_cfg_params->num_thermal_conf = 1; qdf_mem_set(&msg, sizeof(msg), 0); msg.type = WMA_SET_THERMAL_THROTTLE_CFG; @@ -15587,6 +15590,8 @@ QDF_STATUS sme_set_thermal_throttle_cfg(mac_handle_t mac_handle, bool enable, QDF_MODULE_ID_WMA, QDF_MODULE_ID_WMA, &msg); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + sme_err("failed to schedule throttle config req %d", + qdf_status); qdf_mem_free(therm_cfg_params); qdf_status = QDF_STATUS_E_FAILURE; }