1 | /* SPDX-License-Identifier: ISC */ |
2 | /* |
3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
4 | * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. |
5 | */ |
6 | |
7 | #ifndef _COREDUMP_H_ |
8 | #define _COREDUMP_H_ |
9 | |
10 | #include "core.h" |
11 | |
12 | #define ATH10K_FW_CRASH_DUMP_VERSION 1 |
13 | |
14 | /** |
15 | * enum ath10k_fw_crash_dump_type - types of data in the dump file |
16 | * @ATH10K_FW_CRASH_DUMP_REGISTERS: Register crash dump in binary format |
17 | * @ATH10K_FW_CRASH_DUMP_CE_DATA: Copy Engine crash dump data |
18 | * @ATH10K_FW_CRASH_DUMP_RAM_DATA: RAM crash dump data, contains multiple |
19 | * struct ath10k_dump_ram_data_hdr |
20 | * @ATH10K_FW_CRASH_DUMP_MAX: Maximum enumeration |
21 | */ |
22 | enum ath10k_fw_crash_dump_type { |
23 | ATH10K_FW_CRASH_DUMP_REGISTERS = 0, |
24 | ATH10K_FW_CRASH_DUMP_CE_DATA = 1, |
25 | |
26 | /* contains multiple struct ath10k_dump_ram_data_hdr */ |
27 | ATH10K_FW_CRASH_DUMP_RAM_DATA = 2, |
28 | |
29 | ATH10K_FW_CRASH_DUMP_MAX, |
30 | }; |
31 | |
32 | struct ath10k_tlv_dump_data { |
33 | /* see ath10k_fw_crash_dump_type above */ |
34 | __le32 type; |
35 | |
36 | /* in bytes */ |
37 | __le32 tlv_len; |
38 | |
39 | /* pad to 32-bit boundaries as needed */ |
40 | u8 tlv_data[]; |
41 | } __packed; |
42 | |
43 | struct ath10k_dump_file_data { |
44 | /* dump file information */ |
45 | |
46 | /* "ATH10K-FW-DUMP" */ |
47 | char df_magic[16]; |
48 | |
49 | __le32 len; |
50 | |
51 | /* file dump version */ |
52 | __le32 version; |
53 | |
54 | /* some info we can get from ath10k struct that might help */ |
55 | |
56 | guid_t guid; |
57 | |
58 | __le32 chip_id; |
59 | |
60 | /* 0 for now, in place for later hardware */ |
61 | __le32 bus_type; |
62 | |
63 | __le32 target_version; |
64 | __le32 fw_version_major; |
65 | __le32 fw_version_minor; |
66 | __le32 fw_version_release; |
67 | __le32 fw_version_build; |
68 | __le32 phy_capability; |
69 | __le32 hw_min_tx_power; |
70 | __le32 hw_max_tx_power; |
71 | __le32 ht_cap_info; |
72 | __le32 vht_cap_info; |
73 | __le32 num_rf_chains; |
74 | |
75 | /* firmware version string */ |
76 | char fw_ver[ETHTOOL_FWVERS_LEN]; |
77 | |
78 | /* Kernel related information */ |
79 | |
80 | /* time-of-day stamp */ |
81 | __le64 tv_sec; |
82 | |
83 | /* time-of-day stamp, nano-seconds */ |
84 | __le64 tv_nsec; |
85 | |
86 | /* LINUX_VERSION_CODE */ |
87 | __le32 kernel_ver_code; |
88 | |
89 | /* VERMAGIC_STRING */ |
90 | char kernel_ver[64]; |
91 | |
92 | /* room for growth w/out changing binary format */ |
93 | u8 unused[128]; |
94 | |
95 | /* struct ath10k_tlv_dump_data + more */ |
96 | u8 data[]; |
97 | } __packed; |
98 | |
99 | struct ath10k_dump_ram_data_hdr { |
100 | /* enum ath10k_mem_region_type */ |
101 | __le32 region_type; |
102 | |
103 | __le32 start; |
104 | |
105 | /* length of payload data, not including this header */ |
106 | __le32 length; |
107 | |
108 | u8 data[]; |
109 | }; |
110 | |
111 | /* magic number to fill the holes not copied due to sections in regions */ |
112 | #define ATH10K_MAGIC_NOT_COPIED 0xAA |
113 | |
114 | /* part of user space ABI */ |
115 | enum ath10k_mem_region_type { |
116 | ATH10K_MEM_REGION_TYPE_REG = 1, |
117 | ATH10K_MEM_REGION_TYPE_DRAM = 2, |
118 | ATH10K_MEM_REGION_TYPE_AXI = 3, |
119 | ATH10K_MEM_REGION_TYPE_IRAM1 = 4, |
120 | ATH10K_MEM_REGION_TYPE_IRAM2 = 5, |
121 | ATH10K_MEM_REGION_TYPE_IOSRAM = 6, |
122 | ATH10K_MEM_REGION_TYPE_IOREG = 7, |
123 | ATH10K_MEM_REGION_TYPE_MSA = 8, |
124 | }; |
125 | |
126 | /* Define a section of the region which should be copied. As not all parts |
127 | * of the memory is possible to copy, for example some of the registers can |
128 | * be like that, sections can be used to define what is safe to copy. |
129 | * |
130 | * To minimize the size of the array, the list must obey the format: |
131 | * '{start0,stop0},{start1,stop1},{start2,stop2}....' The values below must |
132 | * also obey to 'start0 < stop0 < start1 < stop1 < start2 < ...', otherwise |
133 | * we may encounter error in the dump processing. |
134 | */ |
135 | struct ath10k_mem_section { |
136 | u32 start; |
137 | u32 end; |
138 | }; |
139 | |
140 | /* One region of a memory layout. If the sections field is null entire |
141 | * region is copied. If sections is non-null only the areas specified in |
142 | * sections are copied and rest of the areas are filled with |
143 | * ATH10K_MAGIC_NOT_COPIED. |
144 | */ |
145 | struct ath10k_mem_region { |
146 | enum ath10k_mem_region_type type; |
147 | u32 start; |
148 | u32 len; |
149 | |
150 | const char *name; |
151 | |
152 | struct { |
153 | const struct ath10k_mem_section *sections; |
154 | u32 size; |
155 | } section_table; |
156 | }; |
157 | |
158 | /* Contains the memory layout of a hardware version identified with the |
159 | * hardware id, split into regions. |
160 | */ |
161 | struct ath10k_hw_mem_layout { |
162 | u32 hw_id; |
163 | u32 hw_rev; |
164 | enum ath10k_bus bus; |
165 | |
166 | struct { |
167 | const struct ath10k_mem_region *regions; |
168 | int size; |
169 | } region_table; |
170 | }; |
171 | |
172 | /* FIXME: where to put this? */ |
173 | extern unsigned long ath10k_coredump_mask; |
174 | |
175 | #ifdef CONFIG_DEV_COREDUMP |
176 | |
177 | int ath10k_coredump_submit(struct ath10k *ar); |
178 | struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar); |
179 | int ath10k_coredump_create(struct ath10k *ar); |
180 | int ath10k_coredump_register(struct ath10k *ar); |
181 | void ath10k_coredump_unregister(struct ath10k *ar); |
182 | void ath10k_coredump_destroy(struct ath10k *ar); |
183 | |
184 | const struct ath10k_hw_mem_layout *_ath10k_coredump_get_mem_layout(struct ath10k *ar); |
185 | const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar); |
186 | |
187 | #else /* CONFIG_DEV_COREDUMP */ |
188 | |
189 | static inline int ath10k_coredump_submit(struct ath10k *ar) |
190 | { |
191 | return 0; |
192 | } |
193 | |
194 | static inline struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar) |
195 | { |
196 | return NULL; |
197 | } |
198 | |
199 | static inline int ath10k_coredump_create(struct ath10k *ar) |
200 | { |
201 | return 0; |
202 | } |
203 | |
204 | static inline int ath10k_coredump_register(struct ath10k *ar) |
205 | { |
206 | return 0; |
207 | } |
208 | |
209 | static inline void ath10k_coredump_unregister(struct ath10k *ar) |
210 | { |
211 | } |
212 | |
213 | static inline void ath10k_coredump_destroy(struct ath10k *ar) |
214 | { |
215 | } |
216 | |
217 | static inline const struct ath10k_hw_mem_layout * |
218 | ath10k_coredump_get_mem_layout(struct ath10k *ar) |
219 | { |
220 | return NULL; |
221 | } |
222 | |
223 | static inline const struct ath10k_hw_mem_layout * |
224 | _ath10k_coredump_get_mem_layout(struct ath10k *ar) |
225 | { |
226 | return NULL; |
227 | } |
228 | |
229 | #endif /* CONFIG_DEV_COREDUMP */ |
230 | |
231 | #endif /* _COREDUMP_H_ */ |
232 | |