diff options
author | Alexander Bondar <alexander.bondar@intel.com> | 2013-05-21 07:49:09 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-05-29 03:03:24 -0400 |
commit | b571a69745dc90aec3d0505a7ceac2702a93861b (patch) | |
tree | ed53d39bc904ddaa66e050ca494ec5b84d4fe3b6 /drivers | |
parent | d64048edcd714095a5cf2d7019769d0d94e19892 (diff) |
iwlwifi: mvm: add debugfs for powersave
Add debugfs files to control powersave parameters for testing.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/debugfs.c | 337 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mvm.h | 65 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/power.c | 66 |
3 files changed, 468 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 95871b2d63d1..69e0806075a2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
@@ -300,6 +300,146 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file, | |||
300 | return count; | 300 | return count; |
301 | } | 301 | } |
302 | 302 | ||
303 | static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm, | ||
304 | struct ieee80211_vif *vif, | ||
305 | enum iwl_dbgfs_pm_mask param, int val) | ||
306 | { | ||
307 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
308 | struct iwl_dbgfs_pm *dbgfs_pm = &mvmvif->dbgfs_pm; | ||
309 | |||
310 | dbgfs_pm->mask |= param; | ||
311 | |||
312 | switch (param) { | ||
313 | case MVM_DEBUGFS_PM_KEEP_ALIVE: { | ||
314 | struct ieee80211_hw *hw = mvm->hw; | ||
315 | int dtimper = hw->conf.ps_dtim_period ?: 1; | ||
316 | int dtimper_msec = dtimper * vif->bss_conf.beacon_int; | ||
317 | |||
318 | IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val); | ||
319 | if (val * MSEC_PER_SEC < 3 * dtimper_msec) { | ||
320 | IWL_WARN(mvm, | ||
321 | "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n", | ||
322 | val * MSEC_PER_SEC, 3 * dtimper_msec); | ||
323 | } | ||
324 | dbgfs_pm->keep_alive_seconds = val; | ||
325 | break; | ||
326 | } | ||
327 | case MVM_DEBUGFS_PM_SKIP_OVER_DTIM: | ||
328 | IWL_DEBUG_POWER(mvm, "skip_over_dtim %s\n", | ||
329 | val ? "enabled" : "disabled"); | ||
330 | dbgfs_pm->skip_over_dtim = val; | ||
331 | break; | ||
332 | case MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS: | ||
333 | IWL_DEBUG_POWER(mvm, "skip_dtim_periods=%d\n", val); | ||
334 | dbgfs_pm->skip_dtim_periods = val; | ||
335 | break; | ||
336 | case MVM_DEBUGFS_PM_RX_DATA_TIMEOUT: | ||
337 | IWL_DEBUG_POWER(mvm, "rx_data_timeout=%d\n", val); | ||
338 | dbgfs_pm->rx_data_timeout = val; | ||
339 | break; | ||
340 | case MVM_DEBUGFS_PM_TX_DATA_TIMEOUT: | ||
341 | IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val); | ||
342 | dbgfs_pm->tx_data_timeout = val; | ||
343 | break; | ||
344 | case MVM_DEBUGFS_PM_DISABLE_POWER_OFF: | ||
345 | IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val); | ||
346 | dbgfs_pm->disable_power_off = val; | ||
347 | break; | ||
348 | } | ||
349 | } | ||
350 | |||
351 | static ssize_t iwl_dbgfs_pm_params_write(struct file *file, | ||
352 | const char __user *user_buf, | ||
353 | size_t count, loff_t *ppos) | ||
354 | { | ||
355 | struct ieee80211_vif *vif = file->private_data; | ||
356 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
357 | struct iwl_mvm *mvm = mvmvif->dbgfs_data; | ||
358 | enum iwl_dbgfs_pm_mask param; | ||
359 | char buf[32] = {}; | ||
360 | int val; | ||
361 | int ret; | ||
362 | |||
363 | if (copy_from_user(buf, user_buf, sizeof(buf))) | ||
364 | return -EFAULT; | ||
365 | |||
366 | if (!strncmp("keep_alive=", buf, 11)) { | ||
367 | if (sscanf(buf + 11, "%d", &val) != 1) | ||
368 | return -EINVAL; | ||
369 | param = MVM_DEBUGFS_PM_KEEP_ALIVE; | ||
370 | } else if (!strncmp("skip_over_dtim=", buf, 15)) { | ||
371 | if (sscanf(buf + 15, "%d", &val) != 1) | ||
372 | return -EINVAL; | ||
373 | param = MVM_DEBUGFS_PM_SKIP_OVER_DTIM; | ||
374 | } else if (!strncmp("skip_dtim_periods=", buf, 18)) { | ||
375 | if (sscanf(buf + 18, "%d", &val) != 1) | ||
376 | return -EINVAL; | ||
377 | param = MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS; | ||
378 | } else if (!strncmp("rx_data_timeout=", buf, 16)) { | ||
379 | if (sscanf(buf + 16, "%d", &val) != 1) | ||
380 | return -EINVAL; | ||
381 | param = MVM_DEBUGFS_PM_RX_DATA_TIMEOUT; | ||
382 | } else if (!strncmp("tx_data_timeout=", buf, 16)) { | ||
383 | if (sscanf(buf + 16, "%d", &val) != 1) | ||
384 | return -EINVAL; | ||
385 | param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT; | ||
386 | } else if (!strncmp("disable_power_off=", buf, 18)) { | ||
387 | if (sscanf(buf + 18, "%d", &val) != 1) | ||
388 | return -EINVAL; | ||
389 | param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF; | ||
390 | } else { | ||
391 | return -EINVAL; | ||
392 | } | ||
393 | |||
394 | mutex_lock(&mvm->mutex); | ||
395 | iwl_dbgfs_update_pm(mvm, vif, param, val); | ||
396 | ret = iwl_mvm_power_update_mode(mvm, vif); | ||
397 | mutex_unlock(&mvm->mutex); | ||
398 | |||
399 | return ret ?: count; | ||
400 | } | ||
401 | |||
402 | static ssize_t iwl_dbgfs_pm_params_read(struct file *file, | ||
403 | char __user *user_buf, | ||
404 | size_t count, loff_t *ppos) | ||
405 | { | ||
406 | struct ieee80211_vif *vif = file->private_data; | ||
407 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
408 | struct iwl_mvm *mvm = mvmvif->dbgfs_data; | ||
409 | struct iwl_powertable_cmd cmd = {}; | ||
410 | char buf[256]; | ||
411 | int bufsz = sizeof(buf); | ||
412 | int pos = 0; | ||
413 | |||
414 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); | ||
415 | |||
416 | pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n", | ||
417 | (cmd.flags & | ||
418 | cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ? | ||
419 | 0 : 1); | ||
420 | pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n", | ||
421 | le32_to_cpu(cmd.skip_dtim_periods)); | ||
422 | pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n", | ||
423 | iwlmvm_mod_params.power_scheme); | ||
424 | pos += scnprintf(buf+pos, bufsz-pos, "flags = %d\n", | ||
425 | le16_to_cpu(cmd.flags)); | ||
426 | pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", | ||
427 | cmd.keep_alive_seconds); | ||
428 | |||
429 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { | ||
430 | pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n", | ||
431 | (cmd.flags & | ||
432 | cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ? | ||
433 | 1 : 0); | ||
434 | pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n", | ||
435 | le32_to_cpu(cmd.rx_data_timeout)); | ||
436 | pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n", | ||
437 | le32_to_cpu(cmd.tx_data_timeout)); | ||
438 | } | ||
439 | |||
440 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
441 | } | ||
442 | |||
303 | static ssize_t iwl_dbgfs_mac_params_read(struct file *file, | 443 | static ssize_t iwl_dbgfs_mac_params_read(struct file *file, |
304 | char __user *user_buf, | 444 | char __user *user_buf, |
305 | size_t count, loff_t *ppos) | 445 | size_t count, loff_t *ppos) |
@@ -481,6 +621,191 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, | |||
481 | return count; | 621 | return count; |
482 | } | 622 | } |
483 | 623 | ||
624 | static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif, | ||
625 | enum iwl_dbgfs_bf_mask param, int value) | ||
626 | { | ||
627 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
628 | struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf; | ||
629 | |||
630 | dbgfs_bf->mask |= param; | ||
631 | |||
632 | switch (param) { | ||
633 | case MVM_DEBUGFS_BF_ENERGY_DELTA: | ||
634 | dbgfs_bf->bf_energy_delta = value; | ||
635 | break; | ||
636 | case MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA: | ||
637 | dbgfs_bf->bf_roaming_energy_delta = value; | ||
638 | break; | ||
639 | case MVM_DEBUGFS_BF_ROAMING_STATE: | ||
640 | dbgfs_bf->bf_roaming_state = value; | ||
641 | break; | ||
642 | case MVM_DEBUGFS_BF_TEMPERATURE_DELTA: | ||
643 | dbgfs_bf->bf_temperature_delta = value; | ||
644 | break; | ||
645 | case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER: | ||
646 | dbgfs_bf->bf_enable_beacon_filter = value; | ||
647 | break; | ||
648 | case MVM_DEBUGFS_BF_DEBUG_FLAG: | ||
649 | dbgfs_bf->bf_debug_flag = value; | ||
650 | break; | ||
651 | case MVM_DEBUGFS_BF_ESCAPE_TIMER: | ||
652 | dbgfs_bf->bf_escape_timer = value; | ||
653 | break; | ||
654 | case MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT: | ||
655 | dbgfs_bf->ba_enable_beacon_abort = value; | ||
656 | break; | ||
657 | case MVM_DEBUGFS_BA_ESCAPE_TIMER: | ||
658 | dbgfs_bf->ba_escape_timer = value; | ||
659 | break; | ||
660 | } | ||
661 | } | ||
662 | |||
663 | static ssize_t iwl_dbgfs_bf_params_write(struct file *file, | ||
664 | const char __user *user_buf, | ||
665 | size_t count, loff_t *ppos) | ||
666 | { | ||
667 | struct ieee80211_vif *vif = file->private_data; | ||
668 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
669 | struct iwl_mvm *mvm = mvmvif->dbgfs_data; | ||
670 | enum iwl_dbgfs_bf_mask param; | ||
671 | char buf[256]; | ||
672 | int buf_size; | ||
673 | int value; | ||
674 | int ret = 0; | ||
675 | |||
676 | memset(buf, 0, sizeof(buf)); | ||
677 | buf_size = min(count, sizeof(buf) - 1); | ||
678 | if (copy_from_user(buf, user_buf, buf_size)) | ||
679 | return -EFAULT; | ||
680 | |||
681 | if (!strncmp("bf_energy_delta=", buf, 16)) { | ||
682 | if (sscanf(buf+16, "%d", &value) != 1) | ||
683 | return -EINVAL; | ||
684 | if (value < IWL_BF_ENERGY_DELTA_MIN || | ||
685 | value > IWL_BF_ENERGY_DELTA_MAX) | ||
686 | return -EINVAL; | ||
687 | param = MVM_DEBUGFS_BF_ENERGY_DELTA; | ||
688 | } else if (!strncmp("bf_roaming_energy_delta=", buf, 24)) { | ||
689 | if (sscanf(buf+24, "%d", &value) != 1) | ||
690 | return -EINVAL; | ||
691 | if (value < IWL_BF_ROAMING_ENERGY_DELTA_MIN || | ||
692 | value > IWL_BF_ROAMING_ENERGY_DELTA_MAX) | ||
693 | return -EINVAL; | ||
694 | param = MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA; | ||
695 | } else if (!strncmp("bf_roaming_state=", buf, 17)) { | ||
696 | if (sscanf(buf+17, "%d", &value) != 1) | ||
697 | return -EINVAL; | ||
698 | if (value < IWL_BF_ROAMING_STATE_MIN || | ||
699 | value > IWL_BF_ROAMING_STATE_MAX) | ||
700 | return -EINVAL; | ||
701 | param = MVM_DEBUGFS_BF_ROAMING_STATE; | ||
702 | } else if (!strncmp("bf_temperature_delta=", buf, 21)) { | ||
703 | if (sscanf(buf+21, "%d", &value) != 1) | ||
704 | return -EINVAL; | ||
705 | if (value < IWL_BF_TEMPERATURE_DELTA_MIN || | ||
706 | value > IWL_BF_TEMPERATURE_DELTA_MAX) | ||
707 | return -EINVAL; | ||
708 | param = MVM_DEBUGFS_BF_TEMPERATURE_DELTA; | ||
709 | } else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) { | ||
710 | if (sscanf(buf+24, "%d", &value) != 1) | ||
711 | return -EINVAL; | ||
712 | if (value < 0 || value > 1) | ||
713 | return -EINVAL; | ||
714 | param = MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER; | ||
715 | } else if (!strncmp("bf_debug_flag=", buf, 14)) { | ||
716 | if (sscanf(buf+14, "%d", &value) != 1) | ||
717 | return -EINVAL; | ||
718 | if (value < 0 || value > 1) | ||
719 | return -EINVAL; | ||
720 | param = MVM_DEBUGFS_BF_DEBUG_FLAG; | ||
721 | } else if (!strncmp("bf_escape_timer=", buf, 16)) { | ||
722 | if (sscanf(buf+16, "%d", &value) != 1) | ||
723 | return -EINVAL; | ||
724 | if (value < IWL_BF_ESCAPE_TIMER_MIN || | ||
725 | value > IWL_BF_ESCAPE_TIMER_MAX) | ||
726 | return -EINVAL; | ||
727 | param = MVM_DEBUGFS_BF_ESCAPE_TIMER; | ||
728 | } else if (!strncmp("ba_escape_timer=", buf, 16)) { | ||
729 | if (sscanf(buf+16, "%d", &value) != 1) | ||
730 | return -EINVAL; | ||
731 | if (value < IWL_BA_ESCAPE_TIMER_MIN || | ||
732 | value > IWL_BA_ESCAPE_TIMER_MAX) | ||
733 | return -EINVAL; | ||
734 | param = MVM_DEBUGFS_BA_ESCAPE_TIMER; | ||
735 | } else if (!strncmp("ba_enable_beacon_abort=", buf, 23)) { | ||
736 | if (sscanf(buf+23, "%d", &value) != 1) | ||
737 | return -EINVAL; | ||
738 | if (value < 0 || value > 1) | ||
739 | return -EINVAL; | ||
740 | param = MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT; | ||
741 | } else { | ||
742 | return -EINVAL; | ||
743 | } | ||
744 | |||
745 | mutex_lock(&mvm->mutex); | ||
746 | iwl_dbgfs_update_bf(vif, param, value); | ||
747 | if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) { | ||
748 | ret = iwl_mvm_disable_beacon_filter(mvm, vif); | ||
749 | } else { | ||
750 | if (mvmvif->bf_enabled) | ||
751 | ret = iwl_mvm_enable_beacon_filter(mvm, vif); | ||
752 | else | ||
753 | ret = iwl_mvm_disable_beacon_filter(mvm, vif); | ||
754 | } | ||
755 | mutex_unlock(&mvm->mutex); | ||
756 | |||
757 | return ret ?: count; | ||
758 | } | ||
759 | |||
760 | static ssize_t iwl_dbgfs_bf_params_read(struct file *file, | ||
761 | char __user *user_buf, | ||
762 | size_t count, loff_t *ppos) | ||
763 | { | ||
764 | struct ieee80211_vif *vif = file->private_data; | ||
765 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
766 | char buf[256]; | ||
767 | int pos = 0; | ||
768 | const size_t bufsz = sizeof(buf); | ||
769 | struct iwl_beacon_filter_cmd cmd = { | ||
770 | .bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT, | ||
771 | .bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT, | ||
772 | .bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT, | ||
773 | .bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT, | ||
774 | .bf_enable_beacon_filter = IWL_BF_ENABLE_BEACON_FILTER_DEFAULT, | ||
775 | .bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT, | ||
776 | .bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT), | ||
777 | .ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT), | ||
778 | .ba_enable_beacon_abort = IWL_BA_ENABLE_BEACON_ABORT_DEFAULT, | ||
779 | }; | ||
780 | |||
781 | iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); | ||
782 | if (mvmvif->bf_enabled) | ||
783 | cmd.bf_enable_beacon_filter = 1; | ||
784 | else | ||
785 | cmd.bf_enable_beacon_filter = 0; | ||
786 | |||
787 | pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n", | ||
788 | cmd.bf_energy_delta); | ||
789 | pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n", | ||
790 | cmd.bf_roaming_energy_delta); | ||
791 | pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n", | ||
792 | cmd.bf_roaming_state); | ||
793 | pos += scnprintf(buf+pos, bufsz-pos, "bf_temperature_delta = %d\n", | ||
794 | cmd.bf_temperature_delta); | ||
795 | pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n", | ||
796 | cmd.bf_enable_beacon_filter); | ||
797 | pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n", | ||
798 | cmd.bf_debug_flag); | ||
799 | pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n", | ||
800 | cmd.bf_escape_timer); | ||
801 | pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n", | ||
802 | cmd.ba_escape_timer); | ||
803 | pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n", | ||
804 | cmd.ba_enable_beacon_abort); | ||
805 | |||
806 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
807 | } | ||
808 | |||
484 | #ifdef CONFIG_PM_SLEEP | 809 | #ifdef CONFIG_PM_SLEEP |
485 | static ssize_t iwl_dbgfs_d3_sram_write(struct file *file, | 810 | static ssize_t iwl_dbgfs_d3_sram_write(struct file *file, |
486 | const char __user *user_buf, | 811 | const char __user *user_buf, |
@@ -594,6 +919,8 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram); | |||
594 | 919 | ||
595 | /* Interface specific debugfs entries */ | 920 | /* Interface specific debugfs entries */ |
596 | MVM_DEBUGFS_READ_FILE_OPS(mac_params); | 921 | MVM_DEBUGFS_READ_FILE_OPS(mac_params); |
922 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params); | ||
923 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params); | ||
597 | 924 | ||
598 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | 925 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) |
599 | { | 926 | { |
@@ -647,9 +974,19 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
647 | return; | 974 | return; |
648 | } | 975 | } |
649 | 976 | ||
977 | if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM && | ||
978 | vif->type == NL80211_IFTYPE_STATION && !vif->p2p) | ||
979 | MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR | | ||
980 | S_IRUSR); | ||
981 | |||
650 | MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, | 982 | MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, |
651 | S_IRUSR); | 983 | S_IRUSR); |
652 | 984 | ||
985 | if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p && | ||
986 | mvmvif == mvm->bf_allowed_vif) | ||
987 | MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir, | ||
988 | S_IRUSR | S_IWUSR); | ||
989 | |||
653 | /* | 990 | /* |
654 | * Create symlink for convenience pointing to interface specific | 991 | * Create symlink for convenience pointing to interface specific |
655 | * debugfs entries for the driver. For example, under | 992 | * debugfs entries for the driver. For example, under |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 0e7450372f2c..6a3220b6273e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -150,6 +150,54 @@ enum iwl_power_scheme { | |||
150 | 150 | ||
151 | #define IWL_CONN_MAX_LISTEN_INTERVAL 70 | 151 | #define IWL_CONN_MAX_LISTEN_INTERVAL 70 |
152 | 152 | ||
153 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
154 | enum iwl_dbgfs_pm_mask { | ||
155 | MVM_DEBUGFS_PM_KEEP_ALIVE = BIT(0), | ||
156 | MVM_DEBUGFS_PM_SKIP_OVER_DTIM = BIT(1), | ||
157 | MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS = BIT(2), | ||
158 | MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3), | ||
159 | MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4), | ||
160 | MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5), | ||
161 | }; | ||
162 | |||
163 | struct iwl_dbgfs_pm { | ||
164 | u8 keep_alive_seconds; | ||
165 | u32 rx_data_timeout; | ||
166 | u32 tx_data_timeout; | ||
167 | bool skip_over_dtim; | ||
168 | u8 skip_dtim_periods; | ||
169 | bool disable_power_off; | ||
170 | int mask; | ||
171 | }; | ||
172 | |||
173 | /* beacon filtering */ | ||
174 | |||
175 | enum iwl_dbgfs_bf_mask { | ||
176 | MVM_DEBUGFS_BF_ENERGY_DELTA = BIT(0), | ||
177 | MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA = BIT(1), | ||
178 | MVM_DEBUGFS_BF_ROAMING_STATE = BIT(2), | ||
179 | MVM_DEBUGFS_BF_TEMPERATURE_DELTA = BIT(3), | ||
180 | MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER = BIT(4), | ||
181 | MVM_DEBUGFS_BF_DEBUG_FLAG = BIT(5), | ||
182 | MVM_DEBUGFS_BF_ESCAPE_TIMER = BIT(6), | ||
183 | MVM_DEBUGFS_BA_ESCAPE_TIMER = BIT(7), | ||
184 | MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT = BIT(8), | ||
185 | }; | ||
186 | |||
187 | struct iwl_dbgfs_bf { | ||
188 | u8 bf_energy_delta; | ||
189 | u8 bf_roaming_energy_delta; | ||
190 | u8 bf_roaming_state; | ||
191 | u8 bf_temperature_delta; | ||
192 | u8 bf_enable_beacon_filter; | ||
193 | u8 bf_debug_flag; | ||
194 | u32 bf_escape_timer; | ||
195 | u32 ba_escape_timer; | ||
196 | u8 ba_enable_beacon_abort; | ||
197 | int mask; | ||
198 | }; | ||
199 | #endif | ||
200 | |||
153 | enum iwl_mvm_smps_type_request { | 201 | enum iwl_mvm_smps_type_request { |
154 | IWL_MVM_SMPS_REQ_BT_COEX, | 202 | IWL_MVM_SMPS_REQ_BT_COEX, |
155 | IWL_MVM_SMPS_REQ_TT, | 203 | IWL_MVM_SMPS_REQ_TT, |
@@ -225,6 +273,8 @@ struct iwl_mvm_vif { | |||
225 | struct dentry *dbgfs_dir; | 273 | struct dentry *dbgfs_dir; |
226 | struct dentry *dbgfs_slink; | 274 | struct dentry *dbgfs_slink; |
227 | void *dbgfs_data; | 275 | void *dbgfs_data; |
276 | struct iwl_dbgfs_pm dbgfs_pm; | ||
277 | struct iwl_dbgfs_bf dbgfs_bf; | ||
228 | #endif | 278 | #endif |
229 | 279 | ||
230 | enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ]; | 280 | enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ]; |
@@ -631,6 +681,21 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
631 | void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 681 | void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
632 | 682 | ||
633 | /* beacon filtering */ | 683 | /* beacon filtering */ |
684 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
685 | void | ||
686 | iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif, | ||
687 | struct iwl_beacon_filter_cmd *cmd); | ||
688 | int iwl_mvm_dbgfs_set_fw_dbg_log(struct iwl_mvm *mvm); | ||
689 | #else | ||
690 | static inline void | ||
691 | iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif, | ||
692 | struct iwl_beacon_filter_cmd *cmd) | ||
693 | {} | ||
694 | static inline int iwl_mvm_dbgfs_set_fw_dbg_log(struct iwl_mvm *mvm) | ||
695 | { | ||
696 | return 0; | ||
697 | } | ||
698 | #endif | ||
634 | int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, | 699 | int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, |
635 | struct ieee80211_vif *vif); | 700 | struct ieee80211_vif *vif); |
636 | int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, | 701 | int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 516e64e7706f..67cf24aa72f9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
@@ -119,6 +119,7 @@ static int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm, | |||
119 | if (!mvmvif->bf_enabled) | 119 | if (!mvmvif->bf_enabled) |
120 | return 0; | 120 | return 0; |
121 | 121 | ||
122 | iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); | ||
122 | return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); | 123 | return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); |
123 | } | 124 | } |
124 | 125 | ||
@@ -153,6 +154,8 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
153 | int dtimper, dtimper_msec; | 154 | int dtimper, dtimper_msec; |
154 | int keep_alive; | 155 | int keep_alive; |
155 | bool radar_detect = false; | 156 | bool radar_detect = false; |
157 | struct iwl_mvm_vif *mvmvif __maybe_unused = | ||
158 | iwl_mvm_vif_from_mac80211(vif); | ||
156 | 159 | ||
157 | /* | 160 | /* |
158 | * Regardless of power management state the driver must set | 161 | * Regardless of power management state the driver must set |
@@ -166,6 +169,11 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
166 | 169 | ||
167 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); | 170 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); |
168 | 171 | ||
172 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
173 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF && | ||
174 | mvmvif->dbgfs_pm.disable_power_off) | ||
175 | cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK); | ||
176 | #endif | ||
169 | if (!vif->bss_conf.ps) | 177 | if (!vif->bss_conf.ps) |
170 | return; | 178 | return; |
171 | 179 | ||
@@ -205,6 +213,28 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
205 | cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); | 213 | cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); |
206 | cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); | 214 | cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); |
207 | } | 215 | } |
216 | |||
217 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
218 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE) | ||
219 | cmd->keep_alive_seconds = mvmvif->dbgfs_pm.keep_alive_seconds; | ||
220 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_OVER_DTIM) { | ||
221 | if (mvmvif->dbgfs_pm.skip_over_dtim) | ||
222 | cmd->flags |= | ||
223 | cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); | ||
224 | else | ||
225 | cmd->flags &= | ||
226 | cpu_to_le16(~POWER_FLAGS_SKIP_OVER_DTIM_MSK); | ||
227 | } | ||
228 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_RX_DATA_TIMEOUT) | ||
229 | cmd->rx_data_timeout = | ||
230 | cpu_to_le32(mvmvif->dbgfs_pm.rx_data_timeout); | ||
231 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_TX_DATA_TIMEOUT) | ||
232 | cmd->tx_data_timeout = | ||
233 | cpu_to_le32(mvmvif->dbgfs_pm.tx_data_timeout); | ||
234 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS) | ||
235 | cmd->skip_dtim_periods = | ||
236 | cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods); | ||
237 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | ||
208 | } | 238 | } |
209 | 239 | ||
210 | int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 240 | int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
@@ -233,6 +263,8 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
233 | int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 263 | int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
234 | { | 264 | { |
235 | struct iwl_powertable_cmd cmd = {}; | 265 | struct iwl_powertable_cmd cmd = {}; |
266 | struct iwl_mvm_vif *mvmvif __maybe_unused = | ||
267 | iwl_mvm_vif_from_mac80211(vif); | ||
236 | 268 | ||
237 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | 269 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) |
238 | return 0; | 270 | return 0; |
@@ -240,12 +272,45 @@ int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
240 | if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) | 272 | if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) |
241 | cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); | 273 | cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); |
242 | 274 | ||
275 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
276 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF && | ||
277 | mvmvif->dbgfs_pm.disable_power_off) | ||
278 | cmd.flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK); | ||
279 | #endif | ||
243 | iwl_mvm_power_log(mvm, &cmd); | 280 | iwl_mvm_power_log(mvm, &cmd); |
244 | 281 | ||
245 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, | 282 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, |
246 | sizeof(cmd), &cmd); | 283 | sizeof(cmd), &cmd); |
247 | } | 284 | } |
248 | 285 | ||
286 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
287 | void | ||
288 | iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif, | ||
289 | struct iwl_beacon_filter_cmd *cmd) | ||
290 | { | ||
291 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
292 | struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf; | ||
293 | |||
294 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ENERGY_DELTA) | ||
295 | cmd->bf_energy_delta = dbgfs_bf->bf_energy_delta; | ||
296 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA) | ||
297 | cmd->bf_roaming_energy_delta = | ||
298 | dbgfs_bf->bf_roaming_energy_delta; | ||
299 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_STATE) | ||
300 | cmd->bf_roaming_state = dbgfs_bf->bf_roaming_state; | ||
301 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMPERATURE_DELTA) | ||
302 | cmd->bf_temperature_delta = dbgfs_bf->bf_temperature_delta; | ||
303 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_DEBUG_FLAG) | ||
304 | cmd->bf_debug_flag = dbgfs_bf->bf_debug_flag; | ||
305 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ESCAPE_TIMER) | ||
306 | cmd->bf_escape_timer = cpu_to_le32(dbgfs_bf->bf_escape_timer); | ||
307 | if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ESCAPE_TIMER) | ||
308 | cmd->ba_escape_timer = cpu_to_le32(dbgfs_bf->ba_escape_timer); | ||
309 | if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT) | ||
310 | cmd->ba_enable_beacon_abort = dbgfs_bf->ba_enable_beacon_abort; | ||
311 | } | ||
312 | #endif | ||
313 | |||
249 | int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, | 314 | int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, |
250 | struct ieee80211_vif *vif) | 315 | struct ieee80211_vif *vif) |
251 | { | 316 | { |
@@ -260,6 +325,7 @@ int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, | |||
260 | vif->type != NL80211_IFTYPE_STATION || vif->p2p) | 325 | vif->type != NL80211_IFTYPE_STATION || vif->p2p) |
261 | return 0; | 326 | return 0; |
262 | 327 | ||
328 | iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); | ||
263 | ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); | 329 | ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); |
264 | 330 | ||
265 | if (!ret) | 331 | if (!ret) |