// SPDX-License-Identifier: GPL-2.0-only /****************************************************************************** * * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. * Copyright (C) 2018, 2020 Intel Corporation * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. *****************************************************************************/ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> #include <net/mac80211.h> #include "iwl-io.h" #include "iwl-modparams.h" #include "iwl-debug.h" #include "agn.h" #include "dev.h" #include "commands.h" #include "tt.h" /* default Thermal Throttling transaction table * Current state | Throttling Down | Throttling Up *============================================================================= * Condition Nxt State Condition Nxt State Condition Nxt State *----------------------------------------------------------------------------- * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0 * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1 * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0 *============================================================================= */ static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = …; static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = …; static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = …; static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = …; /* Advance Thermal Throttling default restriction table */ static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = …; bool iwl_tt_is_low_power_state(struct iwl_priv *priv) { … } u8 iwl_tt_current_power_mode(struct iwl_priv *priv) { … } bool iwl_ht_enabled(struct iwl_priv *priv) { … } static bool iwl_within_ct_kill_margin(struct iwl_priv *priv) { … } bool iwl_check_for_ct_kill(struct iwl_priv *priv) { … } enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv) { … } enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv) { … } #define CT_KILL_EXIT_DURATION … #define CT_KILL_WAITING_DURATION … /* * toggle the bit to wake up uCode and check the temperature * if the temperature is below CT, uCode will stay awake and send card * state notification with CT_KILL bit clear to inform Thermal Throttling * Management to change state. Otherwise, uCode will go back to sleep * without doing anything, driver should continue the 5 seconds timer * to wake up uCode for temperature check until temperature drop below CT */ static void iwl_tt_check_exit_ct_kill(struct timer_list *t) { … } static void iwl_perform_ct_kill_task(struct iwl_priv *priv, bool stop) { … } static void iwl_tt_ready_for_ct_kill(struct timer_list *t) { … } static void iwl_prepare_ct_kill_task(struct iwl_priv *priv) { … } #define IWL_MINIMAL_POWER_THRESHOLD … #define IWL_REDUCED_PERFORMANCE_THRESHOLD_2 … #define IWL_REDUCED_PERFORMANCE_THRESHOLD_1 … /* * Legacy thermal throttling * 1) Avoid NIC destruction due to high temperatures * Chip will identify dangerously high temperatures that can * harm the device and will power down * 2) Avoid the NIC power down due to high temperature * Throttle early enough to lower the power consumption before * drastic steps are needed */ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) { … } /* * Advance thermal throttling * 1) Avoid NIC destruction due to high temperatures * Chip will identify dangerously high temperatures that can * harm the device and will power down * 2) Avoid the NIC power down due to high temperature * Throttle early enough to lower the power consumption before * drastic steps are needed * Actions include relaxing the power down sleep thresholds and * decreasing the number of TX streams * 3) Avoid throughput performance impact as much as possible * *============================================================================= * Condition Nxt State Condition Nxt State Condition Nxt State *----------------------------------------------------------------------------- * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0 * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1 * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0 *============================================================================= */ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) { … } /* Card State Notification indicated reach critical temperature * if PSP not enable, no Thermal Throttling function will be performed * just set the GP1 bit to acknowledge the event * otherwise, go into IWL_TI_CT_KILL state * since Card State Notification will not provide any temperature reading * for Legacy mode * so just pass the CT_KILL temperature to iwl_legacy_tt_handler() * for advance mode * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state */ static void iwl_bg_ct_enter(struct work_struct *work) { … } /* Card State Notification indicated out of critical temperature * since Card State Notification will not provide any temperature reading * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state */ static void iwl_bg_ct_exit(struct work_struct *work) { … } void iwl_tt_enter_ct_kill(struct iwl_priv *priv) { … } void iwl_tt_exit_ct_kill(struct iwl_priv *priv) { … } static void iwl_bg_tt_work(struct work_struct *work) { … } void iwl_tt_handler(struct iwl_priv *priv) { … } /* Thermal throttling initialization * For advance thermal throttling: * Initialize Thermal Index and temperature threshold table * Initialize thermal throttling restriction table */ void iwl_tt_initialize(struct iwl_priv *priv) { … } /* cleanup thermal throttling management related memory and timer */ void iwl_tt_exit(struct iwl_priv *priv) { … }