diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-debugfs.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debugfs.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index e320cc10167e..d0c63cfee15c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -804,6 +804,89 @@ DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); | |||
804 | DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); | 804 | DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); |
805 | DEBUGFS_READ_FILE_OPS(current_sleep_command); | 805 | DEBUGFS_READ_FILE_OPS(current_sleep_command); |
806 | 806 | ||
807 | static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, | ||
808 | char __user *user_buf, | ||
809 | size_t count, loff_t *ppos) | ||
810 | { | ||
811 | struct iwl_priv *priv = file->private_data; | ||
812 | int pos = 0, ofs = 0; | ||
813 | int cnt = 0, entry; | ||
814 | |||
815 | char *buf; | ||
816 | int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + | ||
817 | (hw_params(priv).max_txq_num * 32 * 8) + 400; | ||
818 | const u8 *ptr; | ||
819 | ssize_t ret; | ||
820 | |||
821 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
822 | if (!buf) { | ||
823 | IWL_ERR(priv, "Can not allocate buffer\n"); | ||
824 | return -ENOMEM; | ||
825 | } | ||
826 | if (priv->tx_traffic && | ||
827 | (iwl_get_debug_level(priv->shrd) & IWL_DL_TX)) { | ||
828 | ptr = priv->tx_traffic; | ||
829 | pos += scnprintf(buf + pos, bufsz - pos, | ||
830 | "Tx Traffic idx: %u\n", priv->tx_traffic_idx); | ||
831 | for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { | ||
832 | for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; | ||
833 | entry++, ofs += 16) { | ||
834 | pos += scnprintf(buf + pos, bufsz - pos, | ||
835 | "0x%.4x ", ofs); | ||
836 | hex_dump_to_buffer(ptr + ofs, 16, 16, 2, | ||
837 | buf + pos, bufsz - pos, 0); | ||
838 | pos += strlen(buf + pos); | ||
839 | if (bufsz - pos > 0) | ||
840 | buf[pos++] = '\n'; | ||
841 | } | ||
842 | } | ||
843 | } | ||
844 | |||
845 | if (priv->rx_traffic && | ||
846 | (iwl_get_debug_level(priv->shrd) & IWL_DL_RX)) { | ||
847 | ptr = priv->rx_traffic; | ||
848 | pos += scnprintf(buf + pos, bufsz - pos, | ||
849 | "Rx Traffic idx: %u\n", priv->rx_traffic_idx); | ||
850 | for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { | ||
851 | for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; | ||
852 | entry++, ofs += 16) { | ||
853 | pos += scnprintf(buf + pos, bufsz - pos, | ||
854 | "0x%.4x ", ofs); | ||
855 | hex_dump_to_buffer(ptr + ofs, 16, 16, 2, | ||
856 | buf + pos, bufsz - pos, 0); | ||
857 | pos += strlen(buf + pos); | ||
858 | if (bufsz - pos > 0) | ||
859 | buf[pos++] = '\n'; | ||
860 | } | ||
861 | } | ||
862 | } | ||
863 | |||
864 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
865 | kfree(buf); | ||
866 | return ret; | ||
867 | } | ||
868 | |||
869 | static ssize_t iwl_dbgfs_traffic_log_write(struct file *file, | ||
870 | const char __user *user_buf, | ||
871 | size_t count, loff_t *ppos) | ||
872 | { | ||
873 | struct iwl_priv *priv = file->private_data; | ||
874 | char buf[8]; | ||
875 | int buf_size; | ||
876 | int traffic_log; | ||
877 | |||
878 | memset(buf, 0, sizeof(buf)); | ||
879 | buf_size = min(count, sizeof(buf) - 1); | ||
880 | if (copy_from_user(buf, user_buf, buf_size)) | ||
881 | return -EFAULT; | ||
882 | if (sscanf(buf, "%d", &traffic_log) != 1) | ||
883 | return -EFAULT; | ||
884 | if (traffic_log == 0) | ||
885 | iwl_reset_traffic_log(priv); | ||
886 | |||
887 | return count; | ||
888 | } | ||
889 | |||
807 | static const char *fmt_value = " %-30s %10u\n"; | 890 | static const char *fmt_value = " %-30s %10u\n"; |
808 | static const char *fmt_hex = " %-30s 0x%02X\n"; | 891 | static const char *fmt_hex = " %-30s 0x%02X\n"; |
809 | static const char *fmt_table = " %-30s %10u %10u %10u %10u\n"; | 892 | static const char *fmt_table = " %-30s %10u %10u %10u %10u\n"; |
@@ -2340,6 +2423,7 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, | |||
2340 | 2423 | ||
2341 | DEBUGFS_READ_FILE_OPS(rx_statistics); | 2424 | DEBUGFS_READ_FILE_OPS(rx_statistics); |
2342 | DEBUGFS_READ_FILE_OPS(tx_statistics); | 2425 | DEBUGFS_READ_FILE_OPS(tx_statistics); |
2426 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); | ||
2343 | DEBUGFS_READ_FILE_OPS(ucode_rx_stats); | 2427 | DEBUGFS_READ_FILE_OPS(ucode_rx_stats); |
2344 | DEBUGFS_READ_FILE_OPS(ucode_tx_stats); | 2428 | DEBUGFS_READ_FILE_OPS(ucode_tx_stats); |
2345 | DEBUGFS_READ_FILE_OPS(ucode_general_stats); | 2429 | DEBUGFS_READ_FILE_OPS(ucode_general_stats); |
@@ -2400,6 +2484,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
2400 | DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); | 2484 | DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); |
2401 | DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); | 2485 | DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); |
2402 | DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR); | 2486 | DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR); |
2487 | DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR); | ||
2403 | DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); | 2488 | DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); |
2404 | DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR); | 2489 | DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR); |
2405 | DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); | 2490 | DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); |