diff options
author | Jouni Malinen <jouni@qca.qualcomm.com> | 2011-10-11 10:31:54 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2011-11-11 05:50:56 -0500 |
commit | 4b28a80dd6713c404f4f0084007456b769aba553 (patch) | |
tree | 3a36051268f4010159adb379815ddb357e8b558c /drivers/net/wireless/ath/ath6kl/debug.c | |
parent | e8091281f588812b128e102307e13acd9e917a5b (diff) |
ath6kl: Add debugfs file for target roam table
The new roam_table debugfs file can be used to display the current
roam table from the target.
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/debug.c')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/debug.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index b9bf28d72844..cec958a3d43f 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c | |||
@@ -966,6 +966,111 @@ static const struct file_operations fops_diag_reg_write = { | |||
966 | .llseek = default_llseek, | 966 | .llseek = default_llseek, |
967 | }; | 967 | }; |
968 | 968 | ||
969 | int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, const void *buf, | ||
970 | size_t len) | ||
971 | { | ||
972 | const struct wmi_target_roam_tbl *tbl; | ||
973 | u16 num_entries; | ||
974 | |||
975 | if (len < sizeof(*tbl)) | ||
976 | return -EINVAL; | ||
977 | |||
978 | tbl = (const struct wmi_target_roam_tbl *) buf; | ||
979 | num_entries = le16_to_cpu(tbl->num_entries); | ||
980 | if (sizeof(*tbl) + num_entries * sizeof(struct wmi_bss_roam_info) > | ||
981 | len) | ||
982 | return -EINVAL; | ||
983 | |||
984 | if (ar->debug.roam_tbl == NULL || | ||
985 | ar->debug.roam_tbl_len < (unsigned int) len) { | ||
986 | kfree(ar->debug.roam_tbl); | ||
987 | ar->debug.roam_tbl = kmalloc(len, GFP_ATOMIC); | ||
988 | if (ar->debug.roam_tbl == NULL) | ||
989 | return -ENOMEM; | ||
990 | } | ||
991 | |||
992 | memcpy(ar->debug.roam_tbl, buf, len); | ||
993 | ar->debug.roam_tbl_len = len; | ||
994 | |||
995 | if (test_bit(ROAM_TBL_PEND, &ar->flag)) { | ||
996 | clear_bit(ROAM_TBL_PEND, &ar->flag); | ||
997 | wake_up(&ar->event_wq); | ||
998 | } | ||
999 | |||
1000 | return 0; | ||
1001 | } | ||
1002 | |||
1003 | static ssize_t ath6kl_roam_table_read(struct file *file, char __user *user_buf, | ||
1004 | size_t count, loff_t *ppos) | ||
1005 | { | ||
1006 | struct ath6kl *ar = file->private_data; | ||
1007 | int ret; | ||
1008 | long left; | ||
1009 | struct wmi_target_roam_tbl *tbl; | ||
1010 | u16 num_entries, i; | ||
1011 | char *buf; | ||
1012 | unsigned int len, buf_len; | ||
1013 | ssize_t ret_cnt; | ||
1014 | |||
1015 | if (down_interruptible(&ar->sem)) | ||
1016 | return -EBUSY; | ||
1017 | |||
1018 | set_bit(ROAM_TBL_PEND, &ar->flag); | ||
1019 | |||
1020 | ret = ath6kl_wmi_get_roam_tbl_cmd(ar->wmi); | ||
1021 | if (ret) { | ||
1022 | up(&ar->sem); | ||
1023 | return ret; | ||
1024 | } | ||
1025 | |||
1026 | left = wait_event_interruptible_timeout( | ||
1027 | ar->event_wq, !test_bit(ROAM_TBL_PEND, &ar->flag), WMI_TIMEOUT); | ||
1028 | up(&ar->sem); | ||
1029 | |||
1030 | if (left <= 0) | ||
1031 | return -ETIMEDOUT; | ||
1032 | |||
1033 | if (ar->debug.roam_tbl == NULL) | ||
1034 | return -ENOMEM; | ||
1035 | |||
1036 | tbl = (struct wmi_target_roam_tbl *) ar->debug.roam_tbl; | ||
1037 | num_entries = le16_to_cpu(tbl->num_entries); | ||
1038 | |||
1039 | buf_len = 100 + num_entries * 100; | ||
1040 | buf = kzalloc(buf_len, GFP_KERNEL); | ||
1041 | if (buf == NULL) | ||
1042 | return -ENOMEM; | ||
1043 | len = 0; | ||
1044 | len += scnprintf(buf + len, buf_len - len, | ||
1045 | "roam_mode=%u\n\n" | ||
1046 | "# roam_util bssid rssi rssidt last_rssi util bias\n", | ||
1047 | le16_to_cpu(tbl->roam_mode)); | ||
1048 | |||
1049 | for (i = 0; i < num_entries; i++) { | ||
1050 | struct wmi_bss_roam_info *info = &tbl->info[i]; | ||
1051 | len += scnprintf(buf + len, buf_len - len, | ||
1052 | "%d %pM %d %d %d %d %d\n", | ||
1053 | a_sle32_to_cpu(info->roam_util), info->bssid, | ||
1054 | info->rssi, info->rssidt, info->last_rssi, | ||
1055 | info->util, info->bias); | ||
1056 | } | ||
1057 | |||
1058 | if (len > buf_len) | ||
1059 | len = buf_len; | ||
1060 | |||
1061 | ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
1062 | |||
1063 | kfree(buf); | ||
1064 | return ret_cnt; | ||
1065 | } | ||
1066 | |||
1067 | static const struct file_operations fops_roam_table = { | ||
1068 | .read = ath6kl_roam_table_read, | ||
1069 | .open = ath6kl_debugfs_open, | ||
1070 | .owner = THIS_MODULE, | ||
1071 | .llseek = default_llseek, | ||
1072 | }; | ||
1073 | |||
969 | int ath6kl_debug_init(struct ath6kl *ar) | 1074 | int ath6kl_debug_init(struct ath6kl *ar) |
970 | { | 1075 | { |
971 | ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE); | 1076 | ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE); |
@@ -1024,6 +1129,9 @@ int ath6kl_debug_init(struct ath6kl *ar) | |||
1024 | debugfs_create_file("war_stats", S_IRUSR, ar->debugfs_phy, ar, | 1129 | debugfs_create_file("war_stats", S_IRUSR, ar->debugfs_phy, ar, |
1025 | &fops_war_stats); | 1130 | &fops_war_stats); |
1026 | 1131 | ||
1132 | debugfs_create_file("roam_table", S_IRUSR, ar->debugfs_phy, ar, | ||
1133 | &fops_roam_table); | ||
1134 | |||
1027 | return 0; | 1135 | return 0; |
1028 | } | 1136 | } |
1029 | 1137 | ||
@@ -1031,6 +1139,7 @@ void ath6kl_debug_cleanup(struct ath6kl *ar) | |||
1031 | { | 1139 | { |
1032 | vfree(ar->debug.fwlog_buf.buf); | 1140 | vfree(ar->debug.fwlog_buf.buf); |
1033 | kfree(ar->debug.fwlog_tmp); | 1141 | kfree(ar->debug.fwlog_tmp); |
1142 | kfree(ar->debug.roam_tbl); | ||
1034 | } | 1143 | } |
1035 | 1144 | ||
1036 | #endif | 1145 | #endif |