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