diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-power.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-power.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 2e71803e09ba..028e3053c0ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -82,7 +82,7 @@ | |||
82 | 82 | ||
83 | /* default power management (not Tx power) table values */ | 83 | /* default power management (not Tx power) table values */ |
84 | /* for tim 0-10 */ | 84 | /* for tim 0-10 */ |
85 | static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = { | 85 | static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = { |
86 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, | 86 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, |
87 | {{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}, |
88 | {{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}, |
@@ -93,7 +93,7 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = { | |||
93 | 93 | ||
94 | 94 | ||
95 | /* for tim = 3-10 */ | 95 | /* for tim = 3-10 */ |
96 | static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = { | 96 | static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = { |
97 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, | 97 | {{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, 4)}, 0}, | 98 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, |
99 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0}, | 99 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0}, |
@@ -103,7 +103,7 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = { | |||
103 | }; | 103 | }; |
104 | 104 | ||
105 | /* for tim > 11 */ | 105 | /* for tim > 11 */ |
106 | static struct iwl_power_vec_entry range_2[IWL_POWER_AC] = { | 106 | static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = { |
107 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, | 107 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, |
108 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, | 108 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, |
109 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, | 109 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, |
@@ -112,12 +112,19 @@ static struct iwl_power_vec_entry range_2[IWL_POWER_AC] = { | |||
112 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} | 112 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} |
113 | }; | 113 | }; |
114 | 114 | ||
115 | /* set card power command */ | ||
116 | static int iwl_set_power(struct iwl_priv *priv, void *cmd) | ||
117 | { | ||
118 | return iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD, | ||
119 | sizeof(struct iwl_powertable_cmd), | ||
120 | cmd, NULL); | ||
121 | } | ||
115 | /* decide the right power level according to association status | 122 | /* decide the right power level according to association status |
116 | * and battery status | 123 | * and battery status |
117 | */ | 124 | */ |
118 | static u16 iwl_get_auto_power_mode(struct iwl_priv *priv) | 125 | static u16 iwl_get_auto_power_mode(struct iwl_priv *priv) |
119 | { | 126 | { |
120 | u16 mode = priv->power_data.user_power_setting; | 127 | u16 mode; |
121 | 128 | ||
122 | switch (priv->power_data.user_power_setting) { | 129 | switch (priv->power_data.user_power_setting) { |
123 | case IWL_POWER_AUTO: | 130 | case IWL_POWER_AUTO: |
@@ -129,12 +136,16 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv) | |||
129 | else | 136 | else |
130 | mode = IWL_POWER_ON_AC_DISASSOC; | 137 | mode = IWL_POWER_ON_AC_DISASSOC; |
131 | break; | 138 | break; |
139 | /* FIXME: remove battery and ac from here */ | ||
132 | case IWL_POWER_BATTERY: | 140 | case IWL_POWER_BATTERY: |
133 | mode = IWL_POWER_INDEX_3; | 141 | mode = IWL_POWER_INDEX_3; |
134 | break; | 142 | break; |
135 | case IWL_POWER_AC: | 143 | case IWL_POWER_AC: |
136 | mode = IWL_POWER_MODE_CAM; | 144 | mode = IWL_POWER_MODE_CAM; |
137 | break; | 145 | break; |
146 | default: | ||
147 | mode = priv->power_data.user_power_setting; | ||
148 | break; | ||
138 | } | 149 | } |
139 | return mode; | 150 | return mode; |
140 | } | 151 | } |
@@ -144,7 +155,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv) | |||
144 | { | 155 | { |
145 | int ret = 0, i; | 156 | int ret = 0, i; |
146 | struct iwl_power_mgr *pow_data; | 157 | struct iwl_power_mgr *pow_data; |
147 | int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_AC; | 158 | int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX; |
148 | u16 pci_pm; | 159 | u16 pci_pm; |
149 | 160 | ||
150 | IWL_DEBUG_POWER("Initialize power \n"); | 161 | IWL_DEBUG_POWER("Initialize power \n"); |
@@ -162,11 +173,11 @@ static int iwl_power_init_handle(struct iwl_priv *priv) | |||
162 | if (ret != 0) | 173 | if (ret != 0) |
163 | return 0; | 174 | return 0; |
164 | else { | 175 | else { |
165 | struct iwl4965_powertable_cmd *cmd; | 176 | struct iwl_powertable_cmd *cmd; |
166 | 177 | ||
167 | IWL_DEBUG_POWER("adjust power command flags\n"); | 178 | IWL_DEBUG_POWER("adjust power command flags\n"); |
168 | 179 | ||
169 | for (i = 0; i < IWL_POWER_AC; i++) { | 180 | for (i = 0; i < IWL_POWER_MAX; i++) { |
170 | cmd = &pow_data->pwr_range_0[i].cmd; | 181 | cmd = &pow_data->pwr_range_0[i].cmd; |
171 | 182 | ||
172 | if (pci_pm & 0x1) | 183 | if (pci_pm & 0x1) |
@@ -180,7 +191,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv) | |||
180 | 191 | ||
181 | /* adjust power command according to dtim period and power level*/ | 192 | /* adjust power command according to dtim period and power level*/ |
182 | static int iwl_update_power_command(struct iwl_priv *priv, | 193 | static int iwl_update_power_command(struct iwl_priv *priv, |
183 | struct iwl4965_powertable_cmd *cmd, | 194 | struct iwl_powertable_cmd *cmd, |
184 | u16 mode) | 195 | u16 mode) |
185 | { | 196 | { |
186 | int ret = 0, i; | 197 | int ret = 0, i; |
@@ -204,7 +215,7 @@ static int iwl_update_power_command(struct iwl_priv *priv, | |||
204 | range = &pow_data->pwr_range_2[0]; | 215 | range = &pow_data->pwr_range_2[0]; |
205 | 216 | ||
206 | period = pow_data->dtim_period; | 217 | period = pow_data->dtim_period; |
207 | memcpy(cmd, &range[mode].cmd, sizeof(struct iwl4965_powertable_cmd)); | 218 | memcpy(cmd, &range[mode].cmd, sizeof(struct iwl_powertable_cmd)); |
208 | 219 | ||
209 | if (period == 0) { | 220 | if (period == 0) { |
210 | period = 1; | 221 | period = 1; |
@@ -258,17 +269,18 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh) | |||
258 | * else user level */ | 269 | * else user level */ |
259 | 270 | ||
260 | switch (setting->system_power_setting) { | 271 | switch (setting->system_power_setting) { |
261 | case IWL_POWER_AUTO: | 272 | case IWL_POWER_SYS_AUTO: |
262 | final_mode = iwl_get_auto_power_mode(priv); | 273 | final_mode = iwl_get_auto_power_mode(priv); |
263 | break; | 274 | break; |
264 | case IWL_POWER_BATTERY: | 275 | case IWL_POWER_SYS_BATTERY: |
265 | final_mode = IWL_POWER_INDEX_3; | 276 | final_mode = IWL_POWER_INDEX_3; |
266 | break; | 277 | break; |
267 | case IWL_POWER_AC: | 278 | case IWL_POWER_SYS_AC: |
268 | final_mode = IWL_POWER_MODE_CAM; | 279 | final_mode = IWL_POWER_MODE_CAM; |
269 | break; | 280 | break; |
270 | default: | 281 | default: |
271 | final_mode = setting->system_power_setting; | 282 | final_mode = IWL_POWER_INDEX_3; |
283 | WARN_ON(1); | ||
272 | } | 284 | } |
273 | 285 | ||
274 | if (setting->critical_power_setting > final_mode) | 286 | if (setting->critical_power_setting > final_mode) |
@@ -280,7 +292,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh) | |||
280 | 292 | ||
281 | if (!iwl_is_rfkill(priv) && !setting->power_disabled && | 293 | if (!iwl_is_rfkill(priv) && !setting->power_disabled && |
282 | ((setting->power_mode != final_mode) || refresh)) { | 294 | ((setting->power_mode != final_mode) || refresh)) { |
283 | struct iwl4965_powertable_cmd cmd; | 295 | struct iwl_powertable_cmd cmd; |
284 | 296 | ||
285 | if (final_mode != IWL_POWER_MODE_CAM) | 297 | if (final_mode != IWL_POWER_MODE_CAM) |
286 | set_bit(STATUS_POWER_PMI, &priv->status); | 298 | set_bit(STATUS_POWER_PMI, &priv->status); |
@@ -291,8 +303,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh) | |||
291 | if (final_mode == IWL_POWER_INDEX_5) | 303 | if (final_mode == IWL_POWER_INDEX_5) |
292 | cmd.flags |= IWL_POWER_FAST_PD; | 304 | cmd.flags |= IWL_POWER_FAST_PD; |
293 | 305 | ||
294 | if (priv->cfg->ops->lib->set_power) | 306 | ret = iwl_set_power(priv, &cmd); |
295 | ret = priv->cfg->ops->lib->set_power(priv, &cmd); | ||
296 | 307 | ||
297 | if (final_mode == IWL_POWER_MODE_CAM) | 308 | if (final_mode == IWL_POWER_MODE_CAM) |
298 | clear_bit(STATUS_POWER_PMI, &priv->status); | 309 | clear_bit(STATUS_POWER_PMI, &priv->status); |
@@ -388,7 +399,7 @@ void iwl_power_initialize(struct iwl_priv *priv) | |||
388 | iwl_power_init_handle(priv); | 399 | iwl_power_init_handle(priv); |
389 | priv->power_data.user_power_setting = IWL_POWER_AUTO; | 400 | priv->power_data.user_power_setting = IWL_POWER_AUTO; |
390 | priv->power_data.power_disabled = 0; | 401 | priv->power_data.power_disabled = 0; |
391 | priv->power_data.system_power_setting = IWL_POWER_AUTO; | 402 | priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO; |
392 | priv->power_data.is_battery_active = 0; | 403 | priv->power_data.is_battery_active = 0; |
393 | priv->power_data.power_disabled = 0; | 404 | priv->power_data.power_disabled = 0; |
394 | priv->power_data.critical_power_setting = 0; | 405 | priv->power_data.critical_power_setting = 0; |