brintos

brintos / linux-shallow public Read only

0
0
Text · 20.8 KiB · 43e8d04 Raw
669 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/******************************************************************************3 *4 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.5 * Copyright (C) 2018, 2020 Intel Corporation6 *7 * Portions of this file are derived from the ipw3945 project, as well8 * as portions of the ieee80211 subsystem header files.9 *****************************************************************************/10 11 12#include <linux/kernel.h>13#include <linux/module.h>14#include <linux/slab.h>15#include <net/mac80211.h>16#include "iwl-io.h"17#include "iwl-modparams.h"18#include "iwl-debug.h"19#include "agn.h"20#include "dev.h"21#include "commands.h"22#include "tt.h"23 24/* default Thermal Throttling transaction table25 * Current state   |         Throttling Down               |  Throttling Up26 *=============================================================================27 *                 Condition Nxt State  Condition Nxt State Condition Nxt State28 *-----------------------------------------------------------------------------29 *     IWL_TI_0     T >= 114   CT_KILL  114>T>=105   TI_1      N/A      N/A30 *     IWL_TI_1     T >= 114   CT_KILL  114>T>=110   TI_2     T<=95     TI_031 *     IWL_TI_2     T >= 114   CT_KILL                        T<=100    TI_132 *    IWL_CT_KILL      N/A       N/A       N/A        N/A     T<=95     TI_033 *=============================================================================34 */35static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = {36	{IWL_TI_0, IWL_ABSOLUTE_ZERO, 104},37	{IWL_TI_1, 105, CT_KILL_THRESHOLD - 1},38	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}39};40static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = {41	{IWL_TI_0, IWL_ABSOLUTE_ZERO, 95},42	{IWL_TI_2, 110, CT_KILL_THRESHOLD - 1},43	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}44};45static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = {46	{IWL_TI_1, IWL_ABSOLUTE_ZERO, 100},47	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX},48	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}49};50static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = {51	{IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD},52	{IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX},53	{IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}54};55 56/* Advance Thermal Throttling default restriction table */57static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = {58	{IWL_ANT_OK_MULTI, IWL_ANT_OK_MULTI, true },59	{IWL_ANT_OK_SINGLE, IWL_ANT_OK_MULTI, true },60	{IWL_ANT_OK_SINGLE, IWL_ANT_OK_SINGLE, false },61	{IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false }62};63 64bool iwl_tt_is_low_power_state(struct iwl_priv *priv)65{66	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;67 68	if (tt->state >= IWL_TI_1)69		return true;70	return false;71}72 73u8 iwl_tt_current_power_mode(struct iwl_priv *priv)74{75	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;76 77	return tt->tt_power_mode;78}79 80bool iwl_ht_enabled(struct iwl_priv *priv)81{82	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;83	struct iwl_tt_restriction *restriction;84 85	if (!priv->thermal_throttle.advanced_tt)86		return true;87	restriction = tt->restriction + tt->state;88	return restriction->is_ht;89}90 91static bool iwl_within_ct_kill_margin(struct iwl_priv *priv)92{93	s32 temp = priv->temperature; /* degrees CELSIUS except specified */94	bool within_margin = false;95 96	if (!priv->thermal_throttle.advanced_tt)97		within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=98				CT_KILL_THRESHOLD_LEGACY) ? true : false;99	else100		within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=101				CT_KILL_THRESHOLD) ? true : false;102	return within_margin;103}104 105bool iwl_check_for_ct_kill(struct iwl_priv *priv)106{107	bool is_ct_kill = false;108 109	if (iwl_within_ct_kill_margin(priv)) {110		iwl_tt_enter_ct_kill(priv);111		is_ct_kill = true;112	}113	return is_ct_kill;114}115 116enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv)117{118	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;119	struct iwl_tt_restriction *restriction;120 121	if (!priv->thermal_throttle.advanced_tt)122		return IWL_ANT_OK_MULTI;123	restriction = tt->restriction + tt->state;124	return restriction->tx_stream;125}126 127enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv)128{129	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;130	struct iwl_tt_restriction *restriction;131 132	if (!priv->thermal_throttle.advanced_tt)133		return IWL_ANT_OK_MULTI;134	restriction = tt->restriction + tt->state;135	return restriction->rx_stream;136}137 138#define CT_KILL_EXIT_DURATION (5)	/* 5 seconds duration */139#define CT_KILL_WAITING_DURATION (300)	/* 300ms duration */140 141/*142 * toggle the bit to wake up uCode and check the temperature143 * if the temperature is below CT, uCode will stay awake and send card144 * state notification with CT_KILL bit clear to inform Thermal Throttling145 * Management to change state. Otherwise, uCode will go back to sleep146 * without doing anything, driver should continue the 5 seconds timer147 * to wake up uCode for temperature check until temperature drop below CT148 */149static void iwl_tt_check_exit_ct_kill(struct timer_list *t)150{151	struct iwl_priv *priv = from_timer(priv, t,152					   thermal_throttle.ct_kill_exit_tm);153	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;154 155	if (test_bit(STATUS_EXIT_PENDING, &priv->status))156		return;157 158	if (tt->state == IWL_TI_CT_KILL) {159		if (priv->thermal_throttle.ct_kill_toggle) {160			iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,161				    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);162			priv->thermal_throttle.ct_kill_toggle = false;163		} else {164			iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET,165				    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);166			priv->thermal_throttle.ct_kill_toggle = true;167		}168		iwl_read32(priv->trans, CSR_UCODE_DRV_GP1);169		if (iwl_trans_grab_nic_access(priv->trans))170			iwl_trans_release_nic_access(priv->trans);171 172		/* Reschedule the ct_kill timer to occur in173		 * CT_KILL_EXIT_DURATION seconds to ensure we get a174		 * thermal update */175		IWL_DEBUG_TEMP(priv, "schedule ct_kill exit timer\n");176		mod_timer(&priv->thermal_throttle.ct_kill_exit_tm,177			  jiffies + CT_KILL_EXIT_DURATION * HZ);178	}179}180 181static void iwl_perform_ct_kill_task(struct iwl_priv *priv,182			   bool stop)183{184	if (stop) {185		IWL_DEBUG_TEMP(priv, "Stop all queues\n");186		if (priv->mac80211_registered)187			ieee80211_stop_queues(priv->hw);188		IWL_DEBUG_TEMP(priv,189				"Schedule 5 seconds CT_KILL Timer\n");190		mod_timer(&priv->thermal_throttle.ct_kill_exit_tm,191			  jiffies + CT_KILL_EXIT_DURATION * HZ);192	} else {193		IWL_DEBUG_TEMP(priv, "Wake all queues\n");194		if (priv->mac80211_registered)195			ieee80211_wake_queues(priv->hw);196	}197}198 199static void iwl_tt_ready_for_ct_kill(struct timer_list *t)200{201	struct iwl_priv *priv = from_timer(priv, t,202					   thermal_throttle.ct_kill_waiting_tm);203	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;204 205	if (test_bit(STATUS_EXIT_PENDING, &priv->status))206		return;207 208	/* temperature timer expired, ready to go into CT_KILL state */209	if (tt->state != IWL_TI_CT_KILL) {210		IWL_DEBUG_TEMP(priv, "entering CT_KILL state when "211				"temperature timer expired\n");212		tt->state = IWL_TI_CT_KILL;213		set_bit(STATUS_CT_KILL, &priv->status);214		iwl_perform_ct_kill_task(priv, true);215	}216}217 218static void iwl_prepare_ct_kill_task(struct iwl_priv *priv)219{220	IWL_DEBUG_TEMP(priv, "Prepare to enter IWL_TI_CT_KILL\n");221	/* make request to retrieve statistics information */222	iwl_send_statistics_request(priv, 0, false);223	/* Reschedule the ct_kill wait timer */224	mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm,225		 jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION));226}227 228#define IWL_MINIMAL_POWER_THRESHOLD		(CT_KILL_THRESHOLD_LEGACY)229#define IWL_REDUCED_PERFORMANCE_THRESHOLD_2	(100)230#define IWL_REDUCED_PERFORMANCE_THRESHOLD_1	(90)231 232/*233 * Legacy thermal throttling234 * 1) Avoid NIC destruction due to high temperatures235 *	Chip will identify dangerously high temperatures that can236 *	harm the device and will power down237 * 2) Avoid the NIC power down due to high temperature238 *	Throttle early enough to lower the power consumption before239 *	drastic steps are needed240 */241static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)242{243	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;244	enum iwl_tt_state old_state;245 246#ifdef CONFIG_IWLWIFI_DEBUG247	if ((tt->tt_previous_temp) &&248	    (temp > tt->tt_previous_temp) &&249	    ((temp - tt->tt_previous_temp) >250	    IWL_TT_INCREASE_MARGIN)) {251		IWL_DEBUG_TEMP(priv,252			"Temperature increase %d degree Celsius\n",253			(temp - tt->tt_previous_temp));254	}255#endif256	old_state = tt->state;257	/* in Celsius */258	if (temp >= IWL_MINIMAL_POWER_THRESHOLD)259		tt->state = IWL_TI_CT_KILL;260	else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2)261		tt->state = IWL_TI_2;262	else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1)263		tt->state = IWL_TI_1;264	else265		tt->state = IWL_TI_0;266 267#ifdef CONFIG_IWLWIFI_DEBUG268	tt->tt_previous_temp = temp;269#endif270	/* stop ct_kill_waiting_tm timer */271	del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);272	if (tt->state != old_state) {273		switch (tt->state) {274		case IWL_TI_0:275			/*276			 * When the system is ready to go back to IWL_TI_0277			 * we only have to call iwl_power_update_mode() to278			 * do so.279			 */280			break;281		case IWL_TI_1:282			tt->tt_power_mode = IWL_POWER_INDEX_3;283			break;284		case IWL_TI_2:285			tt->tt_power_mode = IWL_POWER_INDEX_4;286			break;287		default:288			tt->tt_power_mode = IWL_POWER_INDEX_5;289			break;290		}291		mutex_lock(&priv->mutex);292		if (old_state == IWL_TI_CT_KILL)293			clear_bit(STATUS_CT_KILL, &priv->status);294		if (tt->state != IWL_TI_CT_KILL &&295		    iwl_power_update_mode(priv, true)) {296			/* TT state not updated297			 * try again during next temperature read298			 */299			if (old_state == IWL_TI_CT_KILL)300				set_bit(STATUS_CT_KILL, &priv->status);301			tt->state = old_state;302			IWL_ERR(priv, "Cannot update power mode, "303					"TT state not updated\n");304		} else {305			if (tt->state == IWL_TI_CT_KILL) {306				if (force) {307					set_bit(STATUS_CT_KILL, &priv->status);308					iwl_perform_ct_kill_task(priv, true);309				} else {310					iwl_prepare_ct_kill_task(priv);311					tt->state = old_state;312				}313			} else if (old_state == IWL_TI_CT_KILL) {314				iwl_perform_ct_kill_task(priv, false);315			}316			IWL_DEBUG_TEMP(priv, "Temperature state changed %u\n",317					tt->state);318			IWL_DEBUG_TEMP(priv, "Power Index change to %u\n",319					tt->tt_power_mode);320		}321		mutex_unlock(&priv->mutex);322	}323}324 325/*326 * Advance thermal throttling327 * 1) Avoid NIC destruction due to high temperatures328 *	Chip will identify dangerously high temperatures that can329 *	harm the device and will power down330 * 2) Avoid the NIC power down due to high temperature331 *	Throttle early enough to lower the power consumption before332 *	drastic steps are needed333 *	Actions include relaxing the power down sleep thresholds and334 *	decreasing the number of TX streams335 * 3) Avoid throughput performance impact as much as possible336 *337 *=============================================================================338 *                 Condition Nxt State  Condition Nxt State Condition Nxt State339 *-----------------------------------------------------------------------------340 *     IWL_TI_0     T >= 114   CT_KILL  114>T>=105   TI_1      N/A      N/A341 *     IWL_TI_1     T >= 114   CT_KILL  114>T>=110   TI_2     T<=95     TI_0342 *     IWL_TI_2     T >= 114   CT_KILL                        T<=100    TI_1343 *    IWL_CT_KILL      N/A       N/A       N/A        N/A     T<=95     TI_0344 *=============================================================================345 */346static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)347{348	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;349	int i;350	bool changed = false;351	enum iwl_tt_state old_state;352	struct iwl_tt_trans *transaction;353 354	old_state = tt->state;355	for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) {356		/* based on the current TT state,357		 * find the curresponding transaction table358		 * each table has (IWL_TI_STATE_MAX - 1) entries359		 * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1))360		 * will advance to the correct table.361		 * then based on the current temperature362		 * find the next state need to transaction to363		 * go through all the possible (IWL_TI_STATE_MAX - 1) entries364		 * in the current table to see if transaction is needed365		 */366		transaction = tt->transaction +367			((old_state * (IWL_TI_STATE_MAX - 1)) + i);368		if (temp >= transaction->tt_low &&369		    temp <= transaction->tt_high) {370#ifdef CONFIG_IWLWIFI_DEBUG371			if ((tt->tt_previous_temp) &&372			    (temp > tt->tt_previous_temp) &&373			    ((temp - tt->tt_previous_temp) >374			    IWL_TT_INCREASE_MARGIN)) {375				IWL_DEBUG_TEMP(priv,376					"Temperature increase %d "377					"degree Celsius\n",378					(temp - tt->tt_previous_temp));379			}380			tt->tt_previous_temp = temp;381#endif382			if (old_state !=383			    transaction->next_state) {384				changed = true;385				tt->state =386					transaction->next_state;387			}388			break;389		}390	}391	/* stop ct_kill_waiting_tm timer */392	del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);393	if (changed) {394		if (tt->state >= IWL_TI_1) {395			/* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */396			tt->tt_power_mode = IWL_POWER_INDEX_5;397 398			if (!iwl_ht_enabled(priv)) {399				struct iwl_rxon_context *ctx;400 401				for_each_context(priv, ctx) {402					struct iwl_rxon_cmd *rxon;403 404					rxon = &ctx->staging;405 406					/* disable HT */407					rxon->flags &= ~(408						RXON_FLG_CHANNEL_MODE_MSK |409						RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |410						RXON_FLG_HT40_PROT_MSK |411						RXON_FLG_HT_PROT_MSK);412				}413			} else {414				/* check HT capability and set415				 * according to the system HT capability416				 * in case get disabled before */417				iwl_set_rxon_ht(priv, &priv->current_ht_config);418			}419 420		} else {421			/*422			 * restore system power setting -- it will be423			 * recalculated automatically.424			 */425 426			/* check HT capability and set427			 * according to the system HT capability428			 * in case get disabled before */429			iwl_set_rxon_ht(priv, &priv->current_ht_config);430		}431		mutex_lock(&priv->mutex);432		if (old_state == IWL_TI_CT_KILL)433			clear_bit(STATUS_CT_KILL, &priv->status);434		if (tt->state != IWL_TI_CT_KILL &&435		    iwl_power_update_mode(priv, true)) {436			/* TT state not updated437			 * try again during next temperature read438			 */439			IWL_ERR(priv, "Cannot update power mode, "440					"TT state not updated\n");441			if (old_state == IWL_TI_CT_KILL)442				set_bit(STATUS_CT_KILL, &priv->status);443			tt->state = old_state;444		} else {445			IWL_DEBUG_TEMP(priv,446					"Thermal Throttling to new state: %u\n",447					tt->state);448			if (old_state != IWL_TI_CT_KILL &&449			    tt->state == IWL_TI_CT_KILL) {450				if (force) {451					IWL_DEBUG_TEMP(priv,452						"Enter IWL_TI_CT_KILL\n");453					set_bit(STATUS_CT_KILL, &priv->status);454					iwl_perform_ct_kill_task(priv, true);455				} else {456					tt->state = old_state;457					iwl_prepare_ct_kill_task(priv);458				}459			} else if (old_state == IWL_TI_CT_KILL &&460				  tt->state != IWL_TI_CT_KILL) {461				IWL_DEBUG_TEMP(priv, "Exit IWL_TI_CT_KILL\n");462				iwl_perform_ct_kill_task(priv, false);463			}464		}465		mutex_unlock(&priv->mutex);466	}467}468 469/* Card State Notification indicated reach critical temperature470 * if PSP not enable, no Thermal Throttling function will be performed471 * just set the GP1 bit to acknowledge the event472 * otherwise, go into IWL_TI_CT_KILL state473 * since Card State Notification will not provide any temperature reading474 * for Legacy mode475 * so just pass the CT_KILL temperature to iwl_legacy_tt_handler()476 * for advance mode477 * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state478 */479static void iwl_bg_ct_enter(struct work_struct *work)480{481	struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter);482	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;483 484	if (test_bit(STATUS_EXIT_PENDING, &priv->status))485		return;486 487	if (!iwl_is_ready(priv))488		return;489 490	if (tt->state != IWL_TI_CT_KILL) {491		IWL_ERR(priv, "Device reached critical temperature "492			      "- ucode going to sleep!\n");493		if (!priv->thermal_throttle.advanced_tt)494			iwl_legacy_tt_handler(priv,495					      IWL_MINIMAL_POWER_THRESHOLD,496					      true);497		else498			iwl_advance_tt_handler(priv,499					       CT_KILL_THRESHOLD + 1, true);500	}501}502 503/* Card State Notification indicated out of critical temperature504 * since Card State Notification will not provide any temperature reading505 * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature506 * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state507 */508static void iwl_bg_ct_exit(struct work_struct *work)509{510	struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit);511	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;512 513	if (test_bit(STATUS_EXIT_PENDING, &priv->status))514		return;515 516	if (!iwl_is_ready(priv))517		return;518 519	/* stop ct_kill_exit_tm timer */520	del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);521 522	if (tt->state == IWL_TI_CT_KILL) {523		IWL_ERR(priv,524			"Device temperature below critical"525			"- ucode awake!\n");526		/*527		 * exit from CT_KILL state528		 * reset the current temperature reading529		 */530		priv->temperature = 0;531		if (!priv->thermal_throttle.advanced_tt)532			iwl_legacy_tt_handler(priv,533				      IWL_REDUCED_PERFORMANCE_THRESHOLD_2,534				      true);535		else536			iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD,537					       true);538	}539}540 541void iwl_tt_enter_ct_kill(struct iwl_priv *priv)542{543	if (test_bit(STATUS_EXIT_PENDING, &priv->status))544		return;545 546	IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n");547	queue_work(priv->workqueue, &priv->ct_enter);548}549 550void iwl_tt_exit_ct_kill(struct iwl_priv *priv)551{552	if (test_bit(STATUS_EXIT_PENDING, &priv->status))553		return;554 555	IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n");556	queue_work(priv->workqueue, &priv->ct_exit);557}558 559static void iwl_bg_tt_work(struct work_struct *work)560{561	struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);562	s32 temp = priv->temperature; /* degrees CELSIUS except specified */563 564	if (test_bit(STATUS_EXIT_PENDING, &priv->status))565		return;566 567	if (!priv->thermal_throttle.advanced_tt)568		iwl_legacy_tt_handler(priv, temp, false);569	else570		iwl_advance_tt_handler(priv, temp, false);571}572 573void iwl_tt_handler(struct iwl_priv *priv)574{575	if (test_bit(STATUS_EXIT_PENDING, &priv->status))576		return;577 578	IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n");579	queue_work(priv->workqueue, &priv->tt_work);580}581 582/* Thermal throttling initialization583 * For advance thermal throttling:584 *     Initialize Thermal Index and temperature threshold table585 *     Initialize thermal throttling restriction table586 */587void iwl_tt_initialize(struct iwl_priv *priv)588{589	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;590	int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);591	struct iwl_tt_trans *transaction;592 593	IWL_DEBUG_TEMP(priv, "Initialize Thermal Throttling\n");594 595	memset(tt, 0, sizeof(struct iwl_tt_mgmt));596 597	tt->state = IWL_TI_0;598	timer_setup(&priv->thermal_throttle.ct_kill_exit_tm,599		    iwl_tt_check_exit_ct_kill, 0);600	timer_setup(&priv->thermal_throttle.ct_kill_waiting_tm,601		    iwl_tt_ready_for_ct_kill, 0);602	/* setup deferred ct kill work */603	INIT_WORK(&priv->tt_work, iwl_bg_tt_work);604	INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);605	INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);606 607	if (priv->lib->adv_thermal_throttle) {608		IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n");609		tt->restriction = kcalloc(IWL_TI_STATE_MAX,610					  sizeof(struct iwl_tt_restriction),611					  GFP_KERNEL);612		tt->transaction = kcalloc(IWL_TI_STATE_MAX *613					  (IWL_TI_STATE_MAX - 1),614					  sizeof(struct iwl_tt_trans),615					  GFP_KERNEL);616		if (!tt->restriction || !tt->transaction) {617			IWL_ERR(priv, "Fallback to Legacy Throttling\n");618			priv->thermal_throttle.advanced_tt = false;619			kfree(tt->restriction);620			tt->restriction = NULL;621			kfree(tt->transaction);622			tt->transaction = NULL;623		} else {624			transaction = tt->transaction +625				(IWL_TI_0 * (IWL_TI_STATE_MAX - 1));626			memcpy(transaction, &tt_range_0[0], size);627			transaction = tt->transaction +628				(IWL_TI_1 * (IWL_TI_STATE_MAX - 1));629			memcpy(transaction, &tt_range_1[0], size);630			transaction = tt->transaction +631				(IWL_TI_2 * (IWL_TI_STATE_MAX - 1));632			memcpy(transaction, &tt_range_2[0], size);633			transaction = tt->transaction +634				(IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1));635			memcpy(transaction, &tt_range_3[0], size);636			size = sizeof(struct iwl_tt_restriction) *637				IWL_TI_STATE_MAX;638			memcpy(tt->restriction,639				&restriction_range[0], size);640			priv->thermal_throttle.advanced_tt = true;641		}642	} else {643		IWL_DEBUG_TEMP(priv, "Legacy Thermal Throttling\n");644		priv->thermal_throttle.advanced_tt = false;645	}646}647 648/* cleanup thermal throttling management related memory and timer */649void iwl_tt_exit(struct iwl_priv *priv)650{651	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;652 653	/* stop ct_kill_exit_tm timer if activated */654	del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);655	/* stop ct_kill_waiting_tm timer if activated */656	del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);657	cancel_work_sync(&priv->tt_work);658	cancel_work_sync(&priv->ct_enter);659	cancel_work_sync(&priv->ct_exit);660 661	if (priv->thermal_throttle.advanced_tt) {662		/* free advance thermal throttling memory */663		kfree(tt->restriction);664		tt->restriction = NULL;665		kfree(tt->transaction);666		tt->transaction = NULL;667	}668}669