aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c46
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c83
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c317
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h30
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c66
10 files changed, 256 insertions, 313 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 319df4ab7f13..2232b1794e76 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1606,7 +1606,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
1606 set_bit(STATUS_READY, &priv->status); 1606 set_bit(STATUS_READY, &priv->status);
1607 wake_up_interruptible(&priv->wait_command_queue); 1607 wake_up_interruptible(&priv->wait_command_queue);
1608 1608
1609 iwl_power_update_mode(priv, 1); 1609 iwl_power_update_mode(priv, true);
1610 1610
1611 /* reassociate for ADHOC mode */ 1611 /* reassociate for ADHOC mode */
1612 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) { 1612 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
@@ -2075,7 +2075,7 @@ void iwl_post_associate(struct iwl_priv *priv)
2075 * If chain noise has already been run, then we need to enable 2075 * If chain noise has already been run, then we need to enable
2076 * power management here */ 2076 * power management here */
2077 if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) 2077 if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
2078 iwl_power_update_mode(priv, 0); 2078 iwl_power_update_mode(priv, false);
2079 2079
2080 /* Enable Rx differential gain and sensitivity calibrations */ 2080 /* Enable Rx differential gain and sensitivity calibrations */
2081 iwl_chain_noise_reset(priv); 2081 iwl_chain_noise_reset(priv);
@@ -2565,47 +2565,6 @@ static ssize_t store_filter_flags(struct device *d,
2565static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, 2565static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
2566 store_filter_flags); 2566 store_filter_flags);
2567 2567
2568static ssize_t store_power_level(struct device *d,
2569 struct device_attribute *attr,
2570 const char *buf, size_t count)
2571{
2572 struct iwl_priv *priv = dev_get_drvdata(d);
2573 int ret;
2574 unsigned long mode;
2575
2576
2577 mutex_lock(&priv->mutex);
2578
2579 ret = strict_strtoul(buf, 10, &mode);
2580 if (ret)
2581 goto out;
2582
2583 ret = iwl_power_set_user_mode(priv, mode);
2584 if (ret) {
2585 IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
2586 goto out;
2587 }
2588 ret = count;
2589
2590 out:
2591 mutex_unlock(&priv->mutex);
2592 return ret;
2593}
2594
2595static ssize_t show_power_level(struct device *d,
2596 struct device_attribute *attr, char *buf)
2597{
2598 struct iwl_priv *priv = dev_get_drvdata(d);
2599 int level = priv->power_data.power_mode;
2600 char *p = buf;
2601
2602 p += sprintf(p, "%d\n", level);
2603 return p - buf + 1;
2604}
2605
2606static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
2607 store_power_level);
2608
2609 2568
2610static ssize_t show_statistics(struct device *d, 2569static ssize_t show_statistics(struct device *d,
2611 struct device_attribute *attr, char *buf) 2570 struct device_attribute *attr, char *buf)
@@ -2698,7 +2657,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
2698static struct attribute *iwl_sysfs_entries[] = { 2657static struct attribute *iwl_sysfs_entries[] = {
2699 &dev_attr_flags.attr, 2658 &dev_attr_flags.attr,
2700 &dev_attr_filter_flags.attr, 2659 &dev_attr_filter_flags.attr,
2701 &dev_attr_power_level.attr,
2702 &dev_attr_statistics.attr, 2660 &dev_attr_statistics.attr,
2703 &dev_attr_temperature.attr, 2661 &dev_attr_temperature.attr,
2704 &dev_attr_tx_power.attr, 2662 &dev_attr_tx_power.attr,
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 13180d6ee2f7..c4b565a2de94 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -852,7 +852,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
852 priv->cfg->ops->lib->update_chain_flags(priv); 852 priv->cfg->ops->lib->update_chain_flags(priv);
853 853
854 data->state = IWL_CHAIN_NOISE_DONE; 854 data->state = IWL_CHAIN_NOISE_DONE;
855 iwl_power_update_mode(priv, 0); 855 iwl_power_update_mode(priv, false);
856} 856}
857EXPORT_SYMBOL(iwl_chain_noise_calibration); 857EXPORT_SYMBOL(iwl_chain_noise_calibration);
858 858
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 6188c54113b0..68d7719071f7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2313,15 +2313,22 @@ struct iwl_spectrum_notification {
2313 * PM allow: 2313 * PM allow:
2314 * bit 0 - '0' Driver not allow power management 2314 * bit 0 - '0' Driver not allow power management
2315 * '1' Driver allow PM (use rest of parameters) 2315 * '1' Driver allow PM (use rest of parameters)
2316 *
2316 * uCode send sleep notifications: 2317 * uCode send sleep notifications:
2317 * bit 1 - '0' Don't send sleep notification 2318 * bit 1 - '0' Don't send sleep notification
2318 * '1' send sleep notification (SEND_PM_NOTIFICATION) 2319 * '1' send sleep notification (SEND_PM_NOTIFICATION)
2320 *
2319 * Sleep over DTIM 2321 * Sleep over DTIM
2320 * bit 2 - '0' PM have to walk up every DTIM 2322 * bit 2 - '0' PM have to walk up every DTIM
2321 * '1' PM could sleep over DTIM till listen Interval. 2323 * '1' PM could sleep over DTIM till listen Interval.
2324 *
2322 * PCI power managed 2325 * PCI power managed
2323 * bit 3 - '0' (PCI_CFG_LINK_CTRL & 0x1) 2326 * bit 3 - '0' (PCI_CFG_LINK_CTRL & 0x1)
2324 * '1' !(PCI_CFG_LINK_CTRL & 0x1) 2327 * '1' !(PCI_CFG_LINK_CTRL & 0x1)
2328 *
2329 * Fast PD
2330 * bit 4 - '1' Put radio to sleep when receiving frame for others
2331 *
2325 * Force sleep Modes 2332 * Force sleep Modes
2326 * bit 31/30- '00' use both mac/xtal sleeps 2333 * bit 31/30- '00' use both mac/xtal sleeps
2327 * '01' force Mac sleep 2334 * '01' force Mac sleep
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 36c6e16285de..af735128333a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1568,7 +1568,8 @@ int iwl_setup_mac(struct iwl_priv *priv)
1568 IEEE80211_HW_NOISE_DBM | 1568 IEEE80211_HW_NOISE_DBM |
1569 IEEE80211_HW_AMPDU_AGGREGATION | 1569 IEEE80211_HW_AMPDU_AGGREGATION |
1570 IEEE80211_HW_SPECTRUM_MGMT | 1570 IEEE80211_HW_SPECTRUM_MGMT |
1571 IEEE80211_HW_SUPPORTS_PS; 1571 IEEE80211_HW_SUPPORTS_PS |
1572 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
1572 hw->wiphy->interface_modes = 1573 hw->wiphy->interface_modes =
1573 BIT(NL80211_IFTYPE_STATION) | 1574 BIT(NL80211_IFTYPE_STATION) |
1574 BIT(NL80211_IFTYPE_ADHOC); 1575 BIT(NL80211_IFTYPE_ADHOC);
@@ -1663,8 +1664,6 @@ int iwl_init_drv(struct iwl_priv *priv)
1663 priv->qos_data.qos_cap.val = 0; 1664 priv->qos_data.qos_cap.val = 0;
1664 1665
1665 priv->rates_mask = IWL_RATES_MASK; 1666 priv->rates_mask = IWL_RATES_MASK;
1666 /* If power management is turned on, default to CAM mode */
1667 priv->power_mode = IWL_POWER_MODE_CAM;
1668 priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX; 1667 priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX;
1669 1668
1670 ret = iwl_init_channel_map(priv); 1669 ret = iwl_init_channel_map(priv);
@@ -2551,7 +2550,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2551 if (bss_conf->assoc) { 2550 if (bss_conf->assoc) {
2552 priv->assoc_id = bss_conf->aid; 2551 priv->assoc_id = bss_conf->aid;
2553 priv->beacon_int = bss_conf->beacon_int; 2552 priv->beacon_int = bss_conf->beacon_int;
2554 priv->power_data.dtim_period = bss_conf->dtim_period;
2555 priv->timestamp = bss_conf->timestamp; 2553 priv->timestamp = bss_conf->timestamp;
2556 priv->assoc_capability = bss_conf->assoc_capability; 2554 priv->assoc_capability = bss_conf->assoc_capability;
2557 2555
@@ -2801,13 +2799,10 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2801 iwl_set_rate(priv); 2799 iwl_set_rate(priv);
2802 } 2800 }
2803 2801
2804 if (changed & IEEE80211_CONF_CHANGE_PS && 2802 if (changed & IEEE80211_CONF_CHANGE_PS) {
2805 priv->iw_mode == NL80211_IFTYPE_STATION) { 2803 ret = iwl_power_update_mode(priv, false);
2806 priv->power_data.power_disabled =
2807 !(conf->flags & IEEE80211_CONF_PS);
2808 ret = iwl_power_update_mode(priv, 0);
2809 if (ret) 2804 if (ret)
2810 IWL_DEBUG_MAC80211(priv, "Error setting power level\n"); 2805 IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
2811 } 2806 }
2812 2807
2813 if (changed & IEEE80211_CONF_CHANGE_POWER) { 2808 if (changed & IEEE80211_CONF_CHANGE_POWER) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 82befb7ce997..723f38a023ce 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -88,6 +88,8 @@ struct iwl_debugfs {
88 struct dentry *file_led; 88 struct dentry *file_led;
89#endif 89#endif
90 struct dentry *file_disable_ht40; 90 struct dentry *file_disable_ht40;
91 struct dentry *file_sleep_level_override;
92 struct dentry *file_current_sleep_command;
91 } dbgfs_data_files; 93 } dbgfs_data_files;
92 struct dir_rf_files { 94 struct dir_rf_files {
93 struct dentry *file_disable_sensitivity; 95 struct dentry *file_disable_sensitivity;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 7b578d41101f..f68fb4711da2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -776,6 +776,83 @@ static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
776 return ret; 776 return ret;
777} 777}
778 778
779static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
780 const char __user *user_buf,
781 size_t count, loff_t *ppos)
782{
783 struct iwl_priv *priv = file->private_data;
784 char buf[8];
785 int buf_size;
786 int value;
787
788 memset(buf, 0, sizeof(buf));
789 buf_size = min(count, sizeof(buf) - 1);
790 if (copy_from_user(buf, user_buf, buf_size))
791 return -EFAULT;
792
793 if (sscanf(buf, "%d", &value) != 1)
794 return -EINVAL;
795
796 /*
797 * Our users expect 0 to be "CAM", but 0 isn't actually
798 * valid here. However, let's not confuse them and present
799 * IWL_POWER_INDEX_1 as "1", not "0".
800 */
801 if (value > 0)
802 value -= 1;
803
804 if (value != -1 && (value < 0 || value >= IWL_POWER_NUM))
805 return -EINVAL;
806
807 priv->power_data.debug_sleep_level_override = value;
808
809 iwl_power_update_mode(priv, false);
810
811 return count;
812}
813
814static ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
815 char __user *user_buf,
816 size_t count, loff_t *ppos)
817{
818 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
819 char buf[10];
820 int pos, value;
821 const size_t bufsz = sizeof(buf);
822
823 /* see the write function */
824 value = priv->power_data.debug_sleep_level_override;
825 if (value >= 0)
826 value += 1;
827
828 pos = scnprintf(buf, bufsz, "%d\n", value);
829 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
830}
831
832static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
833 char __user *user_buf,
834 size_t count, loff_t *ppos)
835{
836 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
837 char buf[200];
838 int pos = 0, i;
839 const size_t bufsz = sizeof(buf);
840 struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd;
841
842 pos += scnprintf(buf + pos, bufsz - pos,
843 "flags: %#.2x\n", le16_to_cpu(cmd->flags));
844 pos += scnprintf(buf + pos, bufsz - pos,
845 "RX/TX timeout: %d/%d usec\n",
846 le32_to_cpu(cmd->rx_data_timeout),
847 le32_to_cpu(cmd->tx_data_timeout));
848 for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
849 pos += scnprintf(buf + pos, bufsz - pos,
850 "sleep_interval[%d]: %d\n", i,
851 le32_to_cpu(cmd->sleep_interval[i]));
852
853 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
854}
855
779DEBUGFS_READ_WRITE_FILE_OPS(sram); 856DEBUGFS_READ_WRITE_FILE_OPS(sram);
780DEBUGFS_WRITE_FILE_OPS(log_event); 857DEBUGFS_WRITE_FILE_OPS(log_event);
781DEBUGFS_READ_FILE_OPS(nvm); 858DEBUGFS_READ_FILE_OPS(nvm);
@@ -789,6 +866,8 @@ DEBUGFS_READ_FILE_OPS(led);
789#endif 866#endif
790DEBUGFS_READ_FILE_OPS(thermal_throttling); 867DEBUGFS_READ_FILE_OPS(thermal_throttling);
791DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); 868DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
869DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
870DEBUGFS_READ_FILE_OPS(current_sleep_command);
792 871
793static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, 872static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
794 char __user *user_buf, 873 char __user *user_buf,
@@ -1533,6 +1612,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1533#ifdef CONFIG_IWLWIFI_LEDS 1612#ifdef CONFIG_IWLWIFI_LEDS
1534 DEBUGFS_ADD_FILE(led, data); 1613 DEBUGFS_ADD_FILE(led, data);
1535#endif 1614#endif
1615 DEBUGFS_ADD_FILE(sleep_level_override, data);
1616 DEBUGFS_ADD_FILE(current_sleep_command, data);
1536 DEBUGFS_ADD_FILE(thermal_throttling, data); 1617 DEBUGFS_ADD_FILE(thermal_throttling, data);
1537 DEBUGFS_ADD_FILE(disable_ht40, data); 1618 DEBUGFS_ADD_FILE(disable_ht40, data);
1538 DEBUGFS_ADD_FILE(rx_statistics, debug); 1619 DEBUGFS_ADD_FILE(rx_statistics, debug);
@@ -1572,6 +1653,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
1572 if (!priv->dbgfs) 1653 if (!priv->dbgfs)
1573 return; 1654 return;
1574 1655
1656 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sleep_level_override);
1657 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_current_sleep_command);
1575 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm); 1658 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
1576 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); 1659 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
1577 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); 1660 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 1aa2ae6d0756..b96c3c9e92a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1119,7 +1119,6 @@ struct iwl_priv {
1119 /* context information */ 1119 /* context information */
1120 u16 rates_mask; 1120 u16 rates_mask;
1121 1121
1122 u32 power_mode;
1123 u8 bssid[ETH_ALEN]; 1122 u8 bssid[ETH_ALEN];
1124 u16 rts_threshold; 1123 u16 rts_threshold;
1125 u8 mac_addr[ETH_ALEN]; 1124 u8 mac_addr[ETH_ALEN];
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 27ad59d8643e..0b16841f45f4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -42,20 +42,35 @@
42#include "iwl-power.h" 42#include "iwl-power.h"
43 43
44/* 44/*
45 * Setting power level allow the card to go to sleep when not busy. 45 * Setting power level allows the card to go to sleep when not busy.
46 * 46 *
47 * The power level is set to INDEX_1 (the least deep state) by 47 * We calculate a sleep command based on the required latency, which
48 * default, and will, in the future, be the deepest state unless 48 * we get from mac80211. In order to handle thermal throttling, we can
49 * otherwise required by pm_qos network latency requirements. 49 * also use pre-defined power levels.
50 *
51 * Using INDEX_1 without pm_qos is ok because mac80211 will disable
52 * PS when even checking every beacon for the TIM bit would exceed
53 * the required latency.
54 */ 50 */
55 51
56#define IWL_POWER_RANGE_0_MAX (2) 52/*
57#define IWL_POWER_RANGE_1_MAX (10) 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");
58 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
59 74
60#define NOSLP cpu_to_le16(0), 0, 0 75#define NOSLP cpu_to_le16(0), 0, 0
61#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0 76#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
@@ -67,9 +82,8 @@
67 cpu_to_le32(X3), \ 82 cpu_to_le32(X3), \
68 cpu_to_le32(X4)} 83 cpu_to_le32(X4)}
69/* default power management (not Tx power) table values */ 84/* default power management (not Tx power) table values */
70/* for DTIM period 0 through IWL_POWER_RANGE_0_MAX */ 85/* for DTIM period 0 through IWL_DTIM_RANGE_0_MAX */
71static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = { 86static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = {
72 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
73 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, 87 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
74 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, 88 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
75 {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF)}, 0}, 89 {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF)}, 0},
@@ -78,9 +92,8 @@ static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = {
78}; 92};
79 93
80 94
81/* for DTIM period IWL_POWER_RANGE_0_MAX + 1 through IWL_POWER_RANGE_1_MAX */ 95/* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */
82static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = { 96static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = {
83 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
84 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, 97 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
85 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0}, 98 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
86 {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9)}, 0}, 99 {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9)}, 0},
@@ -88,9 +101,8 @@ static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = {
88 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2} 101 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2}
89}; 102};
90 103
91/* for DTIM period > IWL_POWER_RANGE_1_MAX */ 104/* for DTIM period > IWL_DTIM_RANGE_1_MAX */
92static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = { 105static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
93 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
94 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, 106 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
95 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, 107 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
96 {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0}, 108 {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
@@ -98,6 +110,56 @@ static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
98 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} 110 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
99}; 111};
100 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
101/* default Thermal Throttling transaction table 163/* default Thermal Throttling transaction table
102 * Current state | Throttling Down | Throttling Up 164 * Current state | Throttling Down | Throttling Up
103 *============================================================================= 165 *=============================================================================
@@ -138,98 +200,44 @@ static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = {
138 {IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false } 200 {IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false }
139}; 201};
140 202
141/* set card power command */
142static int iwl_set_power(struct iwl_priv *priv, void *cmd)
143{
144 return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,
145 sizeof(struct iwl_powertable_cmd), cmd);
146}
147 203
148/* initialize to default */ 204static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv,
149static void iwl_power_init_handle(struct iwl_priv *priv) 205 struct iwl_powertable_cmd *cmd)
150{ 206{
151 struct iwl_power_mgr *pow_data; 207 memset(cmd, 0, sizeof(*cmd));
152 int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_NUM;
153 struct iwl_powertable_cmd *cmd;
154 int i;
155 u16 lctl;
156
157 IWL_DEBUG_POWER(priv, "Initialize power \n");
158
159 pow_data = &priv->power_data;
160
161 memset(pow_data, 0, sizeof(*pow_data));
162
163 memcpy(&pow_data->pwr_range_0[0], &range_0[0], size);
164 memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
165 memcpy(&pow_data->pwr_range_2[0], &range_2[0], size);
166
167 lctl = iwl_pcie_link_ctl(priv);
168 208
169 IWL_DEBUG_POWER(priv, "adjust power command flags\n"); 209 if (priv->power_data.pci_pm)
210 cmd->flags |= IWL_POWER_PCI_PM_MSK;
170 211
171 for (i = 0; i < IWL_POWER_NUM; i++) { 212 IWL_DEBUG_POWER(priv, "Sleep command for CAM\n");
172 cmd = &pow_data->pwr_range_0[i].cmd;
173
174 if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
175 cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
176 else
177 cmd->flags |= IWL_POWER_PCI_PM_MSK;
178 }
179} 213}
180 214
181/* adjust power command according to DTIM period and power level*/ 215static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv,
182static int iwl_update_power_cmd(struct iwl_priv *priv, 216 struct iwl_powertable_cmd *cmd,
183 struct iwl_powertable_cmd *cmd, u16 mode) 217 int dynps_ms, int wakeup_period)
184{ 218{
185 struct iwl_power_vec_entry *range;
186 struct iwl_power_mgr *pow_data;
187 int i; 219 int i;
188 u32 max_sleep = 0;
189 u8 period;
190 bool skip;
191 220
192 if (mode > IWL_POWER_INDEX_5) { 221 memset(cmd, 0, sizeof(*cmd));
193 IWL_DEBUG_POWER(priv, "Error invalid power mode \n");
194 return -EINVAL;
195 }
196 222
197 pow_data = &priv->power_data; 223 cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK |
224 IWL_POWER_FAST_PD; /* no use seeing frames for others */
198 225
199 if (pow_data->dtim_period <= IWL_POWER_RANGE_0_MAX) 226 if (priv->power_data.pci_pm)
200 range = &pow_data->pwr_range_0[0]; 227 cmd->flags |= IWL_POWER_PCI_PM_MSK;
201 else if (pow_data->dtim_period <= IWL_POWER_RANGE_1_MAX)
202 range = &pow_data->pwr_range_1[0];
203 else
204 range = &pow_data->pwr_range_2[0];
205 228
206 period = pow_data->dtim_period; 229 cmd->rx_data_timeout = cpu_to_le32(1000 * dynps_ms);
207 memcpy(cmd, &range[mode].cmd, sizeof(struct iwl_powertable_cmd)); 230 cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms);
208
209 if (period == 0) {
210 period = 1;
211 skip = false;
212 } else {
213 skip = !!range[mode].no_dtim;
214 }
215
216 if (skip) {
217 __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
218 max_sleep = le32_to_cpu(slp_itrvl);
219 if (max_sleep == 0xFF)
220 max_sleep = period * (skip + 1);
221 else if (max_sleep > period)
222 max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
223 cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
224 } else {
225 max_sleep = period;
226 cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
227 }
228 231
229 for (i = 0; i < IWL_POWER_VEC_SIZE; i++) 232 for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
230 if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep) 233 cmd->sleep_interval[i] = cpu_to_le32(wakeup_period);
231 cmd->sleep_interval[i] = cpu_to_le32(max_sleep); 234
235 IWL_DEBUG_POWER(priv, "Automatic sleep command\n");
236}
232 237
238static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
239{
240 IWL_DEBUG_POWER(priv, "Sending power/sleep command\n");
233 IWL_DEBUG_POWER(priv, "Flags value = 0x%08X\n", cmd->flags); 241 IWL_DEBUG_POWER(priv, "Flags value = 0x%08X\n", cmd->flags);
234 IWL_DEBUG_POWER(priv, "Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout)); 242 IWL_DEBUG_POWER(priv, "Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
235 IWL_DEBUG_POWER(priv, "Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout)); 243 IWL_DEBUG_POWER(priv, "Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
@@ -240,50 +248,54 @@ static int iwl_update_power_cmd(struct iwl_priv *priv,
240 le32_to_cpu(cmd->sleep_interval[3]), 248 le32_to_cpu(cmd->sleep_interval[3]),
241 le32_to_cpu(cmd->sleep_interval[4])); 249 le32_to_cpu(cmd->sleep_interval[4]));
242 250
243 return 0; 251 return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,
252 sizeof(struct iwl_powertable_cmd), cmd);
244} 253}
245 254
246 255
247/*
248 * compute the final power mode index
249 */
250int iwl_power_update_mode(struct iwl_priv *priv, bool force) 256int iwl_power_update_mode(struct iwl_priv *priv, bool force)
251{ 257{
252 struct iwl_power_mgr *setting = &(priv->power_data);
253 int ret = 0; 258 int ret = 0;
254 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 259 struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
255 u16 uninitialized_var(final_mode); 260 bool enabled = (priv->iw_mode == NL80211_IFTYPE_STATION) &&
261 (priv->hw->conf.flags & IEEE80211_CONF_PS);
256 bool update_chains; 262 bool update_chains;
263 struct iwl_powertable_cmd cmd;
264 int dtimper;
257 265
258 /* Don't update the RX chain when chain noise calibration is running */ 266 /* Don't update the RX chain when chain noise calibration is running */
259 update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || 267 update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
260 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; 268 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
261 269
262 final_mode = priv->power_data.user_power_setting; 270 if (priv->vif)
263 271 dtimper = priv->vif->bss_conf.dtim_period;
264 if (setting->power_disabled) 272 else
265 final_mode = IWL_POWER_MODE_CAM; 273 dtimper = 1;
274
275 /* TT power setting overwrites everything */
276 if (tt->state >= IWL_TI_1)
277 iwl_static_sleep_cmd(priv, &cmd, tt->tt_power_mode, dtimper);
278 else if (!enabled)
279 iwl_power_sleep_cam_cmd(priv, &cmd);
280 else if (priv->power_data.debug_sleep_level_override >= 0)
281 iwl_static_sleep_cmd(priv, &cmd,
282 priv->power_data.debug_sleep_level_override,
283 dtimper);
284 else if (no_sleep_autoadjust)
285 iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_1, dtimper);
286 else
287 iwl_power_fill_sleep_cmd(priv, &cmd,
288 priv->hw->conf.dynamic_ps_timeout,
289 priv->hw->conf.max_sleep_period);
266 290
267 if (tt->state >= IWL_TI_1) {
268 /* TT power setting overwrite user & system power setting */
269 final_mode = tt->tt_power_mode;
270 }
271 if (iwl_is_ready_rf(priv) && 291 if (iwl_is_ready_rf(priv) &&
272 ((setting->power_mode != final_mode) || force)) { 292 (memcmp(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd)) || force)) {
273 struct iwl_powertable_cmd cmd; 293 if (cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)
274
275 if (final_mode != IWL_POWER_MODE_CAM)
276 set_bit(STATUS_POWER_PMI, &priv->status); 294 set_bit(STATUS_POWER_PMI, &priv->status);
277 295
278 iwl_update_power_cmd(priv, &cmd, final_mode);
279 cmd.keep_alive_beacons = 0;
280
281 if (final_mode == IWL_POWER_INDEX_5)
282 cmd.flags |= IWL_POWER_FAST_PD;
283
284 ret = iwl_set_power(priv, &cmd); 296 ret = iwl_set_power(priv, &cmd);
285 if (!ret) { 297 if (!ret) {
286 if (final_mode == IWL_POWER_MODE_CAM) 298 if (!(cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK))
287 clear_bit(STATUS_POWER_PMI, &priv->status); 299 clear_bit(STATUS_POWER_PMI, &priv->status);
288 300
289 if (priv->cfg->ops->lib->update_chain_flags && 301 if (priv->cfg->ops->lib->update_chain_flags &&
@@ -294,7 +306,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
294 "Cannot update the power, chain noise " 306 "Cannot update the power, chain noise "
295 "calibration running: %d\n", 307 "calibration running: %d\n",
296 priv->chain_noise_data.state); 308 priv->chain_noise_data.state);
297 setting->power_mode = final_mode; 309 memcpy(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd));
298 } else 310 } else
299 IWL_ERR(priv, "set power fail, ret = %d", ret); 311 IWL_ERR(priv, "set power fail, ret = %d", ret);
300 } 312 }
@@ -303,18 +315,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
303} 315}
304EXPORT_SYMBOL(iwl_power_update_mode); 316EXPORT_SYMBOL(iwl_power_update_mode);
305 317
306/* set user_power_setting */
307int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
308{
309 if (mode >= IWL_POWER_NUM)
310 return -EINVAL;
311
312 priv->power_data.user_power_setting = mode;
313
314 return iwl_power_update_mode(priv, 0);
315}
316EXPORT_SYMBOL(iwl_power_set_user_mode);
317
318bool iwl_ht_enabled(struct iwl_priv *priv) 318bool iwl_ht_enabled(struct iwl_priv *priv)
319{ 319{
320 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 320 struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
@@ -349,7 +349,6 @@ enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv)
349 restriction = tt->restriction + tt->state; 349 restriction = tt->restriction + tt->state;
350 return restriction->rx_stream; 350 return restriction->rx_stream;
351} 351}
352EXPORT_SYMBOL(iwl_rx_ant_restriction);
353 352
354#define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */ 353#define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */
355 354
@@ -429,7 +428,6 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp)
429{ 428{
430 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 429 struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
431 enum iwl_tt_state old_state; 430 enum iwl_tt_state old_state;
432 struct iwl_power_mgr *setting = &priv->power_data;
433 431
434#ifdef CONFIG_IWLWIFI_DEBUG 432#ifdef CONFIG_IWLWIFI_DEBUG
435 if ((tt->tt_previous_temp) && 433 if ((tt->tt_previous_temp) &&
@@ -456,24 +454,13 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp)
456 tt->tt_previous_temp = temp; 454 tt->tt_previous_temp = temp;
457#endif 455#endif
458 if (tt->state != old_state) { 456 if (tt->state != old_state) {
459 if (old_state == IWL_TI_0) {
460 tt->sys_power_mode = setting->power_mode;
461 IWL_DEBUG_POWER(priv, "current power mode: %u\n",
462 setting->power_mode);
463 }
464 switch (tt->state) { 457 switch (tt->state) {
465 case IWL_TI_0: 458 case IWL_TI_0:
466 /* when system ready to go back to IWL_TI_0 state 459 /*
467 * using system power mode instead of TT power mode 460 * When the system is ready to go back to IWL_TI_0
468 * revert back to the orginal power mode which was saved 461 * we only have to call iwl_power_update_mode() to
469 * before enter Thermal Throttling state 462 * do so.
470 * update priv->power_data.user_power_setting to the
471 * required power mode to make sure
472 * iwl_power_update_mode() will update power correctly.
473 */ 463 */
474 priv->power_data.user_power_setting =
475 tt->sys_power_mode;
476 tt->tt_power_mode = tt->sys_power_mode;
477 break; 464 break;
478 case IWL_TI_1: 465 case IWL_TI_1:
479 tt->tt_power_mode = IWL_POWER_INDEX_3; 466 tt->tt_power_mode = IWL_POWER_INDEX_3;
@@ -576,13 +563,8 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp)
576 } 563 }
577 if (changed) { 564 if (changed) {
578 struct iwl_rxon_cmd *rxon = &priv->staging_rxon; 565 struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
579 struct iwl_power_mgr *setting = &priv->power_data;
580 566
581 if (tt->state >= IWL_TI_1) { 567 if (tt->state >= IWL_TI_1) {
582 /* if switching from IWL_TI_0 to other TT state
583 * save previous power setting in tt->sys_power_mode */
584 if (old_state == IWL_TI_0)
585 tt->sys_power_mode = setting->power_mode;
586 /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */ 568 /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
587 tt->tt_power_mode = IWL_POWER_INDEX_5; 569 tt->tt_power_mode = IWL_POWER_INDEX_5;
588 if (!iwl_ht_enabled(priv)) 570 if (!iwl_ht_enabled(priv))
@@ -599,17 +581,11 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp)
599 } 581 }
600 582
601 } else { 583 } else {
602 /* restore system power setting */ 584 /*
603 /* the previous power mode was saved in 585 * restore system power setting -- it will be
604 * tt->sys_power_mode when system move into 586 * recalculated automatically.
605 * Thermal Throttling state
606 * set power_data.user_power_setting to the previous
607 * system power mode to make sure power will get
608 * updated correctly
609 */ 587 */
610 priv->power_data.user_power_setting = 588
611 tt->sys_power_mode;
612 tt->tt_power_mode = tt->sys_power_mode;
613 /* check HT capability and set 589 /* check HT capability and set
614 * according to the system HT capability 590 * according to the system HT capability
615 * in case get disabled before */ 591 * in case get disabled before */
@@ -761,7 +737,6 @@ EXPORT_SYMBOL(iwl_tt_handler);
761void iwl_tt_initialize(struct iwl_priv *priv) 737void iwl_tt_initialize(struct iwl_priv *priv)
762{ 738{
763 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 739 struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
764 struct iwl_power_mgr *setting = &priv->power_data;
765 int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1); 740 int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);
766 struct iwl_tt_trans *transaction; 741 struct iwl_tt_trans *transaction;
767 742
@@ -770,8 +745,6 @@ void iwl_tt_initialize(struct iwl_priv *priv)
770 memset(tt, 0, sizeof(struct iwl_tt_mgmt)); 745 memset(tt, 0, sizeof(struct iwl_tt_mgmt));
771 746
772 tt->state = IWL_TI_0; 747 tt->state = IWL_TI_0;
773 tt->sys_power_mode = setting->power_mode;
774 tt->tt_power_mode = tt->sys_power_mode;
775 init_timer(&priv->thermal_throttle.ct_kill_exit_tm); 748 init_timer(&priv->thermal_throttle.ct_kill_exit_tm);
776 priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv; 749 priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv;
777 priv->thermal_throttle.ct_kill_exit_tm.function = iwl_tt_check_exit_ct_kill; 750 priv->thermal_throttle.ct_kill_exit_tm.function = iwl_tt_check_exit_ct_kill;
@@ -849,9 +822,13 @@ EXPORT_SYMBOL(iwl_tt_exit);
849/* initialize to default */ 822/* initialize to default */
850void iwl_power_initialize(struct iwl_priv *priv) 823void iwl_power_initialize(struct iwl_priv *priv)
851{ 824{
852 iwl_power_init_handle(priv); 825 u16 lctl = iwl_pcie_link_ctl(priv);
853 priv->power_data.user_power_setting = IWL_POWER_INDEX_1; 826
854 /* default to disabled until mac80211 says otherwise */ 827 priv->power_data.pci_pm = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
855 priv->power_data.power_disabled = 1; 828
829 priv->power_data.debug_sleep_level_override = -1;
830
831 memset(&priv->power_data.sleep_cmd, 0,
832 sizeof(priv->power_data.sleep_cmd));
856} 833}
857EXPORT_SYMBOL(iwl_power_initialize); 834EXPORT_SYMBOL(iwl_power_initialize);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 15e3eabd2e84..df6f6a49712b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -28,11 +28,8 @@
28#ifndef __iwl_power_setting_h__ 28#ifndef __iwl_power_setting_h__
29#define __iwl_power_setting_h__ 29#define __iwl_power_setting_h__
30 30
31#include <net/mac80211.h>
32#include "iwl-commands.h" 31#include "iwl-commands.h"
33 32
34struct iwl_priv;
35
36#define IWL_ABSOLUTE_ZERO 0 33#define IWL_ABSOLUTE_ZERO 0
37#define IWL_ABSOLUTE_MAX 0xFFFFFFFF 34#define IWL_ABSOLUTE_MAX 0xFFFFFFFF
38#define IWL_TT_INCREASE_MARGIN 5 35#define IWL_TT_INCREASE_MARGIN 5
@@ -93,8 +90,6 @@ struct iwl_tt_trans {
93 * when thermal throttling state != IWL_TI_0 90 * when thermal throttling state != IWL_TI_0
94 * the tt_power_mode should set to different 91 * the tt_power_mode should set to different
95 * power mode based on the current tt state 92 * power mode based on the current tt state
96 * @sys_power_mode: previous system power mode
97 * before transition into TT state
98 * @tt_previous_temperature: last measured temperature 93 * @tt_previous_temperature: last measured temperature
99 * @iwl_tt_restriction: ptr to restriction tbl, used by advance 94 * @iwl_tt_restriction: ptr to restriction tbl, used by advance
100 * thermal throttling to determine how many tx/rx streams 95 * thermal throttling to determine how many tx/rx streams
@@ -108,7 +103,6 @@ struct iwl_tt_mgmt {
108 enum iwl_tt_state state; 103 enum iwl_tt_state state;
109 bool advanced_tt; 104 bool advanced_tt;
110 u8 tt_power_mode; 105 u8 tt_power_mode;
111 u8 sys_power_mode;
112 bool ct_kill_toggle; 106 bool ct_kill_toggle;
113#ifdef CONFIG_IWLWIFI_DEBUG 107#ifdef CONFIG_IWLWIFI_DEBUG
114 s32 tt_previous_temp; 108 s32 tt_previous_temp;
@@ -118,8 +112,7 @@ struct iwl_tt_mgmt {
118 struct timer_list ct_kill_exit_tm; 112 struct timer_list ct_kill_exit_tm;
119}; 113};
120 114
121enum { 115enum iwl_power_level {
122 IWL_POWER_MODE_CAM, /* Continuously Aware Mode, always on */
123 IWL_POWER_INDEX_1, 116 IWL_POWER_INDEX_1,
124 IWL_POWER_INDEX_2, 117 IWL_POWER_INDEX_2,
125 IWL_POWER_INDEX_3, 118 IWL_POWER_INDEX_3,
@@ -128,26 +121,13 @@ enum {
128 IWL_POWER_NUM 121 IWL_POWER_NUM
129}; 122};
130 123
131/* Power management (not Tx power) structures */
132
133struct iwl_power_vec_entry {
134 struct iwl_powertable_cmd cmd;
135 u8 no_dtim;
136};
137
138struct iwl_power_mgr { 124struct iwl_power_mgr {
139 struct iwl_power_vec_entry pwr_range_0[IWL_POWER_NUM]; 125 struct iwl_powertable_cmd sleep_cmd;
140 struct iwl_power_vec_entry pwr_range_1[IWL_POWER_NUM]; 126 int debug_sleep_level_override;
141 struct iwl_power_vec_entry pwr_range_2[IWL_POWER_NUM]; 127 bool pci_pm;
142 u32 dtim_period;
143 /* final power level that used to calculate final power command */
144 u8 power_mode;
145 u8 user_power_setting; /* set by user through sysfs */
146 u8 power_disabled; /* set by mac80211's CONF_PS */
147}; 128};
148 129
149int iwl_power_update_mode(struct iwl_priv *priv, bool force); 130int iwl_power_update_mode(struct iwl_priv *priv, bool force);
150int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
151bool iwl_ht_enabled(struct iwl_priv *priv); 131bool iwl_ht_enabled(struct iwl_priv *priv);
152enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv); 132enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv);
153enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv); 133enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv);
@@ -158,4 +138,6 @@ void iwl_tt_initialize(struct iwl_priv *priv);
158void iwl_tt_exit(struct iwl_priv *priv); 138void iwl_tt_exit(struct iwl_priv *priv);
159void iwl_power_initialize(struct iwl_priv *priv); 139void iwl_power_initialize(struct iwl_priv *priv);
160 140
141extern bool no_sleep_autoadjust;
142
161#endif /* __iwl_power_setting_h__ */ 143#endif /* __iwl_power_setting_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index e5fa672e8390..e617411d0c5e 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3554,65 +3554,6 @@ static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate,
3554 store_retry_rate); 3554 store_retry_rate);
3555 3555
3556 3556
3557static ssize_t store_power_level(struct device *d,
3558 struct device_attribute *attr,
3559 const char *buf, size_t count)
3560{
3561 struct iwl_priv *priv = dev_get_drvdata(d);
3562 int ret;
3563 unsigned long mode;
3564
3565
3566 mutex_lock(&priv->mutex);
3567
3568 ret = strict_strtoul(buf, 10, &mode);
3569 if (ret)
3570 goto out;
3571
3572 ret = iwl_power_set_user_mode(priv, mode);
3573 if (ret) {
3574 IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
3575 goto out;
3576 }
3577 ret = count;
3578
3579 out:
3580 mutex_unlock(&priv->mutex);
3581 return ret;
3582}
3583
3584static ssize_t show_power_level(struct device *d,
3585 struct device_attribute *attr, char *buf)
3586{
3587 struct iwl_priv *priv = dev_get_drvdata(d);
3588 int level = priv->power_data.power_mode;
3589 char *p = buf;
3590
3591 p += sprintf(p, "%d\n", level);
3592 return p - buf + 1;
3593}
3594
3595static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR,
3596 show_power_level, store_power_level);
3597
3598#define MAX_WX_STRING 80
3599
3600/* Values are in microsecond */
3601static const s32 timeout_duration[] = {
3602 350000,
3603 250000,
3604 75000,
3605 37000,
3606 25000,
3607};
3608static const s32 period_duration[] = {
3609 400000,
3610 700000,
3611 1000000,
3612 1000000,
3613 1000000
3614};
3615
3616static ssize_t show_channels(struct device *d, 3557static ssize_t show_channels(struct device *d,
3617 struct device_attribute *attr, char *buf) 3558 struct device_attribute *attr, char *buf)
3618{ 3559{
@@ -3789,7 +3730,6 @@ static struct attribute *iwl3945_sysfs_entries[] = {
3789#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT 3730#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3790 &dev_attr_measurement.attr, 3731 &dev_attr_measurement.attr,
3791#endif 3732#endif
3792 &dev_attr_power_level.attr,
3793 &dev_attr_retry_rate.attr, 3733 &dev_attr_retry_rate.attr,
3794 &dev_attr_statistics.attr, 3734 &dev_attr_statistics.attr,
3795 &dev_attr_status.attr, 3735 &dev_attr_status.attr,
@@ -3854,8 +3794,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3854 priv->qos_data.qos_cap.val = 0; 3794 priv->qos_data.qos_cap.val = 0;
3855 3795
3856 priv->rates_mask = IWL_RATES_MASK; 3796 priv->rates_mask = IWL_RATES_MASK;
3857 /* If power management is turned on, default to CAM mode */
3858 priv->power_mode = IWL_POWER_MODE_CAM;
3859 priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; 3797 priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
3860 3798
3861 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { 3799 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
@@ -3902,7 +3840,9 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3902 /* Tell mac80211 our characteristics */ 3840 /* Tell mac80211 our characteristics */
3903 hw->flags = IEEE80211_HW_SIGNAL_DBM | 3841 hw->flags = IEEE80211_HW_SIGNAL_DBM |
3904 IEEE80211_HW_NOISE_DBM | 3842 IEEE80211_HW_NOISE_DBM |
3905 IEEE80211_HW_SPECTRUM_MGMT; 3843 IEEE80211_HW_SPECTRUM_MGMT |
3844 IEEE80211_HW_SUPPORTS_PS |
3845 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
3906 3846
3907 hw->wiphy->interface_modes = 3847 hw->wiphy->interface_modes =
3908 BIT(NL80211_IFTYPE_STATION) | 3848 BIT(NL80211_IFTYPE_STATION) |