aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-power.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-power.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c61
1 files changed, 25 insertions, 36 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 75ca6a542174..a4634595c59f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -60,14 +60,6 @@
60#define IWL_POWER_RANGE_1_MAX (10) 60#define IWL_POWER_RANGE_1_MAX (10)
61 61
62 62
63#define NOSLP __constant_cpu_to_le16(0), 0, 0
64#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
65#define SLP_TOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
66#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
67 __constant_cpu_to_le32(X1), \
68 __constant_cpu_to_le32(X2), \
69 __constant_cpu_to_le32(X3), \
70 __constant_cpu_to_le32(X4)}
71 63
72#define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5 64#define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5
73#define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM 65#define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM
@@ -149,7 +141,7 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
149} 141}
150 142
151/* initialize to default */ 143/* initialize to default */
152static int iwl_power_init_handle(struct iwl_priv *priv) 144static void iwl_power_init_handle(struct iwl_priv *priv)
153{ 145{
154 struct iwl_power_mgr *pow_data; 146 struct iwl_power_mgr *pow_data;
155 int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX; 147 int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
@@ -159,7 +151,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
159 151
160 IWL_DEBUG_POWER("Initialize power \n"); 152 IWL_DEBUG_POWER("Initialize power \n");
161 153
162 pow_data = &(priv->power_data); 154 pow_data = &priv->power_data;
163 155
164 memset(pow_data, 0, sizeof(*pow_data)); 156 memset(pow_data, 0, sizeof(*pow_data));
165 157
@@ -179,26 +171,25 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
179 else 171 else
180 cmd->flags |= IWL_POWER_PCI_PM_MSK; 172 cmd->flags |= IWL_POWER_PCI_PM_MSK;
181 } 173 }
182 return 0;
183} 174}
184 175
185/* adjust power command according to DTIM period and power level*/ 176/* adjust power command according to DTIM period and power level*/
186static int iwl_update_power_command(struct iwl_priv *priv, 177static int iwl_update_power_cmd(struct iwl_priv *priv,
187 struct iwl_powertable_cmd *cmd, 178 struct iwl_powertable_cmd *cmd, u16 mode)
188 u16 mode)
189{ 179{
190 int ret = 0, i;
191 u8 skip;
192 u32 max_sleep = 0;
193 struct iwl_power_vec_entry *range; 180 struct iwl_power_vec_entry *range;
194 u8 period = 0;
195 struct iwl_power_mgr *pow_data; 181 struct iwl_power_mgr *pow_data;
182 int i;
183 u32 max_sleep = 0;
184 u8 period;
185 bool skip;
196 186
197 if (mode > IWL_POWER_INDEX_5) { 187 if (mode > IWL_POWER_INDEX_5) {
198 IWL_DEBUG_POWER("Error invalid power mode \n"); 188 IWL_DEBUG_POWER("Error invalid power mode \n");
199 return -1; 189 return -EINVAL;
200 } 190 }
201 pow_data = &(priv->power_data); 191
192 pow_data = &priv->power_data;
202 193
203 if (pow_data->dtim_period <= IWL_POWER_RANGE_0_MAX) 194 if (pow_data->dtim_period <= IWL_POWER_RANGE_0_MAX)
204 range = &pow_data->pwr_range_0[0]; 195 range = &pow_data->pwr_range_0[0];
@@ -212,14 +203,12 @@ static int iwl_update_power_command(struct iwl_priv *priv,
212 203
213 if (period == 0) { 204 if (period == 0) {
214 period = 1; 205 period = 1;
215 skip = 0; 206 skip = false;
216 } else
217 skip = range[mode].no_dtim;
218
219 if (skip == 0) {
220 max_sleep = period;
221 cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
222 } else { 207 } else {
208 skip = !!range[mode].no_dtim;
209 }
210
211 if (skip) {
223 __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]; 212 __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
224 max_sleep = le32_to_cpu(slp_itrvl); 213 max_sleep = le32_to_cpu(slp_itrvl);
225 if (max_sleep == 0xFF) 214 if (max_sleep == 0xFF)
@@ -227,12 +216,14 @@ static int iwl_update_power_command(struct iwl_priv *priv,
227 else if (max_sleep > period) 216 else if (max_sleep > period)
228 max_sleep = (le32_to_cpu(slp_itrvl) / period) * period; 217 max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
229 cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK; 218 cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
219 } else {
220 max_sleep = period;
221 cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
230 } 222 }
231 223
232 for (i = 0; i < IWL_POWER_VEC_SIZE; i++) { 224 for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
233 if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep) 225 if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
234 cmd->sleep_interval[i] = cpu_to_le32(max_sleep); 226 cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
235 }
236 227
237 IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags); 228 IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);
238 IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout)); 229 IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
@@ -244,7 +235,7 @@ static int iwl_update_power_command(struct iwl_priv *priv,
244 le32_to_cpu(cmd->sleep_interval[3]), 235 le32_to_cpu(cmd->sleep_interval[3]),
245 le32_to_cpu(cmd->sleep_interval[4])); 236 le32_to_cpu(cmd->sleep_interval[4]));
246 237
247 return ret; 238 return 0;
248} 239}
249 240
250 241
@@ -295,7 +286,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
295 if (final_mode != IWL_POWER_MODE_CAM) 286 if (final_mode != IWL_POWER_MODE_CAM)
296 set_bit(STATUS_POWER_PMI, &priv->status); 287 set_bit(STATUS_POWER_PMI, &priv->status);
297 288
298 iwl_update_power_command(priv, &cmd, final_mode); 289 iwl_update_power_cmd(priv, &cmd, final_mode);
299 cmd.keep_alive_beacons = 0; 290 cmd.keep_alive_beacons = 0;
300 291
301 if (final_mode == IWL_POWER_INDEX_5) 292 if (final_mode == IWL_POWER_INDEX_5)
@@ -392,13 +383,11 @@ EXPORT_SYMBOL(iwl_power_set_system_mode);
392/* initialize to default */ 383/* initialize to default */
393void iwl_power_initialize(struct iwl_priv *priv) 384void iwl_power_initialize(struct iwl_priv *priv)
394{ 385{
395
396 iwl_power_init_handle(priv); 386 iwl_power_init_handle(priv);
397 priv->power_data.user_power_setting = IWL_POWER_AUTO; 387 priv->power_data.user_power_setting = IWL_POWER_AUTO;
398 priv->power_data.power_disabled = 0;
399 priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO; 388 priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO;
400 priv->power_data.is_battery_active = 0;
401 priv->power_data.power_disabled = 0; 389 priv->power_data.power_disabled = 0;
390 priv->power_data.is_battery_active = 0;
402 priv->power_data.critical_power_setting = 0; 391 priv->power_data.critical_power_setting = 0;
403} 392}
404EXPORT_SYMBOL(iwl_power_initialize); 393EXPORT_SYMBOL(iwl_power_initialize);
@@ -407,8 +396,8 @@ EXPORT_SYMBOL(iwl_power_initialize);
407int iwl_power_temperature_change(struct iwl_priv *priv) 396int iwl_power_temperature_change(struct iwl_priv *priv)
408{ 397{
409 int ret = 0; 398 int ret = 0;
410 u16 new_critical = priv->power_data.critical_power_setting;
411 s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature); 399 s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature);
400 u16 new_critical = priv->power_data.critical_power_setting;
412 401
413 if (temperature > IWL_CT_KILL_TEMPERATURE) 402 if (temperature > IWL_CT_KILL_TEMPERATURE)
414 return 0; 403 return 0;