From 92d2e8b530ec21acb9ebb51eb629f24c370a0366 Mon Sep 17 00:00:00 2001 From: Arun Kumar Khandavalli Date: Mon, 17 Aug 2020 21:34:58 +0530 Subject: [PATCH] qcacld-3.0: Add thermal mitigation support for moselle For older targets thermal mitigation is supported for the apps. In moselle there a new processor wpps on which firmware runs, this commit adds the support for the thermal client wpps. Change-Id: I89896dce808807486ef56b90812369f3d5f4b270 CRs-Fixed: 2757566 --- Kbuild | 1 + .../core/inc/wlan_fw_offload_main.h | 6 + .../core/src/wlan_fw_offload_main.c | 4 + .../dispatcher/inc/cfg_thermal_temp.h | 56 +++- configs/default_defconfig | 6 + core/hdd/inc/wlan_hdd_main.h | 4 + core/hdd/src/wlan_hdd_driver_ops.c | 5 +- core/hdd/src/wlan_hdd_main.c | 22 ++ core/hdd/src/wlan_hdd_sysfs_thermal_cfg.c | 24 +- core/hdd/src/wlan_hdd_thermal.c | 241 +++++++++++++----- core/hdd/src/wlan_hdd_thermal.h | 118 ++++++++- core/hdd/src/wlan_hdd_wext.c | 26 +- core/sme/inc/sme_api.h | 12 +- core/sme/src/common/sme_api.c | 63 ++--- 14 files changed, 466 insertions(+), 122 deletions(-) diff --git a/Kbuild b/Kbuild index d59b72163888..8237067b7765 100644 --- a/Kbuild +++ b/Kbuild @@ -2702,6 +2702,7 @@ cppflags-$(CONFIG_WLAN_SYSFS_DCM) += -DWLAN_SYSFS_DCM cppflags-$(CONFIG_WLAN_SYSFS_HE_BSS_COLOR) += -DWLAN_SYSFS_HE_BSS_COLOR cppflags-$(CONFIG_WLAN_SYSFS_STA_INFO) += -DWLAN_SYSFS_STA_INFO cppflags-$(CONFIG_WLAN_DL_MODES) += -DCONFIG_WLAN_DL_MODES +cppflags-$(CONFIG_WLAN_THERMAL_MULTI_CLIENT_SUPPORT) += -DFEATURE_WPSS_THERMAL_MITIGATION ifeq ($(CONFIG_LEAK_DETECTION), y) cppflags-y += \ 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 736780faa70f..e0bbbbdc7229 100644 --- a/components/fw_offload/core/inc/wlan_fw_offload_main.h +++ b/components/fw_offload/core/inc/wlan_fw_offload_main.h @@ -109,6 +109,9 @@ struct wlan_fwol_coex_config { * @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 + * @mon_id: Monitor client id either the wpps or apps + * @priority_apps: Priority of the apps mitigation to consider by fw + * @priority_wpps: Priority of the wpps mitigation to consider by fw */ struct wlan_fwol_thermal_temp { bool thermal_mitigation_enable; @@ -117,6 +120,9 @@ struct wlan_fwol_thermal_temp { 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; + uint8_t mon_id; + uint8_t priority_apps; + uint8_t priority_wpps; }; /** 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 98da23d285fc..214625ae9313 100644 --- a/components/fw_offload/core/src/wlan_fw_offload_main.c +++ b/components/fw_offload/core/src/wlan_fw_offload_main.c @@ -147,6 +147,10 @@ fwol_init_thermal_temp_in_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_THROTTLE_DUTY_CYCLE_LEVEL4); thermal_temp->throttle_dutycycle_level[5] = cfg_get(psoc, CFG_THROTTLE_DUTY_CYCLE_LEVEL5); + thermal_temp->priority_apps = + cfg_get(psoc, CFG_THERMAL_APPS_PRIORITY); + thermal_temp->priority_wpps = + cfg_get(psoc, CFG_THERMAL_WPPS_PRIOITY); } 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 e500a107cded..a66aaa678d1e 100644 --- a/components/fw_offload/dispatcher/inc/cfg_thermal_temp.h +++ b/components/fw_offload/dispatcher/inc/cfg_thermal_temp.h @@ -340,7 +340,7 @@ * * Supported features: Thermal Mitigation * - * + * */ #define CFG_THERMAL_SAMPLING_TIME CFG_INI_UINT( \ "gThermalSamplingTime", \ @@ -350,6 +350,56 @@ CFG_VALUE_OR_DEFAULT, \ "Thermal mitigation sampling time") +/* + * gThermalAppsPriority - Configure the thermal mitigation APPS priority + * + * @Min: 1 + * @Max: 10 + * @Default: 1 + * + * This ini will control the priority of the thermal mitigation in FW. + * FW will consider this priority while applying the duty cycle from the + * multiple clients. 1 being the least priority and 10 being highest. + * + * Usage: External + * + * Supported features: Thermal Mitigation + * + * + */ +#define CFG_THERMAL_APPS_PRIORITY CFG_INI_UINT( \ + "gThermalAppsPriority", \ + 1, \ + 10, \ + 1, \ + CFG_VALUE_OR_DEFAULT, \ + "Thermal mitigation priority for APPS") + +/* + * gThermalWppsPriority - Configure the thermal mitigation WPPS priority + * + * @Min: 1 + * @Max: 10 + * @Default: 1 + * + * This ini will control the priority of the thermal mitigation in FW. + * FW will consider this priority while applying the duty cycle from the + * multiple clients. 1 being the least priority and 10 being highest. + * + * Usage: External + * + * Supported features: Thermal Mitigation + * + * + */ +#define CFG_THERMAL_WPPS_PRIOITY CFG_INI_UINT( \ + "gThermalWppsPriority", \ + 1, \ + 10, \ + 1, \ + CFG_VALUE_OR_DEFAULT, \ + "Thermal mitigation priority for WPPS") + #define CFG_THERMAL_TEMP_ALL \ CFG(CFG_THERMAL_TEMP_MIN_LEVEL0) \ CFG(CFG_THERMAL_TEMP_MAX_LEVEL0) \ @@ -367,7 +417,9 @@ CFG(CFG_THROTTLE_DUTY_CYCLE_LEVEL3) \ CFG(CFG_THROTTLE_DUTY_CYCLE_LEVEL4) \ CFG(CFG_THROTTLE_DUTY_CYCLE_LEVEL5) \ - CFG(CFG_THERMAL_SAMPLING_TIME) + CFG(CFG_THERMAL_SAMPLING_TIME) \ + CFG(CFG_THERMAL_APPS_PRIORITY) \ + CFG(CFG_THERMAL_WPPS_PRIOITY) #endif diff --git a/configs/default_defconfig b/configs/default_defconfig index 2777e27720da..95669e5e3617 100644 --- a/configs/default_defconfig +++ b/configs/default_defconfig @@ -1166,3 +1166,9 @@ endif #Enable Hang Event CONFIG_WLAN_HANG_EVENT := y + +ifeq ($(CONFIG_CNSS_QCA6750), y) +ifeq ($(CONFIG_FW_THERMAL_THROTTLE), y) +CONFIG_WLAN_THERMAL_MULTI_CLIENT_SUPPORT := y +endif +endif diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 4f43d91921c2..b521d53619a1 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1736,6 +1736,7 @@ struct hdd_adapter_ops_history { * @pm_qos_req: pm_qos request for all cpu cores * @qos_cpu_mask: voted cpu core mask * @adapter_ops_wq: High priority workqueue for handling adapter operations + * @multi_client_thermal_mitigation: Multi client thermal mitigation by fw */ struct hdd_context { struct wlan_objmgr_psoc *psoc; @@ -2070,6 +2071,9 @@ struct hdd_context { qdf_workqueue_t *adapter_ops_wq; struct hdd_adapter_ops_history adapter_ops_history; bool ll_stats_per_chan_rx_tx_time; +#ifdef FEATURE_WPSS_THERMAL_MITIGATION + bool multi_client_thermal_mitigation; +#endif }; /** diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index ca792a67db08..bc9344bd3793 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -46,6 +46,7 @@ #include #include #include +#include "wlan_hdd_thermal.h" #ifdef MODULE #define WLAN_MODULE_NAME module_name(THIS_MODULE) @@ -511,6 +512,7 @@ static int __hdd_soc_probe(struct device *dev, cds_set_driver_loaded(true); cds_set_load_in_progress(false); hdd_start_complete(0); + hdd_thermal_mitigation_register(hdd_ctx, dev); hdd_soc_load_unlock(dev); @@ -684,7 +686,6 @@ static void __hdd_soc_remove(struct device *dev) cds_set_driver_loaded(false); cds_set_unload_in_progress(true); - if (!hdd_wait_for_debugfs_threads_completion()) hdd_warn("Debugfs threads are still active attempting driver unload anyway"); @@ -692,6 +693,7 @@ static void __hdd_soc_remove(struct device *dev) hdd_wlan_stop_modules(hdd_ctx, false); qdf_nbuf_deinit_replenish_timer(); } else { + hdd_thermal_mitigation_unregister(hdd_ctx, dev); hdd_wlan_exit(hdd_ctx); } @@ -1986,6 +1988,7 @@ struct pld_driver_ops wlan_drv_ops = { .runtime_suspend = wlan_hdd_pld_runtime_suspend, .runtime_resume = wlan_hdd_pld_runtime_resume, #endif + .set_curr_therm_cdev_state = wlan_hdd_pld_set_thermal_mitigation, }; int wlan_hdd_register_driver(void) diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 60e6e24da894..a3fb67e46c60 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2222,6 +2222,27 @@ static uint32_t hdd_update_band_cap_from_dot11mode( return band_capability; } +#ifdef FEATURE_WPSS_THERMAL_MITIGATION +static inline +void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx) +{ + struct wmi_unified *wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); + if (!wmi_handle) + return; + + hdd_ctx->multi_client_thermal_mitigation = + wmi_service_enabled(wmi_handle, + wmi_service_thermal_multi_client_support); +} +#else +static inline +void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx) +{ +} +#endif + int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) { int ret; @@ -2526,6 +2547,7 @@ int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) cfg->bcast_twt_support); hdd_update_score_config(hdd_ctx); + hdd_update_multi_client_thermal_support(hdd_ctx); return 0; diff --git a/core/hdd/src/wlan_hdd_sysfs_thermal_cfg.c b/core/hdd/src/wlan_hdd_sysfs_thermal_cfg.c index f541ba9409db..4e3f972ce0f2 100644 --- a/core/hdd/src/wlan_hdd_sysfs_thermal_cfg.c +++ b/core/hdd/src/wlan_hdd_sysfs_thermal_cfg.c @@ -27,6 +27,9 @@ #include "qdf_trace.h" #include "sme_api.h" #include "qdf_status.h" +#include +#include "wlan_hdd_thermal.h" +#include #ifdef FW_THERMAL_THROTTLE_SUPPORT #ifndef QCN7605_SUPPORT @@ -59,6 +62,14 @@ __hdd_sysfs_thermal_cfg_store(struct hdd_context *hdd_ctx, uint16_t val5, val6; QDF_STATUS status; int ret; + struct thermal_mitigation_params therm_cfg_params; + struct wlan_fwol_thermal_temp thermal_temp = {0}; + + 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 status; + } if (!wlan_hdd_validate_modules_state(hdd_ctx)) return -EINVAL; @@ -130,9 +141,18 @@ __hdd_sysfs_thermal_cfg_store(struct hdd_context *hdd_ctx, val6 <= val5) return -EINVAL; + therm_cfg_params.enable = val1; + therm_cfg_params.dc = val2; + therm_cfg_params.levelconf[0].dcoffpercent = val3; + therm_cfg_params.levelconf[0].priority = val4; + therm_cfg_params.levelconf[0].tmplwm = val7; + hdd_thermal_fill_clientid_priority(THERMAL_MONITOR_APPS, + thermal_temp.priority_apps, + thermal_temp.priority_wpps, + &therm_cfg_params); + status = sme_set_thermal_throttle_cfg(hdd_ctx->mac_handle, - val1, val2, val3, - val4, val7); + &therm_cfg_params); if (QDF_IS_STATUS_ERROR(status)) return qdf_status_to_os_return(status); diff --git a/core/hdd/src/wlan_hdd_thermal.c b/core/hdd/src/wlan_hdd_thermal.c index ab3bec05bff1..030c1c3be676 100644 --- a/core/hdd/src/wlan_hdd_thermal.c +++ b/core/hdd/src/wlan_hdd_thermal.c @@ -35,6 +35,9 @@ #include "wlan_hdd_cfg80211.h" #include #include "wlan_fwol_ucfg_api.h" +#include + +#define DC_OFF_PERCENT_WPPS 50 const struct nla_policy wlan_hdd_thermal_mitigation_policy @@ -44,6 +47,102 @@ const struct nla_policy .type = NLA_U32}, }; +#ifdef FEATURE_WPSS_THERMAL_MITIGATION +void +hdd_thermal_fill_clientid_priority(uint8_t mon_id, uint8_t priority_apps, + uint8_t priority_wpps, + struct thermal_mitigation_params *params) +{ + if (mon_id == THERMAL_MONITOR_APPS) { + params->priority = priority_apps; + params->client_id = mon_id; + hdd_debug("Thermal client:%d priority_apps: %d", mon_id, + priority_apps); + } else if (mon_id == THERMAL_MONITOR_WPSS) { + params->priority = priority_wpps; + params->client_id = mon_id; + /* currently hardcoded, can be changed based on requirement */ + params->levelconf[0].dcoffpercent = DC_OFF_PERCENT_WPPS; + hdd_debug("Thermal client:%d priority_wpps: %d", mon_id, + priority_wpps); + } +} +#endif + +static QDF_STATUS +hdd_send_thermal_mitigation_val(struct hdd_context *hdd_ctx, uint32_t level, + uint8_t mon_id) +{ + uint32_t dc, dc_off_percent; + uint32_t prio = 0, target_temp = 0; + struct wlan_fwol_thermal_temp thermal_temp = {0}; + QDF_STATUS status; + bool enable = true; + struct thermal_mitigation_params therm_cfg_params = {0}; + + 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 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 QDF_STATUS_E_INVAL; + } + + dc = thermal_temp.thermal_sampling_time; + therm_cfg_params.enable = enable; + therm_cfg_params.dc = dc; + 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; + therm_cfg_params.pdev_id = 0; + + hdd_thermal_fill_clientid_priority(mon_id, thermal_temp.priority_apps, + thermal_temp.priority_wpps, + &therm_cfg_params); + + hdd_debug("dc %d dc_off_per %d", dc, dc_off_percent); + + status = sme_set_thermal_throttle_cfg(hdd_ctx->mac_handle, + &therm_cfg_params); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err_rl("Failed to set throttle configuration %d", status); + + else + /* + * After SSR, the thermal mitigation level is lost. + * As SSR is hidden from userland, this command will not come + * from userspace after a SSR. To restore this configuration, + * save this in hdd context and restore after re-init. + */ + hdd_ctx->dutycycle_off_percent = dc_off_percent; + + return QDF_STATUS_SUCCESS; +} + /** * __wlan_hdd_cfg80211_set_thermal_mitigation_policy() - Set the thermal policy * @wiphy: Pointer to wireless phy @@ -61,10 +160,7 @@ __wlan_hdd_cfg80211_set_thermal_mitigation_policy(struct wiphy *wiphy, { 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}; + uint32_t level, cmd_type; QDF_STATUS status; hdd_enter(); @@ -100,60 +196,10 @@ __wlan_hdd_cfg80211_set_thermal_mitigation_policy(struct wiphy *wiphy, 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); - else { - /* - * After SSR, the thermal mitigation level is lost. - * As SSR is hidden from userland, this command will not come - * from userspace after a SSR. To restore this configuration, - * save this in hdd context and restore after re-init. - */ - hdd_ctx->dutycycle_off_percent = dc_off_percent; - } - + hdd_debug("thermal mitigation level from userspace %d", level); + status = hdd_send_thermal_mitigation_val(hdd_ctx, level, + THERMAL_MONITOR_APPS); + hdd_exit(); return qdf_status_to_os_return(status); } @@ -200,6 +246,7 @@ QDF_STATUS hdd_restore_thermal_mitigation_config(struct hdd_context *hdd_ctx) uint32_t prio = 0, target_temp = 0; struct wlan_fwol_thermal_temp thermal_temp = {0}; QDF_STATUS status; + struct thermal_mitigation_params therm_cfg_params; status = ucfg_fwol_get_thermal_temp(hdd_ctx->psoc, &thermal_temp); if (QDF_IS_STATUS_ERROR(status)) { @@ -213,17 +260,85 @@ QDF_STATUS hdd_restore_thermal_mitigation_config(struct hdd_context *hdd_ctx) if (!dc_off_percent) enable = false; + therm_cfg_params.enable = enable; + therm_cfg_params.dc = dc; + 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; + therm_cfg_params.client_id = THERMAL_MONITOR_APPS; + therm_cfg_params.priority = 0; hdd_debug("dc %d dc_off_per %d enable %d", dc, dc_off_percent, enable); status = sme_set_thermal_throttle_cfg(hdd_ctx->mac_handle, - enable, - dc, - dc_off_percent, - prio, - target_temp); + &therm_cfg_params); if (QDF_IS_STATUS_ERROR(status)) hdd_err_rl("Failed to set throttle configuration %d", status); return status; } +int wlan_hdd_pld_set_thermal_mitigation(struct device *dev, unsigned long state, + int mon_id) +{ + struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + QDF_STATUS status; + int ret; + + hdd_enter(); + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret) + return ret; + + if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) + return -EINVAL; + + status = hdd_send_thermal_mitigation_val(hdd_ctx, state, mon_id); + + hdd_exit(); + return qdf_status_to_os_return(status); +} + +#ifdef FEATURE_WPSS_THERMAL_MITIGATION +inline void hdd_thermal_mitigation_register_wpps(struct hdd_context *hdd_ctx, + struct device *dev) +{ + if (hdd_ctx->multi_client_thermal_mitigation) + pld_thermal_register(dev, HDD_THERMAL_STATE_LIGHT, + THERMAL_MONITOR_WPSS); +} + +inline void hdd_thermal_mitigation_unregister_wpps(struct hdd_context *hdd_ctx, + struct device *dev) +{ + if (hdd_ctx->multi_client_thermal_mitigation) + pld_thermal_unregister(dev, THERMAL_MONITOR_WPSS); +} +#else +static inline +void hdd_thermal_mitigation_register_wpps(struct hdd_context *hdd_ctx, + struct device *dev) +{ +} + +static inline +void hdd_thermal_mitigation_unregister_wpps(struct hdd_context *hdd_ctx, + struct device *dev) +{ +} +#endif +void hdd_thermal_mitigation_register(struct hdd_context *hdd_ctx, + struct device *dev) +{ + pld_thermal_register(dev, HDD_THERMAL_STATE_EMERGENCY, + THERMAL_MONITOR_APPS); + hdd_thermal_mitigation_register_wpps(hdd_ctx, dev); +} + +void hdd_thermal_mitigation_unregister(struct hdd_context *hdd_ctx, + struct device *dev) +{ + hdd_thermal_mitigation_unregister_wpps(hdd_ctx, dev); + pld_thermal_unregister(dev, THERMAL_MONITOR_APPS); +} diff --git a/core/hdd/src/wlan_hdd_thermal.h b/core/hdd/src/wlan_hdd_thermal.h index 7c4bbd8c090d..3bfcbd490361 100644 --- a/core/hdd/src/wlan_hdd_thermal.h +++ b/core/hdd/src/wlan_hdd_thermal.h @@ -27,8 +27,43 @@ #include #include -#ifdef FW_THERMAL_THROTTLE_SUPPORT +/** + * enum hdd_thermal_states - The various thermal states as supported by WLAN + * @HDD_THERMAL_STATE_NONE - The normal working state + * @HDD_THERMAL_STATE_LIGHT - Intermediate states, WLAN must perform partial + * mitigation + * @HDD_THERMAL_STATE_MODERATE - Intermediate states, WLAN must perform partial + * mitigation + * @HDD_THERMAL_STATE_SEVERE - Intermediate states, WLAN must perform partial + * mitigation + * @HDD_THERMAL_STATE_CRITICAL - Intermediate states, WLAN must perform partial + * mitigation + * @HDD_THERMAL_STATE_EMERGENCY - The highest state, WLAN must enter forced + * IMPS and will disconnect any active STA + * connection + */ +enum hdd_thermal_states { + HDD_THERMAL_STATE_NONE = 0, + HDD_THERMAL_STATE_LIGHT = 1, + HDD_THERMAL_STATE_MODERATE = 2, + HDD_THERMAL_STATE_SEVERE = 3, + HDD_THERMAL_STATE_CRITICAL = 4, + HDD_THERMAL_STATE_EMERGENCY = 5, + HDD_THERMAL_STATE_INVAL = 0xFF, +}; + +/* + * thermal_monitor_id: enum of thermal client + * @THERMAL_MONITOR_APPS: Thermal monitor client of APPS + * @THERMAL_MONITOR_WPSS: Thermal monitor client for WPSS + */ +enum thermal_monitor_id { + THERMAL_MONITOR_APPS = 1, + THERMAL_MONITOR_WPSS, +}; + +#ifdef FW_THERMAL_THROTTLE_SUPPORT int wlan_hdd_cfg80211_set_thermal_mitigation_policy(struct wiphy *wiphy, struct wireless_dev *wdev, @@ -64,6 +99,68 @@ extern const struct nla_policy vendor_command_policy(wlan_hdd_thermal_mitigation_policy, \ QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_MAX) \ }, + +/** + * hdd_thermal_mitigation_register() - Register for platform specific thermal + * mitigation support + * @hdd_ctx: Pointer to Hdd context + * @dev: Pointer to the device + * + * Register to the platform specific thermal mitigation support + * Return: None + */ +void hdd_thermal_mitigation_register(struct hdd_context *hdd_ctx, + struct device *dev); + +/** + * hdd_thermal_mitigation_unregister() - Unregister for platform specific + * thermal mitigation support + * @hdd_ctx: Pointer to Hdd context + * @dev: Pointer to the device + * + * Unregister to the platform specific thermal mitigation support + * Return: None + */ +void hdd_thermal_mitigation_unregister(struct hdd_context *hdd_ctx, + struct device *dev); + +/** + * wlan_hdd_pld_set_thermal_mitigation() - send the suggested thermal value + * to the firmware + * @dev: Pointer to the device + * @state: Thermal state to set + * @mon_id: Thermal monitor id ie.. apps or wpss + * + * Send the requested thermal mitigation value to the firmware * for the + * requested thermal monitor id. + * + * Return: 0 for success or errno for failure. + */ +int wlan_hdd_pld_set_thermal_mitigation(struct device *dev, + unsigned long state, int mon_id); +#ifdef FEATURE_WPSS_THERMAL_MITIGATION +/** + * hdd_thermal_fill_clientid_priority() - fill the client id/priority + * + * @mon_id: Thermal monitor id ie.. apps or wpss + * @priority: Priority of the client to be considered + * + * Fill the clientid/priority for the firmware to consider. + * + * Return: none + */ +void +hdd_thermal_fill_clientid_priority(uint8_t mon_id, uint8_t priority_apps, + uint8_t priority_wpps, + struct thermal_mitigation_params *params); +#else +static inline void +hdd_thermal_fill_clientid_priority(uint8_t mon_id, uint8_t priority_apps, + uint8_t priority_wpps, + struct thermal_mitigation_params *params) +{ +} +#endif #else #define FEATURE_THERMAL_VENDOR_COMMANDS @@ -78,5 +175,24 @@ QDF_STATUS hdd_restore_thermal_mitigation_config(struct hdd_context *hdd_ctx) return false; } +static inline +void hdd_thermal_mitigation_register(struct hdd_context *hdd_ctx, + struct device *dev) +{ +} + +static inline +void hdd_thermal_mitigation_unregister(struct hdd_context *hdd_ctx, + struct device *dev) +{ +} + +static inline +int wlan_hdd_pld_set_thermal_mitigation(struct device *dev, + unsigned long state, int mon_id) +{ + return 0; +} + #endif /* FEATURE_THERMAL_VENDOR_COMMANDS */ #endif /* __HDD_THERMAL_H */ diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 25717095f956..6660192942d8 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -112,6 +112,7 @@ #include "dp_txrx.h" #include "wlan_fwol_ucfg_api.h" #include "wlan_hdd_unit_test.h" +#include "wlan_hdd_thermal.h" /* Private ioctls and their sub-ioctls */ #define WLAN_PRIV_SET_INT_GET_NONE (SIOCIWFIRSTPRIV + 0) @@ -7329,11 +7330,18 @@ static int __iw_set_var_ints_getnone(struct net_device *dev, case WE_SET_THERMAL_THROTTLE_CFG: { QDF_STATUS status; - + struct thermal_mitigation_params therm_cfg_params; + struct wlan_fwol_thermal_temp thermal_temp = {0}; if (num_args != 7) { hdd_err_rl("set_thermal_cfg: Invalid no of args"); return -EINVAL; } + 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); + } /* Check for valid inputs */ if (apps_args[0] < 0 || apps_args[0] > 1 || apps_args[1] < 0 || @@ -7343,12 +7351,18 @@ static int __iw_set_var_ints_getnone(struct net_device *dev, apps_args[5] <= apps_args[4]) return -EINVAL; + therm_cfg_params.enable = apps_args[0]; + therm_cfg_params.dc = apps_args[1]; + therm_cfg_params.levelconf[0].dcoffpercent = apps_args[2]; + therm_cfg_params.levelconf[0].priority = apps_args[3]; + therm_cfg_params.levelconf[0].tmplwm = apps_args[6]; + hdd_thermal_fill_clientid_priority(THERMAL_MONITOR_APPS, + thermal_temp.priority_apps, + thermal_temp.priority_wpps, + &therm_cfg_params); + therm_cfg_params.num_thermal_conf = 1; status = sme_set_thermal_throttle_cfg(hdd_ctx->mac_handle, - apps_args[0], - apps_args[1], - apps_args[2], - apps_args[3], - apps_args[6]); + &therm_cfg_params); if (QDF_IS_STATUS_ERROR(status)) return qdf_status_to_os_return(status); diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 90f46e718d48..a549a1a9ca94 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -3987,18 +3987,12 @@ QDF_STATUS sme_set_md_bl_evt_cb * sme_set_thermal_throttle_cfg() - SME API to set the thermal throttle * configuration parameters * @mac_handle: Opaque handle to the global MAC context - * @enable: Enable Throttle - * @dc: duty cycle in msecs - * @dc_off_percent: duty cycle off percentage - * @prio: Disables the transmit queues in fw that have lower priority - * than value defined by prio - * @target_temp: Target temperature + * @therm_params: Thermal_params * * Return: QDF_STATUS */ -QDF_STATUS sme_set_thermal_throttle_cfg(mac_handle_t mac_handle, bool enable, - uint32_t dc, uint32_t dc_off_percent, - uint32_t prio, uint32_t target_temp); +QDF_STATUS sme_set_thermal_throttle_cfg(mac_handle_t mac_handle, + struct thermal_mitigation_params *therm_params); /** * sme_set_thermal_mgmt() - SME API to set the thermal management params diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 5bbb69d0c698..f2cb9165bcfb 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -15841,55 +15841,42 @@ QDF_STATUS sme_motion_det_base_line_enable( * sme_set_thermal_throttle_cfg() - SME API to set the thermal throttle * configuration parameters * @mac_handle: Opaque handle to the global MAC context - * @enable: Enable Throttle - * @dc: duty cycle in msecs - * @dc_off_percent: duty cycle off percentage - * @prio: Disables the transmit queues in fw that have lower priority - * than value defined by prio - * @target_temp: Target temperature + * @therm_params: structure of thermal configuration parameters * * Return: QDF_STATUS */ -QDF_STATUS sme_set_thermal_throttle_cfg(mac_handle_t mac_handle, bool enable, - uint32_t dc, uint32_t dc_off_percent, - uint32_t prio, uint32_t target_temp) +QDF_STATUS sme_set_thermal_throttle_cfg(mac_handle_t mac_handle, + struct thermal_mitigation_params *therm_params) + { struct scheduler_msg msg; struct mac_context *mac = MAC_CONTEXT(mac_handle); QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; struct thermal_mitigation_params *therm_cfg_params; + therm_cfg_params = qdf_mem_malloc(sizeof(*therm_cfg_params)); + if (!therm_cfg_params) + return QDF_STATUS_E_NOMEM; + + qdf_mem_set(therm_cfg_params, sizeof(*therm_cfg_params), 0); + qdf_mem_copy(therm_cfg_params, therm_params, sizeof(*therm_cfg_params)); + + qdf_mem_set(&msg, sizeof(msg), 0); + msg.type = WMA_SET_THERMAL_THROTTLE_CFG; + msg.reserved = 0; + msg.bodyptr = therm_cfg_params; + qdf_status = sme_acquire_global_lock(&mac->sme); - if (QDF_STATUS_SUCCESS == qdf_status) { - therm_cfg_params = qdf_mem_malloc(sizeof(*therm_cfg_params)); - if (!therm_cfg_params) { - sme_release_global_lock(&mac->sme); - return QDF_STATUS_E_NOMEM; - } - - therm_cfg_params->enable = enable; - therm_cfg_params->dc = dc; - 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; - msg.reserved = 0; - msg.bodyptr = therm_cfg_params; - - qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, - 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; - } - sme_release_global_lock(&mac->sme); + qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, + 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; } + sme_release_global_lock(&mac->sme); return qdf_status; }