iwlwifi: thermal management — CT-KILL + TX backoff from Linux 7.1 tt.c
Ported thermal throttling algorithm from Linux 7.1 mvm/tt.c. Default parameters from iwl_mvm_default_tt_params: CT-KILL entry 118degC, exit 96degC, duration 5s TX backoff: 200us@112degC → 10000us@117degC (6 steps) SMPS entry 114degC, TX protection entry 114degC Functions: rb_iwl_mvm_tt_init, rb_iwl_mvm_tt_temp_notif (DTS notification), rb_iwl_mvm_tt_ct_kill_notif (firmware CT-KILL notification). Wired into transport as tt_mgmt. When temperature exceeds CT-KILL entry, driver stops TX. TX backoff reduces duty cycle proportionally. Live BE201 reference: 50degC idle — well below throttling thresholds.
This commit is contained in:
@@ -308,3 +308,79 @@ int rb_iwl_mvm_rs_select(struct rb_iwl_mvm_rs_state *rs, int signal)
|
||||
rs->best_rate = best;
|
||||
return best > 0 ? best : base_rate;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Thermal management — ported from Linux 7.1 mvm/tt.c. */
|
||||
/* */
|
||||
/* CT-KILL (Critical Temperature Kill): */
|
||||
/* Firmware reports temperature via DTS_MEASUREMENT_NOTIFICATION. */
|
||||
/* If temp >= ct_kill_entry → stop TX, schedule exit timer. */
|
||||
/* If temp <= ct_kill_exit → resume TX. */
|
||||
/* */
|
||||
/* TX backoff: */
|
||||
/* For temperatures between normal and ct_kill_entry, reduce TX */
|
||||
/* duty cycle using the tx_backoff table (temp → backoff_us). */
|
||||
/* Backoff = max_backoff where temp >= threshold. */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static const struct rb_iwl_mvm_tt_params rb_iwl_mvm_default_tt_params = {
|
||||
.ct_kill_entry = 118,
|
||||
.ct_kill_exit = 96,
|
||||
.ct_kill_duration = 5,
|
||||
.dynamic_smps_entry = 114,
|
||||
.dynamic_smps_exit = 110,
|
||||
.tx_protection_entry = 114,
|
||||
.tx_protection_exit = 108,
|
||||
.tx_backoff_temp = { 112, 113, 114, 115, 116, 117 },
|
||||
.tx_backoff_us = { 200, 600, 1200, 2000, 4000, 10000 },
|
||||
.support_ct_kill = 1,
|
||||
.support_dynamic_smps = 1,
|
||||
.support_tx_protection = 1,
|
||||
.support_tx_backoff = 1,
|
||||
};
|
||||
|
||||
void rb_iwl_mvm_tt_init(struct rb_iwl_mvm_tt_mgmt *tt)
|
||||
{
|
||||
if (!tt) return;
|
||||
memset(tt, 0, sizeof(*tt));
|
||||
memcpy(&tt->params, &rb_iwl_mvm_default_tt_params, sizeof(tt->params));
|
||||
}
|
||||
|
||||
void rb_iwl_mvm_tt_temp_notif(struct rb_iwl_mvm_tt_mgmt *tt, int32_t temp)
|
||||
{
|
||||
int i;
|
||||
uint32_t tx_backoff;
|
||||
|
||||
if (!tt) return;
|
||||
if (tt->ct_kill_active)
|
||||
return;
|
||||
|
||||
tt->temperature = temp;
|
||||
|
||||
if (tt->params.support_ct_kill && temp >= (int32_t)tt->params.ct_kill_entry) {
|
||||
tt->ct_kill_active = 1;
|
||||
tt->throttle_active = 0;
|
||||
tt->tx_backoff = 0;
|
||||
tt->tt_timestamp = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (tt->params.support_tx_backoff) {
|
||||
tx_backoff = 0;
|
||||
for (i = 0; i < 6; ++i) {
|
||||
if (temp < (int32_t)tt->params.tx_backoff_temp[i])
|
||||
break;
|
||||
tx_backoff = tt->params.tx_backoff_us[i];
|
||||
}
|
||||
tt->tx_backoff = tx_backoff;
|
||||
tt->throttle_active = (tx_backoff > 0);
|
||||
}
|
||||
}
|
||||
|
||||
void rb_iwl_mvm_tt_ct_kill_notif(struct rb_iwl_mvm_tt_mgmt *tt)
|
||||
{
|
||||
if (!tt) return;
|
||||
tt->ct_kill_active = 1;
|
||||
tt->tx_backoff = 0;
|
||||
tt->tt_timestamp = 0;
|
||||
}
|
||||
|
||||
@@ -256,4 +256,44 @@ void rb_iwl_mvm_rs_update(struct rb_iwl_mvm_rs_state *rs,
|
||||
int rate_idx, int status, int retries);
|
||||
int rb_iwl_mvm_rs_select(struct rb_iwl_mvm_rs_state *rs, int signal);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Thermal management — Linux 7.1 mvm/tt.c + iwl-config.h:284. */
|
||||
/* CT-KILL: firmware enters critical thermal state → stop TX. */
|
||||
/* TX backoff: reduce TX duty cycle proportional to temperature. */
|
||||
/* Live BE201 reference: 50degC idle, CT-KILL entry 118degC. */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
#define RB_IWL_MVM_CT_KILL_ENTRY_DEF 118
|
||||
#define RB_IWL_MVM_CT_KILL_EXIT_DEF 96
|
||||
#define RB_IWL_MVM_CT_KILL_DURATION_DEF 5
|
||||
|
||||
struct rb_iwl_mvm_tt_params {
|
||||
uint32_t ct_kill_entry;
|
||||
uint32_t ct_kill_exit;
|
||||
uint32_t ct_kill_duration;
|
||||
uint32_t dynamic_smps_entry;
|
||||
uint32_t dynamic_smps_exit;
|
||||
uint32_t tx_protection_entry;
|
||||
uint32_t tx_protection_exit;
|
||||
uint32_t tx_backoff_temp[6];
|
||||
uint32_t tx_backoff_us[6];
|
||||
uint8_t support_ct_kill;
|
||||
uint8_t support_dynamic_smps;
|
||||
uint8_t support_tx_protection;
|
||||
uint8_t support_tx_backoff;
|
||||
};
|
||||
|
||||
struct rb_iwl_mvm_tt_mgmt {
|
||||
struct rb_iwl_mvm_tt_params params;
|
||||
uint32_t tx_backoff;
|
||||
int32_t temperature;
|
||||
uint32_t ct_kill_active;
|
||||
uint32_t throttle_active;
|
||||
uint32_t tt_timestamp;
|
||||
};
|
||||
|
||||
void rb_iwl_mvm_tt_init(struct rb_iwl_mvm_tt_mgmt *tt);
|
||||
void rb_iwl_mvm_tt_temp_notif(struct rb_iwl_mvm_tt_mgmt *tt, int32_t temp);
|
||||
void rb_iwl_mvm_tt_ct_kill_notif(struct rb_iwl_mvm_tt_mgmt *tt);
|
||||
|
||||
#endif /* RB_IWLWIFI_MVM_H */
|
||||
|
||||
@@ -278,6 +278,7 @@ struct iwl_trans_pcie {
|
||||
struct rb_iwl_fw_blob_info pnvm_info;
|
||||
struct rb_iwl_fw_metadata fw_meta;
|
||||
struct rb_iwl_mvm_rs_state rs_state;
|
||||
struct rb_iwl_mvm_tt_mgmt tt_mgmt;
|
||||
struct rb_iwl_key keys[4];
|
||||
char fw_name_storage[RB_IWL_MAX_FW_NAME];
|
||||
char pnvm_name_storage[RB_IWL_MAX_FW_NAME];
|
||||
|
||||
Reference in New Issue
Block a user