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