diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-calib.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-power.c | 228 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-power.h | 39 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 20 |
7 files changed, 48 insertions, 292 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 43bc8a66864e..13a35dc710a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1838,7 +1838,6 @@ void iwl_post_associate(struct iwl_priv *priv) | |||
1838 | if (!priv->vif || !priv->is_open) | 1838 | if (!priv->vif || !priv->is_open) |
1839 | return; | 1839 | return; |
1840 | 1840 | ||
1841 | iwl_power_cancel_timeout(priv); | ||
1842 | iwl_scan_cancel_timeout(priv, 200); | 1841 | iwl_scan_cancel_timeout(priv, 200); |
1843 | 1842 | ||
1844 | conf = ieee80211_get_hw_conf(priv->hw); | 1843 | conf = ieee80211_get_hw_conf(priv->hw); |
@@ -1914,7 +1913,7 @@ void iwl_post_associate(struct iwl_priv *priv) | |||
1914 | * If chain noise has already been run, then we need to enable | 1913 | * If chain noise has already been run, then we need to enable |
1915 | * power management here */ | 1914 | * power management here */ |
1916 | if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) | 1915 | if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) |
1917 | iwl_power_enable_management(priv); | 1916 | iwl_power_update_mode(priv, 0); |
1918 | 1917 | ||
1919 | /* Enable Rx differential gain and sensitivity calibrations */ | 1918 | /* Enable Rx differential gain and sensitivity calibrations */ |
1920 | iwl_chain_noise_reset(priv); | 1919 | iwl_chain_noise_reset(priv); |
@@ -2465,26 +2464,11 @@ static ssize_t show_power_level(struct device *d, | |||
2465 | { | 2464 | { |
2466 | struct iwl_priv *priv = dev_get_drvdata(d); | 2465 | struct iwl_priv *priv = dev_get_drvdata(d); |
2467 | int mode = priv->power_data.user_power_setting; | 2466 | int mode = priv->power_data.user_power_setting; |
2468 | int system = priv->power_data.system_power_setting; | ||
2469 | int level = priv->power_data.power_mode; | 2467 | int level = priv->power_data.power_mode; |
2470 | char *p = buf; | 2468 | char *p = buf; |
2471 | 2469 | ||
2472 | switch (system) { | 2470 | p += sprintf(p, "INDEX:%d\t", level); |
2473 | case IWL_POWER_SYS_AUTO: | 2471 | p += sprintf(p, "USER:%d\n", mode); |
2474 | p += sprintf(p, "SYSTEM:auto"); | ||
2475 | break; | ||
2476 | case IWL_POWER_SYS_AC: | ||
2477 | p += sprintf(p, "SYSTEM:ac"); | ||
2478 | break; | ||
2479 | case IWL_POWER_SYS_BATTERY: | ||
2480 | p += sprintf(p, "SYSTEM:battery"); | ||
2481 | break; | ||
2482 | } | ||
2483 | |||
2484 | p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ? | ||
2485 | "fixed" : "auto"); | ||
2486 | p += sprintf(p, "\tINDEX:%d", level); | ||
2487 | p += sprintf(p, "\n"); | ||
2488 | return p - buf + 1; | 2472 | return p - buf + 1; |
2489 | } | 2473 | } |
2490 | 2474 | ||
@@ -2553,7 +2537,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
2553 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); | 2537 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); |
2554 | 2538 | ||
2555 | iwl_setup_scan_deferred_work(priv); | 2539 | iwl_setup_scan_deferred_work(priv); |
2556 | iwl_setup_power_deferred_work(priv); | ||
2557 | 2540 | ||
2558 | if (priv->cfg->ops->lib->setup_deferred_work) | 2541 | if (priv->cfg->ops->lib->setup_deferred_work) |
2559 | priv->cfg->ops->lib->setup_deferred_work(priv); | 2542 | priv->cfg->ops->lib->setup_deferred_work(priv); |
@@ -2573,7 +2556,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
2573 | 2556 | ||
2574 | cancel_delayed_work_sync(&priv->init_alive_start); | 2557 | cancel_delayed_work_sync(&priv->init_alive_start); |
2575 | cancel_delayed_work(&priv->scan_check); | 2558 | cancel_delayed_work(&priv->scan_check); |
2576 | cancel_delayed_work_sync(&priv->set_power_save); | ||
2577 | cancel_delayed_work(&priv->alive_start); | 2559 | cancel_delayed_work(&priv->alive_start); |
2578 | cancel_work_sync(&priv->beacon_update); | 2560 | cancel_work_sync(&priv->beacon_update); |
2579 | del_timer_sync(&priv->statistics_periodic); | 2561 | del_timer_sync(&priv->statistics_periodic); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c index 735f3f19928c..a5d63672ad39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-calib.c | |||
@@ -857,7 +857,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, | |||
857 | priv->cfg->ops->lib->update_chain_flags(priv); | 857 | priv->cfg->ops->lib->update_chain_flags(priv); |
858 | 858 | ||
859 | data->state = IWL_CHAIN_NOISE_DONE; | 859 | data->state = IWL_CHAIN_NOISE_DONE; |
860 | iwl_power_enable_management(priv); | 860 | iwl_power_update_mode(priv, 0); |
861 | } | 861 | } |
862 | EXPORT_SYMBOL(iwl_chain_noise_calibration); | 862 | EXPORT_SYMBOL(iwl_chain_noise_calibration); |
863 | 863 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index aa1e1dc95ef6..112bfa50b8fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1352,7 +1352,6 @@ int iwl_init_drv(struct iwl_priv *priv) | |||
1352 | priv->ibss_beacon = NULL; | 1352 | priv->ibss_beacon = NULL; |
1353 | 1353 | ||
1354 | spin_lock_init(&priv->lock); | 1354 | spin_lock_init(&priv->lock); |
1355 | spin_lock_init(&priv->power_data.lock); | ||
1356 | spin_lock_init(&priv->sta_lock); | 1355 | spin_lock_init(&priv->sta_lock); |
1357 | spin_lock_init(&priv->hcmd_lock); | 1356 | spin_lock_init(&priv->hcmd_lock); |
1358 | 1357 | ||
@@ -2576,14 +2575,13 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2576 | iwl_set_rate(priv); | 2575 | iwl_set_rate(priv); |
2577 | } | 2576 | } |
2578 | 2577 | ||
2579 | if (changed & IEEE80211_CONF_CHANGE_PS) { | 2578 | if (changed & IEEE80211_CONF_CHANGE_PS && |
2580 | if (conf->flags & IEEE80211_CONF_PS) | 2579 | priv->iw_mode == NL80211_IFTYPE_STATION) { |
2581 | ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3); | 2580 | priv->power_data.power_disabled = |
2582 | else | 2581 | !(conf->flags & IEEE80211_CONF_PS); |
2583 | ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM); | 2582 | ret = iwl_power_update_mode(priv, 0); |
2584 | if (ret) | 2583 | if (ret) |
2585 | IWL_DEBUG_MAC80211(priv, "Error setting power level\n"); | 2584 | IWL_DEBUG_MAC80211(priv, "Error setting power level\n"); |
2586 | |||
2587 | } | 2585 | } |
2588 | 2586 | ||
2589 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | 2587 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
@@ -2719,21 +2717,7 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) | |||
2719 | iwlcore_commit_rxon(priv); | 2717 | iwlcore_commit_rxon(priv); |
2720 | } | 2718 | } |
2721 | 2719 | ||
2722 | iwl_power_update_mode(priv, 0); | ||
2723 | |||
2724 | /* Per mac80211.h: This is only used in IBSS mode... */ | ||
2725 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { | 2720 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { |
2726 | |||
2727 | /* switch to CAM during association period. | ||
2728 | * the ucode will block any association/authentication | ||
2729 | * frome during assiciation period if it can not hear | ||
2730 | * the AP because of PM. the timer enable PM back is | ||
2731 | * association do not complete | ||
2732 | */ | ||
2733 | if (priv->hw->conf.channel->flags & | ||
2734 | (IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_RADAR)) | ||
2735 | iwl_power_disable_management(priv, 3000); | ||
2736 | |||
2737 | IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n"); | 2721 | IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n"); |
2738 | mutex_unlock(&priv->mutex); | 2722 | mutex_unlock(&priv->mutex); |
2739 | return; | 2723 | return; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 0f2c1b217515..3049ba25c3fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1075,7 +1075,6 @@ struct iwl_priv { | |||
1075 | 1075 | ||
1076 | struct tasklet_struct irq_tasklet; | 1076 | struct tasklet_struct irq_tasklet; |
1077 | 1077 | ||
1078 | struct delayed_work set_power_save; | ||
1079 | struct delayed_work init_alive_start; | 1078 | struct delayed_work init_alive_start; |
1080 | struct delayed_work alive_start; | 1079 | struct delayed_work alive_start; |
1081 | struct delayed_work scan_check; | 1080 | struct delayed_work scan_check; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index c913069a2496..f2ea3f05f6e1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -41,38 +41,33 @@ | |||
41 | #include "iwl-power.h" | 41 | #include "iwl-power.h" |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * Setting power level allow the card to go to sleep when not busy | 44 | * Setting power level allow the card to go to sleep when not busy. |
45 | * there are three factor that decide the power level to go to, they | ||
46 | * are list here with its priority | ||
47 | * 1- critical_power_setting this will be set according to card temperature. | ||
48 | * 2- system_power_setting this will be set by system PM manager. | ||
49 | * 3- user_power_setting this will be set by user either by writing to sys or | ||
50 | * mac80211 | ||
51 | * | 45 | * |
52 | * if system_power_setting and user_power_setting is set to auto | 46 | * The power level is set to INDEX_1 (the least deep state) by |
53 | * the power level will be decided according to association status and battery | 47 | * default, and will, in the future, be the deepest state unless |
54 | * status. | 48 | * otherwise required by pm_qos network latency requirements. |
55 | * | 49 | * |
50 | * Using INDEX_1 without pm_qos is ok because mac80211 will disable | ||
51 | * PS when even checking every beacon for the TIM bit would exceed | ||
52 | * the required latency. | ||
56 | */ | 53 | */ |
57 | 54 | ||
58 | #define MSEC_TO_USEC 1024 | ||
59 | #define IWL_POWER_RANGE_0_MAX (2) | 55 | #define IWL_POWER_RANGE_0_MAX (2) |
60 | #define IWL_POWER_RANGE_1_MAX (10) | 56 | #define IWL_POWER_RANGE_1_MAX (10) |
61 | 57 | ||
62 | 58 | ||
63 | 59 | #define NOSLP cpu_to_le16(0), 0, 0 | |
64 | #define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5 | 60 | #define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0 |
65 | #define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM | 61 | #define TU_TO_USEC 1024 |
66 | #define IWL_POWER_ON_AC_ASSOC IWL_POWER_MODE_CAM | 62 | #define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC) |
67 | 63 | #define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \ | |
68 | 64 | cpu_to_le32(X1), \ | |
69 | #define IWL_CT_KILL_TEMPERATURE 110 | 65 | cpu_to_le32(X2), \ |
70 | #define IWL_MIN_POWER_TEMPERATURE 100 | 66 | cpu_to_le32(X3), \ |
71 | #define IWL_REDUCED_POWER_TEMPERATURE 95 | 67 | cpu_to_le32(X4)} |
72 | |||
73 | /* default power management (not Tx power) table values */ | 68 | /* default power management (not Tx power) table values */ |
74 | /* for TIM 0-10 */ | 69 | /* for DTIM period 0 through IWL_POWER_RANGE_0_MAX */ |
75 | static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = { | 70 | static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = { |
76 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, | 71 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, |
77 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, | 72 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, |
78 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, | 73 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, |
@@ -82,8 +77,8 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = { | |||
82 | }; | 77 | }; |
83 | 78 | ||
84 | 79 | ||
85 | /* for TIM = 3-10 */ | 80 | /* for DTIM period IWL_POWER_RANGE_0_MAX + 1 through IWL_POWER_RANGE_1_MAX */ |
86 | static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = { | 81 | static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = { |
87 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, | 82 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, |
88 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, | 83 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, |
89 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0}, | 84 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0}, |
@@ -92,8 +87,8 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = { | |||
92 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2} | 87 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2} |
93 | }; | 88 | }; |
94 | 89 | ||
95 | /* for TIM > 11 */ | 90 | /* for DTIM period > IWL_POWER_RANGE_1_MAX */ |
96 | static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = { | 91 | static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = { |
97 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, | 92 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, |
98 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, | 93 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, |
99 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, | 94 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, |
@@ -109,35 +104,12 @@ static int iwl_set_power(struct iwl_priv *priv, void *cmd) | |||
109 | return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, | 104 | return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, |
110 | sizeof(struct iwl_powertable_cmd), cmd); | 105 | sizeof(struct iwl_powertable_cmd), cmd); |
111 | } | 106 | } |
112 | /* decide the right power level according to association status | ||
113 | * and battery status | ||
114 | */ | ||
115 | static u16 iwl_get_auto_power_mode(struct iwl_priv *priv) | ||
116 | { | ||
117 | u16 mode; | ||
118 | |||
119 | switch (priv->power_data.user_power_setting) { | ||
120 | case IWL_POWER_AUTO: | ||
121 | /* if running on battery */ | ||
122 | if (priv->power_data.is_battery_active) | ||
123 | mode = IWL_POWER_ON_BATTERY; | ||
124 | else if (iwl_is_associated(priv)) | ||
125 | mode = IWL_POWER_ON_AC_ASSOC; | ||
126 | else | ||
127 | mode = IWL_POWER_ON_AC_DISASSOC; | ||
128 | break; | ||
129 | default: | ||
130 | mode = priv->power_data.user_power_setting; | ||
131 | break; | ||
132 | } | ||
133 | return mode; | ||
134 | } | ||
135 | 107 | ||
136 | /* initialize to default */ | 108 | /* initialize to default */ |
137 | static void iwl_power_init_handle(struct iwl_priv *priv) | 109 | static void iwl_power_init_handle(struct iwl_priv *priv) |
138 | { | 110 | { |
139 | struct iwl_power_mgr *pow_data; | 111 | struct iwl_power_mgr *pow_data; |
140 | int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX; | 112 | int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_NUM; |
141 | struct iwl_powertable_cmd *cmd; | 113 | struct iwl_powertable_cmd *cmd; |
142 | int i; | 114 | int i; |
143 | u16 lctl; | 115 | u16 lctl; |
@@ -156,7 +128,7 @@ static void iwl_power_init_handle(struct iwl_priv *priv) | |||
156 | 128 | ||
157 | IWL_DEBUG_POWER(priv, "adjust power command flags\n"); | 129 | IWL_DEBUG_POWER(priv, "adjust power command flags\n"); |
158 | 130 | ||
159 | for (i = 0; i < IWL_POWER_MAX; i++) { | 131 | for (i = 0; i < IWL_POWER_NUM; i++) { |
160 | cmd = &pow_data->pwr_range_0[i].cmd; | 132 | cmd = &pow_data->pwr_range_0[i].cmd; |
161 | 133 | ||
162 | if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN) | 134 | if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN) |
@@ -246,33 +218,12 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) | |||
246 | update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || | 218 | update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || |
247 | priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; | 219 | priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; |
248 | 220 | ||
249 | /* If on battery, set to 3, | 221 | final_mode = priv->power_data.user_power_setting; |
250 | * if plugged into AC power, set to CAM ("continuously aware mode"), | ||
251 | * else user level */ | ||
252 | |||
253 | switch (setting->system_power_setting) { | ||
254 | case IWL_POWER_SYS_AUTO: | ||
255 | final_mode = iwl_get_auto_power_mode(priv); | ||
256 | break; | ||
257 | case IWL_POWER_SYS_BATTERY: | ||
258 | final_mode = IWL_POWER_INDEX_3; | ||
259 | break; | ||
260 | case IWL_POWER_SYS_AC: | ||
261 | final_mode = IWL_POWER_MODE_CAM; | ||
262 | break; | ||
263 | default: | ||
264 | final_mode = IWL_POWER_INDEX_3; | ||
265 | WARN_ON(1); | ||
266 | } | ||
267 | |||
268 | if (setting->critical_power_setting > final_mode) | ||
269 | final_mode = setting->critical_power_setting; | ||
270 | 222 | ||
271 | /* driver only support CAM for non STA network */ | 223 | if (setting->power_disabled) |
272 | if (priv->iw_mode != NL80211_IFTYPE_STATION) | ||
273 | final_mode = IWL_POWER_MODE_CAM; | 224 | final_mode = IWL_POWER_MODE_CAM; |
274 | 225 | ||
275 | if (iwl_is_ready_rf(priv) && !setting->power_disabled && | 226 | if (iwl_is_ready_rf(priv) && |
276 | ((setting->power_mode != final_mode) || force)) { | 227 | ((setting->power_mode != final_mode) || force)) { |
277 | struct iwl_powertable_cmd cmd; | 228 | struct iwl_powertable_cmd cmd; |
278 | 229 | ||
@@ -289,8 +240,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) | |||
289 | 240 | ||
290 | if (final_mode == IWL_POWER_MODE_CAM) | 241 | if (final_mode == IWL_POWER_MODE_CAM) |
291 | clear_bit(STATUS_POWER_PMI, &priv->status); | 242 | clear_bit(STATUS_POWER_PMI, &priv->status); |
292 | else | ||
293 | set_bit(STATUS_POWER_PMI, &priv->status); | ||
294 | 243 | ||
295 | if (priv->cfg->ops->lib->update_chain_flags && update_chains) | 244 | if (priv->cfg->ops->lib->update_chain_flags && update_chains) |
296 | priv->cfg->ops->lib->update_chain_flags(priv); | 245 | priv->cfg->ops->lib->update_chain_flags(priv); |
@@ -306,51 +255,10 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) | |||
306 | } | 255 | } |
307 | EXPORT_SYMBOL(iwl_power_update_mode); | 256 | EXPORT_SYMBOL(iwl_power_update_mode); |
308 | 257 | ||
309 | /* Allow other iwl code to disable/enable power management active | ||
310 | * this will be useful for rate scale to disable PM during heavy | ||
311 | * Tx/Rx activities | ||
312 | */ | ||
313 | int iwl_power_disable_management(struct iwl_priv *priv, u32 ms) | ||
314 | { | ||
315 | u16 prev_mode; | ||
316 | int ret = 0; | ||
317 | |||
318 | if (priv->power_data.power_disabled) | ||
319 | return -EBUSY; | ||
320 | |||
321 | prev_mode = priv->power_data.user_power_setting; | ||
322 | priv->power_data.user_power_setting = IWL_POWER_MODE_CAM; | ||
323 | ret = iwl_power_update_mode(priv, 0); | ||
324 | priv->power_data.power_disabled = 1; | ||
325 | priv->power_data.user_power_setting = prev_mode; | ||
326 | cancel_delayed_work(&priv->set_power_save); | ||
327 | if (ms) | ||
328 | queue_delayed_work(priv->workqueue, &priv->set_power_save, | ||
329 | msecs_to_jiffies(ms)); | ||
330 | |||
331 | |||
332 | return ret; | ||
333 | } | ||
334 | EXPORT_SYMBOL(iwl_power_disable_management); | ||
335 | |||
336 | /* Allow other iwl code to disable/enable power management active | ||
337 | * this will be useful for rate scale to disable PM during high | ||
338 | * volume activities | ||
339 | */ | ||
340 | int iwl_power_enable_management(struct iwl_priv *priv) | ||
341 | { | ||
342 | int ret = 0; | ||
343 | |||
344 | priv->power_data.power_disabled = 0; | ||
345 | ret = iwl_power_update_mode(priv, 0); | ||
346 | return ret; | ||
347 | } | ||
348 | EXPORT_SYMBOL(iwl_power_enable_management); | ||
349 | |||
350 | /* set user_power_setting */ | 258 | /* set user_power_setting */ |
351 | int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode) | 259 | int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode) |
352 | { | 260 | { |
353 | if (mode > IWL_POWER_MAX) | 261 | if (mode >= IWL_POWER_NUM) |
354 | return -EINVAL; | 262 | return -EINVAL; |
355 | 263 | ||
356 | priv->power_data.user_power_setting = mode; | 264 | priv->power_data.user_power_setting = mode; |
@@ -359,86 +267,12 @@ int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode) | |||
359 | } | 267 | } |
360 | EXPORT_SYMBOL(iwl_power_set_user_mode); | 268 | EXPORT_SYMBOL(iwl_power_set_user_mode); |
361 | 269 | ||
362 | /* set system_power_setting. This should be set by over all | ||
363 | * PM application. | ||
364 | */ | ||
365 | int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode) | ||
366 | { | ||
367 | if (mode < IWL_POWER_SYS_MAX) | ||
368 | priv->power_data.system_power_setting = mode; | ||
369 | else | ||
370 | return -EINVAL; | ||
371 | return iwl_power_update_mode(priv, 0); | ||
372 | } | ||
373 | EXPORT_SYMBOL(iwl_power_set_system_mode); | ||
374 | |||
375 | /* initialize to default */ | 270 | /* initialize to default */ |
376 | void iwl_power_initialize(struct iwl_priv *priv) | 271 | void iwl_power_initialize(struct iwl_priv *priv) |
377 | { | 272 | { |
378 | iwl_power_init_handle(priv); | 273 | iwl_power_init_handle(priv); |
379 | priv->power_data.user_power_setting = IWL_POWER_AUTO; | 274 | priv->power_data.user_power_setting = IWL_POWER_INDEX_1; |
380 | priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO; | 275 | /* default to disabled until mac80211 says otherwise */ |
381 | priv->power_data.power_disabled = 0; | 276 | priv->power_data.power_disabled = 1; |
382 | priv->power_data.is_battery_active = 0; | ||
383 | priv->power_data.critical_power_setting = 0; | ||
384 | } | 277 | } |
385 | EXPORT_SYMBOL(iwl_power_initialize); | 278 | EXPORT_SYMBOL(iwl_power_initialize); |
386 | |||
387 | /* set critical_power_setting according to temperature value */ | ||
388 | int iwl_power_temperature_change(struct iwl_priv *priv) | ||
389 | { | ||
390 | int ret = 0; | ||
391 | s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature); | ||
392 | u16 new_critical = priv->power_data.critical_power_setting; | ||
393 | |||
394 | if (temperature > IWL_CT_KILL_TEMPERATURE) | ||
395 | return 0; | ||
396 | else if (temperature > IWL_MIN_POWER_TEMPERATURE) | ||
397 | new_critical = IWL_POWER_INDEX_5; | ||
398 | else if (temperature > IWL_REDUCED_POWER_TEMPERATURE) | ||
399 | new_critical = IWL_POWER_INDEX_3; | ||
400 | else | ||
401 | new_critical = IWL_POWER_MODE_CAM; | ||
402 | |||
403 | if (new_critical != priv->power_data.critical_power_setting) | ||
404 | priv->power_data.critical_power_setting = new_critical; | ||
405 | |||
406 | if (priv->power_data.critical_power_setting > | ||
407 | priv->power_data.power_mode) | ||
408 | ret = iwl_power_update_mode(priv, 0); | ||
409 | |||
410 | return ret; | ||
411 | } | ||
412 | EXPORT_SYMBOL(iwl_power_temperature_change); | ||
413 | |||
414 | static void iwl_bg_set_power_save(struct work_struct *work) | ||
415 | { | ||
416 | struct iwl_priv *priv = container_of(work, | ||
417 | struct iwl_priv, set_power_save.work); | ||
418 | IWL_DEBUG_POWER(priv, "update power\n"); | ||
419 | |||
420 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
421 | return; | ||
422 | |||
423 | mutex_lock(&priv->mutex); | ||
424 | |||
425 | /* on starting association we disable power management | ||
426 | * until association, if association failed then this | ||
427 | * timer will expire and enable PM again. | ||
428 | */ | ||
429 | if (!iwl_is_associated(priv)) | ||
430 | iwl_power_enable_management(priv); | ||
431 | |||
432 | mutex_unlock(&priv->mutex); | ||
433 | } | ||
434 | void iwl_setup_power_deferred_work(struct iwl_priv *priv) | ||
435 | { | ||
436 | INIT_DELAYED_WORK(&priv->set_power_save, iwl_bg_set_power_save); | ||
437 | } | ||
438 | EXPORT_SYMBOL(iwl_setup_power_deferred_work); | ||
439 | |||
440 | void iwl_power_cancel_timeout(struct iwl_priv *priv) | ||
441 | { | ||
442 | cancel_delayed_work(&priv->set_power_save); | ||
443 | } | ||
444 | EXPORT_SYMBOL(iwl_power_cancel_timeout); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index 18963392121e..37ba3bb7a25a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h | |||
@@ -40,56 +40,29 @@ enum { | |||
40 | IWL_POWER_INDEX_3, | 40 | IWL_POWER_INDEX_3, |
41 | IWL_POWER_INDEX_4, | 41 | IWL_POWER_INDEX_4, |
42 | IWL_POWER_INDEX_5, | 42 | IWL_POWER_INDEX_5, |
43 | IWL_POWER_AUTO, | 43 | IWL_POWER_NUM |
44 | IWL_POWER_MAX = IWL_POWER_AUTO, | ||
45 | }; | 44 | }; |
46 | 45 | ||
47 | enum { | ||
48 | IWL_POWER_SYS_AUTO, | ||
49 | IWL_POWER_SYS_AC, | ||
50 | IWL_POWER_SYS_BATTERY, | ||
51 | IWL_POWER_SYS_MAX, | ||
52 | }; | ||
53 | |||
54 | |||
55 | /* Power management (not Tx power) structures */ | 46 | /* Power management (not Tx power) structures */ |
56 | 47 | ||
57 | #define NOSLP cpu_to_le16(0), 0, 0 | ||
58 | #define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0 | ||
59 | #define SLP_TOUT(T) cpu_to_le32((T) * MSEC_TO_USEC) | ||
60 | #define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \ | ||
61 | cpu_to_le32(X1), \ | ||
62 | cpu_to_le32(X2), \ | ||
63 | cpu_to_le32(X3), \ | ||
64 | cpu_to_le32(X4)} | ||
65 | struct iwl_power_vec_entry { | 48 | struct iwl_power_vec_entry { |
66 | struct iwl_powertable_cmd cmd; | 49 | struct iwl_powertable_cmd cmd; |
67 | u8 no_dtim; | 50 | u8 no_dtim; |
68 | }; | 51 | }; |
69 | 52 | ||
70 | struct iwl_power_mgr { | 53 | struct iwl_power_mgr { |
71 | spinlock_t lock; | 54 | struct iwl_power_vec_entry pwr_range_0[IWL_POWER_NUM]; |
72 | struct iwl_power_vec_entry pwr_range_0[IWL_POWER_MAX]; | 55 | struct iwl_power_vec_entry pwr_range_1[IWL_POWER_NUM]; |
73 | struct iwl_power_vec_entry pwr_range_1[IWL_POWER_MAX]; | 56 | struct iwl_power_vec_entry pwr_range_2[IWL_POWER_NUM]; |
74 | struct iwl_power_vec_entry pwr_range_2[IWL_POWER_MAX]; | ||
75 | u32 dtim_period; | 57 | u32 dtim_period; |
76 | /* final power level that used to calculate final power command */ | 58 | /* final power level that used to calculate final power command */ |
77 | u8 power_mode; | 59 | u8 power_mode; |
78 | u8 user_power_setting; /* set by user through mac80211 or sysfs */ | 60 | u8 user_power_setting; /* set by user through sysfs */ |
79 | u8 system_power_setting; /* set by kernel system tools */ | 61 | u8 power_disabled; /* set by mac80211's CONF_PS */ |
80 | u8 critical_power_setting; /* set if driver over heated */ | ||
81 | u8 is_battery_active; /* DC/AC power */ | ||
82 | u8 power_disabled; /* flag to disable using power saving level */ | ||
83 | }; | 62 | }; |
84 | 63 | ||
85 | void iwl_setup_power_deferred_work(struct iwl_priv *priv); | ||
86 | void iwl_power_cancel_timeout(struct iwl_priv *priv); | ||
87 | int iwl_power_update_mode(struct iwl_priv *priv, bool force); | 64 | int iwl_power_update_mode(struct iwl_priv *priv, bool force); |
88 | int iwl_power_disable_management(struct iwl_priv *priv, u32 ms); | ||
89 | int iwl_power_enable_management(struct iwl_priv *priv); | ||
90 | int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode); | 65 | int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode); |
91 | int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode); | ||
92 | void iwl_power_initialize(struct iwl_priv *priv); | 66 | void iwl_power_initialize(struct iwl_priv *priv); |
93 | int iwl_power_temperature_change(struct iwl_priv *priv); | ||
94 | 67 | ||
95 | #endif /* __iwl_power_setting_h__ */ | 68 | #endif /* __iwl_power_setting_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 271e5d1f8425..c32ec809053f 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -3845,26 +3845,11 @@ static ssize_t show_power_level(struct device *d, | |||
3845 | { | 3845 | { |
3846 | struct iwl_priv *priv = dev_get_drvdata(d); | 3846 | struct iwl_priv *priv = dev_get_drvdata(d); |
3847 | int mode = priv->power_data.user_power_setting; | 3847 | int mode = priv->power_data.user_power_setting; |
3848 | int system = priv->power_data.system_power_setting; | ||
3849 | int level = priv->power_data.power_mode; | 3848 | int level = priv->power_data.power_mode; |
3850 | char *p = buf; | 3849 | char *p = buf; |
3851 | 3850 | ||
3852 | switch (system) { | 3851 | p += sprintf(p, "INDEX:%d\t", level); |
3853 | case IWL_POWER_SYS_AUTO: | 3852 | p += sprintf(p, "USER:%d\n", mode); |
3854 | p += sprintf(p, "SYSTEM:auto"); | ||
3855 | break; | ||
3856 | case IWL_POWER_SYS_AC: | ||
3857 | p += sprintf(p, "SYSTEM:ac"); | ||
3858 | break; | ||
3859 | case IWL_POWER_SYS_BATTERY: | ||
3860 | p += sprintf(p, "SYSTEM:battery"); | ||
3861 | break; | ||
3862 | } | ||
3863 | |||
3864 | p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ? | ||
3865 | "fixed" : "auto"); | ||
3866 | p += sprintf(p, "\tINDEX:%d", level); | ||
3867 | p += sprintf(p, "\n"); | ||
3868 | return p - buf + 1; | 3853 | return p - buf + 1; |
3869 | } | 3854 | } |
3870 | 3855 | ||
@@ -4108,7 +4093,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
4108 | priv->ibss_beacon = NULL; | 4093 | priv->ibss_beacon = NULL; |
4109 | 4094 | ||
4110 | spin_lock_init(&priv->lock); | 4095 | spin_lock_init(&priv->lock); |
4111 | spin_lock_init(&priv->power_data.lock); | ||
4112 | spin_lock_init(&priv->sta_lock); | 4096 | spin_lock_init(&priv->sta_lock); |
4113 | spin_lock_init(&priv->hcmd_lock); | 4097 | spin_lock_init(&priv->hcmd_lock); |
4114 | 4098 | ||