Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /******************************************************************************
0003  *
0004  * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
0005  * Copyright (C) 2018, 2020 Intel Corporation
0006  *
0007  * Portions of this file are derived from the ipw3945 project, as well
0008  * as portions of the ieee80211 subsystem header files.
0009  *****************************************************************************/
0010 
0011 
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/slab.h>
0015 #include <net/mac80211.h>
0016 #include "iwl-io.h"
0017 #include "iwl-modparams.h"
0018 #include "iwl-debug.h"
0019 #include "agn.h"
0020 #include "dev.h"
0021 #include "commands.h"
0022 #include "tt.h"
0023 
0024 /* default Thermal Throttling transaction table
0025  * Current state   |         Throttling Down               |  Throttling Up
0026  *=============================================================================
0027  *                 Condition Nxt State  Condition Nxt State Condition Nxt State
0028  *-----------------------------------------------------------------------------
0029  *     IWL_TI_0     T >= 114   CT_KILL  114>T>=105   TI_1      N/A      N/A
0030  *     IWL_TI_1     T >= 114   CT_KILL  114>T>=110   TI_2     T<=95     TI_0
0031  *     IWL_TI_2     T >= 114   CT_KILL                        T<=100    TI_1
0032  *    IWL_CT_KILL      N/A       N/A       N/A        N/A     T<=95     TI_0
0033  *=============================================================================
0034  */
0035 static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = {
0036     {IWL_TI_0, IWL_ABSOLUTE_ZERO, 104},
0037     {IWL_TI_1, 105, CT_KILL_THRESHOLD - 1},
0038     {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
0039 };
0040 static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = {
0041     {IWL_TI_0, IWL_ABSOLUTE_ZERO, 95},
0042     {IWL_TI_2, 110, CT_KILL_THRESHOLD - 1},
0043     {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
0044 };
0045 static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = {
0046     {IWL_TI_1, IWL_ABSOLUTE_ZERO, 100},
0047     {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX},
0048     {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
0049 };
0050 static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = {
0051     {IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD},
0052     {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX},
0053     {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
0054 };
0055 
0056 /* Advance Thermal Throttling default restriction table */
0057 static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = {
0058     {IWL_ANT_OK_MULTI, IWL_ANT_OK_MULTI, true },
0059     {IWL_ANT_OK_SINGLE, IWL_ANT_OK_MULTI, true },
0060     {IWL_ANT_OK_SINGLE, IWL_ANT_OK_SINGLE, false },
0061     {IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false }
0062 };
0063 
0064 bool iwl_tt_is_low_power_state(struct iwl_priv *priv)
0065 {
0066     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0067 
0068     if (tt->state >= IWL_TI_1)
0069         return true;
0070     return false;
0071 }
0072 
0073 u8 iwl_tt_current_power_mode(struct iwl_priv *priv)
0074 {
0075     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0076 
0077     return tt->tt_power_mode;
0078 }
0079 
0080 bool iwl_ht_enabled(struct iwl_priv *priv)
0081 {
0082     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0083     struct iwl_tt_restriction *restriction;
0084 
0085     if (!priv->thermal_throttle.advanced_tt)
0086         return true;
0087     restriction = tt->restriction + tt->state;
0088     return restriction->is_ht;
0089 }
0090 
0091 static bool iwl_within_ct_kill_margin(struct iwl_priv *priv)
0092 {
0093     s32 temp = priv->temperature; /* degrees CELSIUS except specified */
0094     bool within_margin = false;
0095 
0096     if (!priv->thermal_throttle.advanced_tt)
0097         within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
0098                 CT_KILL_THRESHOLD_LEGACY) ? true : false;
0099     else
0100         within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
0101                 CT_KILL_THRESHOLD) ? true : false;
0102     return within_margin;
0103 }
0104 
0105 bool iwl_check_for_ct_kill(struct iwl_priv *priv)
0106 {
0107     bool is_ct_kill = false;
0108 
0109     if (iwl_within_ct_kill_margin(priv)) {
0110         iwl_tt_enter_ct_kill(priv);
0111         is_ct_kill = true;
0112     }
0113     return is_ct_kill;
0114 }
0115 
0116 enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv)
0117 {
0118     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0119     struct iwl_tt_restriction *restriction;
0120 
0121     if (!priv->thermal_throttle.advanced_tt)
0122         return IWL_ANT_OK_MULTI;
0123     restriction = tt->restriction + tt->state;
0124     return restriction->tx_stream;
0125 }
0126 
0127 enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv)
0128 {
0129     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0130     struct iwl_tt_restriction *restriction;
0131 
0132     if (!priv->thermal_throttle.advanced_tt)
0133         return IWL_ANT_OK_MULTI;
0134     restriction = tt->restriction + tt->state;
0135     return restriction->rx_stream;
0136 }
0137 
0138 #define CT_KILL_EXIT_DURATION (5)   /* 5 seconds duration */
0139 #define CT_KILL_WAITING_DURATION (300)  /* 300ms duration */
0140 
0141 /*
0142  * toggle the bit to wake up uCode and check the temperature
0143  * if the temperature is below CT, uCode will stay awake and send card
0144  * state notification with CT_KILL bit clear to inform Thermal Throttling
0145  * Management to change state. Otherwise, uCode will go back to sleep
0146  * without doing anything, driver should continue the 5 seconds timer
0147  * to wake up uCode for temperature check until temperature drop below CT
0148  */
0149 static void iwl_tt_check_exit_ct_kill(struct timer_list *t)
0150 {
0151     struct iwl_priv *priv = from_timer(priv, t,
0152                        thermal_throttle.ct_kill_exit_tm);
0153     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0154 
0155     if (test_bit(STATUS_EXIT_PENDING, &priv->status))
0156         return;
0157 
0158     if (tt->state == IWL_TI_CT_KILL) {
0159         if (priv->thermal_throttle.ct_kill_toggle) {
0160             iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,
0161                     CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
0162             priv->thermal_throttle.ct_kill_toggle = false;
0163         } else {
0164             iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET,
0165                     CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
0166             priv->thermal_throttle.ct_kill_toggle = true;
0167         }
0168         iwl_read32(priv->trans, CSR_UCODE_DRV_GP1);
0169         if (iwl_trans_grab_nic_access(priv->trans))
0170             iwl_trans_release_nic_access(priv->trans);
0171 
0172         /* Reschedule the ct_kill timer to occur in
0173          * CT_KILL_EXIT_DURATION seconds to ensure we get a
0174          * thermal update */
0175         IWL_DEBUG_TEMP(priv, "schedule ct_kill exit timer\n");
0176         mod_timer(&priv->thermal_throttle.ct_kill_exit_tm,
0177               jiffies + CT_KILL_EXIT_DURATION * HZ);
0178     }
0179 }
0180 
0181 static void iwl_perform_ct_kill_task(struct iwl_priv *priv,
0182                bool stop)
0183 {
0184     if (stop) {
0185         IWL_DEBUG_TEMP(priv, "Stop all queues\n");
0186         if (priv->mac80211_registered)
0187             ieee80211_stop_queues(priv->hw);
0188         IWL_DEBUG_TEMP(priv,
0189                 "Schedule 5 seconds CT_KILL Timer\n");
0190         mod_timer(&priv->thermal_throttle.ct_kill_exit_tm,
0191               jiffies + CT_KILL_EXIT_DURATION * HZ);
0192     } else {
0193         IWL_DEBUG_TEMP(priv, "Wake all queues\n");
0194         if (priv->mac80211_registered)
0195             ieee80211_wake_queues(priv->hw);
0196     }
0197 }
0198 
0199 static void iwl_tt_ready_for_ct_kill(struct timer_list *t)
0200 {
0201     struct iwl_priv *priv = from_timer(priv, t,
0202                        thermal_throttle.ct_kill_waiting_tm);
0203     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0204 
0205     if (test_bit(STATUS_EXIT_PENDING, &priv->status))
0206         return;
0207 
0208     /* temperature timer expired, ready to go into CT_KILL state */
0209     if (tt->state != IWL_TI_CT_KILL) {
0210         IWL_DEBUG_TEMP(priv, "entering CT_KILL state when "
0211                 "temperature timer expired\n");
0212         tt->state = IWL_TI_CT_KILL;
0213         set_bit(STATUS_CT_KILL, &priv->status);
0214         iwl_perform_ct_kill_task(priv, true);
0215     }
0216 }
0217 
0218 static void iwl_prepare_ct_kill_task(struct iwl_priv *priv)
0219 {
0220     IWL_DEBUG_TEMP(priv, "Prepare to enter IWL_TI_CT_KILL\n");
0221     /* make request to retrieve statistics information */
0222     iwl_send_statistics_request(priv, 0, false);
0223     /* Reschedule the ct_kill wait timer */
0224     mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm,
0225          jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION));
0226 }
0227 
0228 #define IWL_MINIMAL_POWER_THRESHOLD     (CT_KILL_THRESHOLD_LEGACY)
0229 #define IWL_REDUCED_PERFORMANCE_THRESHOLD_2 (100)
0230 #define IWL_REDUCED_PERFORMANCE_THRESHOLD_1 (90)
0231 
0232 /*
0233  * Legacy thermal throttling
0234  * 1) Avoid NIC destruction due to high temperatures
0235  *  Chip will identify dangerously high temperatures that can
0236  *  harm the device and will power down
0237  * 2) Avoid the NIC power down due to high temperature
0238  *  Throttle early enough to lower the power consumption before
0239  *  drastic steps are needed
0240  */
0241 static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
0242 {
0243     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0244     enum iwl_tt_state old_state;
0245 
0246 #ifdef CONFIG_IWLWIFI_DEBUG
0247     if ((tt->tt_previous_temp) &&
0248         (temp > tt->tt_previous_temp) &&
0249         ((temp - tt->tt_previous_temp) >
0250         IWL_TT_INCREASE_MARGIN)) {
0251         IWL_DEBUG_TEMP(priv,
0252             "Temperature increase %d degree Celsius\n",
0253             (temp - tt->tt_previous_temp));
0254     }
0255 #endif
0256     old_state = tt->state;
0257     /* in Celsius */
0258     if (temp >= IWL_MINIMAL_POWER_THRESHOLD)
0259         tt->state = IWL_TI_CT_KILL;
0260     else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2)
0261         tt->state = IWL_TI_2;
0262     else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1)
0263         tt->state = IWL_TI_1;
0264     else
0265         tt->state = IWL_TI_0;
0266 
0267 #ifdef CONFIG_IWLWIFI_DEBUG
0268     tt->tt_previous_temp = temp;
0269 #endif
0270     /* stop ct_kill_waiting_tm timer */
0271     del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
0272     if (tt->state != old_state) {
0273         switch (tt->state) {
0274         case IWL_TI_0:
0275             /*
0276              * When the system is ready to go back to IWL_TI_0
0277              * we only have to call iwl_power_update_mode() to
0278              * do so.
0279              */
0280             break;
0281         case IWL_TI_1:
0282             tt->tt_power_mode = IWL_POWER_INDEX_3;
0283             break;
0284         case IWL_TI_2:
0285             tt->tt_power_mode = IWL_POWER_INDEX_4;
0286             break;
0287         default:
0288             tt->tt_power_mode = IWL_POWER_INDEX_5;
0289             break;
0290         }
0291         mutex_lock(&priv->mutex);
0292         if (old_state == IWL_TI_CT_KILL)
0293             clear_bit(STATUS_CT_KILL, &priv->status);
0294         if (tt->state != IWL_TI_CT_KILL &&
0295             iwl_power_update_mode(priv, true)) {
0296             /* TT state not updated
0297              * try again during next temperature read
0298              */
0299             if (old_state == IWL_TI_CT_KILL)
0300                 set_bit(STATUS_CT_KILL, &priv->status);
0301             tt->state = old_state;
0302             IWL_ERR(priv, "Cannot update power mode, "
0303                     "TT state not updated\n");
0304         } else {
0305             if (tt->state == IWL_TI_CT_KILL) {
0306                 if (force) {
0307                     set_bit(STATUS_CT_KILL, &priv->status);
0308                     iwl_perform_ct_kill_task(priv, true);
0309                 } else {
0310                     iwl_prepare_ct_kill_task(priv);
0311                     tt->state = old_state;
0312                 }
0313             } else if (old_state == IWL_TI_CT_KILL) {
0314                 iwl_perform_ct_kill_task(priv, false);
0315             }
0316             IWL_DEBUG_TEMP(priv, "Temperature state changed %u\n",
0317                     tt->state);
0318             IWL_DEBUG_TEMP(priv, "Power Index change to %u\n",
0319                     tt->tt_power_mode);
0320         }
0321         mutex_unlock(&priv->mutex);
0322     }
0323 }
0324 
0325 /*
0326  * Advance thermal throttling
0327  * 1) Avoid NIC destruction due to high temperatures
0328  *  Chip will identify dangerously high temperatures that can
0329  *  harm the device and will power down
0330  * 2) Avoid the NIC power down due to high temperature
0331  *  Throttle early enough to lower the power consumption before
0332  *  drastic steps are needed
0333  *  Actions include relaxing the power down sleep thresholds and
0334  *  decreasing the number of TX streams
0335  * 3) Avoid throughput performance impact as much as possible
0336  *
0337  *=============================================================================
0338  *                 Condition Nxt State  Condition Nxt State Condition Nxt State
0339  *-----------------------------------------------------------------------------
0340  *     IWL_TI_0     T >= 114   CT_KILL  114>T>=105   TI_1      N/A      N/A
0341  *     IWL_TI_1     T >= 114   CT_KILL  114>T>=110   TI_2     T<=95     TI_0
0342  *     IWL_TI_2     T >= 114   CT_KILL                        T<=100    TI_1
0343  *    IWL_CT_KILL      N/A       N/A       N/A        N/A     T<=95     TI_0
0344  *=============================================================================
0345  */
0346 static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
0347 {
0348     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0349     int i;
0350     bool changed = false;
0351     enum iwl_tt_state old_state;
0352     struct iwl_tt_trans *transaction;
0353 
0354     old_state = tt->state;
0355     for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) {
0356         /* based on the current TT state,
0357          * find the curresponding transaction table
0358          * each table has (IWL_TI_STATE_MAX - 1) entries
0359          * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1))
0360          * will advance to the correct table.
0361          * then based on the current temperature
0362          * find the next state need to transaction to
0363          * go through all the possible (IWL_TI_STATE_MAX - 1) entries
0364          * in the current table to see if transaction is needed
0365          */
0366         transaction = tt->transaction +
0367             ((old_state * (IWL_TI_STATE_MAX - 1)) + i);
0368         if (temp >= transaction->tt_low &&
0369             temp <= transaction->tt_high) {
0370 #ifdef CONFIG_IWLWIFI_DEBUG
0371             if ((tt->tt_previous_temp) &&
0372                 (temp > tt->tt_previous_temp) &&
0373                 ((temp - tt->tt_previous_temp) >
0374                 IWL_TT_INCREASE_MARGIN)) {
0375                 IWL_DEBUG_TEMP(priv,
0376                     "Temperature increase %d "
0377                     "degree Celsius\n",
0378                     (temp - tt->tt_previous_temp));
0379             }
0380             tt->tt_previous_temp = temp;
0381 #endif
0382             if (old_state !=
0383                 transaction->next_state) {
0384                 changed = true;
0385                 tt->state =
0386                     transaction->next_state;
0387             }
0388             break;
0389         }
0390     }
0391     /* stop ct_kill_waiting_tm timer */
0392     del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
0393     if (changed) {
0394         if (tt->state >= IWL_TI_1) {
0395             /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
0396             tt->tt_power_mode = IWL_POWER_INDEX_5;
0397 
0398             if (!iwl_ht_enabled(priv)) {
0399                 struct iwl_rxon_context *ctx;
0400 
0401                 for_each_context(priv, ctx) {
0402                     struct iwl_rxon_cmd *rxon;
0403 
0404                     rxon = &ctx->staging;
0405 
0406                     /* disable HT */
0407                     rxon->flags &= ~(
0408                         RXON_FLG_CHANNEL_MODE_MSK |
0409                         RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
0410                         RXON_FLG_HT40_PROT_MSK |
0411                         RXON_FLG_HT_PROT_MSK);
0412                 }
0413             } else {
0414                 /* check HT capability and set
0415                  * according to the system HT capability
0416                  * in case get disabled before */
0417                 iwl_set_rxon_ht(priv, &priv->current_ht_config);
0418             }
0419 
0420         } else {
0421             /*
0422              * restore system power setting -- it will be
0423              * recalculated automatically.
0424              */
0425 
0426             /* check HT capability and set
0427              * according to the system HT capability
0428              * in case get disabled before */
0429             iwl_set_rxon_ht(priv, &priv->current_ht_config);
0430         }
0431         mutex_lock(&priv->mutex);
0432         if (old_state == IWL_TI_CT_KILL)
0433             clear_bit(STATUS_CT_KILL, &priv->status);
0434         if (tt->state != IWL_TI_CT_KILL &&
0435             iwl_power_update_mode(priv, true)) {
0436             /* TT state not updated
0437              * try again during next temperature read
0438              */
0439             IWL_ERR(priv, "Cannot update power mode, "
0440                     "TT state not updated\n");
0441             if (old_state == IWL_TI_CT_KILL)
0442                 set_bit(STATUS_CT_KILL, &priv->status);
0443             tt->state = old_state;
0444         } else {
0445             IWL_DEBUG_TEMP(priv,
0446                     "Thermal Throttling to new state: %u\n",
0447                     tt->state);
0448             if (old_state != IWL_TI_CT_KILL &&
0449                 tt->state == IWL_TI_CT_KILL) {
0450                 if (force) {
0451                     IWL_DEBUG_TEMP(priv,
0452                         "Enter IWL_TI_CT_KILL\n");
0453                     set_bit(STATUS_CT_KILL, &priv->status);
0454                     iwl_perform_ct_kill_task(priv, true);
0455                 } else {
0456                     tt->state = old_state;
0457                     iwl_prepare_ct_kill_task(priv);
0458                 }
0459             } else if (old_state == IWL_TI_CT_KILL &&
0460                   tt->state != IWL_TI_CT_KILL) {
0461                 IWL_DEBUG_TEMP(priv, "Exit IWL_TI_CT_KILL\n");
0462                 iwl_perform_ct_kill_task(priv, false);
0463             }
0464         }
0465         mutex_unlock(&priv->mutex);
0466     }
0467 }
0468 
0469 /* Card State Notification indicated reach critical temperature
0470  * if PSP not enable, no Thermal Throttling function will be performed
0471  * just set the GP1 bit to acknowledge the event
0472  * otherwise, go into IWL_TI_CT_KILL state
0473  * since Card State Notification will not provide any temperature reading
0474  * for Legacy mode
0475  * so just pass the CT_KILL temperature to iwl_legacy_tt_handler()
0476  * for advance mode
0477  * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state
0478  */
0479 static void iwl_bg_ct_enter(struct work_struct *work)
0480 {
0481     struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter);
0482     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0483 
0484     if (test_bit(STATUS_EXIT_PENDING, &priv->status))
0485         return;
0486 
0487     if (!iwl_is_ready(priv))
0488         return;
0489 
0490     if (tt->state != IWL_TI_CT_KILL) {
0491         IWL_ERR(priv, "Device reached critical temperature "
0492                   "- ucode going to sleep!\n");
0493         if (!priv->thermal_throttle.advanced_tt)
0494             iwl_legacy_tt_handler(priv,
0495                           IWL_MINIMAL_POWER_THRESHOLD,
0496                           true);
0497         else
0498             iwl_advance_tt_handler(priv,
0499                            CT_KILL_THRESHOLD + 1, true);
0500     }
0501 }
0502 
0503 /* Card State Notification indicated out of critical temperature
0504  * since Card State Notification will not provide any temperature reading
0505  * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature
0506  * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state
0507  */
0508 static void iwl_bg_ct_exit(struct work_struct *work)
0509 {
0510     struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit);
0511     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0512 
0513     if (test_bit(STATUS_EXIT_PENDING, &priv->status))
0514         return;
0515 
0516     if (!iwl_is_ready(priv))
0517         return;
0518 
0519     /* stop ct_kill_exit_tm timer */
0520     del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
0521 
0522     if (tt->state == IWL_TI_CT_KILL) {
0523         IWL_ERR(priv,
0524             "Device temperature below critical"
0525             "- ucode awake!\n");
0526         /*
0527          * exit from CT_KILL state
0528          * reset the current temperature reading
0529          */
0530         priv->temperature = 0;
0531         if (!priv->thermal_throttle.advanced_tt)
0532             iwl_legacy_tt_handler(priv,
0533                       IWL_REDUCED_PERFORMANCE_THRESHOLD_2,
0534                       true);
0535         else
0536             iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD,
0537                            true);
0538     }
0539 }
0540 
0541 void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
0542 {
0543     if (test_bit(STATUS_EXIT_PENDING, &priv->status))
0544         return;
0545 
0546     IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n");
0547     queue_work(priv->workqueue, &priv->ct_enter);
0548 }
0549 
0550 void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
0551 {
0552     if (test_bit(STATUS_EXIT_PENDING, &priv->status))
0553         return;
0554 
0555     IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n");
0556     queue_work(priv->workqueue, &priv->ct_exit);
0557 }
0558 
0559 static void iwl_bg_tt_work(struct work_struct *work)
0560 {
0561     struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
0562     s32 temp = priv->temperature; /* degrees CELSIUS except specified */
0563 
0564     if (test_bit(STATUS_EXIT_PENDING, &priv->status))
0565         return;
0566 
0567     if (!priv->thermal_throttle.advanced_tt)
0568         iwl_legacy_tt_handler(priv, temp, false);
0569     else
0570         iwl_advance_tt_handler(priv, temp, false);
0571 }
0572 
0573 void iwl_tt_handler(struct iwl_priv *priv)
0574 {
0575     if (test_bit(STATUS_EXIT_PENDING, &priv->status))
0576         return;
0577 
0578     IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n");
0579     queue_work(priv->workqueue, &priv->tt_work);
0580 }
0581 
0582 /* Thermal throttling initialization
0583  * For advance thermal throttling:
0584  *     Initialize Thermal Index and temperature threshold table
0585  *     Initialize thermal throttling restriction table
0586  */
0587 void iwl_tt_initialize(struct iwl_priv *priv)
0588 {
0589     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0590     int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);
0591     struct iwl_tt_trans *transaction;
0592 
0593     IWL_DEBUG_TEMP(priv, "Initialize Thermal Throttling\n");
0594 
0595     memset(tt, 0, sizeof(struct iwl_tt_mgmt));
0596 
0597     tt->state = IWL_TI_0;
0598     timer_setup(&priv->thermal_throttle.ct_kill_exit_tm,
0599             iwl_tt_check_exit_ct_kill, 0);
0600     timer_setup(&priv->thermal_throttle.ct_kill_waiting_tm,
0601             iwl_tt_ready_for_ct_kill, 0);
0602     /* setup deferred ct kill work */
0603     INIT_WORK(&priv->tt_work, iwl_bg_tt_work);
0604     INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
0605     INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
0606 
0607     if (priv->lib->adv_thermal_throttle) {
0608         IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n");
0609         tt->restriction = kcalloc(IWL_TI_STATE_MAX,
0610                       sizeof(struct iwl_tt_restriction),
0611                       GFP_KERNEL);
0612         tt->transaction = kcalloc(IWL_TI_STATE_MAX *
0613                       (IWL_TI_STATE_MAX - 1),
0614                       sizeof(struct iwl_tt_trans),
0615                       GFP_KERNEL);
0616         if (!tt->restriction || !tt->transaction) {
0617             IWL_ERR(priv, "Fallback to Legacy Throttling\n");
0618             priv->thermal_throttle.advanced_tt = false;
0619             kfree(tt->restriction);
0620             tt->restriction = NULL;
0621             kfree(tt->transaction);
0622             tt->transaction = NULL;
0623         } else {
0624             transaction = tt->transaction +
0625                 (IWL_TI_0 * (IWL_TI_STATE_MAX - 1));
0626             memcpy(transaction, &tt_range_0[0], size);
0627             transaction = tt->transaction +
0628                 (IWL_TI_1 * (IWL_TI_STATE_MAX - 1));
0629             memcpy(transaction, &tt_range_1[0], size);
0630             transaction = tt->transaction +
0631                 (IWL_TI_2 * (IWL_TI_STATE_MAX - 1));
0632             memcpy(transaction, &tt_range_2[0], size);
0633             transaction = tt->transaction +
0634                 (IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1));
0635             memcpy(transaction, &tt_range_3[0], size);
0636             size = sizeof(struct iwl_tt_restriction) *
0637                 IWL_TI_STATE_MAX;
0638             memcpy(tt->restriction,
0639                 &restriction_range[0], size);
0640             priv->thermal_throttle.advanced_tt = true;
0641         }
0642     } else {
0643         IWL_DEBUG_TEMP(priv, "Legacy Thermal Throttling\n");
0644         priv->thermal_throttle.advanced_tt = false;
0645     }
0646 }
0647 
0648 /* cleanup thermal throttling management related memory and timer */
0649 void iwl_tt_exit(struct iwl_priv *priv)
0650 {
0651     struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
0652 
0653     /* stop ct_kill_exit_tm timer if activated */
0654     del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
0655     /* stop ct_kill_waiting_tm timer if activated */
0656     del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
0657     cancel_work_sync(&priv->tt_work);
0658     cancel_work_sync(&priv->ct_enter);
0659     cancel_work_sync(&priv->ct_exit);
0660 
0661     if (priv->thermal_throttle.advanced_tt) {
0662         /* free advance thermal throttling memory */
0663         kfree(tt->restriction);
0664         tt->restriction = NULL;
0665         kfree(tt->transaction);
0666         tt->transaction = NULL;
0667     }
0668 }