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