diff options
-rw-r--r-- | drivers/net/wireless/ath/ath10k/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/core.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/coredump.c | 165 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/coredump.h | 121 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/debug.c | 222 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/debug.h | 16 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/pci.c | 3 |
7 files changed, 291 insertions, 240 deletions
diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile index 8d9a59b7144e..4e6a396827ee 100644 --- a/drivers/net/wireless/ath/ath10k/Makefile +++ b/drivers/net/wireless/ath/ath10k/Makefile | |||
@@ -21,6 +21,7 @@ ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o | |||
21 | ath10k_core-$(CONFIG_THERMAL) += thermal.o | 21 | ath10k_core-$(CONFIG_THERMAL) += thermal.o |
22 | ath10k_core-$(CONFIG_MAC80211_DEBUGFS) += debugfs_sta.o | 22 | ath10k_core-$(CONFIG_MAC80211_DEBUGFS) += debugfs_sta.o |
23 | ath10k_core-$(CONFIG_PM) += wow.o | 23 | ath10k_core-$(CONFIG_PM) += wow.o |
24 | ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += coredump.o | ||
24 | 25 | ||
25 | obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o | 26 | obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o |
26 | ath10k_pci-y += pci.o \ | 27 | ath10k_pci-y += pci.o \ |
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index e5e78a4cacde..fe47516999f6 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "htt.h" | 32 | #include "htt.h" |
33 | #include "testmode.h" | 33 | #include "testmode.h" |
34 | #include "wmi-ops.h" | 34 | #include "wmi-ops.h" |
35 | #include "coredump.h" | ||
35 | 36 | ||
36 | unsigned int ath10k_debug_mask; | 37 | unsigned int ath10k_debug_mask; |
37 | static unsigned int ath10k_cryptmode_param; | 38 | static unsigned int ath10k_cryptmode_param; |
@@ -1864,7 +1865,7 @@ static void ath10k_core_restart(struct work_struct *work) | |||
1864 | 1865 | ||
1865 | mutex_unlock(&ar->conf_mutex); | 1866 | mutex_unlock(&ar->conf_mutex); |
1866 | 1867 | ||
1867 | ret = ath10k_debug_fw_devcoredump(ar); | 1868 | ret = ath10k_coredump_submit(ar); |
1868 | if (ret) | 1869 | if (ret) |
1869 | ath10k_warn(ar, "failed to send firmware crash dump via devcoredump: %d", | 1870 | ath10k_warn(ar, "failed to send firmware crash dump via devcoredump: %d", |
1870 | ret); | 1871 | ret); |
diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c new file mode 100644 index 000000000000..51b86878e733 --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/coredump.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "coredump.h" | ||
18 | |||
19 | #include <linux/devcoredump.h> | ||
20 | #include <linux/utsname.h> | ||
21 | |||
22 | #include "debug.h" | ||
23 | |||
24 | #ifdef CONFIG_DEV_COREDUMP | ||
25 | |||
26 | struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar) | ||
27 | { | ||
28 | struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data; | ||
29 | |||
30 | lockdep_assert_held(&ar->data_lock); | ||
31 | |||
32 | crash_data->crashed_since_read = true; | ||
33 | guid_gen(&crash_data->guid); | ||
34 | ktime_get_real_ts64(&crash_data->timestamp); | ||
35 | |||
36 | return crash_data; | ||
37 | } | ||
38 | EXPORT_SYMBOL(ath10k_coredump_new); | ||
39 | |||
40 | static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar, | ||
41 | bool mark_read) | ||
42 | { | ||
43 | struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data; | ||
44 | struct ath10k_ce_crash_hdr *ce_hdr; | ||
45 | struct ath10k_dump_file_data *dump_data; | ||
46 | struct ath10k_tlv_dump_data *dump_tlv; | ||
47 | size_t hdr_len = sizeof(*dump_data); | ||
48 | size_t len, sofar = 0; | ||
49 | unsigned char *buf; | ||
50 | |||
51 | len = hdr_len; | ||
52 | len += sizeof(*dump_tlv) + sizeof(crash_data->registers); | ||
53 | len += sizeof(*dump_tlv) + sizeof(*ce_hdr) + | ||
54 | CE_COUNT * sizeof(ce_hdr->entries[0]); | ||
55 | |||
56 | sofar += hdr_len; | ||
57 | |||
58 | /* This is going to get big when we start dumping FW RAM and such, | ||
59 | * so go ahead and use vmalloc. | ||
60 | */ | ||
61 | buf = vzalloc(len); | ||
62 | if (!buf) | ||
63 | return NULL; | ||
64 | |||
65 | spin_lock_bh(&ar->data_lock); | ||
66 | |||
67 | if (!crash_data->crashed_since_read) { | ||
68 | spin_unlock_bh(&ar->data_lock); | ||
69 | vfree(buf); | ||
70 | return NULL; | ||
71 | } | ||
72 | |||
73 | dump_data = (struct ath10k_dump_file_data *)(buf); | ||
74 | strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP", | ||
75 | sizeof(dump_data->df_magic)); | ||
76 | dump_data->len = cpu_to_le32(len); | ||
77 | |||
78 | dump_data->version = cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION); | ||
79 | |||
80 | guid_copy(&dump_data->guid, &crash_data->guid); | ||
81 | dump_data->chip_id = cpu_to_le32(ar->chip_id); | ||
82 | dump_data->bus_type = cpu_to_le32(0); | ||
83 | dump_data->target_version = cpu_to_le32(ar->target_version); | ||
84 | dump_data->fw_version_major = cpu_to_le32(ar->fw_version_major); | ||
85 | dump_data->fw_version_minor = cpu_to_le32(ar->fw_version_minor); | ||
86 | dump_data->fw_version_release = cpu_to_le32(ar->fw_version_release); | ||
87 | dump_data->fw_version_build = cpu_to_le32(ar->fw_version_build); | ||
88 | dump_data->phy_capability = cpu_to_le32(ar->phy_capability); | ||
89 | dump_data->hw_min_tx_power = cpu_to_le32(ar->hw_min_tx_power); | ||
90 | dump_data->hw_max_tx_power = cpu_to_le32(ar->hw_max_tx_power); | ||
91 | dump_data->ht_cap_info = cpu_to_le32(ar->ht_cap_info); | ||
92 | dump_data->vht_cap_info = cpu_to_le32(ar->vht_cap_info); | ||
93 | dump_data->num_rf_chains = cpu_to_le32(ar->num_rf_chains); | ||
94 | |||
95 | strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version, | ||
96 | sizeof(dump_data->fw_ver)); | ||
97 | |||
98 | dump_data->kernel_ver_code = 0; | ||
99 | strlcpy(dump_data->kernel_ver, init_utsname()->release, | ||
100 | sizeof(dump_data->kernel_ver)); | ||
101 | |||
102 | dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec); | ||
103 | dump_data->tv_nsec = cpu_to_le64(crash_data->timestamp.tv_nsec); | ||
104 | |||
105 | /* Gather crash-dump */ | ||
106 | dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); | ||
107 | dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS); | ||
108 | dump_tlv->tlv_len = cpu_to_le32(sizeof(crash_data->registers)); | ||
109 | memcpy(dump_tlv->tlv_data, &crash_data->registers, | ||
110 | sizeof(crash_data->registers)); | ||
111 | sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers); | ||
112 | |||
113 | dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); | ||
114 | dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_CE_DATA); | ||
115 | dump_tlv->tlv_len = cpu_to_le32(sizeof(*ce_hdr) + | ||
116 | CE_COUNT * sizeof(ce_hdr->entries[0])); | ||
117 | ce_hdr = (struct ath10k_ce_crash_hdr *)(dump_tlv->tlv_data); | ||
118 | ce_hdr->ce_count = cpu_to_le32(CE_COUNT); | ||
119 | memset(ce_hdr->reserved, 0, sizeof(ce_hdr->reserved)); | ||
120 | memcpy(ce_hdr->entries, crash_data->ce_crash_data, | ||
121 | CE_COUNT * sizeof(ce_hdr->entries[0])); | ||
122 | sofar += sizeof(*dump_tlv) + sizeof(*ce_hdr) + | ||
123 | CE_COUNT * sizeof(ce_hdr->entries[0]); | ||
124 | |||
125 | ar->debug.fw_crash_data->crashed_since_read = !mark_read; | ||
126 | |||
127 | spin_unlock_bh(&ar->data_lock); | ||
128 | |||
129 | return dump_data; | ||
130 | } | ||
131 | |||
132 | int ath10k_coredump_submit(struct ath10k *ar) | ||
133 | { | ||
134 | struct ath10k_dump_file_data *dump; | ||
135 | void *dump_ptr; | ||
136 | u32 dump_len; | ||
137 | |||
138 | /* To keep the dump file available also for debugfs don't mark the | ||
139 | * file read, only debugfs should do that. | ||
140 | */ | ||
141 | dump = ath10k_coredump_build(ar, false); | ||
142 | if (!dump) { | ||
143 | ath10k_warn(ar, "no crash dump data found for devcoredump"); | ||
144 | return -ENODATA; | ||
145 | } | ||
146 | |||
147 | /* Make a copy of the dump file for dev_coredumpv() as during the | ||
148 | * transition period we need to own the original file. Once | ||
149 | * fw_crash_dump debugfs file is removed no need to have a copy | ||
150 | * anymore. | ||
151 | */ | ||
152 | dump_len = le32_to_cpu(dump->len); | ||
153 | dump_ptr = vzalloc(dump_len); | ||
154 | |||
155 | if (!dump_ptr) | ||
156 | return -ENOMEM; | ||
157 | |||
158 | memcpy(dump_ptr, dump, dump_len); | ||
159 | |||
160 | dev_coredumpv(ar->dev, dump_ptr, dump_len, GFP_KERNEL); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | #endif /* CONFIG_DEV_COREDUMP */ | ||
diff --git a/drivers/net/wireless/ath/ath10k/coredump.h b/drivers/net/wireless/ath/ath10k/coredump.h new file mode 100644 index 000000000000..2d2f45b5aa37 --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/coredump.h | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef _COREDUMP_H_ | ||
18 | #define _COREDUMP_H_ | ||
19 | |||
20 | #include "core.h" | ||
21 | |||
22 | #define ATH10K_FW_CRASH_DUMP_VERSION 1 | ||
23 | |||
24 | /** | ||
25 | * enum ath10k_fw_crash_dump_type - types of data in the dump file | ||
26 | * @ATH10K_FW_CRASH_DUMP_REGDUMP: Register crash dump in binary format | ||
27 | */ | ||
28 | enum ath10k_fw_crash_dump_type { | ||
29 | ATH10K_FW_CRASH_DUMP_REGISTERS = 0, | ||
30 | ATH10K_FW_CRASH_DUMP_CE_DATA = 1, | ||
31 | |||
32 | ATH10K_FW_CRASH_DUMP_MAX, | ||
33 | }; | ||
34 | |||
35 | struct ath10k_tlv_dump_data { | ||
36 | /* see ath10k_fw_crash_dump_type above */ | ||
37 | __le32 type; | ||
38 | |||
39 | /* in bytes */ | ||
40 | __le32 tlv_len; | ||
41 | |||
42 | /* pad to 32-bit boundaries as needed */ | ||
43 | u8 tlv_data[]; | ||
44 | } __packed; | ||
45 | |||
46 | struct ath10k_dump_file_data { | ||
47 | /* dump file information */ | ||
48 | |||
49 | /* "ATH10K-FW-DUMP" */ | ||
50 | char df_magic[16]; | ||
51 | |||
52 | __le32 len; | ||
53 | |||
54 | /* file dump version */ | ||
55 | __le32 version; | ||
56 | |||
57 | /* some info we can get from ath10k struct that might help */ | ||
58 | |||
59 | guid_t guid; | ||
60 | |||
61 | __le32 chip_id; | ||
62 | |||
63 | /* 0 for now, in place for later hardware */ | ||
64 | __le32 bus_type; | ||
65 | |||
66 | __le32 target_version; | ||
67 | __le32 fw_version_major; | ||
68 | __le32 fw_version_minor; | ||
69 | __le32 fw_version_release; | ||
70 | __le32 fw_version_build; | ||
71 | __le32 phy_capability; | ||
72 | __le32 hw_min_tx_power; | ||
73 | __le32 hw_max_tx_power; | ||
74 | __le32 ht_cap_info; | ||
75 | __le32 vht_cap_info; | ||
76 | __le32 num_rf_chains; | ||
77 | |||
78 | /* firmware version string */ | ||
79 | char fw_ver[ETHTOOL_FWVERS_LEN]; | ||
80 | |||
81 | /* Kernel related information */ | ||
82 | |||
83 | /* time-of-day stamp */ | ||
84 | __le64 tv_sec; | ||
85 | |||
86 | /* time-of-day stamp, nano-seconds */ | ||
87 | __le64 tv_nsec; | ||
88 | |||
89 | /* LINUX_VERSION_CODE */ | ||
90 | __le32 kernel_ver_code; | ||
91 | |||
92 | /* VERMAGIC_STRING */ | ||
93 | char kernel_ver[64]; | ||
94 | |||
95 | /* room for growth w/out changing binary format */ | ||
96 | u8 unused[128]; | ||
97 | |||
98 | /* struct ath10k_tlv_dump_data + more */ | ||
99 | u8 data[0]; | ||
100 | } __packed; | ||
101 | |||
102 | #ifdef CONFIG_DEV_COREDUMP | ||
103 | |||
104 | int ath10k_coredump_submit(struct ath10k *ar); | ||
105 | struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar); | ||
106 | |||
107 | #else /* CONFIG_DEV_COREDUMP */ | ||
108 | |||
109 | static inline int ath10k_coredump_submit(struct ath10k *ar) | ||
110 | { | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static inline struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar) | ||
115 | { | ||
116 | return NULL; | ||
117 | } | ||
118 | |||
119 | #endif /* CONFIG_DEV_COREDUMP */ | ||
120 | |||
121 | #endif /* _COREDUMP_H_ */ | ||
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 358c34eeb2d2..f8e44882439a 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c | |||
@@ -18,10 +18,8 @@ | |||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/debugfs.h> | 19 | #include <linux/debugfs.h> |
20 | #include <linux/vmalloc.h> | 20 | #include <linux/vmalloc.h> |
21 | #include <linux/utsname.h> | ||
22 | #include <linux/crc32.h> | 21 | #include <linux/crc32.h> |
23 | #include <linux/firmware.h> | 22 | #include <linux/firmware.h> |
24 | #include <linux/devcoredump.h> | ||
25 | 23 | ||
26 | #include "core.h" | 24 | #include "core.h" |
27 | #include "debug.h" | 25 | #include "debug.h" |
@@ -33,86 +31,6 @@ | |||
33 | 31 | ||
34 | #define ATH10K_DEBUG_CAL_DATA_LEN 12064 | 32 | #define ATH10K_DEBUG_CAL_DATA_LEN 12064 |
35 | 33 | ||
36 | #define ATH10K_FW_CRASH_DUMP_VERSION 1 | ||
37 | |||
38 | /** | ||
39 | * enum ath10k_fw_crash_dump_type - types of data in the dump file | ||
40 | * @ATH10K_FW_CRASH_DUMP_REGDUMP: Register crash dump in binary format | ||
41 | */ | ||
42 | enum ath10k_fw_crash_dump_type { | ||
43 | ATH10K_FW_CRASH_DUMP_REGISTERS = 0, | ||
44 | ATH10K_FW_CRASH_DUMP_CE_DATA = 1, | ||
45 | |||
46 | ATH10K_FW_CRASH_DUMP_MAX, | ||
47 | }; | ||
48 | |||
49 | struct ath10k_tlv_dump_data { | ||
50 | /* see ath10k_fw_crash_dump_type above */ | ||
51 | __le32 type; | ||
52 | |||
53 | /* in bytes */ | ||
54 | __le32 tlv_len; | ||
55 | |||
56 | /* pad to 32-bit boundaries as needed */ | ||
57 | u8 tlv_data[]; | ||
58 | } __packed; | ||
59 | |||
60 | struct ath10k_dump_file_data { | ||
61 | /* dump file information */ | ||
62 | |||
63 | /* "ATH10K-FW-DUMP" */ | ||
64 | char df_magic[16]; | ||
65 | |||
66 | __le32 len; | ||
67 | |||
68 | /* file dump version */ | ||
69 | __le32 version; | ||
70 | |||
71 | /* some info we can get from ath10k struct that might help */ | ||
72 | |||
73 | guid_t guid; | ||
74 | |||
75 | __le32 chip_id; | ||
76 | |||
77 | /* 0 for now, in place for later hardware */ | ||
78 | __le32 bus_type; | ||
79 | |||
80 | __le32 target_version; | ||
81 | __le32 fw_version_major; | ||
82 | __le32 fw_version_minor; | ||
83 | __le32 fw_version_release; | ||
84 | __le32 fw_version_build; | ||
85 | __le32 phy_capability; | ||
86 | __le32 hw_min_tx_power; | ||
87 | __le32 hw_max_tx_power; | ||
88 | __le32 ht_cap_info; | ||
89 | __le32 vht_cap_info; | ||
90 | __le32 num_rf_chains; | ||
91 | |||
92 | /* firmware version string */ | ||
93 | char fw_ver[ETHTOOL_FWVERS_LEN]; | ||
94 | |||
95 | /* Kernel related information */ | ||
96 | |||
97 | /* time-of-day stamp */ | ||
98 | __le64 tv_sec; | ||
99 | |||
100 | /* time-of-day stamp, nano-seconds */ | ||
101 | __le64 tv_nsec; | ||
102 | |||
103 | /* LINUX_VERSION_CODE */ | ||
104 | __le32 kernel_ver_code; | ||
105 | |||
106 | /* VERMAGIC_STRING */ | ||
107 | char kernel_ver[64]; | ||
108 | |||
109 | /* room for growth w/out changing binary format */ | ||
110 | u8 unused[128]; | ||
111 | |||
112 | /* struct ath10k_tlv_dump_data + more */ | ||
113 | u8 data[0]; | ||
114 | } __packed; | ||
115 | |||
116 | void ath10k_info(struct ath10k *ar, const char *fmt, ...) | 34 | void ath10k_info(struct ath10k *ar, const char *fmt, ...) |
117 | { | 35 | { |
118 | struct va_format vaf = { | 36 | struct va_format vaf = { |
@@ -711,146 +629,6 @@ static const struct file_operations fops_chip_id = { | |||
711 | .llseek = default_llseek, | 629 | .llseek = default_llseek, |
712 | }; | 630 | }; |
713 | 631 | ||
714 | struct ath10k_fw_crash_data * | ||
715 | ath10k_debug_get_new_fw_crash_data(struct ath10k *ar) | ||
716 | { | ||
717 | struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data; | ||
718 | |||
719 | lockdep_assert_held(&ar->data_lock); | ||
720 | |||
721 | crash_data->crashed_since_read = true; | ||
722 | guid_gen(&crash_data->guid); | ||
723 | ktime_get_real_ts64(&crash_data->timestamp); | ||
724 | |||
725 | return crash_data; | ||
726 | } | ||
727 | EXPORT_SYMBOL(ath10k_debug_get_new_fw_crash_data); | ||
728 | |||
729 | static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar, | ||
730 | bool mark_read) | ||
731 | { | ||
732 | struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data; | ||
733 | struct ath10k_ce_crash_hdr *ce_hdr; | ||
734 | struct ath10k_dump_file_data *dump_data; | ||
735 | struct ath10k_tlv_dump_data *dump_tlv; | ||
736 | size_t hdr_len = sizeof(*dump_data); | ||
737 | size_t len, sofar = 0; | ||
738 | unsigned char *buf; | ||
739 | |||
740 | len = hdr_len; | ||
741 | len += sizeof(*dump_tlv) + sizeof(crash_data->registers); | ||
742 | len += sizeof(*dump_tlv) + sizeof(*ce_hdr) + | ||
743 | CE_COUNT * sizeof(ce_hdr->entries[0]); | ||
744 | |||
745 | sofar += hdr_len; | ||
746 | |||
747 | /* This is going to get big when we start dumping FW RAM and such, | ||
748 | * so go ahead and use vmalloc. | ||
749 | */ | ||
750 | buf = vzalloc(len); | ||
751 | if (!buf) | ||
752 | return NULL; | ||
753 | |||
754 | spin_lock_bh(&ar->data_lock); | ||
755 | |||
756 | if (!crash_data->crashed_since_read) { | ||
757 | spin_unlock_bh(&ar->data_lock); | ||
758 | vfree(buf); | ||
759 | return NULL; | ||
760 | } | ||
761 | |||
762 | dump_data = (struct ath10k_dump_file_data *)(buf); | ||
763 | strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP", | ||
764 | sizeof(dump_data->df_magic)); | ||
765 | dump_data->len = cpu_to_le32(len); | ||
766 | |||
767 | dump_data->version = cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION); | ||
768 | |||
769 | guid_copy(&dump_data->guid, &crash_data->guid); | ||
770 | dump_data->chip_id = cpu_to_le32(ar->chip_id); | ||
771 | dump_data->bus_type = cpu_to_le32(0); | ||
772 | dump_data->target_version = cpu_to_le32(ar->target_version); | ||
773 | dump_data->fw_version_major = cpu_to_le32(ar->fw_version_major); | ||
774 | dump_data->fw_version_minor = cpu_to_le32(ar->fw_version_minor); | ||
775 | dump_data->fw_version_release = cpu_to_le32(ar->fw_version_release); | ||
776 | dump_data->fw_version_build = cpu_to_le32(ar->fw_version_build); | ||
777 | dump_data->phy_capability = cpu_to_le32(ar->phy_capability); | ||
778 | dump_data->hw_min_tx_power = cpu_to_le32(ar->hw_min_tx_power); | ||
779 | dump_data->hw_max_tx_power = cpu_to_le32(ar->hw_max_tx_power); | ||
780 | dump_data->ht_cap_info = cpu_to_le32(ar->ht_cap_info); | ||
781 | dump_data->vht_cap_info = cpu_to_le32(ar->vht_cap_info); | ||
782 | dump_data->num_rf_chains = cpu_to_le32(ar->num_rf_chains); | ||
783 | |||
784 | strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version, | ||
785 | sizeof(dump_data->fw_ver)); | ||
786 | |||
787 | dump_data->kernel_ver_code = 0; | ||
788 | strlcpy(dump_data->kernel_ver, init_utsname()->release, | ||
789 | sizeof(dump_data->kernel_ver)); | ||
790 | |||
791 | dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec); | ||
792 | dump_data->tv_nsec = cpu_to_le64(crash_data->timestamp.tv_nsec); | ||
793 | |||
794 | /* Gather crash-dump */ | ||
795 | dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); | ||
796 | dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS); | ||
797 | dump_tlv->tlv_len = cpu_to_le32(sizeof(crash_data->registers)); | ||
798 | memcpy(dump_tlv->tlv_data, &crash_data->registers, | ||
799 | sizeof(crash_data->registers)); | ||
800 | sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers); | ||
801 | |||
802 | dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); | ||
803 | dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_CE_DATA); | ||
804 | dump_tlv->tlv_len = cpu_to_le32(sizeof(*ce_hdr) + | ||
805 | CE_COUNT * sizeof(ce_hdr->entries[0])); | ||
806 | ce_hdr = (struct ath10k_ce_crash_hdr *)(dump_tlv->tlv_data); | ||
807 | ce_hdr->ce_count = cpu_to_le32(CE_COUNT); | ||
808 | memset(ce_hdr->reserved, 0, sizeof(ce_hdr->reserved)); | ||
809 | memcpy(ce_hdr->entries, crash_data->ce_crash_data, | ||
810 | CE_COUNT * sizeof(ce_hdr->entries[0])); | ||
811 | sofar += sizeof(*dump_tlv) + sizeof(*ce_hdr) + | ||
812 | CE_COUNT * sizeof(ce_hdr->entries[0]); | ||
813 | |||
814 | ar->debug.fw_crash_data->crashed_since_read = !mark_read; | ||
815 | |||
816 | spin_unlock_bh(&ar->data_lock); | ||
817 | |||
818 | return dump_data; | ||
819 | } | ||
820 | |||
821 | int ath10k_debug_fw_devcoredump(struct ath10k *ar) | ||
822 | { | ||
823 | struct ath10k_dump_file_data *dump; | ||
824 | void *dump_ptr; | ||
825 | u32 dump_len; | ||
826 | |||
827 | /* To keep the dump file available also for debugfs don't mark the | ||
828 | * file read, only debugfs should do that. | ||
829 | */ | ||
830 | dump = ath10k_build_dump_file(ar, false); | ||
831 | if (!dump) { | ||
832 | ath10k_warn(ar, "no crash dump data found for devcoredump"); | ||
833 | return -ENODATA; | ||
834 | } | ||
835 | |||
836 | /* Make a copy of the dump file for dev_coredumpv() as during the | ||
837 | * transition period we need to own the original file. Once | ||
838 | * fw_crash_dump debugfs file is removed no need to have a copy | ||
839 | * anymore. | ||
840 | */ | ||
841 | dump_len = le32_to_cpu(dump->len); | ||
842 | dump_ptr = vzalloc(dump_len); | ||
843 | |||
844 | if (!dump_ptr) | ||
845 | return -ENOMEM; | ||
846 | |||
847 | memcpy(dump_ptr, dump, dump_len); | ||
848 | |||
849 | dev_coredumpv(ar->dev, dump_ptr, dump_len, GFP_KERNEL); | ||
850 | |||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static ssize_t ath10k_reg_addr_read(struct file *file, | 632 | static ssize_t ath10k_reg_addr_read(struct file *file, |
855 | char __user *user_buf, | 633 | char __user *user_buf, |
856 | size_t count, loff_t *ppos) | 634 | size_t count, loff_t *ppos) |
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index 134fb68ae546..58046f89dc52 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h | |||
@@ -101,13 +101,8 @@ void ath10k_debug_unregister(struct ath10k *ar); | |||
101 | void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb); | 101 | void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb); |
102 | void ath10k_debug_tpc_stats_process(struct ath10k *ar, | 102 | void ath10k_debug_tpc_stats_process(struct ath10k *ar, |
103 | struct ath10k_tpc_stats *tpc_stats); | 103 | struct ath10k_tpc_stats *tpc_stats); |
104 | struct ath10k_fw_crash_data * | ||
105 | ath10k_debug_get_new_fw_crash_data(struct ath10k *ar); | ||
106 | |||
107 | void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len); | 104 | void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len); |
108 | 105 | ||
109 | int ath10k_debug_fw_devcoredump(struct ath10k *ar); | ||
110 | |||
111 | #define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++) | 106 | #define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++) |
112 | 107 | ||
113 | void ath10k_debug_get_et_strings(struct ieee80211_hw *hw, | 108 | void ath10k_debug_get_et_strings(struct ieee80211_hw *hw, |
@@ -174,12 +169,6 @@ static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, | |||
174 | { | 169 | { |
175 | } | 170 | } |
176 | 171 | ||
177 | static inline struct ath10k_fw_crash_data * | ||
178 | ath10k_debug_get_new_fw_crash_data(struct ath10k *ar) | ||
179 | { | ||
180 | return NULL; | ||
181 | } | ||
182 | |||
183 | static inline u64 ath10k_debug_get_fw_dbglog_mask(struct ath10k *ar) | 172 | static inline u64 ath10k_debug_get_fw_dbglog_mask(struct ath10k *ar) |
184 | { | 173 | { |
185 | return 0; | 174 | return 0; |
@@ -190,11 +179,6 @@ static inline u32 ath10k_debug_get_fw_dbglog_level(struct ath10k *ar) | |||
190 | return 0; | 179 | return 0; |
191 | } | 180 | } |
192 | 181 | ||
193 | static inline int ath10k_debug_fw_devcoredump(struct ath10k *ar) | ||
194 | { | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | #define ATH10K_DFS_STAT_INC(ar, c) do { } while (0) | 182 | #define ATH10K_DFS_STAT_INC(ar, c) do { } while (0) |
199 | 183 | ||
200 | #define ath10k_debug_get_et_strings NULL | 184 | #define ath10k_debug_get_et_strings NULL |
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index b056107aec91..61406bba2b5e 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include "core.h" | 24 | #include "core.h" |
25 | #include "debug.h" | 25 | #include "debug.h" |
26 | #include "coredump.h" | ||
26 | 27 | ||
27 | #include "targaddrs.h" | 28 | #include "targaddrs.h" |
28 | #include "bmi.h" | 29 | #include "bmi.h" |
@@ -1470,7 +1471,7 @@ static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) | |||
1470 | 1471 | ||
1471 | ar->stats.fw_crash_counter++; | 1472 | ar->stats.fw_crash_counter++; |
1472 | 1473 | ||
1473 | crash_data = ath10k_debug_get_new_fw_crash_data(ar); | 1474 | crash_data = ath10k_coredump_new(ar); |
1474 | 1475 | ||
1475 | if (crash_data) | 1476 | if (crash_data) |
1476 | scnprintf(guid, sizeof(guid), "%pUl", &crash_data->guid); | 1477 | scnprintf(guid, sizeof(guid), "%pUl", &crash_data->guid); |