diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/power.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/power.c | 395 |
1 files changed, 243 insertions, 152 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 550824aa84ea..483ecc67501f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
@@ -186,6 +186,92 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm, | |||
186 | } | 186 | } |
187 | } | 187 | } |
188 | 188 | ||
189 | static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm, | ||
190 | struct ieee80211_vif *vif, | ||
191 | struct iwl_mac_power_cmd *cmd) | ||
192 | { | ||
193 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
194 | enum ieee80211_ac_numbers ac; | ||
195 | bool tid_found = false; | ||
196 | |||
197 | for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_BK; ac++) { | ||
198 | if (!mvmvif->queue_params[ac].uapsd) | ||
199 | continue; | ||
200 | |||
201 | if (mvm->cur_ucode != IWL_UCODE_WOWLAN) | ||
202 | cmd->flags |= | ||
203 | cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK); | ||
204 | |||
205 | cmd->uapsd_ac_flags |= BIT(ac); | ||
206 | |||
207 | /* QNDP TID - the highest TID with no admission control */ | ||
208 | if (!tid_found && !mvmvif->queue_params[ac].acm) { | ||
209 | tid_found = true; | ||
210 | switch (ac) { | ||
211 | case IEEE80211_AC_VO: | ||
212 | cmd->qndp_tid = 6; | ||
213 | break; | ||
214 | case IEEE80211_AC_VI: | ||
215 | cmd->qndp_tid = 5; | ||
216 | break; | ||
217 | case IEEE80211_AC_BE: | ||
218 | cmd->qndp_tid = 0; | ||
219 | break; | ||
220 | case IEEE80211_AC_BK: | ||
221 | cmd->qndp_tid = 1; | ||
222 | break; | ||
223 | } | ||
224 | } | ||
225 | } | ||
226 | |||
227 | if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) | ||
228 | return; | ||
229 | |||
230 | cmd->flags |= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK); | ||
231 | |||
232 | if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) | | ||
233 | BIT(IEEE80211_AC_VI) | | ||
234 | BIT(IEEE80211_AC_BE) | | ||
235 | BIT(IEEE80211_AC_BK))) { | ||
236 | cmd->flags |= cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK); | ||
237 | cmd->snooze_interval = cpu_to_le16(IWL_MVM_PS_SNOOZE_INTERVAL); | ||
238 | cmd->snooze_window = (mvm->cur_ucode == IWL_UCODE_WOWLAN) ? | ||
239 | cpu_to_le16(IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW) : | ||
240 | cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW); | ||
241 | } | ||
242 | |||
243 | cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP; | ||
244 | |||
245 | if (mvm->cur_ucode == IWL_UCODE_WOWLAN || cmd->flags & | ||
246 | cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { | ||
247 | cmd->rx_data_timeout_uapsd = | ||
248 | cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT); | ||
249 | cmd->tx_data_timeout_uapsd = | ||
250 | cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT); | ||
251 | } else { | ||
252 | cmd->rx_data_timeout_uapsd = | ||
253 | cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT); | ||
254 | cmd->tx_data_timeout_uapsd = | ||
255 | cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT); | ||
256 | } | ||
257 | |||
258 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { | ||
259 | cmd->heavy_tx_thld_packets = | ||
260 | IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS; | ||
261 | cmd->heavy_rx_thld_packets = | ||
262 | IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS; | ||
263 | } else { | ||
264 | cmd->heavy_tx_thld_packets = | ||
265 | IWL_MVM_PS_HEAVY_TX_THLD_PACKETS; | ||
266 | cmd->heavy_rx_thld_packets = | ||
267 | IWL_MVM_PS_HEAVY_RX_THLD_PACKETS; | ||
268 | } | ||
269 | cmd->heavy_tx_thld_percentage = | ||
270 | IWL_MVM_PS_HEAVY_TX_THLD_PERCENT; | ||
271 | cmd->heavy_rx_thld_percentage = | ||
272 | IWL_MVM_PS_HEAVY_RX_THLD_PERCENT; | ||
273 | } | ||
274 | |||
189 | static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, | 275 | static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, |
190 | struct ieee80211_vif *vif, | 276 | struct ieee80211_vif *vif, |
191 | struct iwl_mac_power_cmd *cmd) | 277 | struct iwl_mac_power_cmd *cmd) |
@@ -198,8 +284,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, | |||
198 | bool radar_detect = false; | 284 | bool radar_detect = false; |
199 | struct iwl_mvm_vif *mvmvif __maybe_unused = | 285 | struct iwl_mvm_vif *mvmvif __maybe_unused = |
200 | iwl_mvm_vif_from_mac80211(vif); | 286 | iwl_mvm_vif_from_mac80211(vif); |
201 | enum ieee80211_ac_numbers ac; | 287 | bool allow_uapsd = true; |
202 | bool tid_found = false; | ||
203 | 288 | ||
204 | cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, | 289 | cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, |
205 | mvmvif->color)); | 290 | mvmvif->color)); |
@@ -217,7 +302,8 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, | |||
217 | keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); | 302 | keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); |
218 | cmd->keep_alive_seconds = cpu_to_le16(keep_alive); | 303 | cmd->keep_alive_seconds = cpu_to_le16(keep_alive); |
219 | 304 | ||
220 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) | 305 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM || |
306 | mvm->ps_prevented) | ||
221 | return; | 307 | return; |
222 | 308 | ||
223 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); | 309 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); |
@@ -227,7 +313,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, | |||
227 | mvmvif->dbgfs_pm.disable_power_off) | 313 | mvmvif->dbgfs_pm.disable_power_off) |
228 | cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK); | 314 | cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK); |
229 | #endif | 315 | #endif |
230 | if (!vif->bss_conf.ps) | 316 | if (!vif->bss_conf.ps || mvmvif->pm_prevented) |
231 | return; | 317 | return; |
232 | 318 | ||
233 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); | 319 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); |
@@ -269,81 +355,24 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, | |||
269 | cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT); | 355 | cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT); |
270 | } | 356 | } |
271 | 357 | ||
272 | for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_BK; ac++) { | 358 | if (!memcmp(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid, |
273 | if (!mvmvif->queue_params[ac].uapsd) | 359 | ETH_ALEN)) |
274 | continue; | 360 | allow_uapsd = false; |
275 | |||
276 | if (mvm->cur_ucode != IWL_UCODE_WOWLAN) | ||
277 | cmd->flags |= | ||
278 | cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK); | ||
279 | |||
280 | cmd->uapsd_ac_flags |= BIT(ac); | ||
281 | 361 | ||
282 | /* QNDP TID - the highest TID with no admission control */ | 362 | if (vif->p2p && |
283 | if (!tid_found && !mvmvif->queue_params[ac].acm) { | 363 | !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD)) |
284 | tid_found = true; | 364 | allow_uapsd = false; |
285 | switch (ac) { | 365 | /* |
286 | case IEEE80211_AC_VO: | 366 | * Avoid using uAPSD if P2P client is associated to GO that uses |
287 | cmd->qndp_tid = 6; | 367 | * opportunistic power save. This is due to current FW limitation. |
288 | break; | 368 | */ |
289 | case IEEE80211_AC_VI: | 369 | if (vif->p2p && |
290 | cmd->qndp_tid = 5; | 370 | vif->bss_conf.p2p_noa_attr.oppps_ctwindow & |
291 | break; | 371 | IEEE80211_P2P_OPPPS_ENABLE_BIT) |
292 | case IEEE80211_AC_BE: | 372 | allow_uapsd = false; |
293 | cmd->qndp_tid = 0; | ||
294 | break; | ||
295 | case IEEE80211_AC_BK: | ||
296 | cmd->qndp_tid = 1; | ||
297 | break; | ||
298 | } | ||
299 | } | ||
300 | } | ||
301 | |||
302 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) { | ||
303 | if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) | | ||
304 | BIT(IEEE80211_AC_VI) | | ||
305 | BIT(IEEE80211_AC_BE) | | ||
306 | BIT(IEEE80211_AC_BK))) { | ||
307 | cmd->flags |= cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK); | ||
308 | cmd->snooze_interval = | ||
309 | cpu_to_le16(IWL_MVM_PS_SNOOZE_INTERVAL); | ||
310 | cmd->snooze_window = | ||
311 | (mvm->cur_ucode == IWL_UCODE_WOWLAN) ? | ||
312 | cpu_to_le16(IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW) : | ||
313 | cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW); | ||
314 | } | ||
315 | |||
316 | cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP; | ||
317 | |||
318 | if (mvm->cur_ucode == IWL_UCODE_WOWLAN || cmd->flags & | ||
319 | cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { | ||
320 | cmd->rx_data_timeout_uapsd = | ||
321 | cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT); | ||
322 | cmd->tx_data_timeout_uapsd = | ||
323 | cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT); | ||
324 | } else { | ||
325 | cmd->rx_data_timeout_uapsd = | ||
326 | cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT); | ||
327 | cmd->tx_data_timeout_uapsd = | ||
328 | cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT); | ||
329 | } | ||
330 | 373 | ||
331 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { | 374 | if (allow_uapsd) |
332 | cmd->heavy_tx_thld_packets = | 375 | iwl_mvm_power_configure_uapsd(mvm, vif, cmd); |
333 | IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS; | ||
334 | cmd->heavy_rx_thld_packets = | ||
335 | IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS; | ||
336 | } else { | ||
337 | cmd->heavy_tx_thld_packets = | ||
338 | IWL_MVM_PS_HEAVY_TX_THLD_PACKETS; | ||
339 | cmd->heavy_rx_thld_packets = | ||
340 | IWL_MVM_PS_HEAVY_RX_THLD_PACKETS; | ||
341 | } | ||
342 | cmd->heavy_tx_thld_percentage = | ||
343 | IWL_MVM_PS_HEAVY_TX_THLD_PERCENT; | ||
344 | cmd->heavy_rx_thld_percentage = | ||
345 | IWL_MVM_PS_HEAVY_RX_THLD_PERCENT; | ||
346 | } | ||
347 | 376 | ||
348 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 377 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
349 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE) | 378 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE) |
@@ -381,6 +410,13 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, | |||
381 | cmd->flags &= | 410 | cmd->flags &= |
382 | cpu_to_le16(~POWER_FLAGS_SNOOZE_ENA_MSK); | 411 | cpu_to_le16(~POWER_FLAGS_SNOOZE_ENA_MSK); |
383 | } | 412 | } |
413 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_UAPSD_MISBEHAVING) { | ||
414 | u16 flag = POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK; | ||
415 | if (mvmvif->dbgfs_pm.uapsd_misbehaving) | ||
416 | cmd->flags |= cpu_to_le16(flag); | ||
417 | else | ||
418 | cmd->flags &= cpu_to_le16(flag); | ||
419 | } | ||
384 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 420 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
385 | } | 421 | } |
386 | 422 | ||
@@ -391,18 +427,11 @@ static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm, | |||
391 | bool ba_enable; | 427 | bool ba_enable; |
392 | struct iwl_mac_power_cmd cmd = {}; | 428 | struct iwl_mac_power_cmd cmd = {}; |
393 | 429 | ||
394 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | 430 | if (vif->type != NL80211_IFTYPE_STATION) |
395 | return 0; | 431 | return 0; |
396 | 432 | ||
397 | /* | 433 | if (vif->p2p && |
398 | * TODO: The following vif_count verification is temporary condition. | 434 | !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS)) |
399 | * Avoid power mode update if more than one interface is currently | ||
400 | * active. Remove this condition when FW will support power management | ||
401 | * on multiple MACs. | ||
402 | */ | ||
403 | IWL_DEBUG_POWER(mvm, "Currently %d interfaces active\n", | ||
404 | mvm->vif_count); | ||
405 | if (mvm->vif_count > 1) | ||
406 | return 0; | 435 | return 0; |
407 | 436 | ||
408 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); | 437 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); |
@@ -446,7 +475,7 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm, | |||
446 | sizeof(cmd), &cmd); | 475 | sizeof(cmd), &cmd); |
447 | } | 476 | } |
448 | 477 | ||
449 | static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) | 478 | static int _iwl_mvm_power_update_device(struct iwl_mvm *mvm, bool force_disable) |
450 | { | 479 | { |
451 | struct iwl_device_power_cmd cmd = { | 480 | struct iwl_device_power_cmd cmd = { |
452 | .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK), | 481 | .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK), |
@@ -455,7 +484,8 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) | |||
455 | if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) | 484 | if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) |
456 | return 0; | 485 | return 0; |
457 | 486 | ||
458 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) | 487 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM || |
488 | force_disable) | ||
459 | cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK); | 489 | cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK); |
460 | 490 | ||
461 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 491 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
@@ -472,6 +502,78 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) | |||
472 | &cmd); | 502 | &cmd); |
473 | } | 503 | } |
474 | 504 | ||
505 | static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) | ||
506 | { | ||
507 | return _iwl_mvm_power_update_device(mvm, false); | ||
508 | } | ||
509 | |||
510 | void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
511 | { | ||
512 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
513 | |||
514 | if (memcmp(vif->bss_conf.bssid, mvmvif->uapsd_misbehaving_bssid, | ||
515 | ETH_ALEN)) | ||
516 | memset(mvmvif->uapsd_misbehaving_bssid, 0, ETH_ALEN); | ||
517 | } | ||
518 | |||
519 | static void iwl_mvm_power_uapsd_misbehav_ap_iterator(void *_data, u8 *mac, | ||
520 | struct ieee80211_vif *vif) | ||
521 | { | ||
522 | u8 *ap_sta_id = _data; | ||
523 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
524 | |||
525 | /* The ap_sta_id is not expected to change during current association | ||
526 | * so no explicit protection is needed | ||
527 | */ | ||
528 | if (mvmvif->ap_sta_id == *ap_sta_id) | ||
529 | memcpy(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid, | ||
530 | ETH_ALEN); | ||
531 | } | ||
532 | |||
533 | int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm, | ||
534 | struct iwl_rx_cmd_buffer *rxb, | ||
535 | struct iwl_device_cmd *cmd) | ||
536 | { | ||
537 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
538 | struct iwl_uapsd_misbehaving_ap_notif *notif = (void *)pkt->data; | ||
539 | u8 ap_sta_id = le32_to_cpu(notif->sta_id); | ||
540 | |||
541 | ieee80211_iterate_active_interfaces_atomic( | ||
542 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, | ||
543 | iwl_mvm_power_uapsd_misbehav_ap_iterator, &ap_sta_id); | ||
544 | |||
545 | return 0; | ||
546 | } | ||
547 | |||
548 | static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac, | ||
549 | struct ieee80211_vif *vif) | ||
550 | { | ||
551 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
552 | struct iwl_mvm *mvm = _data; | ||
553 | int ret; | ||
554 | |||
555 | mvmvif->pm_prevented = (mvm->bound_vif_cnt <= 1) ? false : true; | ||
556 | |||
557 | ret = iwl_mvm_power_mac_update_mode(mvm, vif); | ||
558 | WARN_ONCE(ret, "Failed to update power parameters on a specific vif\n"); | ||
559 | } | ||
560 | |||
561 | static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm, | ||
562 | struct ieee80211_vif *vif, | ||
563 | bool assign) | ||
564 | { | ||
565 | if (vif->type == NL80211_IFTYPE_MONITOR) { | ||
566 | int ret = _iwl_mvm_power_update_device(mvm, assign); | ||
567 | mvm->ps_prevented = assign; | ||
568 | WARN_ONCE(ret, "Failed to update power device state\n"); | ||
569 | } | ||
570 | |||
571 | ieee80211_iterate_active_interfaces(mvm->hw, | ||
572 | IEEE80211_IFACE_ITER_NORMAL, | ||
573 | iwl_mvm_power_binding_iterator, | ||
574 | mvm); | ||
575 | } | ||
576 | |||
475 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 577 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
476 | static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, | 578 | static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, |
477 | struct ieee80211_vif *vif, char *buf, | 579 | struct ieee80211_vif *vif, char *buf, |
@@ -494,70 +596,58 @@ static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, | |||
494 | pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", | 596 | pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", |
495 | le16_to_cpu(cmd.keep_alive_seconds)); | 597 | le16_to_cpu(cmd.keep_alive_seconds)); |
496 | 598 | ||
497 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { | 599 | if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK))) |
498 | pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n", | 600 | return pos; |
499 | (cmd.flags & | 601 | |
500 | cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ? | 602 | pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n", |
501 | 1 : 0); | 603 | (cmd.flags & |
502 | pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n", | 604 | cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ? 1 : 0); |
503 | cmd.skip_dtim_periods); | 605 | pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n", |
504 | if (!(cmd.flags & | 606 | cmd.skip_dtim_periods); |
505 | cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) { | 607 | if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) { |
506 | pos += scnprintf(buf+pos, bufsz-pos, | 608 | pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n", |
507 | "rx_data_timeout = %d\n", | 609 | le32_to_cpu(cmd.rx_data_timeout)); |
508 | le32_to_cpu(cmd.rx_data_timeout)); | 610 | pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n", |
509 | pos += scnprintf(buf+pos, bufsz-pos, | 611 | le32_to_cpu(cmd.tx_data_timeout)); |
510 | "tx_data_timeout = %d\n", | ||
511 | le32_to_cpu(cmd.tx_data_timeout)); | ||
512 | } | ||
513 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK)) | ||
514 | pos += scnprintf(buf+pos, bufsz-pos, | ||
515 | "lprx_rssi_threshold = %d\n", | ||
516 | cmd.lprx_rssi_threshold); | ||
517 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) { | ||
518 | pos += | ||
519 | scnprintf(buf+pos, bufsz-pos, | ||
520 | "rx_data_timeout_uapsd = %d\n", | ||
521 | le32_to_cpu(cmd.rx_data_timeout_uapsd)); | ||
522 | pos += | ||
523 | scnprintf(buf+pos, bufsz-pos, | ||
524 | "tx_data_timeout_uapsd = %d\n", | ||
525 | le32_to_cpu(cmd.tx_data_timeout_uapsd)); | ||
526 | pos += scnprintf(buf+pos, bufsz-pos, "qndp_tid = %d\n", | ||
527 | cmd.qndp_tid); | ||
528 | pos += scnprintf(buf+pos, bufsz-pos, | ||
529 | "uapsd_ac_flags = 0x%x\n", | ||
530 | cmd.uapsd_ac_flags); | ||
531 | pos += scnprintf(buf+pos, bufsz-pos, | ||
532 | "uapsd_max_sp = %d\n", | ||
533 | cmd.uapsd_max_sp); | ||
534 | pos += scnprintf(buf+pos, bufsz-pos, | ||
535 | "heavy_tx_thld_packets = %d\n", | ||
536 | cmd.heavy_tx_thld_packets); | ||
537 | pos += scnprintf(buf+pos, bufsz-pos, | ||
538 | "heavy_rx_thld_packets = %d\n", | ||
539 | cmd.heavy_rx_thld_packets); | ||
540 | pos += scnprintf(buf+pos, bufsz-pos, | ||
541 | "heavy_tx_thld_percentage = %d\n", | ||
542 | cmd.heavy_tx_thld_percentage); | ||
543 | pos += scnprintf(buf+pos, bufsz-pos, | ||
544 | "heavy_rx_thld_percentage = %d\n", | ||
545 | cmd.heavy_rx_thld_percentage); | ||
546 | pos += | ||
547 | scnprintf(buf+pos, bufsz-pos, "snooze_enable = %d\n", | ||
548 | (cmd.flags & | ||
549 | cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) ? | ||
550 | 1 : 0); | ||
551 | } | ||
552 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { | ||
553 | pos += scnprintf(buf+pos, bufsz-pos, | ||
554 | "snooze_interval = %d\n", | ||
555 | cmd.snooze_interval); | ||
556 | pos += scnprintf(buf+pos, bufsz-pos, | ||
557 | "snooze_window = %d\n", | ||
558 | cmd.snooze_window); | ||
559 | } | ||
560 | } | 612 | } |
613 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK)) | ||
614 | pos += scnprintf(buf+pos, bufsz-pos, | ||
615 | "lprx_rssi_threshold = %d\n", | ||
616 | cmd.lprx_rssi_threshold); | ||
617 | |||
618 | if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) | ||
619 | return pos; | ||
620 | |||
621 | pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout_uapsd = %d\n", | ||
622 | le32_to_cpu(cmd.rx_data_timeout_uapsd)); | ||
623 | pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout_uapsd = %d\n", | ||
624 | le32_to_cpu(cmd.tx_data_timeout_uapsd)); | ||
625 | pos += scnprintf(buf+pos, bufsz-pos, "qndp_tid = %d\n", cmd.qndp_tid); | ||
626 | pos += scnprintf(buf+pos, bufsz-pos, "uapsd_ac_flags = 0x%x\n", | ||
627 | cmd.uapsd_ac_flags); | ||
628 | pos += scnprintf(buf+pos, bufsz-pos, "uapsd_max_sp = %d\n", | ||
629 | cmd.uapsd_max_sp); | ||
630 | pos += scnprintf(buf+pos, bufsz-pos, "heavy_tx_thld_packets = %d\n", | ||
631 | cmd.heavy_tx_thld_packets); | ||
632 | pos += scnprintf(buf+pos, bufsz-pos, "heavy_rx_thld_packets = %d\n", | ||
633 | cmd.heavy_rx_thld_packets); | ||
634 | pos += scnprintf(buf+pos, bufsz-pos, "heavy_tx_thld_percentage = %d\n", | ||
635 | cmd.heavy_tx_thld_percentage); | ||
636 | pos += scnprintf(buf+pos, bufsz-pos, "heavy_rx_thld_percentage = %d\n", | ||
637 | cmd.heavy_rx_thld_percentage); | ||
638 | pos += scnprintf(buf+pos, bufsz-pos, "uapsd_misbehaving_enable = %d\n", | ||
639 | (cmd.flags & | ||
640 | cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK)) ? | ||
641 | 1 : 0); | ||
642 | |||
643 | if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK))) | ||
644 | return pos; | ||
645 | |||
646 | pos += scnprintf(buf+pos, bufsz-pos, "snooze_interval = %d\n", | ||
647 | cmd.snooze_interval); | ||
648 | pos += scnprintf(buf+pos, bufsz-pos, "snooze_window = %d\n", | ||
649 | cmd.snooze_window); | ||
650 | |||
561 | return pos; | 651 | return pos; |
562 | } | 652 | } |
563 | 653 | ||
@@ -654,6 +744,7 @@ const struct iwl_mvm_power_ops pm_mac_ops = { | |||
654 | .power_update_mode = iwl_mvm_power_mac_update_mode, | 744 | .power_update_mode = iwl_mvm_power_mac_update_mode, |
655 | .power_update_device_mode = iwl_mvm_power_update_device, | 745 | .power_update_device_mode = iwl_mvm_power_update_device, |
656 | .power_disable = iwl_mvm_power_mac_disable, | 746 | .power_disable = iwl_mvm_power_mac_disable, |
747 | .power_update_binding = _iwl_mvm_power_update_binding, | ||
657 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 748 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
658 | .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read, | 749 | .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read, |
659 | #endif | 750 | #endif |