diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-05-15 06:16:34 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-06-06 07:21:14 -0400 |
commit | 1023fdc4858b6b8cb88ff28cafd425b77555be9f (patch) | |
tree | 16571db8e1a8c8be475b50513a3af33c3583bfc4 /drivers/net/wireless/iwlwifi/dvm/power.c | |
parent | 20041ea622fcb1992df536d253de5120808e64a5 (diff) |
iwlwifi: move DVM code into subdirectory
Since we're working on another mode/driver
inside iwlwifi, move the current one into a
subdirectory to more cleanly separate the
code. While at it, rename all the files.
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/dvm/power.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/power.c | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/power.c b/drivers/net/wireless/iwlwifi/dvm/power.c new file mode 100644 index 000000000000..72c940759ac7 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/dvm/power.c | |||
@@ -0,0 +1,388 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2012 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/slab.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <net/mac80211.h> | ||
35 | #include "iwl-io.h" | ||
36 | #include "iwl-debug.h" | ||
37 | #include "iwl-trans.h" | ||
38 | #include "iwl-modparams.h" | ||
39 | #include "eeprom.h" | ||
40 | #include "dev.h" | ||
41 | #include "agn.h" | ||
42 | #include "commands.h" | ||
43 | #include "power.h" | ||
44 | |||
45 | /* | ||
46 | * Setting power level allows the card to go to sleep when not busy. | ||
47 | * | ||
48 | * We calculate a sleep command based on the required latency, which | ||
49 | * we get from mac80211. In order to handle thermal throttling, we can | ||
50 | * also use pre-defined power levels. | ||
51 | */ | ||
52 | |||
53 | /* | ||
54 | * This defines the old power levels. They are still used by default | ||
55 | * (level 1) and for thermal throttle (levels 3 through 5) | ||
56 | */ | ||
57 | |||
58 | struct iwl_power_vec_entry { | ||
59 | struct iwl_powertable_cmd cmd; | ||
60 | u8 no_dtim; /* number of skip dtim */ | ||
61 | }; | ||
62 | |||
63 | #define IWL_DTIM_RANGE_0_MAX 2 | ||
64 | #define IWL_DTIM_RANGE_1_MAX 10 | ||
65 | |||
66 | #define NOSLP cpu_to_le16(0), 0, 0 | ||
67 | #define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0 | ||
68 | #define ASLP (IWL_POWER_POWER_SAVE_ENA_MSK | \ | ||
69 | IWL_POWER_POWER_MANAGEMENT_ENA_MSK | \ | ||
70 | IWL_POWER_ADVANCE_PM_ENA_MSK) | ||
71 | #define ASLP_TOUT(T) cpu_to_le32(T) | ||
72 | #define TU_TO_USEC 1024 | ||
73 | #define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC) | ||
74 | #define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \ | ||
75 | cpu_to_le32(X1), \ | ||
76 | cpu_to_le32(X2), \ | ||
77 | cpu_to_le32(X3), \ | ||
78 | cpu_to_le32(X4)} | ||
79 | /* default power management (not Tx power) table values */ | ||
80 | /* for DTIM period 0 through IWL_DTIM_RANGE_0_MAX */ | ||
81 | /* DTIM 0 - 2 */ | ||
82 | static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = { | ||
83 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 1, 2, 2, 0xFF)}, 0}, | ||
84 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, | ||
85 | {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF)}, 0}, | ||
86 | {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 2, 4, 4, 0xFF)}, 1}, | ||
87 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 2, 4, 6, 0xFF)}, 2} | ||
88 | }; | ||
89 | |||
90 | |||
91 | /* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */ | ||
92 | /* DTIM 3 - 10 */ | ||
93 | static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = { | ||
94 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, | ||
95 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0}, | ||
96 | {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9)}, 0}, | ||
97 | {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 4, 6, 9, 10)}, 1}, | ||
98 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 6, 10, 10)}, 2} | ||
99 | }; | ||
100 | |||
101 | /* for DTIM period > IWL_DTIM_RANGE_1_MAX */ | ||
102 | /* DTIM 11 - */ | ||
103 | static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = { | ||
104 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, | ||
105 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, | ||
106 | {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0}, | ||
107 | {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0}, | ||
108 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} | ||
109 | }; | ||
110 | |||
111 | /* advance power management */ | ||
112 | /* DTIM 0 - 2 */ | ||
113 | static const struct iwl_power_vec_entry apm_range_0[IWL_POWER_NUM] = { | ||
114 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
115 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
116 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
117 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
118 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
119 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
120 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
121 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
122 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
123 | SLP_VEC(1, 2, 6, 8, 0xFF), ASLP_TOUT(2)}, 2} | ||
124 | }; | ||
125 | |||
126 | |||
127 | /* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */ | ||
128 | /* DTIM 3 - 10 */ | ||
129 | static const struct iwl_power_vec_entry apm_range_1[IWL_POWER_NUM] = { | ||
130 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
131 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
132 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
133 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
134 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
135 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
136 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
137 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
138 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
139 | SLP_VEC(1, 2, 6, 8, 0xFF), 0}, 2} | ||
140 | }; | ||
141 | |||
142 | /* for DTIM period > IWL_DTIM_RANGE_1_MAX */ | ||
143 | /* DTIM 11 - */ | ||
144 | static const struct iwl_power_vec_entry apm_range_2[IWL_POWER_NUM] = { | ||
145 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
146 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
147 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
148 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
149 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
150 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
151 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
152 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
153 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
154 | SLP_VEC(1, 2, 6, 8, 0xFF), ASLP_TOUT(2)}, 2} | ||
155 | }; | ||
156 | |||
157 | static void iwl_static_sleep_cmd(struct iwl_priv *priv, | ||
158 | struct iwl_powertable_cmd *cmd, | ||
159 | enum iwl_power_level lvl, int period) | ||
160 | { | ||
161 | const struct iwl_power_vec_entry *table; | ||
162 | int max_sleep[IWL_POWER_VEC_SIZE] = { 0 }; | ||
163 | int i; | ||
164 | u8 skip; | ||
165 | u32 slp_itrvl; | ||
166 | |||
167 | if (priv->cfg->adv_pm) { | ||
168 | table = apm_range_2; | ||
169 | if (period <= IWL_DTIM_RANGE_1_MAX) | ||
170 | table = apm_range_1; | ||
171 | if (period <= IWL_DTIM_RANGE_0_MAX) | ||
172 | table = apm_range_0; | ||
173 | } else { | ||
174 | table = range_2; | ||
175 | if (period <= IWL_DTIM_RANGE_1_MAX) | ||
176 | table = range_1; | ||
177 | if (period <= IWL_DTIM_RANGE_0_MAX) | ||
178 | table = range_0; | ||
179 | } | ||
180 | |||
181 | if (WARN_ON(lvl < 0 || lvl >= IWL_POWER_NUM)) | ||
182 | memset(cmd, 0, sizeof(*cmd)); | ||
183 | else | ||
184 | *cmd = table[lvl].cmd; | ||
185 | |||
186 | if (period == 0) { | ||
187 | skip = 0; | ||
188 | period = 1; | ||
189 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) | ||
190 | max_sleep[i] = 1; | ||
191 | |||
192 | } else { | ||
193 | skip = table[lvl].no_dtim; | ||
194 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) | ||
195 | max_sleep[i] = le32_to_cpu(cmd->sleep_interval[i]); | ||
196 | max_sleep[IWL_POWER_VEC_SIZE - 1] = skip + 1; | ||
197 | } | ||
198 | |||
199 | slp_itrvl = le32_to_cpu(cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]); | ||
200 | /* figure out the listen interval based on dtim period and skip */ | ||
201 | if (slp_itrvl == 0xFF) | ||
202 | cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1] = | ||
203 | cpu_to_le32(period * (skip + 1)); | ||
204 | |||
205 | slp_itrvl = le32_to_cpu(cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]); | ||
206 | if (slp_itrvl > period) | ||
207 | cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1] = | ||
208 | cpu_to_le32((slp_itrvl / period) * period); | ||
209 | |||
210 | if (skip) | ||
211 | cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK; | ||
212 | else | ||
213 | cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; | ||
214 | |||
215 | if (priv->cfg->base_params->shadow_reg_enable) | ||
216 | cmd->flags |= IWL_POWER_SHADOW_REG_ENA; | ||
217 | else | ||
218 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; | ||
219 | |||
220 | if (iwl_advanced_bt_coexist(priv)) { | ||
221 | if (!priv->cfg->bt_params->bt_sco_disable) | ||
222 | cmd->flags |= IWL_POWER_BT_SCO_ENA; | ||
223 | else | ||
224 | cmd->flags &= ~IWL_POWER_BT_SCO_ENA; | ||
225 | } | ||
226 | |||
227 | |||
228 | slp_itrvl = le32_to_cpu(cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]); | ||
229 | if (slp_itrvl > IWL_CONN_MAX_LISTEN_INTERVAL) | ||
230 | cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1] = | ||
231 | cpu_to_le32(IWL_CONN_MAX_LISTEN_INTERVAL); | ||
232 | |||
233 | /* enforce max sleep interval */ | ||
234 | for (i = IWL_POWER_VEC_SIZE - 1; i >= 0 ; i--) { | ||
235 | if (le32_to_cpu(cmd->sleep_interval[i]) > | ||
236 | (max_sleep[i] * period)) | ||
237 | cmd->sleep_interval[i] = | ||
238 | cpu_to_le32(max_sleep[i] * period); | ||
239 | if (i != (IWL_POWER_VEC_SIZE - 1)) { | ||
240 | if (le32_to_cpu(cmd->sleep_interval[i]) > | ||
241 | le32_to_cpu(cmd->sleep_interval[i+1])) | ||
242 | cmd->sleep_interval[i] = | ||
243 | cmd->sleep_interval[i+1]; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | if (priv->power_data.bus_pm) | ||
248 | cmd->flags |= IWL_POWER_PCI_PM_MSK; | ||
249 | else | ||
250 | cmd->flags &= ~IWL_POWER_PCI_PM_MSK; | ||
251 | |||
252 | IWL_DEBUG_POWER(priv, "numSkipDtim = %u, dtimPeriod = %d\n", | ||
253 | skip, period); | ||
254 | /* The power level here is 0-4 (used as array index), but user expects | ||
255 | to see 1-5 (according to spec). */ | ||
256 | IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1); | ||
257 | } | ||
258 | |||
259 | static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv, | ||
260 | struct iwl_powertable_cmd *cmd) | ||
261 | { | ||
262 | memset(cmd, 0, sizeof(*cmd)); | ||
263 | |||
264 | if (priv->power_data.bus_pm) | ||
265 | cmd->flags |= IWL_POWER_PCI_PM_MSK; | ||
266 | |||
267 | IWL_DEBUG_POWER(priv, "Sleep command for CAM\n"); | ||
268 | } | ||
269 | |||
270 | static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) | ||
271 | { | ||
272 | IWL_DEBUG_POWER(priv, "Sending power/sleep command\n"); | ||
273 | IWL_DEBUG_POWER(priv, "Flags value = 0x%08X\n", cmd->flags); | ||
274 | IWL_DEBUG_POWER(priv, "Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout)); | ||
275 | IWL_DEBUG_POWER(priv, "Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout)); | ||
276 | IWL_DEBUG_POWER(priv, "Sleep interval vector = { %d , %d , %d , %d , %d }\n", | ||
277 | le32_to_cpu(cmd->sleep_interval[0]), | ||
278 | le32_to_cpu(cmd->sleep_interval[1]), | ||
279 | le32_to_cpu(cmd->sleep_interval[2]), | ||
280 | le32_to_cpu(cmd->sleep_interval[3]), | ||
281 | le32_to_cpu(cmd->sleep_interval[4])); | ||
282 | |||
283 | return iwl_dvm_send_cmd_pdu(priv, POWER_TABLE_CMD, CMD_SYNC, | ||
284 | sizeof(struct iwl_powertable_cmd), cmd); | ||
285 | } | ||
286 | |||
287 | static void iwl_power_build_cmd(struct iwl_priv *priv, | ||
288 | struct iwl_powertable_cmd *cmd) | ||
289 | { | ||
290 | bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS; | ||
291 | int dtimper; | ||
292 | |||
293 | dtimper = priv->hw->conf.ps_dtim_period ?: 1; | ||
294 | |||
295 | if (priv->wowlan) | ||
296 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); | ||
297 | else if (!priv->cfg->base_params->no_idle_support && | ||
298 | priv->hw->conf.flags & IEEE80211_CONF_IDLE) | ||
299 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); | ||
300 | else if (iwl_tt_is_low_power_state(priv)) { | ||
301 | /* in thermal throttling low power state */ | ||
302 | iwl_static_sleep_cmd(priv, cmd, | ||
303 | iwl_tt_current_power_mode(priv), dtimper); | ||
304 | } else if (!enabled) | ||
305 | iwl_power_sleep_cam_cmd(priv, cmd); | ||
306 | else if (priv->power_data.debug_sleep_level_override >= 0) | ||
307 | iwl_static_sleep_cmd(priv, cmd, | ||
308 | priv->power_data.debug_sleep_level_override, | ||
309 | dtimper); | ||
310 | else { | ||
311 | /* Note that the user parameter is 1-5 (according to spec), | ||
312 | but we pass 0-4 because it acts as an array index. */ | ||
313 | if (iwlwifi_mod_params.power_level > IWL_POWER_INDEX_1 && | ||
314 | iwlwifi_mod_params.power_level <= IWL_POWER_NUM) | ||
315 | iwl_static_sleep_cmd(priv, cmd, | ||
316 | iwlwifi_mod_params.power_level - 1, dtimper); | ||
317 | else | ||
318 | iwl_static_sleep_cmd(priv, cmd, | ||
319 | IWL_POWER_INDEX_1, dtimper); | ||
320 | } | ||
321 | } | ||
322 | |||
323 | int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, | ||
324 | bool force) | ||
325 | { | ||
326 | int ret; | ||
327 | bool update_chains; | ||
328 | |||
329 | lockdep_assert_held(&priv->mutex); | ||
330 | |||
331 | /* Don't update the RX chain when chain noise calibration is running */ | ||
332 | update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || | ||
333 | priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; | ||
334 | |||
335 | if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force) | ||
336 | return 0; | ||
337 | |||
338 | if (!iwl_is_ready_rf(priv)) | ||
339 | return -EIO; | ||
340 | |||
341 | /* scan complete use sleep_power_next, need to be updated */ | ||
342 | memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd)); | ||
343 | if (test_bit(STATUS_SCANNING, &priv->status) && !force) { | ||
344 | IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n"); | ||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | if (cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK) | ||
349 | iwl_dvm_set_pmi(priv, true); | ||
350 | |||
351 | ret = iwl_set_power(priv, cmd); | ||
352 | if (!ret) { | ||
353 | if (!(cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)) | ||
354 | iwl_dvm_set_pmi(priv, false); | ||
355 | |||
356 | if (update_chains) | ||
357 | iwl_update_chain_flags(priv); | ||
358 | else | ||
359 | IWL_DEBUG_POWER(priv, | ||
360 | "Cannot update the power, chain noise " | ||
361 | "calibration running: %d\n", | ||
362 | priv->chain_noise_data.state); | ||
363 | |||
364 | memcpy(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)); | ||
365 | } else | ||
366 | IWL_ERR(priv, "set power fail, ret = %d", ret); | ||
367 | |||
368 | return ret; | ||
369 | } | ||
370 | |||
371 | int iwl_power_update_mode(struct iwl_priv *priv, bool force) | ||
372 | { | ||
373 | struct iwl_powertable_cmd cmd; | ||
374 | |||
375 | iwl_power_build_cmd(priv, &cmd); | ||
376 | return iwl_power_set_mode(priv, &cmd, force); | ||
377 | } | ||
378 | |||
379 | /* initialize to default */ | ||
380 | void iwl_power_initialize(struct iwl_priv *priv) | ||
381 | { | ||
382 | priv->power_data.bus_pm = priv->trans->pm_support; | ||
383 | |||
384 | priv->power_data.debug_sleep_level_override = -1; | ||
385 | |||
386 | memset(&priv->power_data.sleep_cmd, 0, | ||
387 | sizeof(priv->power_data.sleep_cmd)); | ||
388 | } | ||