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;
}