ath11k_nss: Fix RX thermal throttling on newer 2.12 firmware

There is an issue when enabling thermal support on newer ath11k firmware.
TX/RX rates are being limited, often times 50% of client's HE
capabilities.

The issue stems from a mismatch in WMI API structure. The range to
throttle is currently "-100°C" to "150°C", this essentially means
"always" throttle.

Integrate patch from dd-wrt which adds missing WMI structures and
proper thermal ranges for IPQ5018, IPQ807x, and QCN9000.

Patch-by: Sebastian Gottschall <s.gottschall@dd-wrt.com>
Signed-off-by: Sean Khan <datapronix@protonmail.com>
This commit is contained in:
Sean Khan 2024-08-01 11:08:38 -04:00
parent a87a3382d4
commit 688e25a60a

View File

@ -0,0 +1,241 @@
--- a/drivers/net/wireless/ath/ath11k/thermal.c
+++ b/drivers/net/wireless/ath/ath11k/thermal.c
@@ -135,16 +135,69 @@ int ath11k_thermal_set_throttling(struct
if (ar->state != ATH11K_STATE_ON)
return 0;
+ ar->thermal.throttle_state = throttle_state;
memset(&param, 0, sizeof(param));
param.pdev_id = ar->pdev->pdev_id;
param.enable = throttle_state ? 1 : 0;
param.dc = ATH11K_THERMAL_DEFAULT_DUTY_CYCLE;
param.dc_per_event = 0xFFFFFFFF;
- param.levelconf[0].tmplwm = ATH11K_THERMAL_TEMP_LOW_MARK;
- param.levelconf[0].tmphwm = ATH11K_THERMAL_TEMP_HIGH_MARK;
- param.levelconf[0].dcoffpercent = throttle_state;
- param.levelconf[0].priority = 0; /* disable all data tx queues */
+ switch (ab->hw_rev) {
+ case ATH11K_HW_QCN9074_HW10:
+ param.levelconf[0].tmplwm =
+ ATH11K_THERMAL_TEMP0_LOW_MARK_QCN9000;
+ param.levelconf[0].tmphwm =
+ ATH11K_THERMAL_TEMP0_HIGH_MARK_QCN9000;
+ param.levelconf[1].tmplwm =
+ ATH11K_THERMAL_TEMP1_LOW_MARK_QCN9000;
+ param.levelconf[1].tmphwm =
+ ATH11K_THERMAL_TEMP1_HIGH_MARK_QCN9000;
+ param.levelconf[2].tmplwm =
+ ATH11K_THERMAL_TEMP2_LOW_MARK_QCN9000;
+ param.levelconf[2].tmphwm =
+ ATH11K_THERMAL_TEMP2_HIGH_MARK_QCN9000;
+ param.levelconf[3].tmplwm =
+ ATH11K_THERMAL_TEMP3_LOW_MARK_QCN9000;
+ param.levelconf[3].tmphwm =
+ ATH11K_THERMAL_TEMP3_HIGH_MARK_QCN9000;
+ break;
+ case ATH11K_HW_IPQ5018_HW10:
+ param.levelconf[0].tmplwm =
+ ATH11K_THERMAL_TEMP0_LOW_MARK_IPQ5018;
+ param.levelconf[0].tmphwm =
+ ATH11K_THERMAL_TEMP0_HIGH_MARK_IPQ5018;
+ param.levelconf[1].tmplwm =
+ ATH11K_THERMAL_TEMP1_LOW_MARK_IPQ5018;
+ param.levelconf[1].tmphwm =
+ ATH11K_THERMAL_TEMP1_HIGH_MARK_IPQ5018;
+ param.levelconf[2].tmplwm =
+ ATH11K_THERMAL_TEMP2_LOW_MARK_IPQ5018;
+ param.levelconf[2].tmphwm =
+ ATH11K_THERMAL_TEMP2_HIGH_MARK_IPQ5018;
+ param.levelconf[3].tmplwm =
+ ATH11K_THERMAL_TEMP3_LOW_MARK_IPQ5018;
+ param.levelconf[3].tmphwm =
+ ATH11K_THERMAL_TEMP3_HIGH_MARK_IPQ5018;
+ break;
+ default:
+ param.levelconf[0].tmplwm = ATH11K_THERMAL_TEMP0_LOW_MARK;
+ param.levelconf[0].tmphwm = ATH11K_THERMAL_TEMP0_HIGH_MARK;
+ param.levelconf[1].tmplwm = ATH11K_THERMAL_TEMP1_LOW_MARK;
+ param.levelconf[1].tmphwm = ATH11K_THERMAL_TEMP1_HIGH_MARK;
+ param.levelconf[2].tmplwm = ATH11K_THERMAL_TEMP2_LOW_MARK;
+ param.levelconf[2].tmphwm = ATH11K_THERMAL_TEMP2_HIGH_MARK;
+ param.levelconf[3].tmplwm = ATH11K_THERMAL_TEMP3_LOW_MARK;
+ param.levelconf[3].tmphwm = ATH11K_THERMAL_TEMP3_HIGH_MARK;
+ break;
+ }
+ param.levelconf[0].dcoffpercent = ATH11K_THERMAL_CONFIG_DCOFF0;
+ param.levelconf[0].priority = 7; /* all unicast frames */
+ param.levelconf[1].dcoffpercent = ATH11K_THERMAL_CONFIG_DCOFF1;
+ param.levelconf[1].priority = 7; /* all unicast frames */
+ param.levelconf[2].dcoffpercent = ATH11K_THERMAL_CONFIG_DCOFF2;
+ param.levelconf[2].priority = 7; /* all unicast frames */
+ param.levelconf[3].dcoffpercent = ATH11K_THERMAL_CONFIG_DCOFF3;
+ param.levelconf[3].priority = 7; /* all unicast frames */
ret = ath11k_wmi_send_thermal_mitigation_param_cmd(ar, &param);
if (ret) {
--- a/drivers/net/wireless/ath/ath11k/thermal.h
+++ b/drivers/net/wireless/ath/ath11k/thermal.h
@@ -7,8 +7,56 @@
#ifndef _ATH11K_THERMAL_
#define _ATH11K_THERMAL_
-#define ATH11K_THERMAL_TEMP_LOW_MARK -100
-#define ATH11K_THERMAL_TEMP_HIGH_MARK 150
+
+#define ATH11K_THERMAL_MAX_TEMPERATURE_QCN9000 120
+#define ATH11K_THERMAL_MAX_TEMPERATURE 150
+
+#define ATH11K_THERMAL_TEMP_INFINITE -100
+#define ATH11K_THERMAL_TEMP0_LOW_MARK ATH11K_THERMAL_TEMP_INFINITE
+#define ATH11K_THERMAL_TEMP1_LOW_MARK 100
+#define ATH11K_THERMAL_TEMP2_LOW_MARK 110
+#define ATH11K_THERMAL_TEMP3_LOW_MARK 125
+
+#define ATH11K_THERMAL_TEMP0_HIGH_MARK 110
+#define ATH11K_THERMAL_TEMP1_HIGH_MARK 120
+#define ATH11K_THERMAL_TEMP2_HIGH_MARK 135
+#define ATH11K_THERMAL_TEMP3_HIGH_MARK ATH11K_THERMAL_MAX_TEMPERATURE
+
+#define ATH11K_THERMAL_TEMP0_LOW_MARK_QCN9000 ATH11K_THERMAL_TEMP_INFINITE
+#define ATH11K_THERMAL_TEMP1_LOW_MARK_QCN9000 95
+#define ATH11K_THERMAL_TEMP2_LOW_MARK_QCN9000 100
+#define ATH11K_THERMAL_TEMP3_LOW_MARK_QCN9000 105
+
+#define ATH11K_THERMAL_TEMP0_HIGH_MARK_QCN9000 100
+#define ATH11K_THERMAL_TEMP1_HIGH_MARK_QCN9000 105
+#define ATH11K_THERMAL_TEMP2_HIGH_MARK_QCN9000 110
+#define ATH11K_THERMAL_TEMP3_HIGH_MARK_QCN9000 ATH11K_THERMAL_MAX_TEMPERATURE_QCN9000
+
+#define ATH11K_THERMAL_TEMP0_LOW_MARK_IPQ5018 ATH11K_THERMAL_TEMP_INFINITE
+#define ATH11K_THERMAL_TEMP1_LOW_MARK_IPQ5018 95
+#define ATH11K_THERMAL_TEMP2_LOW_MARK_IPQ5018 100
+#define ATH11K_THERMAL_TEMP3_LOW_MARK_IPQ5018 105
+
+#define ATH11K_THERMAL_TEMP0_HIGH_MARK_IPQ5018 105
+#define ATH11K_THERMAL_TEMP1_HIGH_MARK_IPQ5018 110
+#define ATH11K_THERMAL_TEMP2_HIGH_MARK_IPQ5018 115
+#define ATH11K_THERMAL_TEMP3_HIGH_MARK_IPQ5018 ATH11K_THERMAL_MAX_TEMPERATURE_QCN9000
+
+#define ATH11K_THERMAL_CONFIG_DCOFF0 0
+#define ATH11K_THERMAL_CONFIG_DCOFF1 50
+#define ATH11K_THERMAL_CONFIG_DCOFF2 90
+#define ATH11K_THERMAL_CONFIG_DCOFF3 100
+
+/* This is TX power reduction scaling factor in terms of 0.25db.
+ * Currently for all the levels from 1 to 4 in the enhanced thermal
+ * levels, the pout value will be reduced by -3dB (12 * 0.25).
+ * Customer will have option to configure the power out per thermal level.
+ */
+#define ATH11K_THERMAL_CONFIG_POUT1 12
+#define ATH11K_THERMAL_CONFIG_POUT2 12
+#define ATH11K_THERMAL_CONFIG_POUT3 12
+#define ATH11K_THERMAL_CONFIG_POUT4 12
+
#define ATH11K_THERMAL_THROTTLE_MAX 100
#define ATH11K_THERMAL_DEFAULT_DUTY_CYCLE 100
#define ATH11K_HWMON_NAME_LEN 15
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -3193,6 +3193,7 @@ ath11k_wmi_send_thermal_mitigation_param
lvl_conf->temp_hwm = param->levelconf[i].tmphwm;
lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent;
lvl_conf->prio = param->levelconf[i].priority;
+ lvl_conf->pout_reduction_25db = 0;
lvl_conf++;
}
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -4053,12 +4053,14 @@ struct wmi_11d_new_cc_ev {
u32 new_alpha2;
} __packed;
-#define THERMAL_LEVELS 1
+#define THERMAL_LEVELS 4
struct tt_level_config {
u32 tmplwm;
u32 tmphwm;
u32 dcoffpercent;
u32 priority;
+ u32 pout_reduction_25db;
+ u32 tx_chain_mask;
};
struct thermal_mitigation_params {
@@ -4069,6 +4071,14 @@ struct thermal_mitigation_params {
struct tt_level_config levelconf[THERMAL_LEVELS];
};
+typedef enum {
+ WMI_THERMAL_CLIENT_UNSPECIFIED = 0,
+ WMI_THERMAL_CLIENT_APPS = 1,
+ WMI_THERMAL_CLIENT_WPSS = 2,
+ WMI_THERMAL_CLIENT_FW = 3,
+ WMI_THERMAL_CLIENT_MAX
+} WMI_THERMAL_MITIGATION_CLIENTS;
+
struct wmi_therm_throt_config_request_cmd {
u32 tlv_header;
u32 pdev_id;
@@ -4076,14 +4086,48 @@ struct wmi_therm_throt_config_request_cm
u32 dc;
u32 dc_per_event;
u32 therm_throt_levels;
+ u32 client_id; /* Indicates the client from whom the request is being forwarded to FW. Refer to WMI_THERMAL_MITIGATION_CLIENTS. */
+ u32 priority; /* Indicates the priority, higher the value, higher the priority. Varies from 1 to WMI_THERMAL_CLIENT_MAX_PRIORITY. */
} __packed;
struct wmi_therm_throt_level_config_info {
u32 tlv_header;
+ /** temp_lwm:
+ * temperature sensor value in celsius when to exit to lower zone,
+ * this value can be lower than HWM of lower zone as zone overlapping
+ * is permitted by design to provide hysteresis
+ */
u32 temp_lwm;
+ /** temp_hwm:
+ * temperature sensor value in celsius when to exit to higher zone,
+ * this value can be higher than LWM of higher zone as zone overlapping
+ * is permitted by design to provide hysteresis
+ */
u32 temp_hwm;
+ /** dc_off_percent:
+ * duty cycle off percent 0-100.
+ * 0 means no off, 100 means no on (shutdown the phy).
+ */
u32 dc_off_percent;
+ /** prio:
+ * Disable only the transmit queues in firmware that have lower priority
+ * than value defined by prio.
+ * Prioritization:
+ * 0 = disable all data tx queues, No Prioritization defined
+ * 1 = disable BK tx queue
+ * 2 = disable BK+BE tx queues
+ * 3 = disable BK+BE+VI tx queues
+ */
u32 prio;
+ /**
+ * Pout power reduction in 0.25 dB units.
+ * For example, a value of 5 causes a power reduction of 1.25 dB.
+ */
+ u32 pout_reduction_25db;
+ /** tx chain mask:
+ * Chain mask to apply based on the temp level
+ */
+ u32 tx_chain_mask;
} __packed;
struct wmi_delba_send_cmd {
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -6591,6 +6591,9 @@ static int ath11k_mac_op_start(struct ie
}
}
+ /* set default thermal throttling */
+ ath11k_thermal_set_throttling(ar, 1);
+
mutex_unlock(&ar->conf_mutex);
rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx],