linux/drivers/net/wireless/iwlwifi/iwl-power.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
   4 *
   5 * Portions of this file are derived from the ipw3945 project, as well
   6 * as portions of the ieee80211 subsystem header files.
   7 *
   8 * This program is free software; you can redistribute it and/or modify it
   9 * under the terms of version 2 of the GNU General Public License as
  10 * published by the Free Software Foundation.
  11 *
  12 * This program is distributed in the hope that it will be useful, but WITHOUT
  13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  15 * more details.
  16 *
  17 * You should have received a copy of the GNU General Public License along with
  18 * this program; if not, write to the Free Software Foundation, Inc.,
  19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  20 *
  21 * The full GNU General Public License is included in this distribution in the
  22 * file called LICENSE.
  23 *
  24 * Contact Information:
  25 *  Intel Linux Wireless <ilw@linux.intel.com>
  26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  27 *****************************************************************************/
  28
  29
  30#include <linux/kernel.h>
  31#include <linux/module.h>
  32#include <linux/init.h>
  33
  34#include <net/mac80211.h>
  35
  36#include "iwl-eeprom.h"
  37#include "iwl-dev.h"
  38#include "iwl-core.h"
  39#include "iwl-io.h"
  40#include "iwl-commands.h"
  41#include "iwl-debug.h"
  42#include "iwl-power.h"
  43
  44/*
  45 * Setting power level allows the card to go to sleep when not busy.
  46 *
  47 * We calculate a sleep command based on the required latency, which
  48 * we get from mac80211. In order to handle thermal throttling, we can
  49 * also use pre-defined power levels.
  50 */
  51
  52/*
  53 * For now, keep using power level 1 instead of automatically
  54 * adjusting ...
  55 */
  56bool no_sleep_autoadjust = true;
  57module_param(no_sleep_autoadjust, bool, S_IRUGO);
  58MODULE_PARM_DESC(no_sleep_autoadjust,
  59                 "don't automatically adjust sleep level "
  60                 "according to maximum network latency");
  61
  62/*
  63 * This defines the old power levels. They are still used by default
  64 * (level 1) and for thermal throttle (levels 3 through 5)
  65 */
  66
  67struct iwl_power_vec_entry {
  68        struct iwl_powertable_cmd cmd;
  69        u8 no_dtim;
  70};
  71
  72#define IWL_DTIM_RANGE_0_MAX    2
  73#define IWL_DTIM_RANGE_1_MAX    10
  74
  75#define NOSLP cpu_to_le16(0), 0, 0
  76#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
  77#define TU_TO_USEC 1024
  78#define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC)
  79#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
  80                                     cpu_to_le32(X1), \
  81                                     cpu_to_le32(X2), \
  82                                     cpu_to_le32(X3), \
  83                                     cpu_to_le32(X4)}
  84/* default power management (not Tx power) table values */
  85/* for DTIM period 0 through IWL_DTIM_RANGE_0_MAX */
  86static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = {
  87        {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
  88        {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
  89        {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF)}, 0},
  90        {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 2, 4, 4, 0xFF)}, 1},
  91        {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 2, 4, 6, 0xFF)}, 2}
  92};
  93
  94
  95/* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */
  96static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = {
  97        {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
  98        {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
  99        {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9)}, 0},
 100        {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 4, 6, 9, 10)}, 1},
 101        {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2}
 102};
 103
 104/* for DTIM period > IWL_DTIM_RANGE_1_MAX */
 105static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
 106        {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
 107        {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
 108        {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
 109        {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
 110        {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
 111};
 112
 113static void iwl_static_sleep_cmd(struct iwl_priv *priv,
 114                                 struct iwl_powertable_cmd *cmd,
 115                                 enum iwl_power_level lvl, int period)
 116{
 117        const struct iwl_power_vec_entry *table;
 118        int max_sleep, i;
 119        bool skip;
 120
 121        table = range_2;
 122        if (period < IWL_DTIM_RANGE_1_MAX)
 123                table = range_1;
 124        if (period < IWL_DTIM_RANGE_0_MAX)
 125                table = range_0;
 126
 127        BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM);
 128
 129        *cmd = table[lvl].cmd;
 130
 131        if (period == 0) {
 132                skip = false;
 133                period = 1;
 134        } else {
 135                skip = !!table[lvl].no_dtim;
 136        }
 137
 138        if (skip) {
 139                __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
 140                max_sleep = le32_to_cpu(slp_itrvl);
 141                if (max_sleep == 0xFF)
 142                        max_sleep = period * (skip + 1);
 143                else if (max_sleep > period)
 144                        max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
 145                cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
 146        } else {
 147                max_sleep = period;
 148                cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
 149        }
 150
 151        for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
 152                if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
 153                        cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
 154
 155        if (priv->power_data.pci_pm)
 156                cmd->flags |= IWL_POWER_PCI_PM_MSK;
 157        else
 158                cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
 159
 160        IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1);
 161}
 162
 163/* default Thermal Throttling transaction table
 164 * Current state   |         Throttling Down               |  Throttling Up
 165 *=============================================================================
 166 *                 Condition Nxt State  Condition Nxt State Condition Nxt State
 167 *-----------------------------------------------------------------------------
 168 *     IWL_TI_0     T >= 115   CT_KILL  115>T>=105   TI_1      N/A      N/A
 169 *     IWL_TI_1     T >= 115   CT_KILL  115>T>=110   TI_2     T<=95     TI_0
 170 *     IWL_TI_2     T >= 115   CT_KILL                        T<=100    TI_1
 171 *    IWL_CT_KILL      N/A       N/A       N/A        N/A     T<=95     TI_0
 172 *=============================================================================
 173 */
 174static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = {
 175        {IWL_TI_0, IWL_ABSOLUTE_ZERO, 104},
 176        {IWL_TI_1, 105, CT_KILL_THRESHOLD},
 177        {IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
 178};
 179static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = {
 180        {IWL_TI_0, IWL_ABSOLUTE_ZERO, 95},
 181        {IWL_TI_2, 110, CT_KILL_THRESHOLD},
 182        {IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
 183};
 184static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = {
 185        {IWL_TI_1, IWL_ABSOLUTE_ZERO, 100},
 186        {IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX},
 187        {IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
 188};
 189static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = {
 190        {IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD},
 191        {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX},
 192        {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
 193};
 194
 195/* Advance Thermal Throttling default restriction table */
 196static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = {
 197        {IWL_ANT_OK_MULTI, IWL_ANT_OK_MULTI, true },
 198        {IWL_ANT_OK_SINGLE, IWL_ANT_OK_MULTI, true },
 199        {IWL_ANT_OK_SINGLE, IWL_ANT_OK_SINGLE, false },
 200        {IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false }
 201};
 202
 203
 204static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv,
 205                                    struct iwl_powertable_cmd *cmd)
 206{
 207        memset(cmd, 0, sizeof(*cmd));
 208
 209        if (priv->power_data.pci_pm)
 210                cmd->flags |= IWL_POWER_PCI_PM_MSK;
 211
 212        IWL_DEBUG_POWER(priv, "Sleep command for CAM\n");
 213}
 214
 215static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv,
 216                                     struct iwl_powertable_cmd *cmd,
 217                                     int dynps_ms, int wakeup_period)
 218{
 219        /*
 220         * These are the original power level 3 sleep successions. The
 221         * device may behave better with such succession and was also
 222         * only tested with that. Just like the original sleep commands,
 223         * also adjust the succession here to the wakeup_period below.
 224         * The ranges are the same as for the sleep commands, 0-2, 3-9
 225         * and >10, which is selected based on the DTIM interval for
 226         * the sleep index but here we use the wakeup period since that
 227         * is what we need to do for the latency requirements.
 228         */
 229        static const u8 slp_succ_r0[IWL_POWER_VEC_SIZE] = { 2, 2, 2, 2, 2 };
 230        static const u8 slp_succ_r1[IWL_POWER_VEC_SIZE] = { 2, 4, 6, 7, 9 };
 231        static const u8 slp_succ_r2[IWL_POWER_VEC_SIZE] = { 2, 7, 9, 9, 0xFF };
 232        const u8 *slp_succ = slp_succ_r0;
 233        int i;
 234
 235        if (wakeup_period > IWL_DTIM_RANGE_0_MAX)
 236                slp_succ = slp_succ_r1;
 237        if (wakeup_period > IWL_DTIM_RANGE_1_MAX)
 238                slp_succ = slp_succ_r2;
 239
 240        memset(cmd, 0, sizeof(*cmd));
 241
 242        cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK |
 243                     IWL_POWER_FAST_PD; /* no use seeing frames for others */
 244
 245        if (priv->power_data.pci_pm)
 246                cmd->flags |= IWL_POWER_PCI_PM_MSK;
 247
 248        cmd->rx_data_timeout = cpu_to_le32(1000 * dynps_ms);
 249        cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms);
 250
 251        for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
 252                cmd->sleep_interval[i] =
 253                        cpu_to_le32(min_t(int, slp_succ[i], wakeup_period));
 254
 255        IWL_DEBUG_POWER(priv, "Automatic sleep command\n");
 256}
 257
 258static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
 259{
 260        IWL_DEBUG_POWER(priv, "Sending power/sleep command\n");
 261        IWL_DEBUG_POWER(priv, "Flags value = 0x%08X\n", cmd->flags);
 262        IWL_DEBUG_POWER(priv, "Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
 263        IWL_DEBUG_POWER(priv, "Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
 264        IWL_DEBUG_POWER(priv, "Sleep interval vector = { %d , %d , %d , %d , %d }\n",
 265                        le32_to_cpu(cmd->sleep_interval[0]),
 266                        le32_to_cpu(cmd->sleep_interval[1]),
 267                        le32_to_cpu(cmd->sleep_interval[2]),
 268                        le32_to_cpu(cmd->sleep_interval[3]),
 269                        le32_to_cpu(cmd->sleep_interval[4]));
 270
 271        return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,
 272                                sizeof(struct iwl_powertable_cmd), cmd);
 273}
 274
 275
 276int iwl_power_update_mode(struct iwl_priv *priv, bool force)
 277{
 278        int ret = 0;
 279        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 280        bool enabled = (priv->iw_mode == NL80211_IFTYPE_STATION) &&
 281                        (priv->hw->conf.flags & IEEE80211_CONF_PS);
 282        bool update_chains;
 283        struct iwl_powertable_cmd cmd;
 284        int dtimper;
 285
 286        /* Don't update the RX chain when chain noise calibration is running */
 287        update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
 288                        priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
 289
 290        if (priv->vif)
 291                dtimper = priv->vif->bss_conf.dtim_period;
 292        else
 293                dtimper = 1;
 294
 295        if (priv->cfg->broken_powersave)
 296                iwl_power_sleep_cam_cmd(priv, &cmd);
 297        else if (tt->state >= IWL_TI_1)
 298                iwl_static_sleep_cmd(priv, &cmd, tt->tt_power_mode, dtimper);
 299        else if (!enabled)
 300                iwl_power_sleep_cam_cmd(priv, &cmd);
 301        else if (priv->power_data.debug_sleep_level_override >= 0)
 302                iwl_static_sleep_cmd(priv, &cmd,
 303                                     priv->power_data.debug_sleep_level_override,
 304                                     dtimper);
 305        else if (no_sleep_autoadjust)
 306                iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_1, dtimper);
 307        else
 308                iwl_power_fill_sleep_cmd(priv, &cmd,
 309                                         priv->hw->conf.dynamic_ps_timeout,
 310                                         priv->hw->conf.max_sleep_period);
 311
 312        if (iwl_is_ready_rf(priv) &&
 313            (memcmp(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd)) || force)) {
 314                if (cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)
 315                        set_bit(STATUS_POWER_PMI, &priv->status);
 316
 317                ret = iwl_set_power(priv, &cmd);
 318                if (!ret) {
 319                        if (!(cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK))
 320                                clear_bit(STATUS_POWER_PMI, &priv->status);
 321
 322                        if (priv->cfg->ops->lib->update_chain_flags &&
 323                            update_chains)
 324                                priv->cfg->ops->lib->update_chain_flags(priv);
 325                        else if (priv->cfg->ops->lib->update_chain_flags)
 326                                IWL_DEBUG_POWER(priv,
 327                                        "Cannot update the power, chain noise "
 328                                        "calibration running: %d\n",
 329                                        priv->chain_noise_data.state);
 330                        memcpy(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd));
 331                } else
 332                        IWL_ERR(priv, "set power fail, ret = %d", ret);
 333        }
 334
 335        return ret;
 336}
 337EXPORT_SYMBOL(iwl_power_update_mode);
 338
 339bool iwl_ht_enabled(struct iwl_priv *priv)
 340{
 341        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 342        struct iwl_tt_restriction *restriction;
 343
 344        if (!priv->thermal_throttle.advanced_tt)
 345                return true;
 346        restriction = tt->restriction + tt->state;
 347        return restriction->is_ht;
 348}
 349EXPORT_SYMBOL(iwl_ht_enabled);
 350
 351enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv)
 352{
 353        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 354        struct iwl_tt_restriction *restriction;
 355
 356        if (!priv->thermal_throttle.advanced_tt)
 357                return IWL_ANT_OK_MULTI;
 358        restriction = tt->restriction + tt->state;
 359        return restriction->tx_stream;
 360}
 361EXPORT_SYMBOL(iwl_tx_ant_restriction);
 362
 363enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv)
 364{
 365        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 366        struct iwl_tt_restriction *restriction;
 367
 368        if (!priv->thermal_throttle.advanced_tt)
 369                return IWL_ANT_OK_MULTI;
 370        restriction = tt->restriction + tt->state;
 371        return restriction->rx_stream;
 372}
 373
 374#define CT_KILL_EXIT_DURATION (5)       /* 5 seconds duration */
 375
 376/*
 377 * toggle the bit to wake up uCode and check the temperature
 378 * if the temperature is below CT, uCode will stay awake and send card
 379 * state notification with CT_KILL bit clear to inform Thermal Throttling
 380 * Management to change state. Otherwise, uCode will go back to sleep
 381 * without doing anything, driver should continue the 5 seconds timer
 382 * to wake up uCode for temperature check until temperature drop below CT
 383 */
 384static void iwl_tt_check_exit_ct_kill(unsigned long data)
 385{
 386        struct iwl_priv *priv = (struct iwl_priv *)data;
 387        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 388        unsigned long flags;
 389
 390        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 391                return;
 392
 393        if (tt->state == IWL_TI_CT_KILL) {
 394                if (priv->thermal_throttle.ct_kill_toggle) {
 395                        iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
 396                                    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
 397                        priv->thermal_throttle.ct_kill_toggle = false;
 398                } else {
 399                        iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
 400                                    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
 401                        priv->thermal_throttle.ct_kill_toggle = true;
 402                }
 403                iwl_read32(priv, CSR_UCODE_DRV_GP1);
 404                spin_lock_irqsave(&priv->reg_lock, flags);
 405                if (!iwl_grab_nic_access(priv))
 406                        iwl_release_nic_access(priv);
 407                spin_unlock_irqrestore(&priv->reg_lock, flags);
 408
 409                /* Reschedule the ct_kill timer to occur in
 410                 * CT_KILL_EXIT_DURATION seconds to ensure we get a
 411                 * thermal update */
 412                mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies +
 413                          CT_KILL_EXIT_DURATION * HZ);
 414        }
 415}
 416
 417static void iwl_perform_ct_kill_task(struct iwl_priv *priv,
 418                           bool stop)
 419{
 420        if (stop) {
 421                IWL_DEBUG_POWER(priv, "Stop all queues\n");
 422                if (priv->mac80211_registered)
 423                        ieee80211_stop_queues(priv->hw);
 424                IWL_DEBUG_POWER(priv,
 425                                "Schedule 5 seconds CT_KILL Timer\n");
 426                mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies +
 427                          CT_KILL_EXIT_DURATION * HZ);
 428        } else {
 429                IWL_DEBUG_POWER(priv, "Wake all queues\n");
 430                if (priv->mac80211_registered)
 431                        ieee80211_wake_queues(priv->hw);
 432        }
 433}
 434
 435#define IWL_MINIMAL_POWER_THRESHOLD             (CT_KILL_THRESHOLD_LEGACY)
 436#define IWL_REDUCED_PERFORMANCE_THRESHOLD_2     (100)
 437#define IWL_REDUCED_PERFORMANCE_THRESHOLD_1     (90)
 438
 439/*
 440 * Legacy thermal throttling
 441 * 1) Avoid NIC destruction due to high temperatures
 442 *      Chip will identify dangerously high temperatures that can
 443 *      harm the device and will power down
 444 * 2) Avoid the NIC power down due to high temperature
 445 *      Throttle early enough to lower the power consumption before
 446 *      drastic steps are needed
 447 */
 448static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp)
 449{
 450        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 451        enum iwl_tt_state old_state;
 452
 453#ifdef CONFIG_IWLWIFI_DEBUG
 454        if ((tt->tt_previous_temp) &&
 455            (temp > tt->tt_previous_temp) &&
 456            ((temp - tt->tt_previous_temp) >
 457            IWL_TT_INCREASE_MARGIN)) {
 458                IWL_DEBUG_POWER(priv,
 459                        "Temperature increase %d degree Celsius\n",
 460                        (temp - tt->tt_previous_temp));
 461        }
 462#endif
 463        old_state = tt->state;
 464        /* in Celsius */
 465        if (temp >= IWL_MINIMAL_POWER_THRESHOLD)
 466                tt->state = IWL_TI_CT_KILL;
 467        else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2)
 468                tt->state = IWL_TI_2;
 469        else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1)
 470                tt->state = IWL_TI_1;
 471        else
 472                tt->state = IWL_TI_0;
 473
 474#ifdef CONFIG_IWLWIFI_DEBUG
 475        tt->tt_previous_temp = temp;
 476#endif
 477        if (tt->state != old_state) {
 478                switch (tt->state) {
 479                case IWL_TI_0:
 480                        /*
 481                         * When the system is ready to go back to IWL_TI_0
 482                         * we only have to call iwl_power_update_mode() to
 483                         * do so.
 484                         */
 485                        break;
 486                case IWL_TI_1:
 487                        tt->tt_power_mode = IWL_POWER_INDEX_3;
 488                        break;
 489                case IWL_TI_2:
 490                        tt->tt_power_mode = IWL_POWER_INDEX_4;
 491                        break;
 492                default:
 493                        tt->tt_power_mode = IWL_POWER_INDEX_5;
 494                        break;
 495                }
 496                mutex_lock(&priv->mutex);
 497                if (iwl_power_update_mode(priv, true)) {
 498                        /* TT state not updated
 499                         * try again during next temperature read
 500                         */
 501                        tt->state = old_state;
 502                        IWL_ERR(priv, "Cannot update power mode, "
 503                                        "TT state not updated\n");
 504                } else {
 505                        if (tt->state == IWL_TI_CT_KILL)
 506                                iwl_perform_ct_kill_task(priv, true);
 507                        else if (old_state == IWL_TI_CT_KILL &&
 508                                 tt->state != IWL_TI_CT_KILL)
 509                                iwl_perform_ct_kill_task(priv, false);
 510                        IWL_DEBUG_POWER(priv, "Temperature state changed %u\n",
 511                                        tt->state);
 512                        IWL_DEBUG_POWER(priv, "Power Index change to %u\n",
 513                                        tt->tt_power_mode);
 514                }
 515                mutex_unlock(&priv->mutex);
 516        }
 517}
 518
 519/*
 520 * Advance thermal throttling
 521 * 1) Avoid NIC destruction due to high temperatures
 522 *      Chip will identify dangerously high temperatures that can
 523 *      harm the device and will power down
 524 * 2) Avoid the NIC power down due to high temperature
 525 *      Throttle early enough to lower the power consumption before
 526 *      drastic steps are needed
 527 *      Actions include relaxing the power down sleep thresholds and
 528 *      decreasing the number of TX streams
 529 * 3) Avoid throughput performance impact as much as possible
 530 *
 531 *=============================================================================
 532 *                 Condition Nxt State  Condition Nxt State Condition Nxt State
 533 *-----------------------------------------------------------------------------
 534 *     IWL_TI_0     T >= 115   CT_KILL  115>T>=105   TI_1      N/A      N/A
 535 *     IWL_TI_1     T >= 115   CT_KILL  115>T>=110   TI_2     T<=95     TI_0
 536 *     IWL_TI_2     T >= 115   CT_KILL                        T<=100    TI_1
 537 *    IWL_CT_KILL      N/A       N/A       N/A        N/A     T<=95     TI_0
 538 *=============================================================================
 539 */
 540static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp)
 541{
 542        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 543        int i;
 544        bool changed = false;
 545        enum iwl_tt_state old_state;
 546        struct iwl_tt_trans *transaction;
 547
 548        old_state = tt->state;
 549        for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) {
 550                /* based on the current TT state,
 551                 * find the curresponding transaction table
 552                 * each table has (IWL_TI_STATE_MAX - 1) entries
 553                 * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1))
 554                 * will advance to the correct table.
 555                 * then based on the current temperature
 556                 * find the next state need to transaction to
 557                 * go through all the possible (IWL_TI_STATE_MAX - 1) entries
 558                 * in the current table to see if transaction is needed
 559                 */
 560                transaction = tt->transaction +
 561                        ((old_state * (IWL_TI_STATE_MAX - 1)) + i);
 562                if (temp >= transaction->tt_low &&
 563                    temp <= transaction->tt_high) {
 564#ifdef CONFIG_IWLWIFI_DEBUG
 565                        if ((tt->tt_previous_temp) &&
 566                            (temp > tt->tt_previous_temp) &&
 567                            ((temp - tt->tt_previous_temp) >
 568                            IWL_TT_INCREASE_MARGIN)) {
 569                                IWL_DEBUG_POWER(priv,
 570                                        "Temperature increase %d "
 571                                        "degree Celsius\n",
 572                                        (temp - tt->tt_previous_temp));
 573                        }
 574                        tt->tt_previous_temp = temp;
 575#endif
 576                        if (old_state !=
 577                            transaction->next_state) {
 578                                changed = true;
 579                                tt->state =
 580                                        transaction->next_state;
 581                        }
 582                        break;
 583                }
 584        }
 585        if (changed) {
 586                struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
 587
 588                if (tt->state >= IWL_TI_1) {
 589                        /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
 590                        tt->tt_power_mode = IWL_POWER_INDEX_5;
 591                        if (!iwl_ht_enabled(priv))
 592                                /* disable HT */
 593                                rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
 594                                        RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
 595                                        RXON_FLG_HT40_PROT_MSK |
 596                                        RXON_FLG_HT_PROT_MSK);
 597                        else {
 598                                /* check HT capability and set
 599                                 * according to the system HT capability
 600                                 * in case get disabled before */
 601                                iwl_set_rxon_ht(priv, &priv->current_ht_config);
 602                        }
 603
 604                } else {
 605                        /*
 606                         * restore system power setting -- it will be
 607                         * recalculated automatically.
 608                         */
 609
 610                        /* check HT capability and set
 611                         * according to the system HT capability
 612                         * in case get disabled before */
 613                        iwl_set_rxon_ht(priv, &priv->current_ht_config);
 614                }
 615                mutex_lock(&priv->mutex);
 616                if (iwl_power_update_mode(priv, true)) {
 617                        /* TT state not updated
 618                         * try again during next temperature read
 619                         */
 620                        IWL_ERR(priv, "Cannot update power mode, "
 621                                        "TT state not updated\n");
 622                        tt->state = old_state;
 623                } else {
 624                        IWL_DEBUG_POWER(priv,
 625                                        "Thermal Throttling to new state: %u\n",
 626                                        tt->state);
 627                        if (old_state != IWL_TI_CT_KILL &&
 628                            tt->state == IWL_TI_CT_KILL) {
 629                                IWL_DEBUG_POWER(priv, "Enter IWL_TI_CT_KILL\n");
 630                                iwl_perform_ct_kill_task(priv, true);
 631
 632                        } else if (old_state == IWL_TI_CT_KILL &&
 633                                  tt->state != IWL_TI_CT_KILL) {
 634                                IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n");
 635                                iwl_perform_ct_kill_task(priv, false);
 636                        }
 637                }
 638                mutex_unlock(&priv->mutex);
 639        }
 640}
 641
 642/* Card State Notification indicated reach critical temperature
 643 * if PSP not enable, no Thermal Throttling function will be performed
 644 * just set the GP1 bit to acknowledge the event
 645 * otherwise, go into IWL_TI_CT_KILL state
 646 * since Card State Notification will not provide any temperature reading
 647 * for Legacy mode
 648 * so just pass the CT_KILL temperature to iwl_legacy_tt_handler()
 649 * for advance mode
 650 * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state
 651 */
 652static void iwl_bg_ct_enter(struct work_struct *work)
 653{
 654        struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter);
 655        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 656
 657        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 658                return;
 659
 660        if (!iwl_is_ready(priv))
 661                return;
 662
 663        if (tt->state != IWL_TI_CT_KILL) {
 664                IWL_ERR(priv, "Device reached critical temperature "
 665                              "- ucode going to sleep!\n");
 666                if (!priv->thermal_throttle.advanced_tt)
 667                        iwl_legacy_tt_handler(priv,
 668                                              IWL_MINIMAL_POWER_THRESHOLD);
 669                else
 670                        iwl_advance_tt_handler(priv,
 671                                               CT_KILL_THRESHOLD + 1);
 672        }
 673}
 674
 675/* Card State Notification indicated out of critical temperature
 676 * since Card State Notification will not provide any temperature reading
 677 * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature
 678 * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state
 679 */
 680static void iwl_bg_ct_exit(struct work_struct *work)
 681{
 682        struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit);
 683        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 684
 685        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 686                return;
 687
 688        if (!iwl_is_ready(priv))
 689                return;
 690
 691        /* stop ct_kill_exit_tm timer */
 692        del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
 693
 694        if (tt->state == IWL_TI_CT_KILL) {
 695                IWL_ERR(priv,
 696                        "Device temperature below critical"
 697                        "- ucode awake!\n");
 698                if (!priv->thermal_throttle.advanced_tt)
 699                        iwl_legacy_tt_handler(priv,
 700                                        IWL_REDUCED_PERFORMANCE_THRESHOLD_2);
 701                else
 702                        iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD);
 703        }
 704}
 705
 706void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
 707{
 708        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 709                return;
 710
 711        IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n");
 712        queue_work(priv->workqueue, &priv->ct_enter);
 713}
 714EXPORT_SYMBOL(iwl_tt_enter_ct_kill);
 715
 716void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
 717{
 718        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 719                return;
 720
 721        IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n");
 722        queue_work(priv->workqueue, &priv->ct_exit);
 723}
 724EXPORT_SYMBOL(iwl_tt_exit_ct_kill);
 725
 726static void iwl_bg_tt_work(struct work_struct *work)
 727{
 728        struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
 729        s32 temp = priv->temperature; /* degrees CELSIUS except 4965 */
 730
 731        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 732                return;
 733
 734        if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
 735                temp = KELVIN_TO_CELSIUS(priv->temperature);
 736
 737        if (!priv->thermal_throttle.advanced_tt)
 738                iwl_legacy_tt_handler(priv, temp);
 739        else
 740                iwl_advance_tt_handler(priv, temp);
 741}
 742
 743void iwl_tt_handler(struct iwl_priv *priv)
 744{
 745        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 746                return;
 747
 748        IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n");
 749        queue_work(priv->workqueue, &priv->tt_work);
 750}
 751EXPORT_SYMBOL(iwl_tt_handler);
 752
 753/* Thermal throttling initialization
 754 * For advance thermal throttling:
 755 *     Initialize Thermal Index and temperature threshold table
 756 *     Initialize thermal throttling restriction table
 757 */
 758void iwl_tt_initialize(struct iwl_priv *priv)
 759{
 760        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 761        int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);
 762        struct iwl_tt_trans *transaction;
 763
 764        IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling \n");
 765
 766        memset(tt, 0, sizeof(struct iwl_tt_mgmt));
 767
 768        tt->state = IWL_TI_0;
 769        init_timer(&priv->thermal_throttle.ct_kill_exit_tm);
 770        priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv;
 771        priv->thermal_throttle.ct_kill_exit_tm.function = iwl_tt_check_exit_ct_kill;
 772
 773        /* setup deferred ct kill work */
 774        INIT_WORK(&priv->tt_work, iwl_bg_tt_work);
 775        INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
 776        INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
 777
 778        switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
 779        case CSR_HW_REV_TYPE_6x00:
 780        case CSR_HW_REV_TYPE_6x50:
 781                IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n");
 782                tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) *
 783                                         IWL_TI_STATE_MAX, GFP_KERNEL);
 784                tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) *
 785                        IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1),
 786                        GFP_KERNEL);
 787                if (!tt->restriction || !tt->transaction) {
 788                        IWL_ERR(priv, "Fallback to Legacy Throttling\n");
 789                        priv->thermal_throttle.advanced_tt = false;
 790                        kfree(tt->restriction);
 791                        tt->restriction = NULL;
 792                        kfree(tt->transaction);
 793                        tt->transaction = NULL;
 794                } else {
 795                        transaction = tt->transaction +
 796                                (IWL_TI_0 * (IWL_TI_STATE_MAX - 1));
 797                        memcpy(transaction, &tt_range_0[0], size);
 798                        transaction = tt->transaction +
 799                                (IWL_TI_1 * (IWL_TI_STATE_MAX - 1));
 800                        memcpy(transaction, &tt_range_1[0], size);
 801                        transaction = tt->transaction +
 802                                (IWL_TI_2 * (IWL_TI_STATE_MAX - 1));
 803                        memcpy(transaction, &tt_range_2[0], size);
 804                        transaction = tt->transaction +
 805                                (IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1));
 806                        memcpy(transaction, &tt_range_3[0], size);
 807                        size = sizeof(struct iwl_tt_restriction) *
 808                                IWL_TI_STATE_MAX;
 809                        memcpy(tt->restriction,
 810                                &restriction_range[0], size);
 811                        priv->thermal_throttle.advanced_tt = true;
 812                }
 813                break;
 814        default:
 815                IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n");
 816                priv->thermal_throttle.advanced_tt = false;
 817                break;
 818        }
 819}
 820EXPORT_SYMBOL(iwl_tt_initialize);
 821
 822/* cleanup thermal throttling management related memory and timer */
 823void iwl_tt_exit(struct iwl_priv *priv)
 824{
 825        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 826
 827        /* stop ct_kill_exit_tm timer if activated */
 828        del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
 829        cancel_work_sync(&priv->tt_work);
 830        cancel_work_sync(&priv->ct_enter);
 831        cancel_work_sync(&priv->ct_exit);
 832
 833        if (priv->thermal_throttle.advanced_tt) {
 834                /* free advance thermal throttling memory */
 835                kfree(tt->restriction);
 836                tt->restriction = NULL;
 837                kfree(tt->transaction);
 838                tt->transaction = NULL;
 839        }
 840}
 841EXPORT_SYMBOL(iwl_tt_exit);
 842
 843/* initialize to default */
 844void iwl_power_initialize(struct iwl_priv *priv)
 845{
 846        u16 lctl = iwl_pcie_link_ctl(priv);
 847
 848        priv->power_data.pci_pm = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
 849
 850        priv->power_data.debug_sleep_level_override = -1;
 851
 852        memset(&priv->power_data.sleep_cmd, 0,
 853                sizeof(priv->power_data.sleep_cmd));
 854}
 855EXPORT_SYMBOL(iwl_power_initialize);
 856