aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Liu <alanliu@qca.qualcomm.com>2017-12-22 08:39:32 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2017-12-27 05:20:41 -0500
commit703f261dd77f3afb8058a927ca2f4651691f0495 (patch)
treea9dfff4df47885fbb0a4ec423ea05a34d0b500ec
parent5c9d0a20202beb22a3583c5408157608f400c2d0 (diff)
ath10k: add memory dump support for QCA6174/QCA9377
Add memory dump to the firmware crash data file which is provided to user space via devcoredump interface. This makes it easier for firmware engineers to debug firmware crashes. Due to increased memory consumption the memory dump is disabled by default. To enable it make sure that bit 3 is set in coredump_mask module parameter: modprobe ath10k_core coredump_mask=0xffffffff When RAMDUMP is enabled a buffer for the dump is allocated with vmalloc during device probe. The actual memory layout is different in hardware versions and the layouts are defined in coredump.c. The memory is split to regions and, to get even finegrained control of what to copy, the region can split to smaller sections as not all registers are readable (which could cause the whole system to stall). Signed-off-by: Alan Liu <alanliu@qca.qualcomm.com> [kvalo@qca.qualcomm.com: refactoring and cleanup] Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c10
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h5
-rw-r--r--drivers/net/wireless/ath/ath10k/coredump.c786
-rw-r--r--drivers/net/wireless/ath/ath10k/coredump.h93
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c218
6 files changed, 1112 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 025f365e8177..ea432f10cb38 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -2563,10 +2563,16 @@ static void ath10k_core_register_work(struct work_struct *work)
2563 goto err_release_fw; 2563 goto err_release_fw;
2564 } 2564 }
2565 2565
2566 status = ath10k_coredump_register(ar);
2567 if (status) {
2568 ath10k_err(ar, "unable to register coredump\n");
2569 goto err_unregister_mac;
2570 }
2571
2566 status = ath10k_debug_register(ar); 2572 status = ath10k_debug_register(ar);
2567 if (status) { 2573 if (status) {
2568 ath10k_err(ar, "unable to initialize debugfs\n"); 2574 ath10k_err(ar, "unable to initialize debugfs\n");
2569 goto err_unregister_mac; 2575 goto err_unregister_coredump;
2570 } 2576 }
2571 2577
2572 status = ath10k_spectral_create(ar); 2578 status = ath10k_spectral_create(ar);
@@ -2589,6 +2595,8 @@ err_spectral_destroy:
2589 ath10k_spectral_destroy(ar); 2595 ath10k_spectral_destroy(ar);
2590err_debug_destroy: 2596err_debug_destroy:
2591 ath10k_debug_destroy(ar); 2597 ath10k_debug_destroy(ar);
2598err_unregister_coredump:
2599 ath10k_coredump_unregister(ar);
2592err_unregister_mac: 2600err_unregister_mac:
2593 ath10k_mac_unregister(ar); 2601 ath10k_mac_unregister(ar);
2594err_release_fw: 2602err_release_fw:
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 50bdaa67106d..163cbc746f62 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -460,12 +460,17 @@ struct ath10k_ce_crash_hdr {
460 struct ath10k_ce_crash_data entries[]; 460 struct ath10k_ce_crash_data entries[];
461}; 461};
462 462
463#define MAX_MEM_DUMP_TYPE 5
464
463/* used for crash-dump storage, protected by data-lock */ 465/* used for crash-dump storage, protected by data-lock */
464struct ath10k_fw_crash_data { 466struct ath10k_fw_crash_data {
465 guid_t guid; 467 guid_t guid;
466 struct timespec64 timestamp; 468 struct timespec64 timestamp;
467 __le32 registers[REG_DUMP_COUNT_QCA988X]; 469 __le32 registers[REG_DUMP_COUNT_QCA988X];
468 struct ath10k_ce_crash_data ce_crash_data[CE_COUNT_MAX]; 470 struct ath10k_ce_crash_data ce_crash_data[CE_COUNT_MAX];
471
472 u8 *ramdump_buf;
473 size_t ramdump_buf_len;
469}; 474};
470 475
471struct ath10k_debug { 476struct ath10k_debug {
diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c
index 5e32a11184d2..2f4cb6c473f5 100644
--- a/drivers/net/wireless/ath/ath10k/coredump.c
+++ b/drivers/net/wireless/ath/ath10k/coredump.c
@@ -17,9 +17,754 @@
17#include "coredump.h" 17#include "coredump.h"
18 18
19#include <linux/devcoredump.h> 19#include <linux/devcoredump.h>
20#include <linux/kernel.h>
21#include <linux/types.h>
20#include <linux/utsname.h> 22#include <linux/utsname.h>
21 23
22#include "debug.h" 24#include "debug.h"
25#include "hw.h"
26
27static const struct ath10k_mem_section qca6174_hw21_register_sections[] = {
28 {0x800, 0x810},
29 {0x820, 0x82C},
30 {0x830, 0x8F4},
31 {0x90C, 0x91C},
32 {0xA14, 0xA18},
33 {0xA84, 0xA94},
34 {0xAA8, 0xAD4},
35 {0xADC, 0xB40},
36 {0x1000, 0x10A4},
37 {0x10BC, 0x111C},
38 {0x1134, 0x1138},
39 {0x1144, 0x114C},
40 {0x1150, 0x115C},
41 {0x1160, 0x1178},
42 {0x1240, 0x1260},
43 {0x2000, 0x207C},
44 {0x3000, 0x3014},
45 {0x4000, 0x4014},
46 {0x5000, 0x5124},
47 {0x6000, 0x6040},
48 {0x6080, 0x60CC},
49 {0x6100, 0x611C},
50 {0x6140, 0x61D8},
51 {0x6200, 0x6238},
52 {0x6240, 0x628C},
53 {0x62C0, 0x62EC},
54 {0x6380, 0x63E8},
55 {0x6400, 0x6440},
56 {0x6480, 0x64CC},
57 {0x6500, 0x651C},
58 {0x6540, 0x6580},
59 {0x6600, 0x6638},
60 {0x6640, 0x668C},
61 {0x66C0, 0x66EC},
62 {0x6780, 0x67E8},
63 {0x7080, 0x708C},
64 {0x70C0, 0x70C8},
65 {0x7400, 0x741C},
66 {0x7440, 0x7454},
67 {0x7800, 0x7818},
68 {0x8000, 0x8004},
69 {0x8010, 0x8064},
70 {0x8080, 0x8084},
71 {0x80A0, 0x80A4},
72 {0x80C0, 0x80C4},
73 {0x80E0, 0x80F4},
74 {0x8100, 0x8104},
75 {0x8110, 0x812C},
76 {0x9000, 0x9004},
77 {0x9800, 0x982C},
78 {0x9830, 0x9838},
79 {0x9840, 0x986C},
80 {0x9870, 0x9898},
81 {0x9A00, 0x9C00},
82 {0xD580, 0xD59C},
83 {0xF000, 0xF0E0},
84 {0xF140, 0xF190},
85 {0xF250, 0xF25C},
86 {0xF260, 0xF268},
87 {0xF26C, 0xF2A8},
88 {0x10008, 0x1000C},
89 {0x10014, 0x10018},
90 {0x1001C, 0x10020},
91 {0x10024, 0x10028},
92 {0x10030, 0x10034},
93 {0x10040, 0x10054},
94 {0x10058, 0x1007C},
95 {0x10080, 0x100C4},
96 {0x100C8, 0x10114},
97 {0x1012C, 0x10130},
98 {0x10138, 0x10144},
99 {0x10200, 0x10220},
100 {0x10230, 0x10250},
101 {0x10260, 0x10280},
102 {0x10290, 0x102B0},
103 {0x102C0, 0x102DC},
104 {0x102E0, 0x102F4},
105 {0x102FC, 0x1037C},
106 {0x10380, 0x10390},
107 {0x10800, 0x10828},
108 {0x10840, 0x10844},
109 {0x10880, 0x10884},
110 {0x108C0, 0x108E8},
111 {0x10900, 0x10928},
112 {0x10940, 0x10944},
113 {0x10980, 0x10984},
114 {0x109C0, 0x109E8},
115 {0x10A00, 0x10A28},
116 {0x10A40, 0x10A50},
117 {0x11000, 0x11028},
118 {0x11030, 0x11034},
119 {0x11038, 0x11068},
120 {0x11070, 0x11074},
121 {0x11078, 0x110A8},
122 {0x110B0, 0x110B4},
123 {0x110B8, 0x110E8},
124 {0x110F0, 0x110F4},
125 {0x110F8, 0x11128},
126 {0x11138, 0x11144},
127 {0x11178, 0x11180},
128 {0x111B8, 0x111C0},
129 {0x111F8, 0x11200},
130 {0x11238, 0x1123C},
131 {0x11270, 0x11274},
132 {0x11278, 0x1127C},
133 {0x112B0, 0x112B4},
134 {0x112B8, 0x112BC},
135 {0x112F0, 0x112F4},
136 {0x112F8, 0x112FC},
137 {0x11338, 0x1133C},
138 {0x11378, 0x1137C},
139 {0x113B8, 0x113BC},
140 {0x113F8, 0x113FC},
141 {0x11438, 0x11440},
142 {0x11478, 0x11480},
143 {0x114B8, 0x114BC},
144 {0x114F8, 0x114FC},
145 {0x11538, 0x1153C},
146 {0x11578, 0x1157C},
147 {0x115B8, 0x115BC},
148 {0x115F8, 0x115FC},
149 {0x11638, 0x1163C},
150 {0x11678, 0x1167C},
151 {0x116B8, 0x116BC},
152 {0x116F8, 0x116FC},
153 {0x11738, 0x1173C},
154 {0x11778, 0x1177C},
155 {0x117B8, 0x117BC},
156 {0x117F8, 0x117FC},
157 {0x17000, 0x1701C},
158 {0x17020, 0x170AC},
159 {0x18000, 0x18050},
160 {0x18054, 0x18074},
161 {0x18080, 0x180D4},
162 {0x180DC, 0x18104},
163 {0x18108, 0x1813C},
164 {0x18144, 0x18148},
165 {0x18168, 0x18174},
166 {0x18178, 0x18180},
167 {0x181C8, 0x181E0},
168 {0x181E4, 0x181E8},
169 {0x181EC, 0x1820C},
170 {0x1825C, 0x18280},
171 {0x18284, 0x18290},
172 {0x18294, 0x182A0},
173 {0x18300, 0x18304},
174 {0x18314, 0x18320},
175 {0x18328, 0x18350},
176 {0x1835C, 0x1836C},
177 {0x18370, 0x18390},
178 {0x18398, 0x183AC},
179 {0x183BC, 0x183D8},
180 {0x183DC, 0x183F4},
181 {0x18400, 0x186F4},
182 {0x186F8, 0x1871C},
183 {0x18720, 0x18790},
184 {0x19800, 0x19830},
185 {0x19834, 0x19840},
186 {0x19880, 0x1989C},
187 {0x198A4, 0x198B0},
188 {0x198BC, 0x19900},
189 {0x19C00, 0x19C88},
190 {0x19D00, 0x19D20},
191 {0x19E00, 0x19E7C},
192 {0x19E80, 0x19E94},
193 {0x19E98, 0x19EAC},
194 {0x19EB0, 0x19EBC},
195 {0x19F70, 0x19F74},
196 {0x19F80, 0x19F8C},
197 {0x19FA0, 0x19FB4},
198 {0x19FC0, 0x19FD8},
199 {0x1A000, 0x1A200},
200 {0x1A204, 0x1A210},
201 {0x1A228, 0x1A22C},
202 {0x1A230, 0x1A248},
203 {0x1A250, 0x1A270},
204 {0x1A280, 0x1A290},
205 {0x1A2A0, 0x1A2A4},
206 {0x1A2C0, 0x1A2EC},
207 {0x1A300, 0x1A3BC},
208 {0x1A3F0, 0x1A3F4},
209 {0x1A3F8, 0x1A434},
210 {0x1A438, 0x1A444},
211 {0x1A448, 0x1A468},
212 {0x1A580, 0x1A58C},
213 {0x1A644, 0x1A654},
214 {0x1A670, 0x1A698},
215 {0x1A6AC, 0x1A6B0},
216 {0x1A6D0, 0x1A6D4},
217 {0x1A6EC, 0x1A70C},
218 {0x1A710, 0x1A738},
219 {0x1A7C0, 0x1A7D0},
220 {0x1A7D4, 0x1A7D8},
221 {0x1A7DC, 0x1A7E4},
222 {0x1A7F0, 0x1A7F8},
223 {0x1A888, 0x1A89C},
224 {0x1A8A8, 0x1A8AC},
225 {0x1A8C0, 0x1A8DC},
226 {0x1A8F0, 0x1A8FC},
227 {0x1AE04, 0x1AE08},
228 {0x1AE18, 0x1AE24},
229 {0x1AF80, 0x1AF8C},
230 {0x1AFA0, 0x1AFB4},
231 {0x1B000, 0x1B200},
232 {0x1B284, 0x1B288},
233 {0x1B2D0, 0x1B2D8},
234 {0x1B2DC, 0x1B2EC},
235 {0x1B300, 0x1B340},
236 {0x1B374, 0x1B378},
237 {0x1B380, 0x1B384},
238 {0x1B388, 0x1B38C},
239 {0x1B404, 0x1B408},
240 {0x1B420, 0x1B428},
241 {0x1B440, 0x1B444},
242 {0x1B448, 0x1B44C},
243 {0x1B450, 0x1B458},
244 {0x1B45C, 0x1B468},
245 {0x1B584, 0x1B58C},
246 {0x1B68C, 0x1B690},
247 {0x1B6AC, 0x1B6B0},
248 {0x1B7F0, 0x1B7F8},
249 {0x1C800, 0x1CC00},
250 {0x1CE00, 0x1CE04},
251 {0x1CF80, 0x1CF84},
252 {0x1D200, 0x1D800},
253 {0x1E000, 0x20014},
254 {0x20100, 0x20124},
255 {0x21400, 0x217A8},
256 {0x21800, 0x21BA8},
257 {0x21C00, 0x21FA8},
258 {0x22000, 0x223A8},
259 {0x22400, 0x227A8},
260 {0x22800, 0x22BA8},
261 {0x22C00, 0x22FA8},
262 {0x23000, 0x233A8},
263 {0x24000, 0x24034},
264 {0x26000, 0x26064},
265 {0x27000, 0x27024},
266 {0x34000, 0x3400C},
267 {0x34400, 0x3445C},
268 {0x34800, 0x3485C},
269 {0x34C00, 0x34C5C},
270 {0x35000, 0x3505C},
271 {0x35400, 0x3545C},
272 {0x35800, 0x3585C},
273 {0x35C00, 0x35C5C},
274 {0x36000, 0x3605C},
275 {0x38000, 0x38064},
276 {0x38070, 0x380E0},
277 {0x3A000, 0x3A064},
278 {0x40000, 0x400A4},
279 {0x80000, 0x8000C},
280 {0x80010, 0x80020},
281};
282
283static const struct ath10k_mem_section qca6174_hw30_register_sections[] = {
284 {0x800, 0x810},
285 {0x820, 0x82C},
286 {0x830, 0x8F4},
287 {0x90C, 0x91C},
288 {0xA14, 0xA18},
289 {0xA84, 0xA94},
290 {0xAA8, 0xAD4},
291 {0xADC, 0xB40},
292 {0x1000, 0x10A4},
293 {0x10BC, 0x111C},
294 {0x1134, 0x1138},
295 {0x1144, 0x114C},
296 {0x1150, 0x115C},
297 {0x1160, 0x1178},
298 {0x1240, 0x1260},
299 {0x2000, 0x207C},
300 {0x3000, 0x3014},
301 {0x4000, 0x4014},
302 {0x5000, 0x5124},
303 {0x6000, 0x6040},
304 {0x6080, 0x60CC},
305 {0x6100, 0x611C},
306 {0x6140, 0x61D8},
307 {0x6200, 0x6238},
308 {0x6240, 0x628C},
309 {0x62C0, 0x62EC},
310 {0x6380, 0x63E8},
311 {0x6400, 0x6440},
312 {0x6480, 0x64CC},
313 {0x6500, 0x651C},
314 {0x6540, 0x6580},
315 {0x6600, 0x6638},
316 {0x6640, 0x668C},
317 {0x66C0, 0x66EC},
318 {0x6780, 0x67E8},
319 {0x7080, 0x708C},
320 {0x70C0, 0x70C8},
321 {0x7400, 0x741C},
322 {0x7440, 0x7454},
323 {0x7800, 0x7818},
324 {0x8000, 0x8004},
325 {0x8010, 0x8064},
326 {0x8080, 0x8084},
327 {0x80A0, 0x80A4},
328 {0x80C0, 0x80C4},
329 {0x80E0, 0x80F4},
330 {0x8100, 0x8104},
331 {0x8110, 0x812C},
332 {0x9000, 0x9004},
333 {0x9800, 0x982C},
334 {0x9830, 0x9838},
335 {0x9840, 0x986C},
336 {0x9870, 0x9898},
337 {0x9A00, 0x9C00},
338 {0xD580, 0xD59C},
339 {0xF000, 0xF0E0},
340 {0xF140, 0xF190},
341 {0xF250, 0xF25C},
342 {0xF260, 0xF268},
343 {0xF26C, 0xF2A8},
344 {0x10008, 0x1000C},
345 {0x10014, 0x10018},
346 {0x1001C, 0x10020},
347 {0x10024, 0x10028},
348 {0x10030, 0x10034},
349 {0x10040, 0x10054},
350 {0x10058, 0x1007C},
351 {0x10080, 0x100C4},
352 {0x100C8, 0x10114},
353 {0x1012C, 0x10130},
354 {0x10138, 0x10144},
355 {0x10200, 0x10220},
356 {0x10230, 0x10250},
357 {0x10260, 0x10280},
358 {0x10290, 0x102B0},
359 {0x102C0, 0x102DC},
360 {0x102E0, 0x102F4},
361 {0x102FC, 0x1037C},
362 {0x10380, 0x10390},
363 {0x10800, 0x10828},
364 {0x10840, 0x10844},
365 {0x10880, 0x10884},
366 {0x108C0, 0x108E8},
367 {0x10900, 0x10928},
368 {0x10940, 0x10944},
369 {0x10980, 0x10984},
370 {0x109C0, 0x109E8},
371 {0x10A00, 0x10A28},
372 {0x10A40, 0x10A50},
373 {0x11000, 0x11028},
374 {0x11030, 0x11034},
375 {0x11038, 0x11068},
376 {0x11070, 0x11074},
377 {0x11078, 0x110A8},
378 {0x110B0, 0x110B4},
379 {0x110B8, 0x110E8},
380 {0x110F0, 0x110F4},
381 {0x110F8, 0x11128},
382 {0x11138, 0x11144},
383 {0x11178, 0x11180},
384 {0x111B8, 0x111C0},
385 {0x111F8, 0x11200},
386 {0x11238, 0x1123C},
387 {0x11270, 0x11274},
388 {0x11278, 0x1127C},
389 {0x112B0, 0x112B4},
390 {0x112B8, 0x112BC},
391 {0x112F0, 0x112F4},
392 {0x112F8, 0x112FC},
393 {0x11338, 0x1133C},
394 {0x11378, 0x1137C},
395 {0x113B8, 0x113BC},
396 {0x113F8, 0x113FC},
397 {0x11438, 0x11440},
398 {0x11478, 0x11480},
399 {0x114B8, 0x114BC},
400 {0x114F8, 0x114FC},
401 {0x11538, 0x1153C},
402 {0x11578, 0x1157C},
403 {0x115B8, 0x115BC},
404 {0x115F8, 0x115FC},
405 {0x11638, 0x1163C},
406 {0x11678, 0x1167C},
407 {0x116B8, 0x116BC},
408 {0x116F8, 0x116FC},
409 {0x11738, 0x1173C},
410 {0x11778, 0x1177C},
411 {0x117B8, 0x117BC},
412 {0x117F8, 0x117FC},
413 {0x17000, 0x1701C},
414 {0x17020, 0x170AC},
415 {0x18000, 0x18050},
416 {0x18054, 0x18074},
417 {0x18080, 0x180D4},
418 {0x180DC, 0x18104},
419 {0x18108, 0x1813C},
420 {0x18144, 0x18148},
421 {0x18168, 0x18174},
422 {0x18178, 0x18180},
423 {0x181C8, 0x181E0},
424 {0x181E4, 0x181E8},
425 {0x181EC, 0x1820C},
426 {0x1825C, 0x18280},
427 {0x18284, 0x18290},
428 {0x18294, 0x182A0},
429 {0x18300, 0x18304},
430 {0x18314, 0x18320},
431 {0x18328, 0x18350},
432 {0x1835C, 0x1836C},
433 {0x18370, 0x18390},
434 {0x18398, 0x183AC},
435 {0x183BC, 0x183D8},
436 {0x183DC, 0x183F4},
437 {0x18400, 0x186F4},
438 {0x186F8, 0x1871C},
439 {0x18720, 0x18790},
440 {0x19800, 0x19830},
441 {0x19834, 0x19840},
442 {0x19880, 0x1989C},
443 {0x198A4, 0x198B0},
444 {0x198BC, 0x19900},
445 {0x19C00, 0x19C88},
446 {0x19D00, 0x19D20},
447 {0x19E00, 0x19E7C},
448 {0x19E80, 0x19E94},
449 {0x19E98, 0x19EAC},
450 {0x19EB0, 0x19EBC},
451 {0x19F70, 0x19F74},
452 {0x19F80, 0x19F8C},
453 {0x19FA0, 0x19FB4},
454 {0x19FC0, 0x19FD8},
455 {0x1A000, 0x1A200},
456 {0x1A204, 0x1A210},
457 {0x1A228, 0x1A22C},
458 {0x1A230, 0x1A248},
459 {0x1A250, 0x1A270},
460 {0x1A280, 0x1A290},
461 {0x1A2A0, 0x1A2A4},
462 {0x1A2C0, 0x1A2EC},
463 {0x1A300, 0x1A3BC},
464 {0x1A3F0, 0x1A3F4},
465 {0x1A3F8, 0x1A434},
466 {0x1A438, 0x1A444},
467 {0x1A448, 0x1A468},
468 {0x1A580, 0x1A58C},
469 {0x1A644, 0x1A654},
470 {0x1A670, 0x1A698},
471 {0x1A6AC, 0x1A6B0},
472 {0x1A6D0, 0x1A6D4},
473 {0x1A6EC, 0x1A70C},
474 {0x1A710, 0x1A738},
475 {0x1A7C0, 0x1A7D0},
476 {0x1A7D4, 0x1A7D8},
477 {0x1A7DC, 0x1A7E4},
478 {0x1A7F0, 0x1A7F8},
479 {0x1A888, 0x1A89C},
480 {0x1A8A8, 0x1A8AC},
481 {0x1A8C0, 0x1A8DC},
482 {0x1A8F0, 0x1A8FC},
483 {0x1AE04, 0x1AE08},
484 {0x1AE18, 0x1AE24},
485 {0x1AF80, 0x1AF8C},
486 {0x1AFA0, 0x1AFB4},
487 {0x1B000, 0x1B200},
488 {0x1B284, 0x1B288},
489 {0x1B2D0, 0x1B2D8},
490 {0x1B2DC, 0x1B2EC},
491 {0x1B300, 0x1B340},
492 {0x1B374, 0x1B378},
493 {0x1B380, 0x1B384},
494 {0x1B388, 0x1B38C},
495 {0x1B404, 0x1B408},
496 {0x1B420, 0x1B428},
497 {0x1B440, 0x1B444},
498 {0x1B448, 0x1B44C},
499 {0x1B450, 0x1B458},
500 {0x1B45C, 0x1B468},
501 {0x1B584, 0x1B58C},
502 {0x1B68C, 0x1B690},
503 {0x1B6AC, 0x1B6B0},
504 {0x1B7F0, 0x1B7F8},
505 {0x1C800, 0x1CC00},
506 {0x1CE00, 0x1CE04},
507 {0x1CF80, 0x1CF84},
508 {0x1D200, 0x1D800},
509 {0x1E000, 0x20014},
510 {0x20100, 0x20124},
511 {0x21400, 0x217A8},
512 {0x21800, 0x21BA8},
513 {0x21C00, 0x21FA8},
514 {0x22000, 0x223A8},
515 {0x22400, 0x227A8},
516 {0x22800, 0x22BA8},
517 {0x22C00, 0x22FA8},
518 {0x23000, 0x233A8},
519 {0x24000, 0x24034},
520 {0x26000, 0x26064},
521 {0x27000, 0x27024},
522 {0x34000, 0x3400C},
523 {0x34400, 0x3445C},
524 {0x34800, 0x3485C},
525 {0x34C00, 0x34C5C},
526 {0x35000, 0x3505C},
527 {0x35400, 0x3545C},
528 {0x35800, 0x3585C},
529 {0x35C00, 0x35C5C},
530 {0x36000, 0x3605C},
531 {0x38000, 0x38064},
532 {0x38070, 0x380E0},
533 {0x3A000, 0x3A074},
534 {0x40000, 0x400A4},
535 {0x80000, 0x8000C},
536 {0x80010, 0x80020},
537};
538
539static const struct ath10k_mem_region qca6174_hw10_mem_regions[] = {
540 {
541 .type = ATH10K_MEM_REGION_TYPE_DRAM,
542 .start = 0x400000,
543 .len = 0x70000,
544 .name = "DRAM",
545 .section_table = {
546 .sections = NULL,
547 .size = 0,
548 },
549 },
550 {
551 .type = ATH10K_MEM_REGION_TYPE_REG,
552
553 /* RTC_SOC_BASE_ADDRESS */
554 .start = 0x0,
555
556 /* WLAN_MBOX_BASE_ADDRESS - RTC_SOC_BASE_ADDRESS */
557 .len = 0x800 - 0x0,
558
559 .name = "REG_PART1",
560 .section_table = {
561 .sections = NULL,
562 .size = 0,
563 },
564 },
565 {
566 .type = ATH10K_MEM_REGION_TYPE_REG,
567
568 /* STEREO_BASE_ADDRESS */
569 .start = 0x27000,
570
571 /* USB_BASE_ADDRESS - STEREO_BASE_ADDRESS */
572 .len = 0x60000 - 0x27000,
573
574 .name = "REG_PART2",
575 .section_table = {
576 .sections = NULL,
577 .size = 0,
578 },
579 },
580};
581
582static const struct ath10k_mem_region qca6174_hw21_mem_regions[] = {
583 {
584 .type = ATH10K_MEM_REGION_TYPE_DRAM,
585 .start = 0x400000,
586 .len = 0x70000,
587 .name = "DRAM",
588 .section_table = {
589 .sections = NULL,
590 .size = 0,
591 },
592 },
593 {
594 .type = ATH10K_MEM_REGION_TYPE_AXI,
595 .start = 0xa0000,
596 .len = 0x18000,
597 .name = "AXI",
598 .section_table = {
599 .sections = NULL,
600 .size = 0,
601 },
602 },
603 {
604 .type = ATH10K_MEM_REGION_TYPE_REG,
605 .start = 0x800,
606 .len = 0x80020 - 0x800,
607 .name = "REG_TOTAL",
608 .section_table = {
609 .sections = qca6174_hw21_register_sections,
610 .size = ARRAY_SIZE(qca6174_hw21_register_sections),
611 },
612 },
613};
614
615static const struct ath10k_mem_region qca6174_hw30_mem_regions[] = {
616 {
617 .type = ATH10K_MEM_REGION_TYPE_DRAM,
618 .start = 0x400000,
619 .len = 0x90000,
620 .name = "DRAM",
621 .section_table = {
622 .sections = NULL,
623 .size = 0,
624 },
625 },
626 {
627 .type = ATH10K_MEM_REGION_TYPE_AXI,
628 .start = 0xa0000,
629 .len = 0x18000,
630 .name = "AXI",
631 .section_table = {
632 .sections = NULL,
633 .size = 0,
634 },
635 },
636 {
637 .type = ATH10K_MEM_REGION_TYPE_REG,
638 .start = 0x800,
639 .len = 0x80020 - 0x800,
640 .name = "REG_TOTAL",
641 .section_table = {
642 .sections = qca6174_hw30_register_sections,
643 .size = ARRAY_SIZE(qca6174_hw30_register_sections),
644 },
645 },
646
647 /* IRAM dump must be put last */
648 {
649 .type = ATH10K_MEM_REGION_TYPE_IRAM1,
650 .start = 0x00980000,
651 .len = 0x00080000,
652 .name = "IRAM1",
653 .section_table = {
654 .sections = NULL,
655 .size = 0,
656 },
657 },
658 {
659 .type = ATH10K_MEM_REGION_TYPE_IRAM2,
660 .start = 0x00a00000,
661 .len = 0x00040000,
662 .name = "IRAM2",
663 .section_table = {
664 .sections = NULL,
665 .size = 0,
666 },
667 },
668};
669
670static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
671 {
672 .hw_id = QCA6174_HW_1_0_VERSION,
673 .region_table = {
674 .regions = qca6174_hw10_mem_regions,
675 .size = ARRAY_SIZE(qca6174_hw10_mem_regions),
676 },
677 },
678 {
679 .hw_id = QCA6174_HW_1_1_VERSION,
680 .region_table = {
681 .regions = qca6174_hw10_mem_regions,
682 .size = ARRAY_SIZE(qca6174_hw10_mem_regions),
683 },
684 },
685 {
686 .hw_id = QCA6174_HW_1_3_VERSION,
687 .region_table = {
688 .regions = qca6174_hw10_mem_regions,
689 .size = ARRAY_SIZE(qca6174_hw10_mem_regions),
690 },
691 },
692 {
693 .hw_id = QCA6174_HW_2_1_VERSION,
694 .region_table = {
695 .regions = qca6174_hw21_mem_regions,
696 .size = ARRAY_SIZE(qca6174_hw21_mem_regions),
697 },
698 },
699 {
700 .hw_id = QCA6174_HW_3_0_VERSION,
701 .region_table = {
702 .regions = qca6174_hw30_mem_regions,
703 .size = ARRAY_SIZE(qca6174_hw30_mem_regions),
704 },
705 },
706 {
707 .hw_id = QCA6174_HW_3_2_VERSION,
708 .region_table = {
709 .regions = qca6174_hw30_mem_regions,
710 .size = ARRAY_SIZE(qca6174_hw30_mem_regions),
711 },
712 },
713 {
714 .hw_id = QCA9377_HW_1_1_DEV_VERSION,
715 .region_table = {
716 .regions = qca6174_hw30_mem_regions,
717 .size = ARRAY_SIZE(qca6174_hw30_mem_regions),
718 },
719 },
720};
721
722static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar)
723{
724 const struct ath10k_hw_mem_layout *hw;
725 const struct ath10k_mem_region *mem_region;
726 size_t size = 0;
727 int i;
728
729 hw = ath10k_coredump_get_mem_layout(ar);
730
731 if (!hw)
732 return 0;
733
734 mem_region = &hw->region_table.regions[0];
735
736 for (i = 0; i < hw->region_table.size; i++) {
737 size += mem_region->len;
738 mem_region++;
739 }
740
741 /* reserve space for the headers */
742 size += hw->region_table.size * sizeof(struct ath10k_dump_ram_data_hdr);
743
744 /* make sure it is aligned 16 bytes for debug message print out */
745 size = ALIGN(size, 16);
746
747 return size;
748}
749
750const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar)
751{
752 int i;
753
754 if (!test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask))
755 return NULL;
756
757 if (WARN_ON(ar->target_version == 0))
758 return NULL;
759
760 for (i = 0; i < ARRAY_SIZE(hw_mem_layouts); i++) {
761 if (ar->target_version == hw_mem_layouts[i].hw_id)
762 return &hw_mem_layouts[i];
763 }
764
765 return NULL;
766}
767EXPORT_SYMBOL(ath10k_coredump_get_mem_layout);
23 768
24struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar) 769struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar)
25{ 770{
@@ -57,6 +802,9 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar)
57 len += sizeof(*dump_tlv) + sizeof(*ce_hdr) + 802 len += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
58 CE_COUNT * sizeof(ce_hdr->entries[0]); 803 CE_COUNT * sizeof(ce_hdr->entries[0]);
59 804
805 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask))
806 len += sizeof(*dump_tlv) + crash_data->ramdump_buf_len;
807
60 sofar += hdr_len; 808 sofar += hdr_len;
61 809
62 /* This is going to get big when we start dumping FW RAM and such, 810 /* This is going to get big when we start dumping FW RAM and such,
@@ -123,6 +871,16 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar)
123 CE_COUNT * sizeof(ce_hdr->entries[0]); 871 CE_COUNT * sizeof(ce_hdr->entries[0]);
124 } 872 }
125 873
874 /* Gather ram dump */
875 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask)) {
876 dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
877 dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_RAM_DATA);
878 dump_tlv->tlv_len = cpu_to_le32(crash_data->ramdump_buf_len);
879 memcpy(dump_tlv->tlv_data, crash_data->ramdump_buf,
880 crash_data->ramdump_buf_len);
881 sofar += sizeof(*dump_tlv) + crash_data->ramdump_buf_len;
882 }
883
126 spin_unlock_bh(&ar->data_lock); 884 spin_unlock_bh(&ar->data_lock);
127 885
128 return dump_data; 886 return dump_data;
@@ -160,8 +918,36 @@ int ath10k_coredump_create(struct ath10k *ar)
160 return 0; 918 return 0;
161} 919}
162 920
921int ath10k_coredump_register(struct ath10k *ar)
922{
923 struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data;
924
925 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask)) {
926 crash_data->ramdump_buf_len = ath10k_coredump_get_ramdump_size(ar);
927
928 crash_data->ramdump_buf = vzalloc(crash_data->ramdump_buf_len);
929 if (!crash_data->ramdump_buf)
930 return -ENOMEM;
931 }
932
933 return 0;
934}
935
936void ath10k_coredump_unregister(struct ath10k *ar)
937{
938 struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data;
939
940 vfree(crash_data->ramdump_buf);
941}
942
163void ath10k_coredump_destroy(struct ath10k *ar) 943void ath10k_coredump_destroy(struct ath10k *ar)
164{ 944{
945 if (ar->coredump.fw_crash_data->ramdump_buf) {
946 vfree(ar->coredump.fw_crash_data->ramdump_buf);
947 ar->coredump.fw_crash_data->ramdump_buf = NULL;
948 ar->coredump.fw_crash_data->ramdump_buf_len = 0;
949 }
950
165 vfree(ar->coredump.fw_crash_data); 951 vfree(ar->coredump.fw_crash_data);
166 ar->coredump.fw_crash_data = NULL; 952 ar->coredump.fw_crash_data = NULL;
167} 953}
diff --git a/drivers/net/wireless/ath/ath10k/coredump.h b/drivers/net/wireless/ath/ath10k/coredump.h
index 2d33075f081a..bfee13038e59 100644
--- a/drivers/net/wireless/ath/ath10k/coredump.h
+++ b/drivers/net/wireless/ath/ath10k/coredump.h
@@ -29,6 +29,9 @@ enum ath10k_fw_crash_dump_type {
29 ATH10K_FW_CRASH_DUMP_REGISTERS = 0, 29 ATH10K_FW_CRASH_DUMP_REGISTERS = 0,
30 ATH10K_FW_CRASH_DUMP_CE_DATA = 1, 30 ATH10K_FW_CRASH_DUMP_CE_DATA = 1,
31 31
32 /* contains multiple struct ath10k_dump_ram_data_hdr */
33 ATH10K_FW_CRASH_DUMP_RAM_DATA = 2,
34
32 ATH10K_FW_CRASH_DUMP_MAX, 35 ATH10K_FW_CRASH_DUMP_MAX,
33}; 36};
34 37
@@ -99,13 +102,88 @@ struct ath10k_dump_file_data {
99 u8 data[0]; 102 u8 data[0];
100} __packed; 103} __packed;
101 104
105struct ath10k_dump_ram_data_hdr {
106 /* enum ath10k_mem_region_type */
107 __le32 region_type;
108
109 __le32 start;
110
111 /* length of payload data, not including this header */
112 __le32 length;
113
114 u8 data[0];
115};
116
117/* magic number to fill the holes not copied due to sections in regions */
118#define ATH10K_MAGIC_NOT_COPIED 0xAA
119
120/* part of user space ABI */
121enum ath10k_mem_region_type {
122 ATH10K_MEM_REGION_TYPE_REG = 1,
123 ATH10K_MEM_REGION_TYPE_DRAM = 2,
124 ATH10K_MEM_REGION_TYPE_AXI = 3,
125 ATH10K_MEM_REGION_TYPE_IRAM1 = 4,
126 ATH10K_MEM_REGION_TYPE_IRAM2 = 5,
127};
128
129/* Define a section of the region which should be copied. As not all parts
130 * of the memory is possible to copy, for example some of the registers can
131 * be like that, sections can be used to define what is safe to copy.
132 *
133 * To minimize the size of the array, the list must obey the format:
134 * '{start0,stop0},{start1,stop1},{start2,stop2}....' The values below must
135 * also obey to 'start0 < stop0 < start1 < stop1 < start2 < ...', otherwise
136 * we may encouter error in the dump processing.
137 */
138struct ath10k_mem_section {
139 u32 start;
140 u32 end;
141};
142
143/* One region of a memory layout. If the sections field is null entire
144 * region is copied. If sections is non-null only the areas specified in
145 * sections are copied and rest of the areas are filled with
146 * ATH10K_MAGIC_NOT_COPIED.
147 */
148struct ath10k_mem_region {
149 enum ath10k_mem_region_type type;
150 u32 start;
151 u32 len;
152
153 const char *name;
154
155 struct {
156 const struct ath10k_mem_section *sections;
157 u32 size;
158 } section_table;
159};
160
161/* Contains the memory layout of a hardware version identified with the
162 * hardware id, split into regions.
163 */
164struct ath10k_hw_mem_layout {
165 u32 hw_id;
166
167 struct {
168 const struct ath10k_mem_region *regions;
169 int size;
170 } region_table;
171};
172
173/* FIXME: where to put this? */
174extern unsigned long ath10k_coredump_mask;
175
102#ifdef CONFIG_DEV_COREDUMP 176#ifdef CONFIG_DEV_COREDUMP
103 177
104int ath10k_coredump_submit(struct ath10k *ar); 178int ath10k_coredump_submit(struct ath10k *ar);
105struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar); 179struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar);
106int ath10k_coredump_create(struct ath10k *ar); 180int ath10k_coredump_create(struct ath10k *ar);
181int ath10k_coredump_register(struct ath10k *ar);
182void ath10k_coredump_unregister(struct ath10k *ar);
107void ath10k_coredump_destroy(struct ath10k *ar); 183void ath10k_coredump_destroy(struct ath10k *ar);
108 184
185const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar);
186
109#else /* CONFIG_DEV_COREDUMP */ 187#else /* CONFIG_DEV_COREDUMP */
110 188
111static inline int ath10k_coredump_submit(struct ath10k *ar) 189static inline int ath10k_coredump_submit(struct ath10k *ar)
@@ -123,10 +201,25 @@ static inline int ath10k_coredump_create(struct ath10k *ar)
123 return 0; 201 return 0;
124} 202}
125 203
204static inline int ath10k_coredump_register(struct ath10k *ar)
205{
206 return 0;
207}
208
209static inline void ath10k_coredump_unregister(struct ath10k *ar)
210{
211}
212
126static inline void ath10k_coredump_destroy(struct ath10k *ar) 213static inline void ath10k_coredump_destroy(struct ath10k *ar)
127{ 214{
128} 215}
129 216
217static inline const struct ath10k_hw_mem_layout *
218ath10k_coredump_get_mem_layout(struct ath10k *ar)
219{
220 return NULL;
221}
222
130#endif /* CONFIG_DEV_COREDUMP */ 223#endif /* CONFIG_DEV_COREDUMP */
131 224
132#endif /* _COREDUMP_H_ */ 225#endif /* _COREDUMP_H_ */
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 84aedaa95f84..2bd70a551557 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -888,6 +888,7 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
888#define PCIE_INTR_CLR_ADDRESS ar->regs->pcie_intr_clr_address 888#define PCIE_INTR_CLR_ADDRESS ar->regs->pcie_intr_clr_address
889#define SCRATCH_3_ADDRESS ar->regs->scratch_3_address 889#define SCRATCH_3_ADDRESS ar->regs->scratch_3_address
890#define CPU_INTR_ADDRESS 0x0010 890#define CPU_INTR_ADDRESS 0x0010
891#define FW_RAM_CONFIG_ADDRESS 0x0018
891 892
892#define CCNT_TO_MSEC(ar, x) ((x) / ar->hw_params.channel_counters_freq_hz) 893#define CCNT_TO_MSEC(ar, x) ((x) / ar->hw_params.channel_counters_freq_hz)
893 894
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 61406bba2b5e..962310023126 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -52,6 +52,11 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)");
52#define ATH10K_PCI_TARGET_WAIT 3000 52#define ATH10K_PCI_TARGET_WAIT 3000
53#define ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS 3 53#define ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS 3
54 54
55/* Maximum number of bytes that can be handled atomically by
56 * diag read and write.
57 */
58#define ATH10K_DIAG_TRANSFER_LIMIT 0x5000
59
55static const struct pci_device_id ath10k_pci_id_table[] = { 60static const struct pci_device_id ath10k_pci_id_table[] = {
56 { PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */ 61 { PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */
57 { PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */ 62 { PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */
@@ -1462,6 +1467,218 @@ static void ath10k_pci_dump_registers(struct ath10k *ar,
1462 crash_data->registers[i] = reg_dump_values[i]; 1467 crash_data->registers[i] = reg_dump_values[i];
1463} 1468}
1464 1469
1470static int ath10k_pci_dump_memory_section(struct ath10k *ar,
1471 const struct ath10k_mem_region *mem_region,
1472 u8 *buf, size_t buf_len)
1473{
1474 const struct ath10k_mem_section *cur_section, *next_section;
1475 unsigned int count, section_size, skip_size;
1476 int ret, i, j;
1477
1478 if (!mem_region || !buf)
1479 return 0;
1480
1481 if (mem_region->section_table.size < 0)
1482 return 0;
1483
1484 cur_section = &mem_region->section_table.sections[0];
1485
1486 if (mem_region->start > cur_section->start) {
1487 ath10k_warn(ar, "incorrect memdump region 0x%x with section start addrress 0x%x.\n",
1488 mem_region->start, cur_section->start);
1489 return 0;
1490 }
1491
1492 skip_size = cur_section->start - mem_region->start;
1493
1494 /* fill the gap between the first register section and register
1495 * start address
1496 */
1497 for (i = 0; i < skip_size; i++) {
1498 *buf = ATH10K_MAGIC_NOT_COPIED;
1499 buf++;
1500 }
1501
1502 count = 0;
1503
1504 for (i = 0; cur_section != NULL; i++) {
1505 section_size = cur_section->end - cur_section->start;
1506
1507 if (section_size <= 0) {
1508 ath10k_warn(ar, "incorrect ramdump format with start address 0x%x and stop address 0x%x\n",
1509 cur_section->start,
1510 cur_section->end);
1511 break;
1512 }
1513
1514 if ((i + 1) == mem_region->section_table.size) {
1515 /* last section */
1516 next_section = NULL;
1517 skip_size = 0;
1518 } else {
1519 next_section = cur_section + 1;
1520
1521 if (cur_section->end > next_section->start) {
1522 ath10k_warn(ar, "next ramdump section 0x%x is smaller than current end address 0x%x\n",
1523 next_section->start,
1524 cur_section->end);
1525 break;
1526 }
1527
1528 skip_size = next_section->start - cur_section->end;
1529 }
1530
1531 if (buf_len < (skip_size + section_size)) {
1532 ath10k_warn(ar, "ramdump buffer is too small: %zu\n", buf_len);
1533 break;
1534 }
1535
1536 buf_len -= skip_size + section_size;
1537
1538 /* read section to dest memory */
1539 ret = ath10k_pci_diag_read_mem(ar, cur_section->start,
1540 buf, section_size);
1541 if (ret) {
1542 ath10k_warn(ar, "failed to read ramdump from section 0x%x: %d\n",
1543 cur_section->start, ret);
1544 break;
1545 }
1546
1547 buf += section_size;
1548 count += section_size;
1549
1550 /* fill in the gap between this section and the next */
1551 for (j = 0; j < skip_size; j++) {
1552 *buf = ATH10K_MAGIC_NOT_COPIED;
1553 buf++;
1554 }
1555
1556 count += skip_size;
1557
1558 if (!next_section)
1559 /* this was the last section */
1560 break;
1561
1562 cur_section = next_section;
1563 }
1564
1565 return count;
1566}
1567
1568static int ath10k_pci_set_ram_config(struct ath10k *ar, u32 config)
1569{
1570 u32 val;
1571
1572 ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS +
1573 FW_RAM_CONFIG_ADDRESS, config);
1574
1575 val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
1576 FW_RAM_CONFIG_ADDRESS);
1577 if (val != config) {
1578 ath10k_warn(ar, "failed to set RAM config from 0x%x to 0x%x\n",
1579 val, config);
1580 return -EIO;
1581 }
1582
1583 return 0;
1584}
1585
1586static void ath10k_pci_dump_memory(struct ath10k *ar,
1587 struct ath10k_fw_crash_data *crash_data)
1588{
1589 const struct ath10k_hw_mem_layout *mem_layout;
1590 const struct ath10k_mem_region *current_region;
1591 struct ath10k_dump_ram_data_hdr *hdr;
1592 u32 count, shift;
1593 size_t buf_len;
1594 int ret, i;
1595 u8 *buf;
1596
1597 lockdep_assert_held(&ar->data_lock);
1598
1599 if (!crash_data)
1600 return;
1601
1602 mem_layout = ath10k_coredump_get_mem_layout(ar);
1603 if (!mem_layout)
1604 return;
1605
1606 current_region = &mem_layout->region_table.regions[0];
1607
1608 buf = crash_data->ramdump_buf;
1609 buf_len = crash_data->ramdump_buf_len;
1610
1611 memset(buf, 0, buf_len);
1612
1613 for (i = 0; i < mem_layout->region_table.size; i++) {
1614 count = 0;
1615
1616 if (current_region->len > buf_len) {
1617 ath10k_warn(ar, "memory region %s size %d is larger that remaining ramdump buffer size %zu\n",
1618 current_region->name,
1619 current_region->len,
1620 buf_len);
1621 break;
1622 }
1623
1624 /* To get IRAM dump, the host driver needs to switch target
1625 * ram config from DRAM to IRAM.
1626 */
1627 if (current_region->type == ATH10K_MEM_REGION_TYPE_IRAM1 ||
1628 current_region->type == ATH10K_MEM_REGION_TYPE_IRAM2) {
1629 shift = current_region->start >> 20;
1630
1631 ret = ath10k_pci_set_ram_config(ar, shift);
1632 if (ret) {
1633 ath10k_warn(ar, "failed to switch ram config to IRAM for section %s: %d\n",
1634 current_region->name, ret);
1635 break;
1636 }
1637 }
1638
1639 /* Reserve space for the header. */
1640 hdr = (void *)buf;
1641 buf += sizeof(*hdr);
1642 buf_len -= sizeof(*hdr);
1643
1644 if (current_region->section_table.size > 0) {
1645 /* Copy each section individually. */
1646 count = ath10k_pci_dump_memory_section(ar,
1647 current_region,
1648 buf,
1649 current_region->len);
1650 } else {
1651 /* No individiual memory sections defined so we can
1652 * copy the entire memory region.
1653 */
1654 ret = ath10k_pci_diag_read_mem(ar,
1655 current_region->start,
1656 buf,
1657 current_region->len);
1658 if (ret) {
1659 ath10k_warn(ar, "failed to copy ramdump region %s: %d\n",
1660 current_region->name, ret);
1661 break;
1662 }
1663
1664 count = current_region->len;
1665 }
1666
1667 hdr->region_type = cpu_to_le32(current_region->type);
1668 hdr->start = cpu_to_le32(current_region->start);
1669 hdr->length = cpu_to_le32(count);
1670
1671 if (count == 0)
1672 /* Note: the header remains, just with zero length. */
1673 break;
1674
1675 buf += count;
1676 buf_len -= count;
1677
1678 current_region++;
1679 }
1680}
1681
1465static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) 1682static void ath10k_pci_fw_crashed_dump(struct ath10k *ar)
1466{ 1683{
1467 struct ath10k_fw_crash_data *crash_data; 1684 struct ath10k_fw_crash_data *crash_data;
@@ -1482,6 +1699,7 @@ static void ath10k_pci_fw_crashed_dump(struct ath10k *ar)
1482 ath10k_print_driver_info(ar); 1699 ath10k_print_driver_info(ar);
1483 ath10k_pci_dump_registers(ar, crash_data); 1700 ath10k_pci_dump_registers(ar, crash_data);
1484 ath10k_ce_dump_registers(ar, crash_data); 1701 ath10k_ce_dump_registers(ar, crash_data);
1702 ath10k_pci_dump_memory(ar, crash_data);
1485 1703
1486 spin_unlock_bh(&ar->data_lock); 1704 spin_unlock_bh(&ar->data_lock);
1487 1705