GNU Linux-libre 4.14.259-gnu1
[releases.git] / drivers / net / ethernet / qlogic / qed / qed_debug.c
1 /* QLogic qed NIC Driver
2  * Copyright (c) 2015 QLogic Corporation
3  *
4  * This software is available under the terms of the GNU General Public License
5  * (GPL) Version 2, available from the file COPYING in the main directory of
6  * this source tree.
7  */
8
9 #include <linux/module.h>
10 #include <linux/vmalloc.h>
11 #include <linux/crc32.h>
12 #include "qed.h"
13 #include "qed_hsi.h"
14 #include "qed_hw.h"
15 #include "qed_mcp.h"
16 #include "qed_reg_addr.h"
17
18 /* Memory groups enum */
19 enum mem_groups {
20         MEM_GROUP_PXP_MEM,
21         MEM_GROUP_DMAE_MEM,
22         MEM_GROUP_CM_MEM,
23         MEM_GROUP_QM_MEM,
24         MEM_GROUP_TM_MEM,
25         MEM_GROUP_BRB_RAM,
26         MEM_GROUP_BRB_MEM,
27         MEM_GROUP_PRS_MEM,
28         MEM_GROUP_SDM_MEM,
29         MEM_GROUP_IOR,
30         MEM_GROUP_RAM,
31         MEM_GROUP_BTB_RAM,
32         MEM_GROUP_RDIF_CTX,
33         MEM_GROUP_TDIF_CTX,
34         MEM_GROUP_CFC_MEM,
35         MEM_GROUP_CONN_CFC_MEM,
36         MEM_GROUP_TASK_CFC_MEM,
37         MEM_GROUP_CAU_PI,
38         MEM_GROUP_CAU_MEM,
39         MEM_GROUP_PXP_ILT,
40         MEM_GROUP_PBUF,
41         MEM_GROUP_MULD_MEM,
42         MEM_GROUP_BTB_MEM,
43         MEM_GROUP_IGU_MEM,
44         MEM_GROUP_IGU_MSIX,
45         MEM_GROUP_CAU_SB,
46         MEM_GROUP_BMB_RAM,
47         MEM_GROUP_BMB_MEM,
48         MEM_GROUPS_NUM
49 };
50
51 /* Memory groups names */
52 static const char * const s_mem_group_names[] = {
53         "PXP_MEM",
54         "DMAE_MEM",
55         "CM_MEM",
56         "QM_MEM",
57         "TM_MEM",
58         "BRB_RAM",
59         "BRB_MEM",
60         "PRS_MEM",
61         "SDM_MEM",
62         "IOR",
63         "RAM",
64         "BTB_RAM",
65         "RDIF_CTX",
66         "TDIF_CTX",
67         "CFC_MEM",
68         "CONN_CFC_MEM",
69         "TASK_CFC_MEM",
70         "CAU_PI",
71         "CAU_MEM",
72         "PXP_ILT",
73         "PBUF",
74         "MULD_MEM",
75         "BTB_MEM",
76         "IGU_MEM",
77         "IGU_MSIX",
78         "CAU_SB",
79         "BMB_RAM",
80         "BMB_MEM",
81 };
82
83 /* Idle check conditions */
84
85 static u32 cond5(const u32 *r, const u32 *imm)
86 {
87         return ((r[0] & imm[0]) != imm[1]) && ((r[1] & imm[2]) != imm[3]);
88 }
89
90 static u32 cond7(const u32 *r, const u32 *imm)
91 {
92         return ((r[0] >> imm[0]) & imm[1]) != imm[2];
93 }
94
95 static u32 cond14(const u32 *r, const u32 *imm)
96 {
97         return (r[0] != imm[0]) && (((r[1] >> imm[1]) & imm[2]) == imm[3]);
98 }
99
100 static u32 cond6(const u32 *r, const u32 *imm)
101 {
102         return (r[0] & imm[0]) != imm[1];
103 }
104
105 static u32 cond9(const u32 *r, const u32 *imm)
106 {
107         return ((r[0] & imm[0]) >> imm[1]) !=
108             (((r[0] & imm[2]) >> imm[3]) | ((r[1] & imm[4]) << imm[5]));
109 }
110
111 static u32 cond10(const u32 *r, const u32 *imm)
112 {
113         return ((r[0] & imm[0]) >> imm[1]) != (r[0] & imm[2]);
114 }
115
116 static u32 cond4(const u32 *r, const u32 *imm)
117 {
118         return (r[0] & ~imm[0]) != imm[1];
119 }
120
121 static u32 cond0(const u32 *r, const u32 *imm)
122 {
123         return (r[0] & ~r[1]) != imm[0];
124 }
125
126 static u32 cond1(const u32 *r, const u32 *imm)
127 {
128         return r[0] != imm[0];
129 }
130
131 static u32 cond11(const u32 *r, const u32 *imm)
132 {
133         return r[0] != r[1] && r[2] == imm[0];
134 }
135
136 static u32 cond12(const u32 *r, const u32 *imm)
137 {
138         return r[0] != r[1] && r[2] > imm[0];
139 }
140
141 static u32 cond3(const u32 *r, const u32 *imm)
142 {
143         return r[0] != r[1];
144 }
145
146 static u32 cond13(const u32 *r, const u32 *imm)
147 {
148         return r[0] & imm[0];
149 }
150
151 static u32 cond8(const u32 *r, const u32 *imm)
152 {
153         return r[0] < (r[1] - imm[0]);
154 }
155
156 static u32 cond2(const u32 *r, const u32 *imm)
157 {
158         return r[0] > imm[0];
159 }
160
161 /* Array of Idle Check conditions */
162 static u32(*cond_arr[]) (const u32 *r, const u32 *imm) = {
163         cond0,
164         cond1,
165         cond2,
166         cond3,
167         cond4,
168         cond5,
169         cond6,
170         cond7,
171         cond8,
172         cond9,
173         cond10,
174         cond11,
175         cond12,
176         cond13,
177         cond14,
178 };
179
180 /******************************* Data Types **********************************/
181
182 enum platform_ids {
183         PLATFORM_ASIC,
184         PLATFORM_RESERVED,
185         PLATFORM_RESERVED2,
186         PLATFORM_RESERVED3,
187         MAX_PLATFORM_IDS
188 };
189
190 struct chip_platform_defs {
191         u8 num_ports;
192         u8 num_pfs;
193         u8 num_vfs;
194 };
195
196 /* Chip constant definitions */
197 struct chip_defs {
198         const char *name;
199         struct chip_platform_defs per_platform[MAX_PLATFORM_IDS];
200 };
201
202 /* Platform constant definitions */
203 struct platform_defs {
204         const char *name;
205         u32 delay_factor;
206 };
207
208 /* Storm constant definitions.
209  * Addresses are in bytes, sizes are in quad-regs.
210  */
211 struct storm_defs {
212         char letter;
213         enum block_id block_id;
214         enum dbg_bus_clients dbg_client_id[MAX_CHIP_IDS];
215         bool has_vfc;
216         u32 sem_fast_mem_addr;
217         u32 sem_frame_mode_addr;
218         u32 sem_slow_enable_addr;
219         u32 sem_slow_mode_addr;
220         u32 sem_slow_mode1_conf_addr;
221         u32 sem_sync_dbg_empty_addr;
222         u32 sem_slow_dbg_empty_addr;
223         u32 cm_ctx_wr_addr;
224         u32 cm_conn_ag_ctx_lid_size;
225         u32 cm_conn_ag_ctx_rd_addr;
226         u32 cm_conn_st_ctx_lid_size;
227         u32 cm_conn_st_ctx_rd_addr;
228         u32 cm_task_ag_ctx_lid_size;
229         u32 cm_task_ag_ctx_rd_addr;
230         u32 cm_task_st_ctx_lid_size;
231         u32 cm_task_st_ctx_rd_addr;
232 };
233
234 /* Block constant definitions */
235 struct block_defs {
236         const char *name;
237         bool has_dbg_bus[MAX_CHIP_IDS];
238         bool associated_to_storm;
239
240         /* Valid only if associated_to_storm is true */
241         u32 storm_id;
242         enum dbg_bus_clients dbg_client_id[MAX_CHIP_IDS];
243         u32 dbg_select_addr;
244         u32 dbg_enable_addr;
245         u32 dbg_shift_addr;
246         u32 dbg_force_valid_addr;
247         u32 dbg_force_frame_addr;
248         bool has_reset_bit;
249
250         /* If true, block is taken out of reset before dump */
251         bool unreset;
252         enum dbg_reset_regs reset_reg;
253
254         /* Bit offset in reset register */
255         u8 reset_bit_offset;
256 };
257
258 /* Reset register definitions */
259 struct reset_reg_defs {
260         u32 addr;
261         u32 unreset_val;
262         bool exists[MAX_CHIP_IDS];
263 };
264
265 struct grc_param_defs {
266         u32 default_val[MAX_CHIP_IDS];
267         u32 min;
268         u32 max;
269         bool is_preset;
270         u32 exclude_all_preset_val;
271         u32 crash_preset_val;
272 };
273
274 /* Address is in 128b units. Width is in bits. */
275 struct rss_mem_defs {
276         const char *mem_name;
277         const char *type_name;
278         u32 addr;
279         u32 num_entries[MAX_CHIP_IDS];
280         u32 entry_width[MAX_CHIP_IDS];
281 };
282
283 struct vfc_ram_defs {
284         const char *mem_name;
285         const char *type_name;
286         u32 base_row;
287         u32 num_rows;
288 };
289
290 struct big_ram_defs {
291         const char *instance_name;
292         enum mem_groups mem_group_id;
293         enum mem_groups ram_mem_group_id;
294         enum dbg_grc_params grc_param;
295         u32 addr_reg_addr;
296         u32 data_reg_addr;
297         u32 num_of_blocks[MAX_CHIP_IDS];
298 };
299
300 struct phy_defs {
301         const char *phy_name;
302
303         /* PHY base GRC address */
304         u32 base_addr;
305
306         /* Relative address of indirect TBUS address register (bits 0..7) */
307         u32 tbus_addr_lo_addr;
308
309         /* Relative address of indirect TBUS address register (bits 8..10) */
310         u32 tbus_addr_hi_addr;
311
312         /* Relative address of indirect TBUS data register (bits 0..7) */
313         u32 tbus_data_lo_addr;
314
315         /* Relative address of indirect TBUS data register (bits 8..11) */
316         u32 tbus_data_hi_addr;
317 };
318
319 /******************************** Constants **********************************/
320
321 #define MAX_LCIDS                       320
322 #define MAX_LTIDS                       320
323
324 #define NUM_IOR_SETS                    2
325 #define IORS_PER_SET                    176
326 #define IOR_SET_OFFSET(set_id)          ((set_id) * 256)
327
328 #define BYTES_IN_DWORD                  sizeof(u32)
329
330 /* In the macros below, size and offset are specified in bits */
331 #define CEIL_DWORDS(size)               DIV_ROUND_UP(size, 32)
332 #define FIELD_BIT_OFFSET(type, field)   type ## _ ## field ## _ ## OFFSET
333 #define FIELD_BIT_SIZE(type, field)     type ## _ ## field ## _ ## SIZE
334 #define FIELD_DWORD_OFFSET(type, field) \
335          (int)(FIELD_BIT_OFFSET(type, field) / 32)
336 #define FIELD_DWORD_SHIFT(type, field)  (FIELD_BIT_OFFSET(type, field) % 32)
337 #define FIELD_BIT_MASK(type, field) \
338         (((1 << FIELD_BIT_SIZE(type, field)) - 1) << \
339          FIELD_DWORD_SHIFT(type, field))
340
341 #define SET_VAR_FIELD(var, type, field, val) \
342         do { \
343                 var[FIELD_DWORD_OFFSET(type, field)] &= \
344                 (~FIELD_BIT_MASK(type, field)); \
345                 var[FIELD_DWORD_OFFSET(type, field)] |= \
346                 (val) << FIELD_DWORD_SHIFT(type, field); \
347         } while (0)
348
349 #define ARR_REG_WR(dev, ptt, addr, arr, arr_size) \
350         do { \
351                 for (i = 0; i < (arr_size); i++) \
352                         qed_wr(dev, ptt, addr,  (arr)[i]); \
353         } while (0)
354
355 #define ARR_REG_RD(dev, ptt, addr, arr, arr_size) \
356         do { \
357                 for (i = 0; i < (arr_size); i++) \
358                         (arr)[i] = qed_rd(dev, ptt, addr); \
359         } while (0)
360
361 #ifndef DWORDS_TO_BYTES
362 #define DWORDS_TO_BYTES(dwords)         ((dwords) * BYTES_IN_DWORD)
363 #endif
364 #ifndef BYTES_TO_DWORDS
365 #define BYTES_TO_DWORDS(bytes)          ((bytes) / BYTES_IN_DWORD)
366 #endif
367
368 /* extra lines include a signature line + optional latency events line */
369 #ifndef NUM_DBG_LINES
370 #define NUM_EXTRA_DBG_LINES(block_desc) \
371         (1 + ((block_desc)->has_latency_events ? 1 : 0))
372 #define NUM_DBG_LINES(block_desc) \
373         ((block_desc)->num_of_lines + NUM_EXTRA_DBG_LINES(block_desc))
374 #endif
375
376 #define RAM_LINES_TO_DWORDS(lines)      ((lines) * 2)
377 #define RAM_LINES_TO_BYTES(lines) \
378         DWORDS_TO_BYTES(RAM_LINES_TO_DWORDS(lines))
379
380 #define REG_DUMP_LEN_SHIFT              24
381 #define MEM_DUMP_ENTRY_SIZE_DWORDS \
382         BYTES_TO_DWORDS(sizeof(struct dbg_dump_mem))
383
384 #define IDLE_CHK_RULE_SIZE_DWORDS \
385         BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_rule))
386
387 #define IDLE_CHK_RESULT_HDR_DWORDS \
388         BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_hdr))
389
390 #define IDLE_CHK_RESULT_REG_HDR_DWORDS \
391         BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_reg_hdr))
392
393 #define IDLE_CHK_MAX_ENTRIES_SIZE       32
394
395 /* The sizes and offsets below are specified in bits */
396 #define VFC_CAM_CMD_STRUCT_SIZE         64
397 #define VFC_CAM_CMD_ROW_OFFSET          48
398 #define VFC_CAM_CMD_ROW_SIZE            9
399 #define VFC_CAM_ADDR_STRUCT_SIZE        16
400 #define VFC_CAM_ADDR_OP_OFFSET          0
401 #define VFC_CAM_ADDR_OP_SIZE            4
402 #define VFC_CAM_RESP_STRUCT_SIZE        256
403 #define VFC_RAM_ADDR_STRUCT_SIZE        16
404 #define VFC_RAM_ADDR_OP_OFFSET          0
405 #define VFC_RAM_ADDR_OP_SIZE            2
406 #define VFC_RAM_ADDR_ROW_OFFSET         2
407 #define VFC_RAM_ADDR_ROW_SIZE           10
408 #define VFC_RAM_RESP_STRUCT_SIZE        256
409
410 #define VFC_CAM_CMD_DWORDS              CEIL_DWORDS(VFC_CAM_CMD_STRUCT_SIZE)
411 #define VFC_CAM_ADDR_DWORDS             CEIL_DWORDS(VFC_CAM_ADDR_STRUCT_SIZE)
412 #define VFC_CAM_RESP_DWORDS             CEIL_DWORDS(VFC_CAM_RESP_STRUCT_SIZE)
413 #define VFC_RAM_CMD_DWORDS              VFC_CAM_CMD_DWORDS
414 #define VFC_RAM_ADDR_DWORDS             CEIL_DWORDS(VFC_RAM_ADDR_STRUCT_SIZE)
415 #define VFC_RAM_RESP_DWORDS             CEIL_DWORDS(VFC_RAM_RESP_STRUCT_SIZE)
416
417 #define NUM_VFC_RAM_TYPES               4
418
419 #define VFC_CAM_NUM_ROWS                512
420
421 #define VFC_OPCODE_CAM_RD               14
422 #define VFC_OPCODE_RAM_RD               0
423
424 #define NUM_RSS_MEM_TYPES               5
425
426 #define NUM_BIG_RAM_TYPES               3
427 #define BIG_RAM_BLOCK_SIZE_BYTES        128
428 #define BIG_RAM_BLOCK_SIZE_DWORDS \
429         BYTES_TO_DWORDS(BIG_RAM_BLOCK_SIZE_BYTES)
430
431 #define NUM_PHY_TBUS_ADDRESSES          2048
432 #define PHY_DUMP_SIZE_DWORDS            (NUM_PHY_TBUS_ADDRESSES / 2)
433
434 #define RESET_REG_UNRESET_OFFSET        4
435
436 #define STALL_DELAY_MS                  500
437
438 #define STATIC_DEBUG_LINE_DWORDS        9
439
440 #define NUM_COMMON_GLOBAL_PARAMS        8
441
442 #define FW_IMG_MAIN                     1
443
444 #ifndef REG_FIFO_ELEMENT_DWORDS
445 #define REG_FIFO_ELEMENT_DWORDS         2
446 #endif
447 #define REG_FIFO_DEPTH_ELEMENTS         32
448 #define REG_FIFO_DEPTH_DWORDS \
449         (REG_FIFO_ELEMENT_DWORDS * REG_FIFO_DEPTH_ELEMENTS)
450
451 #ifndef IGU_FIFO_ELEMENT_DWORDS
452 #define IGU_FIFO_ELEMENT_DWORDS         4
453 #endif
454 #define IGU_FIFO_DEPTH_ELEMENTS         64
455 #define IGU_FIFO_DEPTH_DWORDS \
456         (IGU_FIFO_ELEMENT_DWORDS * IGU_FIFO_DEPTH_ELEMENTS)
457
458 #ifndef PROTECTION_OVERRIDE_ELEMENT_DWORDS
459 #define PROTECTION_OVERRIDE_ELEMENT_DWORDS      2
460 #endif
461 #define PROTECTION_OVERRIDE_DEPTH_ELEMENTS      20
462 #define PROTECTION_OVERRIDE_DEPTH_DWORDS \
463         (PROTECTION_OVERRIDE_DEPTH_ELEMENTS * \
464          PROTECTION_OVERRIDE_ELEMENT_DWORDS)
465
466 #define MCP_SPAD_TRACE_OFFSIZE_ADDR \
467         (MCP_REG_SCRATCH + \
468          offsetof(struct static_init, sections[SPAD_SECTION_TRACE]))
469
470 #define EMPTY_FW_VERSION_STR            "???_???_???_???"
471 #define EMPTY_FW_IMAGE_STR              "???????????????"
472
473 /***************************** Constant Arrays *******************************/
474
475 struct dbg_array {
476         const u32 *ptr;
477         u32 size_in_dwords;
478 };
479
480 /* Debug arrays */
481 static struct dbg_array s_dbg_arrays[MAX_BIN_DBG_BUFFER_TYPE] = { {NULL} };
482
483 /* Chip constant definitions array */
484 static struct chip_defs s_chip_defs[MAX_CHIP_IDS] = {
485         { "bb",
486           {{MAX_NUM_PORTS_BB, MAX_NUM_PFS_BB, MAX_NUM_VFS_BB},
487            {0, 0, 0},
488            {0, 0, 0},
489            {0, 0, 0} } },
490         { "ah",
491           {{MAX_NUM_PORTS_K2, MAX_NUM_PFS_K2, MAX_NUM_VFS_K2},
492            {0, 0, 0},
493            {0, 0, 0},
494            {0, 0, 0} } }
495 };
496
497 /* Storm constant definitions array */
498 static struct storm_defs s_storm_defs[] = {
499         /* Tstorm */
500         {'T', BLOCK_TSEM,
501          {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT}, true,
502          TSEM_REG_FAST_MEMORY,
503          TSEM_REG_DBG_FRAME_MODE_BB_K2, TSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
504          TSEM_REG_SLOW_DBG_MODE_BB_K2, TSEM_REG_DBG_MODE1_CFG_BB_K2,
505          TSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_SLOW_DBG_EMPTY_BB_K2,
506          TCM_REG_CTX_RBC_ACCS,
507          4, TCM_REG_AGG_CON_CTX,
508          16, TCM_REG_SM_CON_CTX,
509          2, TCM_REG_AGG_TASK_CTX,
510          4, TCM_REG_SM_TASK_CTX},
511
512         /* Mstorm */
513         {'M', BLOCK_MSEM,
514          {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM}, false,
515          MSEM_REG_FAST_MEMORY,
516          MSEM_REG_DBG_FRAME_MODE_BB_K2, MSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
517          MSEM_REG_SLOW_DBG_MODE_BB_K2, MSEM_REG_DBG_MODE1_CFG_BB_K2,
518          MSEM_REG_SYNC_DBG_EMPTY, MSEM_REG_SLOW_DBG_EMPTY_BB_K2,
519          MCM_REG_CTX_RBC_ACCS,
520          1, MCM_REG_AGG_CON_CTX,
521          10, MCM_REG_SM_CON_CTX,
522          2, MCM_REG_AGG_TASK_CTX,
523          7, MCM_REG_SM_TASK_CTX},
524
525         /* Ustorm */
526         {'U', BLOCK_USEM,
527          {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU}, false,
528          USEM_REG_FAST_MEMORY,
529          USEM_REG_DBG_FRAME_MODE_BB_K2, USEM_REG_SLOW_DBG_ACTIVE_BB_K2,
530          USEM_REG_SLOW_DBG_MODE_BB_K2, USEM_REG_DBG_MODE1_CFG_BB_K2,
531          USEM_REG_SYNC_DBG_EMPTY, USEM_REG_SLOW_DBG_EMPTY_BB_K2,
532          UCM_REG_CTX_RBC_ACCS,
533          2, UCM_REG_AGG_CON_CTX,
534          13, UCM_REG_SM_CON_CTX,
535          3, UCM_REG_AGG_TASK_CTX,
536          3, UCM_REG_SM_TASK_CTX},
537
538         /* Xstorm */
539         {'X', BLOCK_XSEM,
540          {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX}, false,
541          XSEM_REG_FAST_MEMORY,
542          XSEM_REG_DBG_FRAME_MODE_BB_K2, XSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
543          XSEM_REG_SLOW_DBG_MODE_BB_K2, XSEM_REG_DBG_MODE1_CFG_BB_K2,
544          XSEM_REG_SYNC_DBG_EMPTY, XSEM_REG_SLOW_DBG_EMPTY_BB_K2,
545          XCM_REG_CTX_RBC_ACCS,
546          9, XCM_REG_AGG_CON_CTX,
547          15, XCM_REG_SM_CON_CTX,
548          0, 0,
549          0, 0},
550
551         /* Ystorm */
552         {'Y', BLOCK_YSEM,
553          {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY}, false,
554          YSEM_REG_FAST_MEMORY,
555          YSEM_REG_DBG_FRAME_MODE_BB_K2, YSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
556          YSEM_REG_SLOW_DBG_MODE_BB_K2, YSEM_REG_DBG_MODE1_CFG_BB_K2,
557          YSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_SLOW_DBG_EMPTY_BB_K2,
558          YCM_REG_CTX_RBC_ACCS,
559          2, YCM_REG_AGG_CON_CTX,
560          3, YCM_REG_SM_CON_CTX,
561          2, YCM_REG_AGG_TASK_CTX,
562          12, YCM_REG_SM_TASK_CTX},
563
564         /* Pstorm */
565         {'P', BLOCK_PSEM,
566          {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS}, true,
567          PSEM_REG_FAST_MEMORY,
568          PSEM_REG_DBG_FRAME_MODE_BB_K2, PSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
569          PSEM_REG_SLOW_DBG_MODE_BB_K2, PSEM_REG_DBG_MODE1_CFG_BB_K2,
570          PSEM_REG_SYNC_DBG_EMPTY, PSEM_REG_SLOW_DBG_EMPTY_BB_K2,
571          PCM_REG_CTX_RBC_ACCS,
572          0, 0,
573          10, PCM_REG_SM_CON_CTX,
574          0, 0,
575          0, 0}
576 };
577
578 /* Block definitions array */
579
580 static struct block_defs block_grc_defs = {
581         "grc",
582         {true, true}, false, 0,
583         {DBG_BUS_CLIENT_RBCN, DBG_BUS_CLIENT_RBCN},
584         GRC_REG_DBG_SELECT, GRC_REG_DBG_DWORD_ENABLE,
585         GRC_REG_DBG_SHIFT, GRC_REG_DBG_FORCE_VALID,
586         GRC_REG_DBG_FORCE_FRAME,
587         true, false, DBG_RESET_REG_MISC_PL_UA, 1
588 };
589
590 static struct block_defs block_miscs_defs = {
591         "miscs", {false, false}, false, 0,
592         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
593         0, 0, 0, 0, 0,
594         false, false, MAX_DBG_RESET_REGS, 0
595 };
596
597 static struct block_defs block_misc_defs = {
598         "misc", {false, false}, false, 0,
599         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
600         0, 0, 0, 0, 0,
601         false, false, MAX_DBG_RESET_REGS, 0
602 };
603
604 static struct block_defs block_dbu_defs = {
605         "dbu", {false, false}, false, 0,
606         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
607         0, 0, 0, 0, 0,
608         false, false, MAX_DBG_RESET_REGS, 0
609 };
610
611 static struct block_defs block_pglue_b_defs = {
612         "pglue_b",
613         {true, true}, false, 0,
614         {DBG_BUS_CLIENT_RBCH, DBG_BUS_CLIENT_RBCH},
615         PGLUE_B_REG_DBG_SELECT, PGLUE_B_REG_DBG_DWORD_ENABLE,
616         PGLUE_B_REG_DBG_SHIFT, PGLUE_B_REG_DBG_FORCE_VALID,
617         PGLUE_B_REG_DBG_FORCE_FRAME,
618         true, false, DBG_RESET_REG_MISCS_PL_HV, 1
619 };
620
621 static struct block_defs block_cnig_defs = {
622         "cnig",
623         {false, true}, false, 0,
624         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCW},
625         CNIG_REG_DBG_SELECT_K2, CNIG_REG_DBG_DWORD_ENABLE_K2,
626         CNIG_REG_DBG_SHIFT_K2, CNIG_REG_DBG_FORCE_VALID_K2,
627         CNIG_REG_DBG_FORCE_FRAME_K2,
628         true, false, DBG_RESET_REG_MISCS_PL_HV, 0
629 };
630
631 static struct block_defs block_cpmu_defs = {
632         "cpmu", {false, false}, false, 0,
633         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
634         0, 0, 0, 0, 0,
635         true, false, DBG_RESET_REG_MISCS_PL_HV, 8
636 };
637
638 static struct block_defs block_ncsi_defs = {
639         "ncsi",
640         {true, true}, false, 0,
641         {DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCZ},
642         NCSI_REG_DBG_SELECT, NCSI_REG_DBG_DWORD_ENABLE,
643         NCSI_REG_DBG_SHIFT, NCSI_REG_DBG_FORCE_VALID,
644         NCSI_REG_DBG_FORCE_FRAME,
645         true, false, DBG_RESET_REG_MISCS_PL_HV, 5
646 };
647
648 static struct block_defs block_opte_defs = {
649         "opte", {false, false}, false, 0,
650         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
651         0, 0, 0, 0, 0,
652         true, false, DBG_RESET_REG_MISCS_PL_HV, 4
653 };
654
655 static struct block_defs block_bmb_defs = {
656         "bmb",
657         {true, true}, false, 0,
658         {DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCB},
659         BMB_REG_DBG_SELECT, BMB_REG_DBG_DWORD_ENABLE,
660         BMB_REG_DBG_SHIFT, BMB_REG_DBG_FORCE_VALID,
661         BMB_REG_DBG_FORCE_FRAME,
662         true, false, DBG_RESET_REG_MISCS_PL_UA, 7
663 };
664
665 static struct block_defs block_pcie_defs = {
666         "pcie",
667         {false, true}, false, 0,
668         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH},
669         PCIE_REG_DBG_COMMON_SELECT_K2,
670         PCIE_REG_DBG_COMMON_DWORD_ENABLE_K2,
671         PCIE_REG_DBG_COMMON_SHIFT_K2,
672         PCIE_REG_DBG_COMMON_FORCE_VALID_K2,
673         PCIE_REG_DBG_COMMON_FORCE_FRAME_K2,
674         false, false, MAX_DBG_RESET_REGS, 0
675 };
676
677 static struct block_defs block_mcp_defs = {
678         "mcp", {false, false}, false, 0,
679         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
680         0, 0, 0, 0, 0,
681         false, false, MAX_DBG_RESET_REGS, 0
682 };
683
684 static struct block_defs block_mcp2_defs = {
685         "mcp2",
686         {true, true}, false, 0,
687         {DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCZ},
688         MCP2_REG_DBG_SELECT, MCP2_REG_DBG_DWORD_ENABLE,
689         MCP2_REG_DBG_SHIFT, MCP2_REG_DBG_FORCE_VALID,
690         MCP2_REG_DBG_FORCE_FRAME,
691         false, false, MAX_DBG_RESET_REGS, 0
692 };
693
694 static struct block_defs block_pswhst_defs = {
695         "pswhst",
696         {true, true}, false, 0,
697         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
698         PSWHST_REG_DBG_SELECT, PSWHST_REG_DBG_DWORD_ENABLE,
699         PSWHST_REG_DBG_SHIFT, PSWHST_REG_DBG_FORCE_VALID,
700         PSWHST_REG_DBG_FORCE_FRAME,
701         true, false, DBG_RESET_REG_MISC_PL_HV, 0
702 };
703
704 static struct block_defs block_pswhst2_defs = {
705         "pswhst2",
706         {true, true}, false, 0,
707         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
708         PSWHST2_REG_DBG_SELECT, PSWHST2_REG_DBG_DWORD_ENABLE,
709         PSWHST2_REG_DBG_SHIFT, PSWHST2_REG_DBG_FORCE_VALID,
710         PSWHST2_REG_DBG_FORCE_FRAME,
711         true, false, DBG_RESET_REG_MISC_PL_HV, 0
712 };
713
714 static struct block_defs block_pswrd_defs = {
715         "pswrd",
716         {true, true}, false, 0,
717         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
718         PSWRD_REG_DBG_SELECT, PSWRD_REG_DBG_DWORD_ENABLE,
719         PSWRD_REG_DBG_SHIFT, PSWRD_REG_DBG_FORCE_VALID,
720         PSWRD_REG_DBG_FORCE_FRAME,
721         true, false, DBG_RESET_REG_MISC_PL_HV, 2
722 };
723
724 static struct block_defs block_pswrd2_defs = {
725         "pswrd2",
726         {true, true}, false, 0,
727         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
728         PSWRD2_REG_DBG_SELECT, PSWRD2_REG_DBG_DWORD_ENABLE,
729         PSWRD2_REG_DBG_SHIFT, PSWRD2_REG_DBG_FORCE_VALID,
730         PSWRD2_REG_DBG_FORCE_FRAME,
731         true, false, DBG_RESET_REG_MISC_PL_HV, 2
732 };
733
734 static struct block_defs block_pswwr_defs = {
735         "pswwr",
736         {true, true}, false, 0,
737         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
738         PSWWR_REG_DBG_SELECT, PSWWR_REG_DBG_DWORD_ENABLE,
739         PSWWR_REG_DBG_SHIFT, PSWWR_REG_DBG_FORCE_VALID,
740         PSWWR_REG_DBG_FORCE_FRAME,
741         true, false, DBG_RESET_REG_MISC_PL_HV, 3
742 };
743
744 static struct block_defs block_pswwr2_defs = {
745         "pswwr2", {false, false}, false, 0,
746         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
747         0, 0, 0, 0, 0,
748         true, false, DBG_RESET_REG_MISC_PL_HV, 3
749 };
750
751 static struct block_defs block_pswrq_defs = {
752         "pswrq",
753         {true, true}, false, 0,
754         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
755         PSWRQ_REG_DBG_SELECT, PSWRQ_REG_DBG_DWORD_ENABLE,
756         PSWRQ_REG_DBG_SHIFT, PSWRQ_REG_DBG_FORCE_VALID,
757         PSWRQ_REG_DBG_FORCE_FRAME,
758         true, false, DBG_RESET_REG_MISC_PL_HV, 1
759 };
760
761 static struct block_defs block_pswrq2_defs = {
762         "pswrq2",
763         {true, true}, false, 0,
764         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
765         PSWRQ2_REG_DBG_SELECT, PSWRQ2_REG_DBG_DWORD_ENABLE,
766         PSWRQ2_REG_DBG_SHIFT, PSWRQ2_REG_DBG_FORCE_VALID,
767         PSWRQ2_REG_DBG_FORCE_FRAME,
768         true, false, DBG_RESET_REG_MISC_PL_HV, 1
769 };
770
771 static struct block_defs block_pglcs_defs = {
772         "pglcs",
773         {false, true}, false, 0,
774         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH},
775         PGLCS_REG_DBG_SELECT_K2, PGLCS_REG_DBG_DWORD_ENABLE_K2,
776         PGLCS_REG_DBG_SHIFT_K2, PGLCS_REG_DBG_FORCE_VALID_K2,
777         PGLCS_REG_DBG_FORCE_FRAME_K2,
778         true, false, DBG_RESET_REG_MISCS_PL_HV, 2
779 };
780
781 static struct block_defs block_ptu_defs = {
782         "ptu",
783         {true, true}, false, 0,
784         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
785         PTU_REG_DBG_SELECT, PTU_REG_DBG_DWORD_ENABLE,
786         PTU_REG_DBG_SHIFT, PTU_REG_DBG_FORCE_VALID,
787         PTU_REG_DBG_FORCE_FRAME,
788         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 20
789 };
790
791 static struct block_defs block_dmae_defs = {
792         "dmae",
793         {true, true}, false, 0,
794         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
795         DMAE_REG_DBG_SELECT, DMAE_REG_DBG_DWORD_ENABLE,
796         DMAE_REG_DBG_SHIFT, DMAE_REG_DBG_FORCE_VALID,
797         DMAE_REG_DBG_FORCE_FRAME,
798         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 28
799 };
800
801 static struct block_defs block_tcm_defs = {
802         "tcm",
803         {true, true}, true, DBG_TSTORM_ID,
804         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
805         TCM_REG_DBG_SELECT, TCM_REG_DBG_DWORD_ENABLE,
806         TCM_REG_DBG_SHIFT, TCM_REG_DBG_FORCE_VALID,
807         TCM_REG_DBG_FORCE_FRAME,
808         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 5
809 };
810
811 static struct block_defs block_mcm_defs = {
812         "mcm",
813         {true, true}, true, DBG_MSTORM_ID,
814         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
815         MCM_REG_DBG_SELECT, MCM_REG_DBG_DWORD_ENABLE,
816         MCM_REG_DBG_SHIFT, MCM_REG_DBG_FORCE_VALID,
817         MCM_REG_DBG_FORCE_FRAME,
818         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 3
819 };
820
821 static struct block_defs block_ucm_defs = {
822         "ucm",
823         {true, true}, true, DBG_USTORM_ID,
824         {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
825         UCM_REG_DBG_SELECT, UCM_REG_DBG_DWORD_ENABLE,
826         UCM_REG_DBG_SHIFT, UCM_REG_DBG_FORCE_VALID,
827         UCM_REG_DBG_FORCE_FRAME,
828         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 8
829 };
830
831 static struct block_defs block_xcm_defs = {
832         "xcm",
833         {true, true}, true, DBG_XSTORM_ID,
834         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
835         XCM_REG_DBG_SELECT, XCM_REG_DBG_DWORD_ENABLE,
836         XCM_REG_DBG_SHIFT, XCM_REG_DBG_FORCE_VALID,
837         XCM_REG_DBG_FORCE_FRAME,
838         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 19
839 };
840
841 static struct block_defs block_ycm_defs = {
842         "ycm",
843         {true, true}, true, DBG_YSTORM_ID,
844         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY},
845         YCM_REG_DBG_SELECT, YCM_REG_DBG_DWORD_ENABLE,
846         YCM_REG_DBG_SHIFT, YCM_REG_DBG_FORCE_VALID,
847         YCM_REG_DBG_FORCE_FRAME,
848         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 5
849 };
850
851 static struct block_defs block_pcm_defs = {
852         "pcm",
853         {true, true}, true, DBG_PSTORM_ID,
854         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
855         PCM_REG_DBG_SELECT, PCM_REG_DBG_DWORD_ENABLE,
856         PCM_REG_DBG_SHIFT, PCM_REG_DBG_FORCE_VALID,
857         PCM_REG_DBG_FORCE_FRAME,
858         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 4
859 };
860
861 static struct block_defs block_qm_defs = {
862         "qm",
863         {true, true}, false, 0,
864         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCQ},
865         QM_REG_DBG_SELECT, QM_REG_DBG_DWORD_ENABLE,
866         QM_REG_DBG_SHIFT, QM_REG_DBG_FORCE_VALID,
867         QM_REG_DBG_FORCE_FRAME,
868         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 16
869 };
870
871 static struct block_defs block_tm_defs = {
872         "tm",
873         {true, true}, false, 0,
874         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
875         TM_REG_DBG_SELECT, TM_REG_DBG_DWORD_ENABLE,
876         TM_REG_DBG_SHIFT, TM_REG_DBG_FORCE_VALID,
877         TM_REG_DBG_FORCE_FRAME,
878         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 17
879 };
880
881 static struct block_defs block_dorq_defs = {
882         "dorq",
883         {true, true}, false, 0,
884         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY},
885         DORQ_REG_DBG_SELECT, DORQ_REG_DBG_DWORD_ENABLE,
886         DORQ_REG_DBG_SHIFT, DORQ_REG_DBG_FORCE_VALID,
887         DORQ_REG_DBG_FORCE_FRAME,
888         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 18
889 };
890
891 static struct block_defs block_brb_defs = {
892         "brb",
893         {true, true}, false, 0,
894         {DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCR},
895         BRB_REG_DBG_SELECT, BRB_REG_DBG_DWORD_ENABLE,
896         BRB_REG_DBG_SHIFT, BRB_REG_DBG_FORCE_VALID,
897         BRB_REG_DBG_FORCE_FRAME,
898         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 0
899 };
900
901 static struct block_defs block_src_defs = {
902         "src",
903         {true, true}, false, 0,
904         {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF},
905         SRC_REG_DBG_SELECT, SRC_REG_DBG_DWORD_ENABLE,
906         SRC_REG_DBG_SHIFT, SRC_REG_DBG_FORCE_VALID,
907         SRC_REG_DBG_FORCE_FRAME,
908         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 2
909 };
910
911 static struct block_defs block_prs_defs = {
912         "prs",
913         {true, true}, false, 0,
914         {DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCR},
915         PRS_REG_DBG_SELECT, PRS_REG_DBG_DWORD_ENABLE,
916         PRS_REG_DBG_SHIFT, PRS_REG_DBG_FORCE_VALID,
917         PRS_REG_DBG_FORCE_FRAME,
918         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 1
919 };
920
921 static struct block_defs block_tsdm_defs = {
922         "tsdm",
923         {true, true}, true, DBG_TSTORM_ID,
924         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
925         TSDM_REG_DBG_SELECT, TSDM_REG_DBG_DWORD_ENABLE,
926         TSDM_REG_DBG_SHIFT, TSDM_REG_DBG_FORCE_VALID,
927         TSDM_REG_DBG_FORCE_FRAME,
928         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 3
929 };
930
931 static struct block_defs block_msdm_defs = {
932         "msdm",
933         {true, true}, true, DBG_MSTORM_ID,
934         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
935         MSDM_REG_DBG_SELECT, MSDM_REG_DBG_DWORD_ENABLE,
936         MSDM_REG_DBG_SHIFT, MSDM_REG_DBG_FORCE_VALID,
937         MSDM_REG_DBG_FORCE_FRAME,
938         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 6
939 };
940
941 static struct block_defs block_usdm_defs = {
942         "usdm",
943         {true, true}, true, DBG_USTORM_ID,
944         {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
945         USDM_REG_DBG_SELECT, USDM_REG_DBG_DWORD_ENABLE,
946         USDM_REG_DBG_SHIFT, USDM_REG_DBG_FORCE_VALID,
947         USDM_REG_DBG_FORCE_FRAME,
948         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 7
949 };
950
951 static struct block_defs block_xsdm_defs = {
952         "xsdm",
953         {true, true}, true, DBG_XSTORM_ID,
954         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
955         XSDM_REG_DBG_SELECT, XSDM_REG_DBG_DWORD_ENABLE,
956         XSDM_REG_DBG_SHIFT, XSDM_REG_DBG_FORCE_VALID,
957         XSDM_REG_DBG_FORCE_FRAME,
958         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 20
959 };
960
961 static struct block_defs block_ysdm_defs = {
962         "ysdm",
963         {true, true}, true, DBG_YSTORM_ID,
964         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY},
965         YSDM_REG_DBG_SELECT, YSDM_REG_DBG_DWORD_ENABLE,
966         YSDM_REG_DBG_SHIFT, YSDM_REG_DBG_FORCE_VALID,
967         YSDM_REG_DBG_FORCE_FRAME,
968         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 8
969 };
970
971 static struct block_defs block_psdm_defs = {
972         "psdm",
973         {true, true}, true, DBG_PSTORM_ID,
974         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
975         PSDM_REG_DBG_SELECT, PSDM_REG_DBG_DWORD_ENABLE,
976         PSDM_REG_DBG_SHIFT, PSDM_REG_DBG_FORCE_VALID,
977         PSDM_REG_DBG_FORCE_FRAME,
978         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 7
979 };
980
981 static struct block_defs block_tsem_defs = {
982         "tsem",
983         {true, true}, true, DBG_TSTORM_ID,
984         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
985         TSEM_REG_DBG_SELECT, TSEM_REG_DBG_DWORD_ENABLE,
986         TSEM_REG_DBG_SHIFT, TSEM_REG_DBG_FORCE_VALID,
987         TSEM_REG_DBG_FORCE_FRAME,
988         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 4
989 };
990
991 static struct block_defs block_msem_defs = {
992         "msem",
993         {true, true}, true, DBG_MSTORM_ID,
994         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
995         MSEM_REG_DBG_SELECT, MSEM_REG_DBG_DWORD_ENABLE,
996         MSEM_REG_DBG_SHIFT, MSEM_REG_DBG_FORCE_VALID,
997         MSEM_REG_DBG_FORCE_FRAME,
998         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 9
999 };
1000
1001 static struct block_defs block_usem_defs = {
1002         "usem",
1003         {true, true}, true, DBG_USTORM_ID,
1004         {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
1005         USEM_REG_DBG_SELECT, USEM_REG_DBG_DWORD_ENABLE,
1006         USEM_REG_DBG_SHIFT, USEM_REG_DBG_FORCE_VALID,
1007         USEM_REG_DBG_FORCE_FRAME,
1008         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 9
1009 };
1010
1011 static struct block_defs block_xsem_defs = {
1012         "xsem",
1013         {true, true}, true, DBG_XSTORM_ID,
1014         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
1015         XSEM_REG_DBG_SELECT, XSEM_REG_DBG_DWORD_ENABLE,
1016         XSEM_REG_DBG_SHIFT, XSEM_REG_DBG_FORCE_VALID,
1017         XSEM_REG_DBG_FORCE_FRAME,
1018         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 21
1019 };
1020
1021 static struct block_defs block_ysem_defs = {
1022         "ysem",
1023         {true, true}, true, DBG_YSTORM_ID,
1024         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY},
1025         YSEM_REG_DBG_SELECT, YSEM_REG_DBG_DWORD_ENABLE,
1026         YSEM_REG_DBG_SHIFT, YSEM_REG_DBG_FORCE_VALID,
1027         YSEM_REG_DBG_FORCE_FRAME,
1028         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 11
1029 };
1030
1031 static struct block_defs block_psem_defs = {
1032         "psem",
1033         {true, true}, true, DBG_PSTORM_ID,
1034         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
1035         PSEM_REG_DBG_SELECT, PSEM_REG_DBG_DWORD_ENABLE,
1036         PSEM_REG_DBG_SHIFT, PSEM_REG_DBG_FORCE_VALID,
1037         PSEM_REG_DBG_FORCE_FRAME,
1038         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 10
1039 };
1040
1041 static struct block_defs block_rss_defs = {
1042         "rss",
1043         {true, true}, false, 0,
1044         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
1045         RSS_REG_DBG_SELECT, RSS_REG_DBG_DWORD_ENABLE,
1046         RSS_REG_DBG_SHIFT, RSS_REG_DBG_FORCE_VALID,
1047         RSS_REG_DBG_FORCE_FRAME,
1048         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 18
1049 };
1050
1051 static struct block_defs block_tmld_defs = {
1052         "tmld",
1053         {true, true}, false, 0,
1054         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
1055         TMLD_REG_DBG_SELECT, TMLD_REG_DBG_DWORD_ENABLE,
1056         TMLD_REG_DBG_SHIFT, TMLD_REG_DBG_FORCE_VALID,
1057         TMLD_REG_DBG_FORCE_FRAME,
1058         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 13
1059 };
1060
1061 static struct block_defs block_muld_defs = {
1062         "muld",
1063         {true, true}, false, 0,
1064         {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
1065         MULD_REG_DBG_SELECT, MULD_REG_DBG_DWORD_ENABLE,
1066         MULD_REG_DBG_SHIFT, MULD_REG_DBG_FORCE_VALID,
1067         MULD_REG_DBG_FORCE_FRAME,
1068         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 14
1069 };
1070
1071 static struct block_defs block_yuld_defs = {
1072         "yuld",
1073         {true, true}, false, 0,
1074         {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
1075         YULD_REG_DBG_SELECT_BB_K2, YULD_REG_DBG_DWORD_ENABLE_BB_K2,
1076         YULD_REG_DBG_SHIFT_BB_K2, YULD_REG_DBG_FORCE_VALID_BB_K2,
1077         YULD_REG_DBG_FORCE_FRAME_BB_K2,
1078         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2,
1079         15
1080 };
1081
1082 static struct block_defs block_xyld_defs = {
1083         "xyld",
1084         {true, true}, false, 0,
1085         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
1086         XYLD_REG_DBG_SELECT, XYLD_REG_DBG_DWORD_ENABLE,
1087         XYLD_REG_DBG_SHIFT, XYLD_REG_DBG_FORCE_VALID,
1088         XYLD_REG_DBG_FORCE_FRAME,
1089         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 12
1090 };
1091
1092 static struct block_defs block_prm_defs = {
1093         "prm",
1094         {true, true}, false, 0,
1095         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
1096         PRM_REG_DBG_SELECT, PRM_REG_DBG_DWORD_ENABLE,
1097         PRM_REG_DBG_SHIFT, PRM_REG_DBG_FORCE_VALID,
1098         PRM_REG_DBG_FORCE_FRAME,
1099         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 21
1100 };
1101
1102 static struct block_defs block_pbf_pb1_defs = {
1103         "pbf_pb1",
1104         {true, true}, false, 0,
1105         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCV},
1106         PBF_PB1_REG_DBG_SELECT, PBF_PB1_REG_DBG_DWORD_ENABLE,
1107         PBF_PB1_REG_DBG_SHIFT, PBF_PB1_REG_DBG_FORCE_VALID,
1108         PBF_PB1_REG_DBG_FORCE_FRAME,
1109         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1,
1110         11
1111 };
1112
1113 static struct block_defs block_pbf_pb2_defs = {
1114         "pbf_pb2",
1115         {true, true}, false, 0,
1116         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCV},
1117         PBF_PB2_REG_DBG_SELECT, PBF_PB2_REG_DBG_DWORD_ENABLE,
1118         PBF_PB2_REG_DBG_SHIFT, PBF_PB2_REG_DBG_FORCE_VALID,
1119         PBF_PB2_REG_DBG_FORCE_FRAME,
1120         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1,
1121         12
1122 };
1123
1124 static struct block_defs block_rpb_defs = {
1125         "rpb",
1126         {true, true}, false, 0,
1127         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
1128         RPB_REG_DBG_SELECT, RPB_REG_DBG_DWORD_ENABLE,
1129         RPB_REG_DBG_SHIFT, RPB_REG_DBG_FORCE_VALID,
1130         RPB_REG_DBG_FORCE_FRAME,
1131         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 13
1132 };
1133
1134 static struct block_defs block_btb_defs = {
1135         "btb",
1136         {true, true}, false, 0,
1137         {DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCV},
1138         BTB_REG_DBG_SELECT, BTB_REG_DBG_DWORD_ENABLE,
1139         BTB_REG_DBG_SHIFT, BTB_REG_DBG_FORCE_VALID,
1140         BTB_REG_DBG_FORCE_FRAME,
1141         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 10
1142 };
1143
1144 static struct block_defs block_pbf_defs = {
1145         "pbf",
1146         {true, true}, false, 0,
1147         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCV},
1148         PBF_REG_DBG_SELECT, PBF_REG_DBG_DWORD_ENABLE,
1149         PBF_REG_DBG_SHIFT, PBF_REG_DBG_FORCE_VALID,
1150         PBF_REG_DBG_FORCE_FRAME,
1151         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 15
1152 };
1153
1154 static struct block_defs block_rdif_defs = {
1155         "rdif",
1156         {true, true}, false, 0,
1157         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
1158         RDIF_REG_DBG_SELECT, RDIF_REG_DBG_DWORD_ENABLE,
1159         RDIF_REG_DBG_SHIFT, RDIF_REG_DBG_FORCE_VALID,
1160         RDIF_REG_DBG_FORCE_FRAME,
1161         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 16
1162 };
1163
1164 static struct block_defs block_tdif_defs = {
1165         "tdif",
1166         {true, true}, false, 0,
1167         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
1168         TDIF_REG_DBG_SELECT, TDIF_REG_DBG_DWORD_ENABLE,
1169         TDIF_REG_DBG_SHIFT, TDIF_REG_DBG_FORCE_VALID,
1170         TDIF_REG_DBG_FORCE_FRAME,
1171         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 17
1172 };
1173
1174 static struct block_defs block_cdu_defs = {
1175         "cdu",
1176         {true, true}, false, 0,
1177         {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF},
1178         CDU_REG_DBG_SELECT, CDU_REG_DBG_DWORD_ENABLE,
1179         CDU_REG_DBG_SHIFT, CDU_REG_DBG_FORCE_VALID,
1180         CDU_REG_DBG_FORCE_FRAME,
1181         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 23
1182 };
1183
1184 static struct block_defs block_ccfc_defs = {
1185         "ccfc",
1186         {true, true}, false, 0,
1187         {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF},
1188         CCFC_REG_DBG_SELECT, CCFC_REG_DBG_DWORD_ENABLE,
1189         CCFC_REG_DBG_SHIFT, CCFC_REG_DBG_FORCE_VALID,
1190         CCFC_REG_DBG_FORCE_FRAME,
1191         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 24
1192 };
1193
1194 static struct block_defs block_tcfc_defs = {
1195         "tcfc",
1196         {true, true}, false, 0,
1197         {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF},
1198         TCFC_REG_DBG_SELECT, TCFC_REG_DBG_DWORD_ENABLE,
1199         TCFC_REG_DBG_SHIFT, TCFC_REG_DBG_FORCE_VALID,
1200         TCFC_REG_DBG_FORCE_FRAME,
1201         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 25
1202 };
1203
1204 static struct block_defs block_igu_defs = {
1205         "igu",
1206         {true, true}, false, 0,
1207         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
1208         IGU_REG_DBG_SELECT, IGU_REG_DBG_DWORD_ENABLE,
1209         IGU_REG_DBG_SHIFT, IGU_REG_DBG_FORCE_VALID,
1210         IGU_REG_DBG_FORCE_FRAME,
1211         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 27
1212 };
1213
1214 static struct block_defs block_cau_defs = {
1215         "cau",
1216         {true, true}, false, 0,
1217         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
1218         CAU_REG_DBG_SELECT, CAU_REG_DBG_DWORD_ENABLE,
1219         CAU_REG_DBG_SHIFT, CAU_REG_DBG_FORCE_VALID,
1220         CAU_REG_DBG_FORCE_FRAME,
1221         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 19
1222 };
1223
1224 static struct block_defs block_umac_defs = {
1225         "umac",
1226         {false, true}, false, 0,
1227         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCZ},
1228         UMAC_REG_DBG_SELECT_K2, UMAC_REG_DBG_DWORD_ENABLE_K2,
1229         UMAC_REG_DBG_SHIFT_K2, UMAC_REG_DBG_FORCE_VALID_K2,
1230         UMAC_REG_DBG_FORCE_FRAME_K2,
1231         true, false, DBG_RESET_REG_MISCS_PL_HV, 6
1232 };
1233
1234 static struct block_defs block_xmac_defs = {
1235         "xmac", {false, false}, false, 0,
1236         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1237         0, 0, 0, 0, 0,
1238         false, false, MAX_DBG_RESET_REGS, 0
1239 };
1240
1241 static struct block_defs block_dbg_defs = {
1242         "dbg", {false, false}, false, 0,
1243         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1244         0, 0, 0, 0, 0,
1245         true, true, DBG_RESET_REG_MISC_PL_PDA_VAUX, 3
1246 };
1247
1248 static struct block_defs block_nig_defs = {
1249         "nig",
1250         {true, true}, false, 0,
1251         {DBG_BUS_CLIENT_RBCN, DBG_BUS_CLIENT_RBCN},
1252         NIG_REG_DBG_SELECT, NIG_REG_DBG_DWORD_ENABLE,
1253         NIG_REG_DBG_SHIFT, NIG_REG_DBG_FORCE_VALID,
1254         NIG_REG_DBG_FORCE_FRAME,
1255         true, true, DBG_RESET_REG_MISC_PL_PDA_VAUX, 0
1256 };
1257
1258 static struct block_defs block_wol_defs = {
1259         "wol",
1260         {false, true}, false, 0,
1261         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCZ},
1262         WOL_REG_DBG_SELECT_K2, WOL_REG_DBG_DWORD_ENABLE_K2,
1263         WOL_REG_DBG_SHIFT_K2, WOL_REG_DBG_FORCE_VALID_K2,
1264         WOL_REG_DBG_FORCE_FRAME_K2,
1265         true, true, DBG_RESET_REG_MISC_PL_PDA_VAUX, 7
1266 };
1267
1268 static struct block_defs block_bmbn_defs = {
1269         "bmbn",
1270         {false, true}, false, 0,
1271         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCB},
1272         BMBN_REG_DBG_SELECT_K2, BMBN_REG_DBG_DWORD_ENABLE_K2,
1273         BMBN_REG_DBG_SHIFT_K2, BMBN_REG_DBG_FORCE_VALID_K2,
1274         BMBN_REG_DBG_FORCE_FRAME_K2,
1275         false, false, MAX_DBG_RESET_REGS, 0
1276 };
1277
1278 static struct block_defs block_ipc_defs = {
1279         "ipc", {false, false}, false, 0,
1280         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1281         0, 0, 0, 0, 0,
1282         true, false, DBG_RESET_REG_MISCS_PL_UA, 8
1283 };
1284
1285 static struct block_defs block_nwm_defs = {
1286         "nwm",
1287         {false, true}, false, 0,
1288         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCW},
1289         NWM_REG_DBG_SELECT_K2, NWM_REG_DBG_DWORD_ENABLE_K2,
1290         NWM_REG_DBG_SHIFT_K2, NWM_REG_DBG_FORCE_VALID_K2,
1291         NWM_REG_DBG_FORCE_FRAME_K2,
1292         true, false, DBG_RESET_REG_MISCS_PL_HV_2, 0
1293 };
1294
1295 static struct block_defs block_nws_defs = {
1296         "nws",
1297         {false, true}, false, 0,
1298         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCW},
1299         NWS_REG_DBG_SELECT_K2, NWS_REG_DBG_DWORD_ENABLE_K2,
1300         NWS_REG_DBG_SHIFT_K2, NWS_REG_DBG_FORCE_VALID_K2,
1301         NWS_REG_DBG_FORCE_FRAME_K2,
1302         true, false, DBG_RESET_REG_MISCS_PL_HV, 12
1303 };
1304
1305 static struct block_defs block_ms_defs = {
1306         "ms",
1307         {false, true}, false, 0,
1308         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCZ},
1309         MS_REG_DBG_SELECT_K2, MS_REG_DBG_DWORD_ENABLE_K2,
1310         MS_REG_DBG_SHIFT_K2, MS_REG_DBG_FORCE_VALID_K2,
1311         MS_REG_DBG_FORCE_FRAME_K2,
1312         true, false, DBG_RESET_REG_MISCS_PL_HV, 13
1313 };
1314
1315 static struct block_defs block_phy_pcie_defs = {
1316         "phy_pcie",
1317         {false, true}, false, 0,
1318         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH},
1319         PCIE_REG_DBG_COMMON_SELECT_K2,
1320         PCIE_REG_DBG_COMMON_DWORD_ENABLE_K2,
1321         PCIE_REG_DBG_COMMON_SHIFT_K2,
1322         PCIE_REG_DBG_COMMON_FORCE_VALID_K2,
1323         PCIE_REG_DBG_COMMON_FORCE_FRAME_K2,
1324         false, false, MAX_DBG_RESET_REGS, 0
1325 };
1326
1327 static struct block_defs block_led_defs = {
1328         "led", {false, false}, false, 0,
1329         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1330         0, 0, 0, 0, 0,
1331         true, false, DBG_RESET_REG_MISCS_PL_HV, 14
1332 };
1333
1334 static struct block_defs block_avs_wrap_defs = {
1335         "avs_wrap", {false, false}, false, 0,
1336         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1337         0, 0, 0, 0, 0,
1338         true, false, DBG_RESET_REG_MISCS_PL_UA, 11
1339 };
1340
1341 static struct block_defs block_rgfs_defs = {
1342         "rgfs", {false, false}, false, 0,
1343         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1344         0, 0, 0, 0, 0,
1345         false, false, MAX_DBG_RESET_REGS, 0
1346 };
1347
1348 static struct block_defs block_rgsrc_defs = {
1349         "rgsrc", {false, false}, false, 0,
1350         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1351         0, 0, 0, 0, 0,
1352         false, false, MAX_DBG_RESET_REGS, 0
1353 };
1354
1355 static struct block_defs block_tgfs_defs = {
1356         "tgfs", {false, false}, false, 0,
1357         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1358         0, 0, 0, 0, 0,
1359         false, false, MAX_DBG_RESET_REGS, 0
1360 };
1361
1362 static struct block_defs block_tgsrc_defs = {
1363         "tgsrc", {false, false}, false, 0,
1364         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1365         0, 0, 0, 0, 0,
1366         false, false, MAX_DBG_RESET_REGS, 0
1367 };
1368
1369 static struct block_defs block_ptld_defs = {
1370         "ptld", {false, false}, false, 0,
1371         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1372         0, 0, 0, 0, 0,
1373         false, false, MAX_DBG_RESET_REGS, 0
1374 };
1375
1376 static struct block_defs block_ypld_defs = {
1377         "ypld", {false, false}, false, 0,
1378         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1379         0, 0, 0, 0, 0,
1380         false, false, MAX_DBG_RESET_REGS, 0
1381 };
1382
1383 static struct block_defs block_misc_aeu_defs = {
1384         "misc_aeu", {false, false}, false, 0,
1385         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1386         0, 0, 0, 0, 0,
1387         false, false, MAX_DBG_RESET_REGS, 0
1388 };
1389
1390 static struct block_defs block_bar0_map_defs = {
1391         "bar0_map", {false, false}, false, 0,
1392         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1393         0, 0, 0, 0, 0,
1394         false, false, MAX_DBG_RESET_REGS, 0
1395 };
1396
1397 static struct block_defs *s_block_defs[MAX_BLOCK_ID] = {
1398         &block_grc_defs,
1399         &block_miscs_defs,
1400         &block_misc_defs,
1401         &block_dbu_defs,
1402         &block_pglue_b_defs,
1403         &block_cnig_defs,
1404         &block_cpmu_defs,
1405         &block_ncsi_defs,
1406         &block_opte_defs,
1407         &block_bmb_defs,
1408         &block_pcie_defs,
1409         &block_mcp_defs,
1410         &block_mcp2_defs,
1411         &block_pswhst_defs,
1412         &block_pswhst2_defs,
1413         &block_pswrd_defs,
1414         &block_pswrd2_defs,
1415         &block_pswwr_defs,
1416         &block_pswwr2_defs,
1417         &block_pswrq_defs,
1418         &block_pswrq2_defs,
1419         &block_pglcs_defs,
1420         &block_dmae_defs,
1421         &block_ptu_defs,
1422         &block_tcm_defs,
1423         &block_mcm_defs,
1424         &block_ucm_defs,
1425         &block_xcm_defs,
1426         &block_ycm_defs,
1427         &block_pcm_defs,
1428         &block_qm_defs,
1429         &block_tm_defs,
1430         &block_dorq_defs,
1431         &block_brb_defs,
1432         &block_src_defs,
1433         &block_prs_defs,
1434         &block_tsdm_defs,
1435         &block_msdm_defs,
1436         &block_usdm_defs,
1437         &block_xsdm_defs,
1438         &block_ysdm_defs,
1439         &block_psdm_defs,
1440         &block_tsem_defs,
1441         &block_msem_defs,
1442         &block_usem_defs,
1443         &block_xsem_defs,
1444         &block_ysem_defs,
1445         &block_psem_defs,
1446         &block_rss_defs,
1447         &block_tmld_defs,
1448         &block_muld_defs,
1449         &block_yuld_defs,
1450         &block_xyld_defs,
1451         &block_ptld_defs,
1452         &block_ypld_defs,
1453         &block_prm_defs,
1454         &block_pbf_pb1_defs,
1455         &block_pbf_pb2_defs,
1456         &block_rpb_defs,
1457         &block_btb_defs,
1458         &block_pbf_defs,
1459         &block_rdif_defs,
1460         &block_tdif_defs,
1461         &block_cdu_defs,
1462         &block_ccfc_defs,
1463         &block_tcfc_defs,
1464         &block_igu_defs,
1465         &block_cau_defs,
1466         &block_rgfs_defs,
1467         &block_rgsrc_defs,
1468         &block_tgfs_defs,
1469         &block_tgsrc_defs,
1470         &block_umac_defs,
1471         &block_xmac_defs,
1472         &block_dbg_defs,
1473         &block_nig_defs,
1474         &block_wol_defs,
1475         &block_bmbn_defs,
1476         &block_ipc_defs,
1477         &block_nwm_defs,
1478         &block_nws_defs,
1479         &block_ms_defs,
1480         &block_phy_pcie_defs,
1481         &block_led_defs,
1482         &block_avs_wrap_defs,
1483         &block_misc_aeu_defs,
1484         &block_bar0_map_defs,
1485 };
1486
1487 static struct platform_defs s_platform_defs[] = {
1488         {"asic", 1},
1489         {"reserved", 0},
1490         {"reserved2", 0},
1491         {"reserved3", 0}
1492 };
1493
1494 static struct grc_param_defs s_grc_param_defs[] = {
1495         /* DBG_GRC_PARAM_DUMP_TSTORM */
1496         {{1, 1}, 0, 1, false, 1, 1},
1497
1498         /* DBG_GRC_PARAM_DUMP_MSTORM */
1499         {{1, 1}, 0, 1, false, 1, 1},
1500
1501         /* DBG_GRC_PARAM_DUMP_USTORM */
1502         {{1, 1}, 0, 1, false, 1, 1},
1503
1504         /* DBG_GRC_PARAM_DUMP_XSTORM */
1505         {{1, 1}, 0, 1, false, 1, 1},
1506
1507         /* DBG_GRC_PARAM_DUMP_YSTORM */
1508         {{1, 1}, 0, 1, false, 1, 1},
1509
1510         /* DBG_GRC_PARAM_DUMP_PSTORM */
1511         {{1, 1}, 0, 1, false, 1, 1},
1512
1513         /* DBG_GRC_PARAM_DUMP_REGS */
1514         {{1, 1}, 0, 1, false, 0, 1},
1515
1516         /* DBG_GRC_PARAM_DUMP_RAM */
1517         {{1, 1}, 0, 1, false, 0, 1},
1518
1519         /* DBG_GRC_PARAM_DUMP_PBUF */
1520         {{1, 1}, 0, 1, false, 0, 1},
1521
1522         /* DBG_GRC_PARAM_DUMP_IOR */
1523         {{0, 0}, 0, 1, false, 0, 1},
1524
1525         /* DBG_GRC_PARAM_DUMP_VFC */
1526         {{0, 0}, 0, 1, false, 0, 1},
1527
1528         /* DBG_GRC_PARAM_DUMP_CM_CTX */
1529         {{1, 1}, 0, 1, false, 0, 1},
1530
1531         /* DBG_GRC_PARAM_DUMP_ILT */
1532         {{1, 1}, 0, 1, false, 0, 1},
1533
1534         /* DBG_GRC_PARAM_DUMP_RSS */
1535         {{1, 1}, 0, 1, false, 0, 1},
1536
1537         /* DBG_GRC_PARAM_DUMP_CAU */
1538         {{1, 1}, 0, 1, false, 0, 1},
1539
1540         /* DBG_GRC_PARAM_DUMP_QM */
1541         {{1, 1}, 0, 1, false, 0, 1},
1542
1543         /* DBG_GRC_PARAM_DUMP_MCP */
1544         {{1, 1}, 0, 1, false, 0, 1},
1545
1546         /* DBG_GRC_PARAM_RESERVED */
1547         {{1, 1}, 0, 1, false, 0, 1},
1548
1549         /* DBG_GRC_PARAM_DUMP_CFC */
1550         {{1, 1}, 0, 1, false, 0, 1},
1551
1552         /* DBG_GRC_PARAM_DUMP_IGU */
1553         {{1, 1}, 0, 1, false, 0, 1},
1554
1555         /* DBG_GRC_PARAM_DUMP_BRB */
1556         {{0, 0}, 0, 1, false, 0, 1},
1557
1558         /* DBG_GRC_PARAM_DUMP_BTB */
1559         {{0, 0}, 0, 1, false, 0, 1},
1560
1561         /* DBG_GRC_PARAM_DUMP_BMB */
1562         {{0, 0}, 0, 1, false, 0, 1},
1563
1564         /* DBG_GRC_PARAM_DUMP_NIG */
1565         {{1, 1}, 0, 1, false, 0, 1},
1566
1567         /* DBG_GRC_PARAM_DUMP_MULD */
1568         {{1, 1}, 0, 1, false, 0, 1},
1569
1570         /* DBG_GRC_PARAM_DUMP_PRS */
1571         {{1, 1}, 0, 1, false, 0, 1},
1572
1573         /* DBG_GRC_PARAM_DUMP_DMAE */
1574         {{1, 1}, 0, 1, false, 0, 1},
1575
1576         /* DBG_GRC_PARAM_DUMP_TM */
1577         {{1, 1}, 0, 1, false, 0, 1},
1578
1579         /* DBG_GRC_PARAM_DUMP_SDM */
1580         {{1, 1}, 0, 1, false, 0, 1},
1581
1582         /* DBG_GRC_PARAM_DUMP_DIF */
1583         {{1, 1}, 0, 1, false, 0, 1},
1584
1585         /* DBG_GRC_PARAM_DUMP_STATIC */
1586         {{1, 1}, 0, 1, false, 0, 1},
1587
1588         /* DBG_GRC_PARAM_UNSTALL */
1589         {{0, 0}, 0, 1, false, 0, 0},
1590
1591         /* DBG_GRC_PARAM_NUM_LCIDS */
1592         {{MAX_LCIDS, MAX_LCIDS}, 1, MAX_LCIDS, false, MAX_LCIDS,
1593          MAX_LCIDS},
1594
1595         /* DBG_GRC_PARAM_NUM_LTIDS */
1596         {{MAX_LTIDS, MAX_LTIDS}, 1, MAX_LTIDS, false, MAX_LTIDS,
1597          MAX_LTIDS},
1598
1599         /* DBG_GRC_PARAM_EXCLUDE_ALL */
1600         {{0, 0}, 0, 1, true, 0, 0},
1601
1602         /* DBG_GRC_PARAM_CRASH */
1603         {{0, 0}, 0, 1, true, 0, 0},
1604
1605         /* DBG_GRC_PARAM_PARITY_SAFE */
1606         {{0, 0}, 0, 1, false, 1, 0},
1607
1608         /* DBG_GRC_PARAM_DUMP_CM */
1609         {{1, 1}, 0, 1, false, 0, 1},
1610
1611         /* DBG_GRC_PARAM_DUMP_PHY */
1612         {{1, 1}, 0, 1, false, 0, 1},
1613
1614         /* DBG_GRC_PARAM_NO_MCP */
1615         {{0, 0}, 0, 1, false, 0, 0},
1616
1617         /* DBG_GRC_PARAM_NO_FW_VER */
1618         {{0, 0}, 0, 1, false, 0, 0}
1619 };
1620
1621 static struct rss_mem_defs s_rss_mem_defs[] = {
1622         { "rss_mem_cid", "rss_cid", 0,
1623           {256, 320},
1624           {32, 32} },
1625
1626         { "rss_mem_key_msb", "rss_key", 1024,
1627           {128, 208},
1628           {256, 256} },
1629
1630         { "rss_mem_key_lsb", "rss_key", 2048,
1631           {128, 208},
1632           {64, 64} },
1633
1634         { "rss_mem_info", "rss_info", 3072,
1635           {128, 208},
1636           {16, 16} },
1637
1638         { "rss_mem_ind", "rss_ind", 4096,
1639           {16384, 26624},
1640           {16, 16} }
1641 };
1642
1643 static struct vfc_ram_defs s_vfc_ram_defs[] = {
1644         {"vfc_ram_tt1", "vfc_ram", 0, 512},
1645         {"vfc_ram_mtt2", "vfc_ram", 512, 128},
1646         {"vfc_ram_stt2", "vfc_ram", 640, 32},
1647         {"vfc_ram_ro_vect", "vfc_ram", 672, 32}
1648 };
1649
1650 static struct big_ram_defs s_big_ram_defs[] = {
1651         { "BRB", MEM_GROUP_BRB_MEM, MEM_GROUP_BRB_RAM, DBG_GRC_PARAM_DUMP_BRB,
1652           BRB_REG_BIG_RAM_ADDRESS, BRB_REG_BIG_RAM_DATA,
1653           {4800, 5632} },
1654
1655         { "BTB", MEM_GROUP_BTB_MEM, MEM_GROUP_BTB_RAM, DBG_GRC_PARAM_DUMP_BTB,
1656           BTB_REG_BIG_RAM_ADDRESS, BTB_REG_BIG_RAM_DATA,
1657           {2880, 3680} },
1658
1659         { "BMB", MEM_GROUP_BMB_MEM, MEM_GROUP_BMB_RAM, DBG_GRC_PARAM_DUMP_BMB,
1660           BMB_REG_BIG_RAM_ADDRESS, BMB_REG_BIG_RAM_DATA,
1661           {1152, 1152} }
1662 };
1663
1664 static struct reset_reg_defs s_reset_regs_defs[] = {
1665         /* DBG_RESET_REG_MISCS_PL_UA */
1666         { MISCS_REG_RESET_PL_UA, 0x0,
1667           {true, true} },
1668
1669         /* DBG_RESET_REG_MISCS_PL_HV */
1670         { MISCS_REG_RESET_PL_HV, 0x0,
1671           {true, true} },
1672
1673         /* DBG_RESET_REG_MISCS_PL_HV_2 */
1674         { MISCS_REG_RESET_PL_HV_2_K2, 0x0,
1675           {false, true} },
1676
1677         /* DBG_RESET_REG_MISC_PL_UA */
1678         { MISC_REG_RESET_PL_UA, 0x0,
1679           {true, true} },
1680
1681         /* DBG_RESET_REG_MISC_PL_HV */
1682         { MISC_REG_RESET_PL_HV, 0x0,
1683           {true, true} },
1684
1685         /* DBG_RESET_REG_MISC_PL_PDA_VMAIN_1 */
1686         { MISC_REG_RESET_PL_PDA_VMAIN_1, 0x4404040,
1687           {true, true} },
1688
1689         /* DBG_RESET_REG_MISC_PL_PDA_VMAIN_2 */
1690         { MISC_REG_RESET_PL_PDA_VMAIN_2, 0x7c00007,
1691           {true, true} },
1692
1693         /* DBG_RESET_REG_MISC_PL_PDA_VAUX */
1694         { MISC_REG_RESET_PL_PDA_VAUX, 0x2,
1695           {true, true} },
1696 };
1697
1698 static struct phy_defs s_phy_defs[] = {
1699         {"nw_phy", NWS_REG_NWS_CMU_K2,
1700          PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_7_0_K2,
1701          PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_15_8_K2,
1702          PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_7_0_K2,
1703          PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_11_8_K2},
1704         {"sgmii_phy", MS_REG_MS_CMU_K2,
1705          PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X132_K2,
1706          PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X133_K2,
1707          PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X130_K2,
1708          PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X131_K2},
1709         {"pcie_phy0", PHY_PCIE_REG_PHY0_K2,
1710          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2,
1711          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2,
1712          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2,
1713          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2},
1714         {"pcie_phy1", PHY_PCIE_REG_PHY1_K2,
1715          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2,
1716          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2,
1717          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2,
1718          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2},
1719 };
1720
1721 /**************************** Private Functions ******************************/
1722
1723 /* Reads and returns a single dword from the specified unaligned buffer */
1724 static u32 qed_read_unaligned_dword(u8 *buf)
1725 {
1726         u32 dword;
1727
1728         memcpy((u8 *)&dword, buf, sizeof(dword));
1729         return dword;
1730 }
1731
1732 /* Returns the value of the specified GRC param */
1733 static u32 qed_grc_get_param(struct qed_hwfn *p_hwfn,
1734                              enum dbg_grc_params grc_param)
1735 {
1736         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1737
1738         return dev_data->grc.param_val[grc_param];
1739 }
1740
1741 /* Initializes the GRC parameters */
1742 static void qed_dbg_grc_init_params(struct qed_hwfn *p_hwfn)
1743 {
1744         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1745
1746         if (!dev_data->grc.params_initialized) {
1747                 qed_dbg_grc_set_params_default(p_hwfn);
1748                 dev_data->grc.params_initialized = 1;
1749         }
1750 }
1751
1752 /* Initializes debug data for the specified device */
1753 static enum dbg_status qed_dbg_dev_init(struct qed_hwfn *p_hwfn,
1754                                         struct qed_ptt *p_ptt)
1755 {
1756         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1757
1758         if (dev_data->initialized)
1759                 return DBG_STATUS_OK;
1760
1761         if (QED_IS_K2(p_hwfn->cdev)) {
1762                 dev_data->chip_id = CHIP_K2;
1763                 dev_data->mode_enable[MODE_K2] = 1;
1764         } else if (QED_IS_BB_B0(p_hwfn->cdev)) {
1765                 dev_data->chip_id = CHIP_BB;
1766                 dev_data->mode_enable[MODE_BB] = 1;
1767         } else {
1768                 return DBG_STATUS_UNKNOWN_CHIP;
1769         }
1770
1771         dev_data->platform_id = PLATFORM_ASIC;
1772         dev_data->mode_enable[MODE_ASIC] = 1;
1773
1774         /* Initializes the GRC parameters */
1775         qed_dbg_grc_init_params(p_hwfn);
1776
1777         dev_data->initialized = true;
1778
1779         return DBG_STATUS_OK;
1780 }
1781
1782 static struct dbg_bus_block *get_dbg_bus_block_desc(struct qed_hwfn *p_hwfn,
1783                                                     enum block_id block_id)
1784 {
1785         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1786
1787         return (struct dbg_bus_block *)&dbg_bus_blocks[block_id *
1788                                                        MAX_CHIP_IDS +
1789                                                        dev_data->chip_id];
1790 }
1791
1792 /* Reads the FW info structure for the specified Storm from the chip,
1793  * and writes it to the specified fw_info pointer.
1794  */
1795 static void qed_read_fw_info(struct qed_hwfn *p_hwfn,
1796                              struct qed_ptt *p_ptt,
1797                              u8 storm_id, struct fw_info *fw_info)
1798 {
1799         struct storm_defs *storm = &s_storm_defs[storm_id];
1800         struct fw_info_location fw_info_location;
1801         u32 addr, i, *dest;
1802
1803         memset(&fw_info_location, 0, sizeof(fw_info_location));
1804         memset(fw_info, 0, sizeof(*fw_info));
1805
1806         /* Read first the address that points to fw_info location.
1807          * The address is located in the last line of the Storm RAM.
1808          */
1809         addr = storm->sem_fast_mem_addr + SEM_FAST_REG_INT_RAM +
1810                DWORDS_TO_BYTES(SEM_FAST_REG_INT_RAM_SIZE) -
1811                sizeof(fw_info_location);
1812         dest = (u32 *)&fw_info_location;
1813
1814         for (i = 0; i < BYTES_TO_DWORDS(sizeof(fw_info_location));
1815              i++, addr += BYTES_IN_DWORD)
1816                 dest[i] = qed_rd(p_hwfn, p_ptt, addr);
1817
1818         /* Read FW version info from Storm RAM */
1819         if (fw_info_location.size > 0 && fw_info_location.size <=
1820             sizeof(*fw_info)) {
1821                 addr = fw_info_location.grc_addr;
1822                 dest = (u32 *)fw_info;
1823                 for (i = 0; i < BYTES_TO_DWORDS(fw_info_location.size);
1824                      i++, addr += BYTES_IN_DWORD)
1825                         dest[i] = qed_rd(p_hwfn, p_ptt, addr);
1826         }
1827 }
1828
1829 /* Dumps the specified string to the specified buffer.
1830  * Returns the dumped size in bytes.
1831  */
1832 static u32 qed_dump_str(char *dump_buf, bool dump, const char *str)
1833 {
1834         if (dump)
1835                 strcpy(dump_buf, str);
1836
1837         return (u32)strlen(str) + 1;
1838 }
1839
1840 /* Dumps zeros to align the specified buffer to dwords.
1841  * Returns the dumped size in bytes.
1842  */
1843 static u32 qed_dump_align(char *dump_buf, bool dump, u32 byte_offset)
1844 {
1845         u8 offset_in_dword, align_size;
1846
1847         offset_in_dword = (u8)(byte_offset & 0x3);
1848         align_size = offset_in_dword ? BYTES_IN_DWORD - offset_in_dword : 0;
1849
1850         if (dump && align_size)
1851                 memset(dump_buf, 0, align_size);
1852
1853         return align_size;
1854 }
1855
1856 /* Writes the specified string param to the specified buffer.
1857  * Returns the dumped size in dwords.
1858  */
1859 static u32 qed_dump_str_param(u32 *dump_buf,
1860                               bool dump,
1861                               const char *param_name, const char *param_val)
1862 {
1863         char *char_buf = (char *)dump_buf;
1864         u32 offset = 0;
1865
1866         /* Dump param name */
1867         offset += qed_dump_str(char_buf + offset, dump, param_name);
1868
1869         /* Indicate a string param value */
1870         if (dump)
1871                 *(char_buf + offset) = 1;
1872         offset++;
1873
1874         /* Dump param value */
1875         offset += qed_dump_str(char_buf + offset, dump, param_val);
1876
1877         /* Align buffer to next dword */
1878         offset += qed_dump_align(char_buf + offset, dump, offset);
1879
1880         return BYTES_TO_DWORDS(offset);
1881 }
1882
1883 /* Writes the specified numeric param to the specified buffer.
1884  * Returns the dumped size in dwords.
1885  */
1886 static u32 qed_dump_num_param(u32 *dump_buf,
1887                               bool dump, const char *param_name, u32 param_val)
1888 {
1889         char *char_buf = (char *)dump_buf;
1890         u32 offset = 0;
1891
1892         /* Dump param name */
1893         offset += qed_dump_str(char_buf + offset, dump, param_name);
1894
1895         /* Indicate a numeric param value */
1896         if (dump)
1897                 *(char_buf + offset) = 0;
1898         offset++;
1899
1900         /* Align buffer to next dword */
1901         offset += qed_dump_align(char_buf + offset, dump, offset);
1902
1903         /* Dump param value (and change offset from bytes to dwords) */
1904         offset = BYTES_TO_DWORDS(offset);
1905         if (dump)
1906                 *(dump_buf + offset) = param_val;
1907         offset++;
1908
1909         return offset;
1910 }
1911
1912 /* Reads the FW version and writes it as a param to the specified buffer.
1913  * Returns the dumped size in dwords.
1914  */
1915 static u32 qed_dump_fw_ver_param(struct qed_hwfn *p_hwfn,
1916                                  struct qed_ptt *p_ptt,
1917                                  u32 *dump_buf, bool dump)
1918 {
1919         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1920         char fw_ver_str[16] = EMPTY_FW_VERSION_STR;
1921         char fw_img_str[16] = EMPTY_FW_IMAGE_STR;
1922         struct fw_info fw_info = { {0}, {0} };
1923         u32 offset = 0;
1924
1925         if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {
1926                 /* Read FW image/version from PRAM in a non-reset SEMI */
1927                 bool found = false;
1928                 u8 storm_id;
1929
1930                 for (storm_id = 0; storm_id < MAX_DBG_STORMS && !found;
1931                      storm_id++) {
1932                         struct storm_defs *storm = &s_storm_defs[storm_id];
1933
1934                         /* Read FW version/image */
1935                         if (dev_data->block_in_reset[storm->block_id])
1936                                 continue;
1937
1938                         /* Read FW info for the current Storm */
1939                         qed_read_fw_info(p_hwfn, p_ptt, storm_id, &fw_info);
1940
1941                         /* Create FW version/image strings */
1942                         if (snprintf(fw_ver_str, sizeof(fw_ver_str),
1943                                      "%d_%d_%d_%d", fw_info.ver.num.major,
1944                                      fw_info.ver.num.minor, fw_info.ver.num.rev,
1945                                      fw_info.ver.num.eng) < 0)
1946                                 DP_NOTICE(p_hwfn,
1947                                           "Unexpected debug error: invalid FW version string\n");
1948                         switch (fw_info.ver.image_id) {
1949                         case FW_IMG_MAIN:
1950                                 strcpy(fw_img_str, "main");
1951                                 break;
1952                         default:
1953                                 strcpy(fw_img_str, "unknown");
1954                                 break;
1955                         }
1956
1957                         found = true;
1958                 }
1959         }
1960
1961         /* Dump FW version, image and timestamp */
1962         offset += qed_dump_str_param(dump_buf + offset,
1963                                      dump, "fw-version", fw_ver_str);
1964         offset += qed_dump_str_param(dump_buf + offset,
1965                                      dump, "fw-image", fw_img_str);
1966         offset += qed_dump_num_param(dump_buf + offset,
1967                                      dump,
1968                                      "fw-timestamp", fw_info.ver.timestamp);
1969
1970         return offset;
1971 }
1972
1973 /* Reads the MFW version and writes it as a param to the specified buffer.
1974  * Returns the dumped size in dwords.
1975  */
1976 static u32 qed_dump_mfw_ver_param(struct qed_hwfn *p_hwfn,
1977                                   struct qed_ptt *p_ptt,
1978                                   u32 *dump_buf, bool dump)
1979 {
1980         char mfw_ver_str[16] = EMPTY_FW_VERSION_STR;
1981
1982         if (dump &&
1983             !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {
1984                 u32 global_section_offsize, global_section_addr, mfw_ver;
1985                 u32 public_data_addr, global_section_offsize_addr;
1986
1987                 /* Find MCP public data GRC address. Needs to be ORed with
1988                  * MCP_REG_SCRATCH due to a HW bug.
1989                  */
1990                 public_data_addr = qed_rd(p_hwfn,
1991                                           p_ptt,
1992                                           MISC_REG_SHARED_MEM_ADDR) |
1993                                    MCP_REG_SCRATCH;
1994
1995                 /* Find MCP public global section offset */
1996                 global_section_offsize_addr = public_data_addr +
1997                                               offsetof(struct mcp_public_data,
1998                                                        sections) +
1999                                               sizeof(offsize_t) * PUBLIC_GLOBAL;
2000                 global_section_offsize = qed_rd(p_hwfn, p_ptt,
2001                                                 global_section_offsize_addr);
2002                 global_section_addr =
2003                         MCP_REG_SCRATCH +
2004                         (global_section_offsize & OFFSIZE_OFFSET_MASK) * 4;
2005
2006                 /* Read MFW version from MCP public global section */
2007                 mfw_ver = qed_rd(p_hwfn, p_ptt,
2008                                  global_section_addr +
2009                                  offsetof(struct public_global, mfw_ver));
2010
2011                 /* Dump MFW version param */
2012                 if (snprintf(mfw_ver_str, sizeof(mfw_ver_str), "%d_%d_%d_%d",
2013                              (u8)(mfw_ver >> 24), (u8)(mfw_ver >> 16),
2014                              (u8)(mfw_ver >> 8), (u8)mfw_ver) < 0)
2015                         DP_NOTICE(p_hwfn,
2016                                   "Unexpected debug error: invalid MFW version string\n");
2017         }
2018
2019         return qed_dump_str_param(dump_buf, dump, "mfw-version", mfw_ver_str);
2020 }
2021
2022 /* Writes a section header to the specified buffer.
2023  * Returns the dumped size in dwords.
2024  */
2025 static u32 qed_dump_section_hdr(u32 *dump_buf,
2026                                 bool dump, const char *name, u32 num_params)
2027 {
2028         return qed_dump_num_param(dump_buf, dump, name, num_params);
2029 }
2030
2031 /* Writes the common global params to the specified buffer.
2032  * Returns the dumped size in dwords.
2033  */
2034 static u32 qed_dump_common_global_params(struct qed_hwfn *p_hwfn,
2035                                          struct qed_ptt *p_ptt,
2036                                          u32 *dump_buf,
2037                                          bool dump,
2038                                          u8 num_specific_global_params)
2039 {
2040         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2041         u32 offset = 0;
2042         u8 num_params;
2043
2044         /* Dump global params section header */
2045         num_params = NUM_COMMON_GLOBAL_PARAMS + num_specific_global_params;
2046         offset += qed_dump_section_hdr(dump_buf + offset,
2047                                        dump, "global_params", num_params);
2048
2049         /* Store params */
2050         offset += qed_dump_fw_ver_param(p_hwfn, p_ptt, dump_buf + offset, dump);
2051         offset += qed_dump_mfw_ver_param(p_hwfn,
2052                                          p_ptt, dump_buf + offset, dump);
2053         offset += qed_dump_num_param(dump_buf + offset,
2054                                      dump, "tools-version", TOOLS_VERSION);
2055         offset += qed_dump_str_param(dump_buf + offset,
2056                                      dump,
2057                                      "chip",
2058                                      s_chip_defs[dev_data->chip_id].name);
2059         offset += qed_dump_str_param(dump_buf + offset,
2060                                      dump,
2061                                      "platform",
2062                                      s_platform_defs[dev_data->platform_id].
2063                                      name);
2064         offset +=
2065             qed_dump_num_param(dump_buf + offset, dump, "pci-func",
2066                                p_hwfn->abs_pf_id);
2067
2068         return offset;
2069 }
2070
2071 /* Writes the "last" section (including CRC) to the specified buffer at the
2072  * given offset. Returns the dumped size in dwords.
2073  */
2074 static u32 qed_dump_last_section(struct qed_hwfn *p_hwfn,
2075                                  u32 *dump_buf, u32 offset, bool dump)
2076 {
2077         u32 start_offset = offset;
2078
2079         /* Dump CRC section header */
2080         offset += qed_dump_section_hdr(dump_buf + offset, dump, "last", 0);
2081
2082         /* Calculate CRC32 and add it to the dword after the "last" section */
2083         if (dump)
2084                 *(dump_buf + offset) = ~crc32(0xffffffff,
2085                                               (u8 *)dump_buf,
2086                                               DWORDS_TO_BYTES(offset));
2087
2088         offset++;
2089
2090         return offset - start_offset;
2091 }
2092
2093 /* Update blocks reset state  */
2094 static void qed_update_blocks_reset_state(struct qed_hwfn *p_hwfn,
2095                                           struct qed_ptt *p_ptt)
2096 {
2097         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2098         u32 reg_val[MAX_DBG_RESET_REGS] = { 0 };
2099         u32 i;
2100
2101         /* Read reset registers */
2102         for (i = 0; i < MAX_DBG_RESET_REGS; i++)
2103                 if (s_reset_regs_defs[i].exists[dev_data->chip_id])
2104                         reg_val[i] = qed_rd(p_hwfn,
2105                                             p_ptt, s_reset_regs_defs[i].addr);
2106
2107         /* Check if blocks are in reset */
2108         for (i = 0; i < MAX_BLOCK_ID; i++) {
2109                 struct block_defs *block = s_block_defs[i];
2110
2111                 dev_data->block_in_reset[i] = block->has_reset_bit &&
2112                     !(reg_val[block->reset_reg] & BIT(block->reset_bit_offset));
2113         }
2114 }
2115
2116 /* Enable / disable the Debug block */
2117 static void qed_bus_enable_dbg_block(struct qed_hwfn *p_hwfn,
2118                                      struct qed_ptt *p_ptt, bool enable)
2119 {
2120         qed_wr(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON, enable ? 1 : 0);
2121 }
2122
2123 /* Resets the Debug block */
2124 static void qed_bus_reset_dbg_block(struct qed_hwfn *p_hwfn,
2125                                     struct qed_ptt *p_ptt)
2126 {
2127         u32 dbg_reset_reg_addr, old_reset_reg_val, new_reset_reg_val;
2128         struct block_defs *dbg_block = s_block_defs[BLOCK_DBG];
2129
2130         dbg_reset_reg_addr = s_reset_regs_defs[dbg_block->reset_reg].addr;
2131         old_reset_reg_val = qed_rd(p_hwfn, p_ptt, dbg_reset_reg_addr);
2132         new_reset_reg_val =
2133             old_reset_reg_val & ~BIT(dbg_block->reset_bit_offset);
2134
2135         qed_wr(p_hwfn, p_ptt, dbg_reset_reg_addr, new_reset_reg_val);
2136         qed_wr(p_hwfn, p_ptt, dbg_reset_reg_addr, old_reset_reg_val);
2137 }
2138
2139 static void qed_bus_set_framing_mode(struct qed_hwfn *p_hwfn,
2140                                      struct qed_ptt *p_ptt,
2141                                      enum dbg_bus_frame_modes mode)
2142 {
2143         qed_wr(p_hwfn, p_ptt, DBG_REG_FRAMING_MODE, (u8)mode);
2144 }
2145
2146 /* Enable / disable Debug Bus clients according to the specified mask
2147  * (1 = enable, 0 = disable).
2148  */
2149 static void qed_bus_enable_clients(struct qed_hwfn *p_hwfn,
2150                                    struct qed_ptt *p_ptt, u32 client_mask)
2151 {
2152         qed_wr(p_hwfn, p_ptt, DBG_REG_CLIENT_ENABLE, client_mask);
2153 }
2154
2155 static bool qed_is_mode_match(struct qed_hwfn *p_hwfn, u16 *modes_buf_offset)
2156 {
2157         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2158         bool arg1, arg2;
2159         const u32 *ptr;
2160         u8 tree_val;
2161
2162         /* Get next element from modes tree buffer */
2163         ptr = s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr;
2164         tree_val = ((u8 *)ptr)[(*modes_buf_offset)++];
2165
2166         switch (tree_val) {
2167         case INIT_MODE_OP_NOT:
2168                 return !qed_is_mode_match(p_hwfn, modes_buf_offset);
2169         case INIT_MODE_OP_OR:
2170         case INIT_MODE_OP_AND:
2171                 arg1 = qed_is_mode_match(p_hwfn, modes_buf_offset);
2172                 arg2 = qed_is_mode_match(p_hwfn, modes_buf_offset);
2173                 return (tree_val == INIT_MODE_OP_OR) ? (arg1 ||
2174                                                         arg2) : (arg1 && arg2);
2175         default:
2176                 return dev_data->mode_enable[tree_val - MAX_INIT_MODE_OPS] > 0;
2177         }
2178 }
2179
2180 /* Returns true if the specified entity (indicated by GRC param) should be
2181  * included in the dump, false otherwise.
2182  */
2183 static bool qed_grc_is_included(struct qed_hwfn *p_hwfn,
2184                                 enum dbg_grc_params grc_param)
2185 {
2186         return qed_grc_get_param(p_hwfn, grc_param) > 0;
2187 }
2188
2189 /* Returns true of the specified Storm should be included in the dump, false
2190  * otherwise.
2191  */
2192 static bool qed_grc_is_storm_included(struct qed_hwfn *p_hwfn,
2193                                       enum dbg_storms storm)
2194 {
2195         return qed_grc_get_param(p_hwfn, (enum dbg_grc_params)storm) > 0;
2196 }
2197
2198 /* Returns true if the specified memory should be included in the dump, false
2199  * otherwise.
2200  */
2201 static bool qed_grc_is_mem_included(struct qed_hwfn *p_hwfn,
2202                                     enum block_id block_id, u8 mem_group_id)
2203 {
2204         struct block_defs *block = s_block_defs[block_id];
2205         u8 i;
2206
2207         /* Check Storm match */
2208         if (block->associated_to_storm &&
2209             !qed_grc_is_storm_included(p_hwfn,
2210                                        (enum dbg_storms)block->storm_id))
2211                 return false;
2212
2213         for (i = 0; i < NUM_BIG_RAM_TYPES; i++) {
2214                 struct big_ram_defs *big_ram = &s_big_ram_defs[i];
2215
2216                 if (mem_group_id == big_ram->mem_group_id ||
2217                     mem_group_id == big_ram->ram_mem_group_id)
2218                         return qed_grc_is_included(p_hwfn, big_ram->grc_param);
2219         }
2220
2221         switch (mem_group_id) {
2222         case MEM_GROUP_PXP_ILT:
2223         case MEM_GROUP_PXP_MEM:
2224                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PXP);
2225         case MEM_GROUP_RAM:
2226                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RAM);
2227         case MEM_GROUP_PBUF:
2228                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PBUF);
2229         case MEM_GROUP_CAU_MEM:
2230         case MEM_GROUP_CAU_SB:
2231         case MEM_GROUP_CAU_PI:
2232                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU);
2233         case MEM_GROUP_QM_MEM:
2234                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_QM);
2235         case MEM_GROUP_CFC_MEM:
2236         case MEM_GROUP_CONN_CFC_MEM:
2237         case MEM_GROUP_TASK_CFC_MEM:
2238                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CFC);
2239         case MEM_GROUP_IGU_MEM:
2240         case MEM_GROUP_IGU_MSIX:
2241                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IGU);
2242         case MEM_GROUP_MULD_MEM:
2243                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MULD);
2244         case MEM_GROUP_PRS_MEM:
2245                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PRS);
2246         case MEM_GROUP_DMAE_MEM:
2247                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DMAE);
2248         case MEM_GROUP_TM_MEM:
2249                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_TM);
2250         case MEM_GROUP_SDM_MEM:
2251                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_SDM);
2252         case MEM_GROUP_TDIF_CTX:
2253         case MEM_GROUP_RDIF_CTX:
2254                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DIF);
2255         case MEM_GROUP_CM_MEM:
2256                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM);
2257         case MEM_GROUP_IOR:
2258                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IOR);
2259         default:
2260                 return true;
2261         }
2262 }
2263
2264 /* Stalls all Storms */
2265 static void qed_grc_stall_storms(struct qed_hwfn *p_hwfn,
2266                                  struct qed_ptt *p_ptt, bool stall)
2267 {
2268         u32 reg_addr;
2269         u8 storm_id;
2270
2271         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
2272                 if (!qed_grc_is_storm_included(p_hwfn,
2273                                                (enum dbg_storms)storm_id))
2274                         continue;
2275
2276                 reg_addr = s_storm_defs[storm_id].sem_fast_mem_addr +
2277                     SEM_FAST_REG_STALL_0_BB_K2;
2278                 qed_wr(p_hwfn, p_ptt, reg_addr, stall ? 1 : 0);
2279         }
2280
2281         msleep(STALL_DELAY_MS);
2282 }
2283
2284 /* Takes all blocks out of reset */
2285 static void qed_grc_unreset_blocks(struct qed_hwfn *p_hwfn,
2286                                    struct qed_ptt *p_ptt)
2287 {
2288         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2289         u32 reg_val[MAX_DBG_RESET_REGS] = { 0 };
2290         u32 block_id, i;
2291
2292         /* Fill reset regs values */
2293         for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
2294                 struct block_defs *block = s_block_defs[block_id];
2295
2296                 if (block->has_reset_bit && block->unreset)
2297                         reg_val[block->reset_reg] |=
2298                             BIT(block->reset_bit_offset);
2299         }
2300
2301         /* Write reset registers */
2302         for (i = 0; i < MAX_DBG_RESET_REGS; i++) {
2303                 if (!s_reset_regs_defs[i].exists[dev_data->chip_id])
2304                         continue;
2305
2306                 reg_val[i] |= s_reset_regs_defs[i].unreset_val;
2307
2308                 if (reg_val[i])
2309                         qed_wr(p_hwfn,
2310                                p_ptt,
2311                                s_reset_regs_defs[i].addr +
2312                                RESET_REG_UNRESET_OFFSET, reg_val[i]);
2313         }
2314 }
2315
2316 /* Returns the attention block data of the specified block */
2317 static const struct dbg_attn_block_type_data *
2318 qed_get_block_attn_data(enum block_id block_id, enum dbg_attn_type attn_type)
2319 {
2320         const struct dbg_attn_block *base_attn_block_arr =
2321                 (const struct dbg_attn_block *)
2322                 s_dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr;
2323
2324         return &base_attn_block_arr[block_id].per_type_data[attn_type];
2325 }
2326
2327 /* Returns the attention registers of the specified block */
2328 static const struct dbg_attn_reg *
2329 qed_get_block_attn_regs(enum block_id block_id, enum dbg_attn_type attn_type,
2330                         u8 *num_attn_regs)
2331 {
2332         const struct dbg_attn_block_type_data *block_type_data =
2333                 qed_get_block_attn_data(block_id, attn_type);
2334
2335         *num_attn_regs = block_type_data->num_regs;
2336
2337         return &((const struct dbg_attn_reg *)
2338                  s_dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)[block_type_data->
2339                                                           regs_offset];
2340 }
2341
2342 /* For each block, clear the status of all parities */
2343 static void qed_grc_clear_all_prty(struct qed_hwfn *p_hwfn,
2344                                    struct qed_ptt *p_ptt)
2345 {
2346         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2347         const struct dbg_attn_reg *attn_reg_arr;
2348         u8 reg_idx, num_attn_regs;
2349         u32 block_id;
2350
2351         for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
2352                 if (dev_data->block_in_reset[block_id])
2353                         continue;
2354
2355                 attn_reg_arr = qed_get_block_attn_regs((enum block_id)block_id,
2356                                                        ATTN_TYPE_PARITY,
2357                                                        &num_attn_regs);
2358
2359                 for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
2360                         const struct dbg_attn_reg *reg_data =
2361                                 &attn_reg_arr[reg_idx];
2362                         u16 modes_buf_offset;
2363                         bool eval_mode;
2364
2365                         /* Check mode */
2366                         eval_mode = GET_FIELD(reg_data->mode.data,
2367                                               DBG_MODE_HDR_EVAL_MODE) > 0;
2368                         modes_buf_offset =
2369                                 GET_FIELD(reg_data->mode.data,
2370                                           DBG_MODE_HDR_MODES_BUF_OFFSET);
2371
2372                         /* If Mode match: clear parity status */
2373                         if (!eval_mode ||
2374                             qed_is_mode_match(p_hwfn, &modes_buf_offset))
2375                                 qed_rd(p_hwfn, p_ptt,
2376                                        DWORDS_TO_BYTES(reg_data->
2377                                                        sts_clr_address));
2378                 }
2379         }
2380 }
2381
2382 /* Dumps GRC registers section header. Returns the dumped size in dwords.
2383  * The following parameters are dumped:
2384  * - count:      no. of dumped entries
2385  * - split:      split type
2386  * - id:         split ID (dumped only if split_id >= 0)
2387  * - param_name: user parameter value (dumped only if param_name != NULL
2388  *               and param_val != NULL).
2389  */
2390 static u32 qed_grc_dump_regs_hdr(u32 *dump_buf,
2391                                  bool dump,
2392                                  u32 num_reg_entries,
2393                                  const char *split_type,
2394                                  int split_id,
2395                                  const char *param_name, const char *param_val)
2396 {
2397         u8 num_params = 2 + (split_id >= 0 ? 1 : 0) + (param_name ? 1 : 0);
2398         u32 offset = 0;
2399
2400         offset += qed_dump_section_hdr(dump_buf + offset,
2401                                        dump, "grc_regs", num_params);
2402         offset += qed_dump_num_param(dump_buf + offset,
2403                                      dump, "count", num_reg_entries);
2404         offset += qed_dump_str_param(dump_buf + offset,
2405                                      dump, "split", split_type);
2406         if (split_id >= 0)
2407                 offset += qed_dump_num_param(dump_buf + offset,
2408                                              dump, "id", split_id);
2409         if (param_name && param_val)
2410                 offset += qed_dump_str_param(dump_buf + offset,
2411                                              dump, param_name, param_val);
2412
2413         return offset;
2414 }
2415
2416 /* Dumps the GRC registers in the specified address range.
2417  * Returns the dumped size in dwords.
2418  * The addr and len arguments are specified in dwords.
2419  */
2420 static u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn,
2421                                    struct qed_ptt *p_ptt,
2422                                    u32 *dump_buf,
2423                                    bool dump, u32 addr, u32 len, bool wide_bus)
2424 {
2425         u32 byte_addr = DWORDS_TO_BYTES(addr), offset = 0, i;
2426
2427         if (!dump)
2428                 return len;
2429
2430         for (i = 0; i < len; i++, byte_addr += BYTES_IN_DWORD, offset++)
2431                 *(dump_buf + offset) = qed_rd(p_hwfn, p_ptt, byte_addr);
2432
2433         return offset;
2434 }
2435
2436 /* Dumps GRC registers sequence header. Returns the dumped size in dwords.
2437  * The addr and len arguments are specified in dwords.
2438  */
2439 static u32 qed_grc_dump_reg_entry_hdr(u32 *dump_buf,
2440                                       bool dump, u32 addr, u32 len)
2441 {
2442         if (dump)
2443                 *dump_buf = addr | (len << REG_DUMP_LEN_SHIFT);
2444
2445         return 1;
2446 }
2447
2448 /* Dumps GRC registers sequence. Returns the dumped size in dwords.
2449  * The addr and len arguments are specified in dwords.
2450  */
2451 static u32 qed_grc_dump_reg_entry(struct qed_hwfn *p_hwfn,
2452                                   struct qed_ptt *p_ptt,
2453                                   u32 *dump_buf,
2454                                   bool dump, u32 addr, u32 len, bool wide_bus)
2455 {
2456         u32 offset = 0;
2457
2458         offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, len);
2459         offset += qed_grc_dump_addr_range(p_hwfn,
2460                                           p_ptt,
2461                                           dump_buf + offset,
2462                                           dump, addr, len, wide_bus);
2463
2464         return offset;
2465 }
2466
2467 /* Dumps GRC registers sequence with skip cycle.
2468  * Returns the dumped size in dwords.
2469  * - addr:      start GRC address in dwords
2470  * - total_len: total no. of dwords to dump
2471  * - read_len:  no. consecutive dwords to read
2472  * - skip_len:  no. of dwords to skip (and fill with zeros)
2473  */
2474 static u32 qed_grc_dump_reg_entry_skip(struct qed_hwfn *p_hwfn,
2475                                        struct qed_ptt *p_ptt,
2476                                        u32 *dump_buf,
2477                                        bool dump,
2478                                        u32 addr,
2479                                        u32 total_len,
2480                                        u32 read_len, u32 skip_len)
2481 {
2482         u32 offset = 0, reg_offset = 0;
2483
2484         offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, total_len);
2485
2486         if (!dump)
2487                 return offset + total_len;
2488
2489         while (reg_offset < total_len) {
2490                 u32 curr_len = min_t(u32, read_len, total_len - reg_offset);
2491
2492                 offset += qed_grc_dump_addr_range(p_hwfn,
2493                                                   p_ptt,
2494                                                   dump_buf + offset,
2495                                                   dump, addr, curr_len, false);
2496                 reg_offset += curr_len;
2497                 addr += curr_len;
2498
2499                 if (reg_offset < total_len) {
2500                         curr_len = min_t(u32, skip_len, total_len - skip_len);
2501                         memset(dump_buf + offset, 0, DWORDS_TO_BYTES(curr_len));
2502                         offset += curr_len;
2503                         reg_offset += curr_len;
2504                         addr += curr_len;
2505                 }
2506         }
2507
2508         return offset;
2509 }
2510
2511 /* Dumps GRC registers entries. Returns the dumped size in dwords. */
2512 static u32 qed_grc_dump_regs_entries(struct qed_hwfn *p_hwfn,
2513                                      struct qed_ptt *p_ptt,
2514                                      struct dbg_array input_regs_arr,
2515                                      u32 *dump_buf,
2516                                      bool dump,
2517                                      bool block_enable[MAX_BLOCK_ID],
2518                                      u32 *num_dumped_reg_entries)
2519 {
2520         u32 i, offset = 0, input_offset = 0;
2521         bool mode_match = true;
2522
2523         *num_dumped_reg_entries = 0;
2524
2525         while (input_offset < input_regs_arr.size_in_dwords) {
2526                 const struct dbg_dump_cond_hdr *cond_hdr =
2527                     (const struct dbg_dump_cond_hdr *)
2528                     &input_regs_arr.ptr[input_offset++];
2529                 u16 modes_buf_offset;
2530                 bool eval_mode;
2531
2532                 /* Check mode/block */
2533                 eval_mode = GET_FIELD(cond_hdr->mode.data,
2534                                       DBG_MODE_HDR_EVAL_MODE) > 0;
2535                 if (eval_mode) {
2536                         modes_buf_offset =
2537                                 GET_FIELD(cond_hdr->mode.data,
2538                                           DBG_MODE_HDR_MODES_BUF_OFFSET);
2539                         mode_match = qed_is_mode_match(p_hwfn,
2540                                                        &modes_buf_offset);
2541                 }
2542
2543                 if (!mode_match || !block_enable[cond_hdr->block_id]) {
2544                         input_offset += cond_hdr->data_size;
2545                         continue;
2546                 }
2547
2548                 for (i = 0; i < cond_hdr->data_size; i++, input_offset++) {
2549                         const struct dbg_dump_reg *reg =
2550                             (const struct dbg_dump_reg *)
2551                             &input_regs_arr.ptr[input_offset];
2552                         u32 addr, len;
2553                         bool wide_bus;
2554
2555                         addr = GET_FIELD(reg->data, DBG_DUMP_REG_ADDRESS);
2556                         len = GET_FIELD(reg->data, DBG_DUMP_REG_LENGTH);
2557                         wide_bus = GET_FIELD(reg->data, DBG_DUMP_REG_WIDE_BUS);
2558                         offset += qed_grc_dump_reg_entry(p_hwfn,
2559                                                          p_ptt,
2560                                                          dump_buf + offset,
2561                                                          dump,
2562                                                          addr,
2563                                                          len,
2564                                                          wide_bus);
2565                         (*num_dumped_reg_entries)++;
2566                 }
2567         }
2568
2569         return offset;
2570 }
2571
2572 /* Dumps GRC registers entries. Returns the dumped size in dwords. */
2573 static u32 qed_grc_dump_split_data(struct qed_hwfn *p_hwfn,
2574                                    struct qed_ptt *p_ptt,
2575                                    struct dbg_array input_regs_arr,
2576                                    u32 *dump_buf,
2577                                    bool dump,
2578                                    bool block_enable[MAX_BLOCK_ID],
2579                                    const char *split_type_name,
2580                                    u32 split_id,
2581                                    const char *param_name,
2582                                    const char *param_val)
2583 {
2584         u32 num_dumped_reg_entries, offset;
2585
2586         /* Calculate register dump header size (and skip it for now) */
2587         offset = qed_grc_dump_regs_hdr(dump_buf,
2588                                        false,
2589                                        0,
2590                                        split_type_name,
2591                                        split_id, param_name, param_val);
2592
2593         /* Dump registers */
2594         offset += qed_grc_dump_regs_entries(p_hwfn,
2595                                             p_ptt,
2596                                             input_regs_arr,
2597                                             dump_buf + offset,
2598                                             dump,
2599                                             block_enable,
2600                                             &num_dumped_reg_entries);
2601
2602         /* Write register dump header */
2603         if (dump && num_dumped_reg_entries > 0)
2604                 qed_grc_dump_regs_hdr(dump_buf,
2605                                       dump,
2606                                       num_dumped_reg_entries,
2607                                       split_type_name,
2608                                       split_id, param_name, param_val);
2609
2610         return num_dumped_reg_entries > 0 ? offset : 0;
2611 }
2612
2613 /* Dumps registers according to the input registers array. Returns the dumped
2614  * size in dwords.
2615  */
2616 static u32 qed_grc_dump_registers(struct qed_hwfn *p_hwfn,
2617                                   struct qed_ptt *p_ptt,
2618                                   u32 *dump_buf,
2619                                   bool dump,
2620                                   bool block_enable[MAX_BLOCK_ID],
2621                                   const char *param_name, const char *param_val)
2622 {
2623         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2624         struct chip_platform_defs *chip_platform;
2625         u32 offset = 0, input_offset = 0;
2626         struct chip_defs *chip;
2627         u8 port_id, pf_id, vf_id;
2628         u16 fid;
2629
2630         chip = &s_chip_defs[dev_data->chip_id];
2631         chip_platform = &chip->per_platform[dev_data->platform_id];
2632
2633         if (dump)
2634                 DP_VERBOSE(p_hwfn, QED_MSG_DEBUG, "Dumping registers...\n");
2635
2636         while (input_offset <
2637                s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].size_in_dwords) {
2638                 const struct dbg_dump_split_hdr *split_hdr;
2639                 struct dbg_array curr_input_regs_arr;
2640                 u32 split_data_size;
2641                 u8 split_type_id;
2642
2643                 split_hdr =
2644                         (const struct dbg_dump_split_hdr *)
2645                         &s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr[input_offset++];
2646                 split_type_id =
2647                         GET_FIELD(split_hdr->hdr,
2648                                   DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
2649                 split_data_size =
2650                         GET_FIELD(split_hdr->hdr,
2651                                   DBG_DUMP_SPLIT_HDR_DATA_SIZE);
2652                 curr_input_regs_arr.ptr =
2653                         &s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr[input_offset];
2654                 curr_input_regs_arr.size_in_dwords = split_data_size;
2655
2656                 switch (split_type_id) {
2657                 case SPLIT_TYPE_NONE:
2658                         offset += qed_grc_dump_split_data(p_hwfn,
2659                                                           p_ptt,
2660                                                           curr_input_regs_arr,
2661                                                           dump_buf + offset,
2662                                                           dump,
2663                                                           block_enable,
2664                                                           "eng",
2665                                                           (u32)(-1),
2666                                                           param_name,
2667                                                           param_val);
2668                         break;
2669
2670                 case SPLIT_TYPE_PORT:
2671                         for (port_id = 0; port_id < chip_platform->num_ports;
2672                              port_id++) {
2673                                 if (dump)
2674                                         qed_port_pretend(p_hwfn, p_ptt,
2675                                                          port_id);
2676                                 offset +=
2677                                     qed_grc_dump_split_data(p_hwfn, p_ptt,
2678                                                             curr_input_regs_arr,
2679                                                             dump_buf + offset,
2680                                                             dump, block_enable,
2681                                                             "port", port_id,
2682                                                             param_name,
2683                                                             param_val);
2684                         }
2685                         break;
2686
2687                 case SPLIT_TYPE_PF:
2688                 case SPLIT_TYPE_PORT_PF:
2689                         for (pf_id = 0; pf_id < chip_platform->num_pfs;
2690                              pf_id++) {
2691                                 u8 pfid_shift =
2692                                         PXP_PRETEND_CONCRETE_FID_PFID_SHIFT;
2693
2694                                 if (dump) {
2695                                         fid = pf_id << pfid_shift;
2696                                         qed_fid_pretend(p_hwfn, p_ptt, fid);
2697                                 }
2698
2699                                 offset +=
2700                                     qed_grc_dump_split_data(p_hwfn,
2701                                                             p_ptt,
2702                                                             curr_input_regs_arr,
2703                                                             dump_buf + offset,
2704                                                             dump,
2705                                                             block_enable,
2706                                                             "pf",
2707                                                             pf_id,
2708                                                             param_name,
2709                                                             param_val);
2710                         }
2711                         break;
2712
2713                 case SPLIT_TYPE_VF:
2714                         for (vf_id = 0; vf_id < chip_platform->num_vfs;
2715                              vf_id++) {
2716                                 u8 vfvalid_shift =
2717                                         PXP_PRETEND_CONCRETE_FID_VFVALID_SHIFT;
2718                                 u8 vfid_shift =
2719                                         PXP_PRETEND_CONCRETE_FID_VFID_SHIFT;
2720
2721                                 if (dump) {
2722                                         fid = BIT(vfvalid_shift) |
2723                                               (vf_id << vfid_shift);
2724                                         qed_fid_pretend(p_hwfn, p_ptt, fid);
2725                                 }
2726
2727                                 offset +=
2728                                     qed_grc_dump_split_data(p_hwfn, p_ptt,
2729                                                             curr_input_regs_arr,
2730                                                             dump_buf + offset,
2731                                                             dump, block_enable,
2732                                                             "vf", vf_id,
2733                                                             param_name,
2734                                                             param_val);
2735                         }
2736                         break;
2737
2738                 default:
2739                         break;
2740                 }
2741
2742                 input_offset += split_data_size;
2743         }
2744
2745         /* Pretend to original PF */
2746         if (dump) {
2747                 fid = p_hwfn->rel_pf_id << PXP_PRETEND_CONCRETE_FID_PFID_SHIFT;
2748                 qed_fid_pretend(p_hwfn, p_ptt, fid);
2749         }
2750
2751         return offset;
2752 }
2753
2754 /* Dump reset registers. Returns the dumped size in dwords. */
2755 static u32 qed_grc_dump_reset_regs(struct qed_hwfn *p_hwfn,
2756                                    struct qed_ptt *p_ptt,
2757                                    u32 *dump_buf, bool dump)
2758 {
2759         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2760         u32 i, offset = 0, num_regs = 0;
2761
2762         /* Calculate header size */
2763         offset += qed_grc_dump_regs_hdr(dump_buf,
2764                                         false, 0, "eng", -1, NULL, NULL);
2765
2766         /* Write reset registers */
2767         for (i = 0; i < MAX_DBG_RESET_REGS; i++) {
2768                 if (!s_reset_regs_defs[i].exists[dev_data->chip_id])
2769                         continue;
2770
2771                 offset += qed_grc_dump_reg_entry(p_hwfn,
2772                                                  p_ptt,
2773                                                  dump_buf + offset,
2774                                                  dump,
2775                                                  BYTES_TO_DWORDS
2776                                                  (s_reset_regs_defs[i].addr), 1,
2777                                                  false);
2778                 num_regs++;
2779         }
2780
2781         /* Write header */
2782         if (dump)
2783                 qed_grc_dump_regs_hdr(dump_buf,
2784                                       true, num_regs, "eng", -1, NULL, NULL);
2785
2786         return offset;
2787 }
2788
2789 /* Dump registers that are modified during GRC Dump and therefore must be
2790  * dumped first. Returns the dumped size in dwords.
2791  */
2792 static u32 qed_grc_dump_modified_regs(struct qed_hwfn *p_hwfn,
2793                                       struct qed_ptt *p_ptt,
2794                                       u32 *dump_buf, bool dump)
2795 {
2796         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2797         u32 block_id, offset = 0, num_reg_entries = 0;
2798         const struct dbg_attn_reg *attn_reg_arr;
2799         u8 storm_id, reg_idx, num_attn_regs;
2800
2801         /* Calculate header size */
2802         offset += qed_grc_dump_regs_hdr(dump_buf,
2803                                         false, 0, "eng", -1, NULL, NULL);
2804
2805         /* Write parity registers */
2806         for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
2807                 if (dev_data->block_in_reset[block_id] && dump)
2808                         continue;
2809
2810                 attn_reg_arr = qed_get_block_attn_regs((enum block_id)block_id,
2811                                                        ATTN_TYPE_PARITY,
2812                                                        &num_attn_regs);
2813
2814                 for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
2815                         const struct dbg_attn_reg *reg_data =
2816                                 &attn_reg_arr[reg_idx];
2817                         u16 modes_buf_offset;
2818                         bool eval_mode;
2819                         u32 addr;
2820
2821                         /* Check mode */
2822                         eval_mode = GET_FIELD(reg_data->mode.data,
2823                                               DBG_MODE_HDR_EVAL_MODE) > 0;
2824                         modes_buf_offset =
2825                                 GET_FIELD(reg_data->mode.data,
2826                                           DBG_MODE_HDR_MODES_BUF_OFFSET);
2827                         if (eval_mode &&
2828                             !qed_is_mode_match(p_hwfn, &modes_buf_offset))
2829                                 continue;
2830
2831                         /* Mode match: read & dump registers */
2832                         addr = reg_data->mask_address;
2833                         offset += qed_grc_dump_reg_entry(p_hwfn,
2834                                                          p_ptt,
2835                                                          dump_buf + offset,
2836                                                          dump,
2837                                                          addr,
2838                                                          1, false);
2839                         addr = GET_FIELD(reg_data->data,
2840                                          DBG_ATTN_REG_STS_ADDRESS);
2841                         offset += qed_grc_dump_reg_entry(p_hwfn,
2842                                                          p_ptt,
2843                                                          dump_buf + offset,
2844                                                          dump,
2845                                                          addr,
2846                                                          1, false);
2847                         num_reg_entries += 2;
2848                 }
2849         }
2850
2851         /* Write Storm stall status registers */
2852         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
2853                 struct storm_defs *storm = &s_storm_defs[storm_id];
2854                 u32 addr;
2855
2856                 if (dev_data->block_in_reset[storm->block_id] && dump)
2857                         continue;
2858
2859                 addr =
2860                     BYTES_TO_DWORDS(s_storm_defs[storm_id].sem_fast_mem_addr +
2861                                     SEM_FAST_REG_STALLED);
2862                 offset += qed_grc_dump_reg_entry(p_hwfn,
2863                                                  p_ptt,
2864                                                  dump_buf + offset,
2865                                                  dump,
2866                                                  addr,
2867                                                  1,
2868                                                  false);
2869                 num_reg_entries++;
2870         }
2871
2872         /* Write header */
2873         if (dump)
2874                 qed_grc_dump_regs_hdr(dump_buf,
2875                                       true,
2876                                       num_reg_entries, "eng", -1, NULL, NULL);
2877
2878         return offset;
2879 }
2880
2881 /* Dumps registers that can't be represented in the debug arrays */
2882 static u32 qed_grc_dump_special_regs(struct qed_hwfn *p_hwfn,
2883                                      struct qed_ptt *p_ptt,
2884                                      u32 *dump_buf, bool dump)
2885 {
2886         u32 offset = 0, addr;
2887
2888         offset += qed_grc_dump_regs_hdr(dump_buf,
2889                                         dump, 2, "eng", -1, NULL, NULL);
2890
2891         /* Dump R/TDIF_REG_DEBUG_ERROR_INFO_SIZE (every 8'th register should be
2892          * skipped).
2893          */
2894         addr = BYTES_TO_DWORDS(RDIF_REG_DEBUG_ERROR_INFO);
2895         offset += qed_grc_dump_reg_entry_skip(p_hwfn,
2896                                               p_ptt,
2897                                               dump_buf + offset,
2898                                               dump,
2899                                               addr,
2900                                               RDIF_REG_DEBUG_ERROR_INFO_SIZE,
2901                                               7,
2902                                               1);
2903         addr = BYTES_TO_DWORDS(TDIF_REG_DEBUG_ERROR_INFO);
2904         offset +=
2905             qed_grc_dump_reg_entry_skip(p_hwfn,
2906                                         p_ptt,
2907                                         dump_buf + offset,
2908                                         dump,
2909                                         addr,
2910                                         TDIF_REG_DEBUG_ERROR_INFO_SIZE,
2911                                         7,
2912                                         1);
2913
2914         return offset;
2915 }
2916
2917 /* Dumps a GRC memory header (section and params). Returns the dumped size in
2918  * dwords. The following parameters are dumped:
2919  * - name:         dumped only if it's not NULL.
2920  * - addr:         in dwords, dumped only if name is NULL.
2921  * - len:          in dwords, always dumped.
2922  * - width:        dumped if it's not zero.
2923  * - packed:       dumped only if it's not false.
2924  * - mem_group:    always dumped.
2925  * - is_storm:     true only if the memory is related to a Storm.
2926  * - storm_letter: valid only if is_storm is true.
2927  *
2928  */
2929 static u32 qed_grc_dump_mem_hdr(struct qed_hwfn *p_hwfn,
2930                                 u32 *dump_buf,
2931                                 bool dump,
2932                                 const char *name,
2933                                 u32 addr,
2934                                 u32 len,
2935                                 u32 bit_width,
2936                                 bool packed,
2937                                 const char *mem_group,
2938                                 bool is_storm, char storm_letter)
2939 {
2940         u8 num_params = 3;
2941         u32 offset = 0;
2942         char buf[64];
2943
2944         if (!len)
2945                 DP_NOTICE(p_hwfn,
2946                           "Unexpected GRC Dump error: dumped memory size must be non-zero\n");
2947
2948         if (bit_width)
2949                 num_params++;
2950         if (packed)
2951                 num_params++;
2952
2953         /* Dump section header */
2954         offset += qed_dump_section_hdr(dump_buf + offset,
2955                                        dump, "grc_mem", num_params);
2956
2957         if (name) {
2958                 /* Dump name */
2959                 if (is_storm) {
2960                         strcpy(buf, "?STORM_");
2961                         buf[0] = storm_letter;
2962                         strcpy(buf + strlen(buf), name);
2963                 } else {
2964                         strcpy(buf, name);
2965                 }
2966
2967                 offset += qed_dump_str_param(dump_buf + offset,
2968                                              dump, "name", buf);
2969                 if (dump)
2970                         DP_VERBOSE(p_hwfn,
2971                                    QED_MSG_DEBUG,
2972                                    "Dumping %d registers from %s...\n",
2973                                    len, buf);
2974         } else {
2975                 /* Dump address */
2976                 u32 addr_in_bytes = DWORDS_TO_BYTES(addr);
2977
2978                 offset += qed_dump_num_param(dump_buf + offset,
2979                                              dump, "addr", addr_in_bytes);
2980                 if (dump && len > 64)
2981                         DP_VERBOSE(p_hwfn,
2982                                    QED_MSG_DEBUG,
2983                                    "Dumping %d registers from address 0x%x...\n",
2984                                    len, addr_in_bytes);
2985         }
2986
2987         /* Dump len */
2988         offset += qed_dump_num_param(dump_buf + offset, dump, "len", len);
2989
2990         /* Dump bit width */
2991         if (bit_width)
2992                 offset += qed_dump_num_param(dump_buf + offset,
2993                                              dump, "width", bit_width);
2994
2995         /* Dump packed */
2996         if (packed)
2997                 offset += qed_dump_num_param(dump_buf + offset,
2998                                              dump, "packed", 1);
2999
3000         /* Dump reg type */
3001         if (is_storm) {
3002                 strcpy(buf, "?STORM_");
3003                 buf[0] = storm_letter;
3004                 strcpy(buf + strlen(buf), mem_group);
3005         } else {
3006                 strcpy(buf, mem_group);
3007         }
3008
3009         offset += qed_dump_str_param(dump_buf + offset, dump, "type", buf);
3010
3011         return offset;
3012 }
3013
3014 /* Dumps a single GRC memory. If name is NULL, the memory is stored by address.
3015  * Returns the dumped size in dwords.
3016  * The addr and len arguments are specified in dwords.
3017  */
3018 static u32 qed_grc_dump_mem(struct qed_hwfn *p_hwfn,
3019                             struct qed_ptt *p_ptt,
3020                             u32 *dump_buf,
3021                             bool dump,
3022                             const char *name,
3023                             u32 addr,
3024                             u32 len,
3025                             bool wide_bus,
3026                             u32 bit_width,
3027                             bool packed,
3028                             const char *mem_group,
3029                             bool is_storm, char storm_letter)
3030 {
3031         u32 offset = 0;
3032
3033         offset += qed_grc_dump_mem_hdr(p_hwfn,
3034                                        dump_buf + offset,
3035                                        dump,
3036                                        name,
3037                                        addr,
3038                                        len,
3039                                        bit_width,
3040                                        packed,
3041                                        mem_group, is_storm, storm_letter);
3042         offset += qed_grc_dump_addr_range(p_hwfn,
3043                                           p_ptt,
3044                                           dump_buf + offset,
3045                                           dump, addr, len, wide_bus);
3046
3047         return offset;
3048 }
3049
3050 /* Dumps GRC memories entries. Returns the dumped size in dwords. */
3051 static u32 qed_grc_dump_mem_entries(struct qed_hwfn *p_hwfn,
3052                                     struct qed_ptt *p_ptt,
3053                                     struct dbg_array input_mems_arr,
3054                                     u32 *dump_buf, bool dump)
3055 {
3056         u32 i, offset = 0, input_offset = 0;
3057         bool mode_match = true;
3058
3059         while (input_offset < input_mems_arr.size_in_dwords) {
3060                 const struct dbg_dump_cond_hdr *cond_hdr;
3061                 u16 modes_buf_offset;
3062                 u32 num_entries;
3063                 bool eval_mode;
3064
3065                 cond_hdr = (const struct dbg_dump_cond_hdr *)
3066                            &input_mems_arr.ptr[input_offset++];
3067                 num_entries = cond_hdr->data_size / MEM_DUMP_ENTRY_SIZE_DWORDS;
3068
3069                 /* Check required mode */
3070                 eval_mode = GET_FIELD(cond_hdr->mode.data,
3071                                       DBG_MODE_HDR_EVAL_MODE) > 0;
3072                 if (eval_mode) {
3073                         modes_buf_offset =
3074                                 GET_FIELD(cond_hdr->mode.data,
3075                                           DBG_MODE_HDR_MODES_BUF_OFFSET);
3076                         mode_match = qed_is_mode_match(p_hwfn,
3077                                                        &modes_buf_offset);
3078                 }
3079
3080                 if (!mode_match) {
3081                         input_offset += cond_hdr->data_size;
3082                         continue;
3083                 }
3084
3085                 for (i = 0; i < num_entries;
3086                      i++, input_offset += MEM_DUMP_ENTRY_SIZE_DWORDS) {
3087                         const struct dbg_dump_mem *mem =
3088                                 (const struct dbg_dump_mem *)
3089                                 &input_mems_arr.ptr[input_offset];
3090                         u8 mem_group_id = GET_FIELD(mem->dword0,
3091                                                     DBG_DUMP_MEM_MEM_GROUP_ID);
3092                         bool is_storm = false, mem_wide_bus;
3093                         enum dbg_grc_params grc_param;
3094                         char storm_letter = 'a';
3095                         enum block_id block_id;
3096                         u32 mem_addr, mem_len;
3097
3098                         if (mem_group_id >= MEM_GROUPS_NUM) {
3099                                 DP_NOTICE(p_hwfn, "Invalid mem_group_id\n");
3100                                 return 0;
3101                         }
3102
3103                         block_id = (enum block_id)cond_hdr->block_id;
3104                         if (!qed_grc_is_mem_included(p_hwfn,
3105                                                      block_id,
3106                                                      mem_group_id))
3107                                 continue;
3108
3109                         mem_addr = GET_FIELD(mem->dword0, DBG_DUMP_MEM_ADDRESS);
3110                         mem_len = GET_FIELD(mem->dword1, DBG_DUMP_MEM_LENGTH);
3111                         mem_wide_bus = GET_FIELD(mem->dword1,
3112                                                  DBG_DUMP_MEM_WIDE_BUS);
3113
3114                         /* Update memory length for CCFC/TCFC memories
3115                          * according to number of LCIDs/LTIDs.
3116                          */
3117                         if (mem_group_id == MEM_GROUP_CONN_CFC_MEM) {
3118                                 if (mem_len % MAX_LCIDS) {
3119                                         DP_NOTICE(p_hwfn,
3120                                                   "Invalid CCFC connection memory size\n");
3121                                         return 0;
3122                                 }
3123
3124                                 grc_param = DBG_GRC_PARAM_NUM_LCIDS;
3125                                 mem_len = qed_grc_get_param(p_hwfn, grc_param) *
3126                                           (mem_len / MAX_LCIDS);
3127                         } else if (mem_group_id == MEM_GROUP_TASK_CFC_MEM) {
3128                                 if (mem_len % MAX_LTIDS) {
3129                                         DP_NOTICE(p_hwfn,
3130                                                   "Invalid TCFC task memory size\n");
3131                                         return 0;
3132                                 }
3133
3134                                 grc_param = DBG_GRC_PARAM_NUM_LTIDS;
3135                                 mem_len = qed_grc_get_param(p_hwfn, grc_param) *
3136                                           (mem_len / MAX_LTIDS);
3137                         }
3138
3139                         /* If memory is associated with Storm, update Storm
3140                          * details.
3141                          */
3142                         if (s_block_defs
3143                             [cond_hdr->block_id]->associated_to_storm) {
3144                                 is_storm = true;
3145                                 storm_letter =
3146                                     s_storm_defs[s_block_defs
3147                                                  [cond_hdr->block_id]->
3148                                                  storm_id].letter;
3149                         }
3150
3151                         /* Dump memory */
3152                         offset += qed_grc_dump_mem(p_hwfn,
3153                                                 p_ptt,
3154                                                 dump_buf + offset,
3155                                                 dump,
3156                                                 NULL,
3157                                                 mem_addr,
3158                                                 mem_len,
3159                                                 mem_wide_bus,
3160                                                 0,
3161                                                 false,
3162                                                 s_mem_group_names[mem_group_id],
3163                                                 is_storm,
3164                                                 storm_letter);
3165                 }
3166         }
3167
3168         return offset;
3169 }
3170
3171 /* Dumps GRC memories according to the input array dump_mem.
3172  * Returns the dumped size in dwords.
3173  */
3174 static u32 qed_grc_dump_memories(struct qed_hwfn *p_hwfn,
3175                                  struct qed_ptt *p_ptt,
3176                                  u32 *dump_buf, bool dump)
3177 {
3178         u32 offset = 0, input_offset = 0;
3179
3180         while (input_offset <
3181                s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].size_in_dwords) {
3182                 const struct dbg_dump_split_hdr *split_hdr;
3183                 struct dbg_array curr_input_mems_arr;
3184                 u32 split_data_size;
3185                 u8 split_type_id;
3186
3187                 split_hdr = (const struct dbg_dump_split_hdr *)
3188                         &s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr[input_offset++];
3189                 split_type_id =
3190                         GET_FIELD(split_hdr->hdr,
3191                                   DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
3192                 split_data_size =
3193                         GET_FIELD(split_hdr->hdr,
3194                                   DBG_DUMP_SPLIT_HDR_DATA_SIZE);
3195                 curr_input_mems_arr.ptr =
3196                         &s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr[input_offset];
3197                 curr_input_mems_arr.size_in_dwords = split_data_size;
3198
3199                 switch (split_type_id) {
3200                 case SPLIT_TYPE_NONE:
3201                         offset += qed_grc_dump_mem_entries(p_hwfn,
3202                                                            p_ptt,
3203                                                            curr_input_mems_arr,
3204                                                            dump_buf + offset,
3205                                                            dump);
3206                         break;
3207
3208                 default:
3209                         DP_NOTICE(p_hwfn,
3210                                   "Dumping split memories is currently not supported\n");
3211                         break;
3212                 }
3213
3214                 input_offset += split_data_size;
3215         }
3216
3217         return offset;
3218 }
3219
3220 /* Dumps GRC context data for the specified Storm.
3221  * Returns the dumped size in dwords.
3222  * The lid_size argument is specified in quad-regs.
3223  */
3224 static u32 qed_grc_dump_ctx_data(struct qed_hwfn *p_hwfn,
3225                                  struct qed_ptt *p_ptt,
3226                                  u32 *dump_buf,
3227                                  bool dump,
3228                                  const char *name,
3229                                  u32 num_lids,
3230                                  u32 lid_size,
3231                                  u32 rd_reg_addr,
3232                                  u8 storm_id)
3233 {
3234         struct storm_defs *storm = &s_storm_defs[storm_id];
3235         u32 i, lid, total_size, offset = 0;
3236
3237         if (!lid_size)
3238                 return 0;
3239
3240         lid_size *= BYTES_IN_DWORD;
3241         total_size = num_lids * lid_size;
3242
3243         offset += qed_grc_dump_mem_hdr(p_hwfn,
3244                                        dump_buf + offset,
3245                                        dump,
3246                                        name,
3247                                        0,
3248                                        total_size,
3249                                        lid_size * 32,
3250                                        false, name, true, storm->letter);
3251
3252         if (!dump)
3253                 return offset + total_size;
3254
3255         /* Dump context data */
3256         for (lid = 0; lid < num_lids; lid++) {
3257                 for (i = 0; i < lid_size; i++, offset++) {
3258                         qed_wr(p_hwfn,
3259                                p_ptt, storm->cm_ctx_wr_addr, (i << 9) | lid);
3260                         *(dump_buf + offset) = qed_rd(p_hwfn,
3261                                                       p_ptt, rd_reg_addr);
3262                 }
3263         }
3264
3265         return offset;
3266 }
3267
3268 /* Dumps GRC contexts. Returns the dumped size in dwords. */
3269 static u32 qed_grc_dump_ctx(struct qed_hwfn *p_hwfn,
3270                             struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3271 {
3272         enum dbg_grc_params grc_param;
3273         u32 offset = 0;
3274         u8 storm_id;
3275
3276         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
3277                 struct storm_defs *storm = &s_storm_defs[storm_id];
3278
3279                 if (!qed_grc_is_storm_included(p_hwfn,
3280                                                (enum dbg_storms)storm_id))
3281                         continue;
3282
3283                 /* Dump Conn AG context size */
3284                 grc_param = DBG_GRC_PARAM_NUM_LCIDS;
3285                 offset +=
3286                         qed_grc_dump_ctx_data(p_hwfn,
3287                                               p_ptt,
3288                                               dump_buf + offset,
3289                                               dump,
3290                                               "CONN_AG_CTX",
3291                                               qed_grc_get_param(p_hwfn,
3292                                                                 grc_param),
3293                                               storm->cm_conn_ag_ctx_lid_size,
3294                                               storm->cm_conn_ag_ctx_rd_addr,
3295                                               storm_id);
3296
3297                 /* Dump Conn ST context size */
3298                 grc_param = DBG_GRC_PARAM_NUM_LCIDS;
3299                 offset +=
3300                         qed_grc_dump_ctx_data(p_hwfn,
3301                                               p_ptt,
3302                                               dump_buf + offset,
3303                                               dump,
3304                                               "CONN_ST_CTX",
3305                                               qed_grc_get_param(p_hwfn,
3306                                                                 grc_param),
3307                                               storm->cm_conn_st_ctx_lid_size,
3308                                               storm->cm_conn_st_ctx_rd_addr,
3309                                               storm_id);
3310
3311                 /* Dump Task AG context size */
3312                 grc_param = DBG_GRC_PARAM_NUM_LTIDS;
3313                 offset +=
3314                         qed_grc_dump_ctx_data(p_hwfn,
3315                                               p_ptt,
3316                                               dump_buf + offset,
3317                                               dump,
3318                                               "TASK_AG_CTX",
3319                                               qed_grc_get_param(p_hwfn,
3320                                                                 grc_param),
3321                                               storm->cm_task_ag_ctx_lid_size,
3322                                               storm->cm_task_ag_ctx_rd_addr,
3323                                               storm_id);
3324
3325                 /* Dump Task ST context size */
3326                 grc_param = DBG_GRC_PARAM_NUM_LTIDS;
3327                 offset +=
3328                         qed_grc_dump_ctx_data(p_hwfn,
3329                                               p_ptt,
3330                                               dump_buf + offset,
3331                                               dump,
3332                                               "TASK_ST_CTX",
3333                                               qed_grc_get_param(p_hwfn,
3334                                                                 grc_param),
3335                                               storm->cm_task_st_ctx_lid_size,
3336                                               storm->cm_task_st_ctx_rd_addr,
3337                                               storm_id);
3338         }
3339
3340         return offset;
3341 }
3342
3343 /* Dumps GRC IORs data. Returns the dumped size in dwords. */
3344 static u32 qed_grc_dump_iors(struct qed_hwfn *p_hwfn,
3345                              struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3346 {
3347         char buf[10] = "IOR_SET_?";
3348         u32 addr, offset = 0;
3349         u8 storm_id, set_id;
3350
3351         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
3352                 struct storm_defs *storm = &s_storm_defs[storm_id];
3353
3354                 if (!qed_grc_is_storm_included(p_hwfn,
3355                                                (enum dbg_storms)storm_id))
3356                         continue;
3357
3358                 for (set_id = 0; set_id < NUM_IOR_SETS; set_id++) {
3359                         addr = BYTES_TO_DWORDS(storm->sem_fast_mem_addr +
3360                                                SEM_FAST_REG_STORM_REG_FILE) +
3361                                IOR_SET_OFFSET(set_id);
3362                         buf[strlen(buf) - 1] = '0' + set_id;
3363                         offset += qed_grc_dump_mem(p_hwfn,
3364                                                    p_ptt,
3365                                                    dump_buf + offset,
3366                                                    dump,
3367                                                    buf,
3368                                                    addr,
3369                                                    IORS_PER_SET,
3370                                                    false,
3371                                                    32,
3372                                                    false,
3373                                                    "ior",
3374                                                    true,
3375                                                    storm->letter);
3376                 }
3377         }
3378
3379         return offset;
3380 }
3381
3382 /* Dump VFC CAM. Returns the dumped size in dwords. */
3383 static u32 qed_grc_dump_vfc_cam(struct qed_hwfn *p_hwfn,
3384                                 struct qed_ptt *p_ptt,
3385                                 u32 *dump_buf, bool dump, u8 storm_id)
3386 {
3387         u32 total_size = VFC_CAM_NUM_ROWS * VFC_CAM_RESP_DWORDS;
3388         struct storm_defs *storm = &s_storm_defs[storm_id];
3389         u32 cam_addr[VFC_CAM_ADDR_DWORDS] = { 0 };
3390         u32 cam_cmd[VFC_CAM_CMD_DWORDS] = { 0 };
3391         u32 row, i, offset = 0;
3392
3393         offset += qed_grc_dump_mem_hdr(p_hwfn,
3394                                        dump_buf + offset,
3395                                        dump,
3396                                        "vfc_cam",
3397                                        0,
3398                                        total_size,
3399                                        256,
3400                                        false, "vfc_cam", true, storm->letter);
3401
3402         if (!dump)
3403                 return offset + total_size;
3404
3405         /* Prepare CAM address */
3406         SET_VAR_FIELD(cam_addr, VFC_CAM_ADDR, OP, VFC_OPCODE_CAM_RD);
3407
3408         for (row = 0; row < VFC_CAM_NUM_ROWS;
3409              row++, offset += VFC_CAM_RESP_DWORDS) {
3410                 /* Write VFC CAM command */
3411                 SET_VAR_FIELD(cam_cmd, VFC_CAM_CMD, ROW, row);
3412                 ARR_REG_WR(p_hwfn,
3413                            p_ptt,
3414                            storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_DATA_WR,
3415                            cam_cmd, VFC_CAM_CMD_DWORDS);
3416
3417                 /* Write VFC CAM address */
3418                 ARR_REG_WR(p_hwfn,
3419                            p_ptt,
3420                            storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_ADDR,
3421                            cam_addr, VFC_CAM_ADDR_DWORDS);
3422
3423                 /* Read VFC CAM read response */
3424                 ARR_REG_RD(p_hwfn,
3425                            p_ptt,
3426                            storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_DATA_RD,
3427                            dump_buf + offset, VFC_CAM_RESP_DWORDS);
3428         }
3429
3430         return offset;
3431 }
3432
3433 /* Dump VFC RAM. Returns the dumped size in dwords. */
3434 static u32 qed_grc_dump_vfc_ram(struct qed_hwfn *p_hwfn,
3435                                 struct qed_ptt *p_ptt,
3436                                 u32 *dump_buf,
3437                                 bool dump,
3438                                 u8 storm_id, struct vfc_ram_defs *ram_defs)
3439 {
3440         u32 total_size = ram_defs->num_rows * VFC_RAM_RESP_DWORDS;
3441         struct storm_defs *storm = &s_storm_defs[storm_id];
3442         u32 ram_addr[VFC_RAM_ADDR_DWORDS] = { 0 };
3443         u32 ram_cmd[VFC_RAM_CMD_DWORDS] = { 0 };
3444         u32 row, i, offset = 0;
3445
3446         offset += qed_grc_dump_mem_hdr(p_hwfn,
3447                                        dump_buf + offset,
3448                                        dump,
3449                                        ram_defs->mem_name,
3450                                        0,
3451                                        total_size,
3452                                        256,
3453                                        false,
3454                                        ram_defs->type_name,
3455                                        true, storm->letter);
3456
3457         /* Prepare RAM address */
3458         SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, OP, VFC_OPCODE_RAM_RD);
3459
3460         if (!dump)
3461                 return offset + total_size;
3462
3463         for (row = ram_defs->base_row;
3464              row < ram_defs->base_row + ram_defs->num_rows;
3465              row++, offset += VFC_RAM_RESP_DWORDS) {
3466                 /* Write VFC RAM command */
3467                 ARR_REG_WR(p_hwfn,
3468                            p_ptt,
3469                            storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_DATA_WR,
3470                            ram_cmd, VFC_RAM_CMD_DWORDS);
3471
3472                 /* Write VFC RAM address */
3473                 SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, ROW, row);
3474                 ARR_REG_WR(p_hwfn,
3475                            p_ptt,
3476                            storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_ADDR,
3477                            ram_addr, VFC_RAM_ADDR_DWORDS);
3478
3479                 /* Read VFC RAM read response */
3480                 ARR_REG_RD(p_hwfn,
3481                            p_ptt,
3482                            storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_DATA_RD,
3483                            dump_buf + offset, VFC_RAM_RESP_DWORDS);
3484         }
3485
3486         return offset;
3487 }
3488
3489 /* Dumps GRC VFC data. Returns the dumped size in dwords. */
3490 static u32 qed_grc_dump_vfc(struct qed_hwfn *p_hwfn,
3491                             struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3492 {
3493         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3494         u8 storm_id, i;
3495         u32 offset = 0;
3496
3497         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
3498                 if (!qed_grc_is_storm_included(p_hwfn,
3499                                                (enum dbg_storms)storm_id) ||
3500                     !s_storm_defs[storm_id].has_vfc ||
3501                     (storm_id == DBG_PSTORM_ID && dev_data->platform_id !=
3502                      PLATFORM_ASIC))
3503                         continue;
3504
3505                 /* Read CAM */
3506                 offset += qed_grc_dump_vfc_cam(p_hwfn,
3507                                                p_ptt,
3508                                                dump_buf + offset,
3509                                                dump, storm_id);
3510
3511                 /* Read RAM */
3512                 for (i = 0; i < NUM_VFC_RAM_TYPES; i++)
3513                         offset += qed_grc_dump_vfc_ram(p_hwfn,
3514                                                        p_ptt,
3515                                                        dump_buf + offset,
3516                                                        dump,
3517                                                        storm_id,
3518                                                        &s_vfc_ram_defs[i]);
3519         }
3520
3521         return offset;
3522 }
3523
3524 /* Dumps GRC RSS data. Returns the dumped size in dwords. */
3525 static u32 qed_grc_dump_rss(struct qed_hwfn *p_hwfn,
3526                             struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3527 {
3528         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3529         u32 offset = 0;
3530         u8 rss_mem_id;
3531
3532         for (rss_mem_id = 0; rss_mem_id < NUM_RSS_MEM_TYPES; rss_mem_id++) {
3533                 u32 rss_addr, num_entries, entry_width, total_dwords, i;
3534                 struct rss_mem_defs *rss_defs;
3535                 u32 addr, size;
3536                 bool packed;
3537
3538                 rss_defs = &s_rss_mem_defs[rss_mem_id];
3539                 rss_addr = rss_defs->addr;
3540                 num_entries = rss_defs->num_entries[dev_data->chip_id];
3541                 entry_width = rss_defs->entry_width[dev_data->chip_id];
3542                 total_dwords = (num_entries * entry_width) / 32;
3543                 packed = (entry_width == 16);
3544
3545                 offset += qed_grc_dump_mem_hdr(p_hwfn,
3546                                                dump_buf + offset,
3547                                                dump,
3548                                                rss_defs->mem_name,
3549                                                0,
3550                                                total_dwords,
3551                                                entry_width,
3552                                                packed,
3553                                                rss_defs->type_name, false, 0);
3554
3555                 /* Dump RSS data */
3556                 if (!dump) {
3557                         offset += total_dwords;
3558                         continue;
3559                 }
3560
3561                 addr = BYTES_TO_DWORDS(RSS_REG_RSS_RAM_DATA);
3562                 size = RSS_REG_RSS_RAM_DATA_SIZE;
3563                 for (i = 0; i < total_dwords; i += size, rss_addr++) {
3564                         qed_wr(p_hwfn, p_ptt, RSS_REG_RSS_RAM_ADDR, rss_addr);
3565                         offset += qed_grc_dump_addr_range(p_hwfn,
3566                                                           p_ptt,
3567                                                           dump_buf + offset,
3568                                                           dump,
3569                                                           addr,
3570                                                           size,
3571                                                           false);
3572                 }
3573         }
3574
3575         return offset;
3576 }
3577
3578 /* Dumps GRC Big RAM. Returns the dumped size in dwords. */
3579 static u32 qed_grc_dump_big_ram(struct qed_hwfn *p_hwfn,
3580                                 struct qed_ptt *p_ptt,
3581                                 u32 *dump_buf, bool dump, u8 big_ram_id)
3582 {
3583         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3584         u32 total_blocks, ram_size, offset = 0, i;
3585         char mem_name[12] = "???_BIG_RAM";
3586         char type_name[8] = "???_RAM";
3587         struct big_ram_defs *big_ram;
3588
3589         big_ram = &s_big_ram_defs[big_ram_id];
3590         total_blocks = big_ram->num_of_blocks[dev_data->chip_id];
3591         ram_size = total_blocks * BIG_RAM_BLOCK_SIZE_DWORDS;
3592
3593         strscpy(type_name, big_ram->instance_name, sizeof(type_name));
3594         strscpy(mem_name, big_ram->instance_name, sizeof(mem_name));
3595
3596         /* Dump memory header */
3597         offset += qed_grc_dump_mem_hdr(p_hwfn,
3598                                        dump_buf + offset,
3599                                        dump,
3600                                        mem_name,
3601                                        0,
3602                                        ram_size,
3603                                        BIG_RAM_BLOCK_SIZE_BYTES * 8,
3604                                        false, type_name, false, 0);
3605
3606         /* Read and dump Big RAM data */
3607         if (!dump)
3608                 return offset + ram_size;
3609
3610         /* Dump Big RAM */
3611         for (i = 0; i < total_blocks / 2; i++) {
3612                 u32 addr, len;
3613
3614                 qed_wr(p_hwfn, p_ptt, big_ram->addr_reg_addr, i);
3615                 addr = BYTES_TO_DWORDS(big_ram->data_reg_addr);
3616                 len = 2 * BIG_RAM_BLOCK_SIZE_DWORDS;
3617                 offset += qed_grc_dump_addr_range(p_hwfn,
3618                                                   p_ptt,
3619                                                   dump_buf + offset,
3620                                                   dump,
3621                                                   addr,
3622                                                   len,
3623                                                   false);
3624         }
3625
3626         return offset;
3627 }
3628
3629 static u32 qed_grc_dump_mcp(struct qed_hwfn *p_hwfn,
3630                             struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3631 {
3632         bool block_enable[MAX_BLOCK_ID] = { 0 };
3633         u32 offset = 0, addr;
3634         bool halted = false;
3635
3636         /* Halt MCP */
3637         if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {
3638                 halted = !qed_mcp_halt(p_hwfn, p_ptt);
3639                 if (!halted)
3640                         DP_NOTICE(p_hwfn, "MCP halt failed!\n");
3641         }
3642
3643         /* Dump MCP scratchpad */
3644         offset += qed_grc_dump_mem(p_hwfn,
3645                                    p_ptt,
3646                                    dump_buf + offset,
3647                                    dump,
3648                                    NULL,
3649                                    BYTES_TO_DWORDS(MCP_REG_SCRATCH),
3650                                    MCP_REG_SCRATCH_SIZE,
3651                                    false, 0, false, "MCP", false, 0);
3652
3653         /* Dump MCP cpu_reg_file */
3654         offset += qed_grc_dump_mem(p_hwfn,
3655                                    p_ptt,
3656                                    dump_buf + offset,
3657                                    dump,
3658                                    NULL,
3659                                    BYTES_TO_DWORDS(MCP_REG_CPU_REG_FILE),
3660                                    MCP_REG_CPU_REG_FILE_SIZE,
3661                                    false, 0, false, "MCP", false, 0);
3662
3663         /* Dump MCP registers */
3664         block_enable[BLOCK_MCP] = true;
3665         offset += qed_grc_dump_registers(p_hwfn,
3666                                          p_ptt,
3667                                          dump_buf + offset,
3668                                          dump, block_enable, "block", "MCP");
3669
3670         /* Dump required non-MCP registers */
3671         offset += qed_grc_dump_regs_hdr(dump_buf + offset,
3672                                         dump, 1, "eng", -1, "block", "MCP");
3673         addr = BYTES_TO_DWORDS(MISC_REG_SHARED_MEM_ADDR);
3674         offset += qed_grc_dump_reg_entry(p_hwfn,
3675                                          p_ptt,
3676                                          dump_buf + offset,
3677                                          dump,
3678                                          addr,
3679                                          1,
3680                                          false);
3681
3682         /* Release MCP */
3683         if (halted && qed_mcp_resume(p_hwfn, p_ptt))
3684                 DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n");
3685
3686         return offset;
3687 }
3688
3689 /* Dumps the tbus indirect memory for all PHYs. */
3690 static u32 qed_grc_dump_phy(struct qed_hwfn *p_hwfn,
3691                             struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3692 {
3693         u32 offset = 0, tbus_lo_offset, tbus_hi_offset;
3694         char mem_name[32];
3695         u8 phy_id;
3696
3697         for (phy_id = 0; phy_id < ARRAY_SIZE(s_phy_defs); phy_id++) {
3698                 u32 addr_lo_addr, addr_hi_addr, data_lo_addr, data_hi_addr;
3699                 struct phy_defs *phy_defs;
3700                 u8 *bytes_buf;
3701
3702                 phy_defs = &s_phy_defs[phy_id];
3703                 addr_lo_addr = phy_defs->base_addr +
3704                                phy_defs->tbus_addr_lo_addr;
3705                 addr_hi_addr = phy_defs->base_addr +
3706                                phy_defs->tbus_addr_hi_addr;
3707                 data_lo_addr = phy_defs->base_addr +
3708                                phy_defs->tbus_data_lo_addr;
3709                 data_hi_addr = phy_defs->base_addr +
3710                                phy_defs->tbus_data_hi_addr;
3711                 bytes_buf = (u8 *)(dump_buf + offset);
3712
3713                 if (snprintf(mem_name, sizeof(mem_name), "tbus_%s",
3714                              phy_defs->phy_name) < 0)
3715                         DP_NOTICE(p_hwfn,
3716                                   "Unexpected debug error: invalid PHY memory name\n");
3717
3718                 offset += qed_grc_dump_mem_hdr(p_hwfn,
3719                                                dump_buf + offset,
3720                                                dump,
3721                                                mem_name,
3722                                                0,
3723                                                PHY_DUMP_SIZE_DWORDS,
3724                                                16, true, mem_name, false, 0);
3725
3726                 if (!dump) {
3727                         offset += PHY_DUMP_SIZE_DWORDS;
3728                         continue;
3729                 }
3730
3731                 for (tbus_hi_offset = 0;
3732                      tbus_hi_offset < (NUM_PHY_TBUS_ADDRESSES >> 8);
3733                      tbus_hi_offset++) {
3734                         qed_wr(p_hwfn, p_ptt, addr_hi_addr, tbus_hi_offset);
3735                         for (tbus_lo_offset = 0; tbus_lo_offset < 256;
3736                              tbus_lo_offset++) {
3737                                 qed_wr(p_hwfn,
3738                                        p_ptt, addr_lo_addr, tbus_lo_offset);
3739                                 *(bytes_buf++) = (u8)qed_rd(p_hwfn,
3740                                                             p_ptt,
3741                                                             data_lo_addr);
3742                                 *(bytes_buf++) = (u8)qed_rd(p_hwfn,
3743                                                             p_ptt,
3744                                                             data_hi_addr);
3745                         }
3746                 }
3747
3748                 offset += PHY_DUMP_SIZE_DWORDS;
3749         }
3750
3751         return offset;
3752 }
3753
3754 static void qed_config_dbg_line(struct qed_hwfn *p_hwfn,
3755                                 struct qed_ptt *p_ptt,
3756                                 enum block_id block_id,
3757                                 u8 line_id,
3758                                 u8 enable_mask,
3759                                 u8 right_shift,
3760                                 u8 force_valid_mask, u8 force_frame_mask)
3761 {
3762         struct block_defs *block = s_block_defs[block_id];
3763
3764         qed_wr(p_hwfn, p_ptt, block->dbg_select_addr, line_id);
3765         qed_wr(p_hwfn, p_ptt, block->dbg_enable_addr, enable_mask);
3766         qed_wr(p_hwfn, p_ptt, block->dbg_shift_addr, right_shift);
3767         qed_wr(p_hwfn, p_ptt, block->dbg_force_valid_addr, force_valid_mask);
3768         qed_wr(p_hwfn, p_ptt, block->dbg_force_frame_addr, force_frame_mask);
3769 }
3770
3771 /* Dumps Static Debug data. Returns the dumped size in dwords. */
3772 static u32 qed_grc_dump_static_debug(struct qed_hwfn *p_hwfn,
3773                                      struct qed_ptt *p_ptt,
3774                                      u32 *dump_buf, bool dump)
3775 {
3776         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3777         u32 block_id, line_id, offset = 0;
3778
3779         /* Skip static debug if a debug bus recording is in progress */
3780         if (qed_rd(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON))
3781                 return 0;
3782
3783         if (dump) {
3784                 DP_VERBOSE(p_hwfn,
3785                            QED_MSG_DEBUG, "Dumping static debug data...\n");
3786
3787                 /* Disable all blocks debug output */
3788                 for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
3789                         struct block_defs *block = s_block_defs[block_id];
3790
3791                         if (block->has_dbg_bus[dev_data->chip_id])
3792                                 qed_wr(p_hwfn, p_ptt, block->dbg_enable_addr,
3793                                        0);
3794                 }
3795
3796                 qed_bus_reset_dbg_block(p_hwfn, p_ptt);
3797                 qed_bus_set_framing_mode(p_hwfn,
3798                                          p_ptt, DBG_BUS_FRAME_MODE_8HW_0ST);
3799                 qed_wr(p_hwfn,
3800                        p_ptt, DBG_REG_DEBUG_TARGET, DBG_BUS_TARGET_ID_INT_BUF);
3801                 qed_wr(p_hwfn, p_ptt, DBG_REG_FULL_MODE, 1);
3802                 qed_bus_enable_dbg_block(p_hwfn, p_ptt, true);
3803         }
3804
3805         /* Dump all static debug lines for each relevant block */
3806         for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
3807                 struct block_defs *block = s_block_defs[block_id];
3808                 struct dbg_bus_block *block_desc;
3809                 u32 block_dwords, addr, len;
3810                 u8 dbg_client_id;
3811
3812                 if (!block->has_dbg_bus[dev_data->chip_id])
3813                         continue;
3814
3815                 block_desc =
3816                         get_dbg_bus_block_desc(p_hwfn,
3817                                                (enum block_id)block_id);
3818                 block_dwords = NUM_DBG_LINES(block_desc) *
3819                                STATIC_DEBUG_LINE_DWORDS;
3820
3821                 /* Dump static section params */
3822                 offset += qed_grc_dump_mem_hdr(p_hwfn,
3823                                                dump_buf + offset,
3824                                                dump,
3825                                                block->name,
3826                                                0,
3827                                                block_dwords,
3828                                                32, false, "STATIC", false, 0);
3829
3830                 if (!dump) {
3831                         offset += block_dwords;
3832                         continue;
3833                 }
3834
3835                 /* If all lines are invalid - dump zeros */
3836                 if (dev_data->block_in_reset[block_id]) {
3837                         memset(dump_buf + offset, 0,
3838                                DWORDS_TO_BYTES(block_dwords));
3839                         offset += block_dwords;
3840                         continue;
3841                 }
3842
3843                 /* Enable block's client */
3844                 dbg_client_id = block->dbg_client_id[dev_data->chip_id];
3845                 qed_bus_enable_clients(p_hwfn,
3846                                        p_ptt,
3847                                        BIT(dbg_client_id));
3848
3849                 addr = BYTES_TO_DWORDS(DBG_REG_CALENDAR_OUT_DATA);
3850                 len = STATIC_DEBUG_LINE_DWORDS;
3851                 for (line_id = 0; line_id < (u32)NUM_DBG_LINES(block_desc);
3852                      line_id++) {
3853                         /* Configure debug line ID */
3854                         qed_config_dbg_line(p_hwfn,
3855                                             p_ptt,
3856                                             (enum block_id)block_id,
3857                                             (u8)line_id, 0xf, 0, 0, 0);
3858
3859                         /* Read debug line info */
3860                         offset += qed_grc_dump_addr_range(p_hwfn,
3861                                                           p_ptt,
3862                                                           dump_buf + offset,
3863                                                           dump,
3864                                                           addr,
3865                                                           len,
3866                                                           true);
3867                 }
3868
3869                 /* Disable block's client and debug output */
3870                 qed_bus_enable_clients(p_hwfn, p_ptt, 0);
3871                 qed_wr(p_hwfn, p_ptt, block->dbg_enable_addr, 0);
3872         }
3873
3874         if (dump) {
3875                 qed_bus_enable_dbg_block(p_hwfn, p_ptt, false);
3876                 qed_bus_enable_clients(p_hwfn, p_ptt, 0);
3877         }
3878
3879         return offset;
3880 }
3881
3882 /* Performs GRC Dump to the specified buffer.
3883  * Returns the dumped size in dwords.
3884  */
3885 static enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn,
3886                                     struct qed_ptt *p_ptt,
3887                                     u32 *dump_buf,
3888                                     bool dump, u32 *num_dumped_dwords)
3889 {
3890         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3891         bool parities_masked = false;
3892         u8 i, port_mode = 0;
3893         u32 offset = 0;
3894
3895         *num_dumped_dwords = 0;
3896
3897         if (dump) {
3898                 /* Find port mode */
3899                 switch (qed_rd(p_hwfn, p_ptt, MISC_REG_PORT_MODE)) {
3900                 case 0:
3901                         port_mode = 1;
3902                         break;
3903                 case 1:
3904                         port_mode = 2;
3905                         break;
3906                 case 2:
3907                         port_mode = 4;
3908                         break;
3909                 }
3910
3911                 /* Update reset state */
3912                 qed_update_blocks_reset_state(p_hwfn, p_ptt);
3913         }
3914
3915         /* Dump global params */
3916         offset += qed_dump_common_global_params(p_hwfn,
3917                                                 p_ptt,
3918                                                 dump_buf + offset, dump, 4);
3919         offset += qed_dump_str_param(dump_buf + offset,
3920                                      dump, "dump-type", "grc-dump");
3921         offset += qed_dump_num_param(dump_buf + offset,
3922                                      dump,
3923                                      "num-lcids",
3924                                      qed_grc_get_param(p_hwfn,
3925                                                 DBG_GRC_PARAM_NUM_LCIDS));
3926         offset += qed_dump_num_param(dump_buf + offset,
3927                                      dump,
3928                                      "num-ltids",
3929                                      qed_grc_get_param(p_hwfn,
3930                                                 DBG_GRC_PARAM_NUM_LTIDS));
3931         offset += qed_dump_num_param(dump_buf + offset,
3932                                      dump, "num-ports", port_mode);
3933
3934         /* Dump reset registers (dumped before taking blocks out of reset ) */
3935         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
3936                 offset += qed_grc_dump_reset_regs(p_hwfn,
3937                                                   p_ptt,
3938                                                   dump_buf + offset, dump);
3939
3940         /* Take all blocks out of reset (using reset registers) */
3941         if (dump) {
3942                 qed_grc_unreset_blocks(p_hwfn, p_ptt);
3943                 qed_update_blocks_reset_state(p_hwfn, p_ptt);
3944         }
3945
3946         /* Disable all parities using MFW command */
3947         if (dump &&
3948             !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {
3949                 parities_masked = !qed_mcp_mask_parities(p_hwfn, p_ptt, 1);
3950                 if (!parities_masked) {
3951                         DP_NOTICE(p_hwfn,
3952                                   "Failed to mask parities using MFW\n");
3953                         if (qed_grc_get_param
3954                             (p_hwfn, DBG_GRC_PARAM_PARITY_SAFE))
3955                                 return DBG_STATUS_MCP_COULD_NOT_MASK_PRTY;
3956                 }
3957         }
3958
3959         /* Dump modified registers (dumped before modifying them) */
3960         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
3961                 offset += qed_grc_dump_modified_regs(p_hwfn,
3962                                                      p_ptt,
3963                                                      dump_buf + offset, dump);
3964
3965         /* Stall storms */
3966         if (dump &&
3967             (qed_grc_is_included(p_hwfn,
3968                                  DBG_GRC_PARAM_DUMP_IOR) ||
3969              qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)))
3970                 qed_grc_stall_storms(p_hwfn, p_ptt, true);
3971
3972         /* Dump all regs  */
3973         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS)) {
3974                 bool block_enable[MAX_BLOCK_ID];
3975
3976                 /* Dump all blocks except MCP */
3977                 for (i = 0; i < MAX_BLOCK_ID; i++)
3978                         block_enable[i] = true;
3979                 block_enable[BLOCK_MCP] = false;
3980                 offset += qed_grc_dump_registers(p_hwfn,
3981                                                  p_ptt,
3982                                                  dump_buf +
3983                                                  offset,
3984                                                  dump,
3985                                                  block_enable, NULL, NULL);
3986
3987                 /* Dump special registers */
3988                 offset += qed_grc_dump_special_regs(p_hwfn,
3989                                                     p_ptt,
3990                                                     dump_buf + offset, dump);
3991         }
3992
3993         /* Dump memories */
3994         offset += qed_grc_dump_memories(p_hwfn, p_ptt, dump_buf + offset, dump);
3995
3996         /* Dump MCP */
3997         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP))
3998                 offset += qed_grc_dump_mcp(p_hwfn,
3999                                            p_ptt, dump_buf + offset, dump);
4000
4001         /* Dump context */
4002         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX))
4003                 offset += qed_grc_dump_ctx(p_hwfn,
4004                                            p_ptt, dump_buf + offset, dump);
4005
4006         /* Dump RSS memories */
4007         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RSS))
4008                 offset += qed_grc_dump_rss(p_hwfn,
4009                                            p_ptt, dump_buf + offset, dump);
4010
4011         /* Dump Big RAM */
4012         for (i = 0; i < NUM_BIG_RAM_TYPES; i++)
4013                 if (qed_grc_is_included(p_hwfn, s_big_ram_defs[i].grc_param))
4014                         offset += qed_grc_dump_big_ram(p_hwfn,
4015                                                        p_ptt,
4016                                                        dump_buf + offset,
4017                                                        dump, i);
4018
4019         /* Dump IORs */
4020         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IOR))
4021                 offset += qed_grc_dump_iors(p_hwfn,
4022                                             p_ptt, dump_buf + offset, dump);
4023
4024         /* Dump VFC */
4025         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC))
4026                 offset += qed_grc_dump_vfc(p_hwfn,
4027                                            p_ptt, dump_buf + offset, dump);
4028
4029         /* Dump PHY tbus */
4030         if (qed_grc_is_included(p_hwfn,
4031                                 DBG_GRC_PARAM_DUMP_PHY) && dev_data->chip_id ==
4032             CHIP_K2 && dev_data->platform_id == PLATFORM_ASIC)
4033                 offset += qed_grc_dump_phy(p_hwfn,
4034                                            p_ptt, dump_buf + offset, dump);
4035
4036         /* Dump static debug data  */
4037         if (qed_grc_is_included(p_hwfn,
4038                                 DBG_GRC_PARAM_DUMP_STATIC) &&
4039             dev_data->bus.state == DBG_BUS_STATE_IDLE)
4040                 offset += qed_grc_dump_static_debug(p_hwfn,
4041                                                     p_ptt,
4042                                                     dump_buf + offset, dump);
4043
4044         /* Dump last section */
4045         offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump);
4046
4047         if (dump) {
4048                 /* Unstall storms */
4049                 if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_UNSTALL))
4050                         qed_grc_stall_storms(p_hwfn, p_ptt, false);
4051
4052                 /* Clear parity status */
4053                 qed_grc_clear_all_prty(p_hwfn, p_ptt);
4054
4055                 /* Enable all parities using MFW command */
4056                 if (parities_masked)
4057                         qed_mcp_mask_parities(p_hwfn, p_ptt, 0);
4058         }
4059
4060         *num_dumped_dwords = offset;
4061
4062         return DBG_STATUS_OK;
4063 }
4064
4065 /* Writes the specified failing Idle Check rule to the specified buffer.
4066  * Returns the dumped size in dwords.
4067  */
4068 static u32 qed_idle_chk_dump_failure(struct qed_hwfn *p_hwfn,
4069                                      struct qed_ptt *p_ptt,
4070                                      u32 *
4071                                      dump_buf,
4072                                      bool dump,
4073                                      u16 rule_id,
4074                                      const struct dbg_idle_chk_rule *rule,
4075                                      u16 fail_entry_id, u32 *cond_reg_values)
4076 {
4077         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4078         const struct dbg_idle_chk_cond_reg *cond_regs;
4079         const struct dbg_idle_chk_info_reg *info_regs;
4080         u32 i, next_reg_offset = 0, offset = 0;
4081         struct dbg_idle_chk_result_hdr *hdr;
4082         const union dbg_idle_chk_reg *regs;
4083         u8 reg_id;
4084
4085         hdr = (struct dbg_idle_chk_result_hdr *)dump_buf;
4086         regs = &((const union dbg_idle_chk_reg *)
4087                  s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr)[rule->reg_offset];
4088         cond_regs = &regs[0].cond_reg;
4089         info_regs = &regs[rule->num_cond_regs].info_reg;
4090
4091         /* Dump rule data */
4092         if (dump) {
4093                 memset(hdr, 0, sizeof(*hdr));
4094                 hdr->rule_id = rule_id;
4095                 hdr->mem_entry_id = fail_entry_id;
4096                 hdr->severity = rule->severity;
4097                 hdr->num_dumped_cond_regs = rule->num_cond_regs;
4098         }
4099
4100         offset += IDLE_CHK_RESULT_HDR_DWORDS;
4101
4102         /* Dump condition register values */
4103         for (reg_id = 0; reg_id < rule->num_cond_regs; reg_id++) {
4104                 const struct dbg_idle_chk_cond_reg *reg = &cond_regs[reg_id];
4105                 struct dbg_idle_chk_result_reg_hdr *reg_hdr;
4106
4107                 reg_hdr = (struct dbg_idle_chk_result_reg_hdr *)
4108                           (dump_buf + offset);
4109
4110                 /* Write register header */
4111                 if (!dump) {
4112                         offset += IDLE_CHK_RESULT_REG_HDR_DWORDS +
4113                             reg->entry_size;
4114                         continue;
4115                 }
4116
4117                 offset += IDLE_CHK_RESULT_REG_HDR_DWORDS;
4118                 memset(reg_hdr, 0, sizeof(*reg_hdr));
4119                 reg_hdr->start_entry = reg->start_entry;
4120                 reg_hdr->size = reg->entry_size;
4121                 SET_FIELD(reg_hdr->data,
4122                           DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM,
4123                           reg->num_entries > 1 || reg->start_entry > 0 ? 1 : 0);
4124                 SET_FIELD(reg_hdr->data,
4125                           DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID, reg_id);
4126
4127                 /* Write register values */
4128                 for (i = 0; i < reg_hdr->size; i++, next_reg_offset++, offset++)
4129                         dump_buf[offset] = cond_reg_values[next_reg_offset];
4130         }
4131
4132         /* Dump info register values */
4133         for (reg_id = 0; reg_id < rule->num_info_regs; reg_id++) {
4134                 const struct dbg_idle_chk_info_reg *reg = &info_regs[reg_id];
4135                 u32 block_id;
4136
4137                 /* Check if register's block is in reset */
4138                 if (!dump) {
4139                         offset += IDLE_CHK_RESULT_REG_HDR_DWORDS + reg->size;
4140                         continue;
4141                 }
4142
4143                 block_id = GET_FIELD(reg->data, DBG_IDLE_CHK_INFO_REG_BLOCK_ID);
4144                 if (block_id >= MAX_BLOCK_ID) {
4145                         DP_NOTICE(p_hwfn, "Invalid block_id\n");
4146                         return 0;
4147                 }
4148
4149                 if (!dev_data->block_in_reset[block_id]) {
4150                         struct dbg_idle_chk_result_reg_hdr *reg_hdr;
4151                         bool wide_bus, eval_mode, mode_match = true;
4152                         u16 modes_buf_offset;
4153                         u32 addr;
4154
4155                         reg_hdr = (struct dbg_idle_chk_result_reg_hdr *)
4156                                   (dump_buf + offset);
4157
4158                         /* Check mode */
4159                         eval_mode = GET_FIELD(reg->mode.data,
4160                                               DBG_MODE_HDR_EVAL_MODE) > 0;
4161                         if (eval_mode) {
4162                                 modes_buf_offset =
4163                                     GET_FIELD(reg->mode.data,
4164                                               DBG_MODE_HDR_MODES_BUF_OFFSET);
4165                                 mode_match =
4166                                         qed_is_mode_match(p_hwfn,
4167                                                           &modes_buf_offset);
4168                         }
4169
4170                         if (!mode_match)
4171                                 continue;
4172
4173                         addr = GET_FIELD(reg->data,
4174                                          DBG_IDLE_CHK_INFO_REG_ADDRESS);
4175                         wide_bus = GET_FIELD(reg->data,
4176                                              DBG_IDLE_CHK_INFO_REG_WIDE_BUS);
4177
4178                         /* Write register header */
4179                         offset += IDLE_CHK_RESULT_REG_HDR_DWORDS;
4180                         hdr->num_dumped_info_regs++;
4181                         memset(reg_hdr, 0, sizeof(*reg_hdr));
4182                         reg_hdr->size = reg->size;
4183                         SET_FIELD(reg_hdr->data,
4184                                   DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID,
4185                                   rule->num_cond_regs + reg_id);
4186
4187                         /* Write register values */
4188                         offset += qed_grc_dump_addr_range(p_hwfn,
4189                                                           p_ptt,
4190                                                           dump_buf + offset,
4191                                                           dump,
4192                                                           addr,
4193                                                           reg->size, wide_bus);
4194                 }
4195         }
4196
4197         return offset;
4198 }
4199
4200 /* Dumps idle check rule entries. Returns the dumped size in dwords. */
4201 static u32
4202 qed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
4203                                u32 *dump_buf, bool dump,
4204                                const struct dbg_idle_chk_rule *input_rules,
4205                                u32 num_input_rules, u32 *num_failing_rules)
4206 {
4207         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4208         u32 cond_reg_values[IDLE_CHK_MAX_ENTRIES_SIZE];
4209         u32 i, offset = 0;
4210         u16 entry_id;
4211         u8 reg_id;
4212
4213         *num_failing_rules = 0;
4214
4215         for (i = 0; i < num_input_rules; i++) {
4216                 const struct dbg_idle_chk_cond_reg *cond_regs;
4217                 const struct dbg_idle_chk_rule *rule;
4218                 const union dbg_idle_chk_reg *regs;
4219                 u16 num_reg_entries = 1;
4220                 bool check_rule = true;
4221                 const u32 *imm_values;
4222
4223                 rule = &input_rules[i];
4224                 regs = &((const union dbg_idle_chk_reg *)
4225                          s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr)
4226                         [rule->reg_offset];
4227                 cond_regs = &regs[0].cond_reg;
4228                 imm_values = &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr
4229                              [rule->imm_offset];
4230
4231                 /* Check if all condition register blocks are out of reset, and
4232                  * find maximal number of entries (all condition registers that
4233                  * are memories must have the same size, which is > 1).
4234                  */
4235                 for (reg_id = 0; reg_id < rule->num_cond_regs && check_rule;
4236                      reg_id++) {
4237                         u32 block_id =
4238                                 GET_FIELD(cond_regs[reg_id].data,
4239                                           DBG_IDLE_CHK_COND_REG_BLOCK_ID);
4240
4241                         if (block_id >= MAX_BLOCK_ID) {
4242                                 DP_NOTICE(p_hwfn, "Invalid block_id\n");
4243                                 return 0;
4244                         }
4245
4246                         check_rule = !dev_data->block_in_reset[block_id];
4247                         if (cond_regs[reg_id].num_entries > num_reg_entries)
4248                                 num_reg_entries = cond_regs[reg_id].num_entries;
4249                 }
4250
4251                 if (!check_rule && dump)
4252                         continue;
4253
4254                 /* Go over all register entries (number of entries is the same
4255                  * for all condition registers).
4256                  */
4257                 for (entry_id = 0; entry_id < num_reg_entries; entry_id++) {
4258                         u32 next_reg_offset = 0;
4259
4260                         if (!dump) {
4261                                 offset += qed_idle_chk_dump_failure(p_hwfn,
4262                                                         p_ptt,
4263                                                         dump_buf + offset,
4264                                                         false,
4265                                                         rule->rule_id,
4266                                                         rule,
4267                                                         entry_id,
4268                                                         NULL);
4269                                 (*num_failing_rules)++;
4270                                 break;
4271                         }
4272
4273                         /* Read current entry of all condition registers */
4274                         for (reg_id = 0; reg_id < rule->num_cond_regs;
4275                              reg_id++) {
4276                                 const struct dbg_idle_chk_cond_reg *reg =
4277                                     &cond_regs[reg_id];
4278                                 u32 padded_entry_size, addr;
4279                                 bool wide_bus;
4280
4281                                 /* Find GRC address (if it's a memory, the
4282                                  * address of the specific entry is calculated).
4283                                  */
4284                                 addr = GET_FIELD(reg->data,
4285                                                  DBG_IDLE_CHK_COND_REG_ADDRESS);
4286                                 wide_bus =
4287                                     GET_FIELD(reg->data,
4288                                               DBG_IDLE_CHK_COND_REG_WIDE_BUS);
4289                                 if (reg->num_entries > 1 ||
4290                                     reg->start_entry > 0) {
4291                                         padded_entry_size =
4292                                             reg->entry_size > 1 ?
4293                                             roundup_pow_of_two(reg->entry_size)
4294                                             : 1;
4295                                         addr += (reg->start_entry + entry_id) *
4296                                                 padded_entry_size;
4297                                 }
4298
4299                                 /* Read registers */
4300                                 if (next_reg_offset + reg->entry_size >=
4301                                     IDLE_CHK_MAX_ENTRIES_SIZE) {
4302                                         DP_NOTICE(p_hwfn,
4303                                                   "idle check registers entry is too large\n");
4304                                         return 0;
4305                                 }
4306
4307                                 next_reg_offset +=
4308                                     qed_grc_dump_addr_range(p_hwfn, p_ptt,
4309                                                             cond_reg_values +
4310                                                             next_reg_offset,
4311                                                             dump, addr,
4312                                                             reg->entry_size,
4313                                                             wide_bus);
4314                         }
4315
4316                         /* Call rule condition function.
4317                          * If returns true, it's a failure.
4318                          */
4319                         if ((*cond_arr[rule->cond_id]) (cond_reg_values,
4320                                                         imm_values)) {
4321                                 offset += qed_idle_chk_dump_failure(p_hwfn,
4322                                                         p_ptt,
4323                                                         dump_buf + offset,
4324                                                         dump,
4325                                                         rule->rule_id,
4326                                                         rule,
4327                                                         entry_id,
4328                                                         cond_reg_values);
4329                                 (*num_failing_rules)++;
4330                                 break;
4331                         }
4332                 }
4333         }
4334
4335         return offset;
4336 }
4337
4338 /* Performs Idle Check Dump to the specified buffer.
4339  * Returns the dumped size in dwords.
4340  */
4341 static u32 qed_idle_chk_dump(struct qed_hwfn *p_hwfn,
4342                              struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
4343 {
4344         u32 num_failing_rules_offset, offset = 0, input_offset = 0;
4345         u32 num_failing_rules = 0;
4346
4347         /* Dump global params */
4348         offset += qed_dump_common_global_params(p_hwfn,
4349                                                 p_ptt,
4350                                                 dump_buf + offset, dump, 1);
4351         offset += qed_dump_str_param(dump_buf + offset,
4352                                      dump, "dump-type", "idle-chk");
4353
4354         /* Dump idle check section header with a single parameter */
4355         offset += qed_dump_section_hdr(dump_buf + offset, dump, "idle_chk", 1);
4356         num_failing_rules_offset = offset;
4357         offset += qed_dump_num_param(dump_buf + offset, dump, "num_rules", 0);
4358
4359         while (input_offset <
4360                s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].size_in_dwords) {
4361                 const struct dbg_idle_chk_cond_hdr *cond_hdr =
4362                         (const struct dbg_idle_chk_cond_hdr *)
4363                         &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr
4364                         [input_offset++];
4365                 bool eval_mode, mode_match = true;
4366                 u32 curr_failing_rules;
4367                 u16 modes_buf_offset;
4368
4369                 /* Check mode */
4370                 eval_mode = GET_FIELD(cond_hdr->mode.data,
4371                                       DBG_MODE_HDR_EVAL_MODE) > 0;
4372                 if (eval_mode) {
4373                         modes_buf_offset =
4374                                 GET_FIELD(cond_hdr->mode.data,
4375                                           DBG_MODE_HDR_MODES_BUF_OFFSET);
4376                         mode_match = qed_is_mode_match(p_hwfn,
4377                                                        &modes_buf_offset);
4378                 }
4379
4380                 if (mode_match) {
4381                         offset +=
4382                             qed_idle_chk_dump_rule_entries(p_hwfn,
4383                                 p_ptt,
4384                                 dump_buf + offset,
4385                                 dump,
4386                                 (const struct dbg_idle_chk_rule *)
4387                                 &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].
4388                                 ptr[input_offset],
4389                                 cond_hdr->data_size / IDLE_CHK_RULE_SIZE_DWORDS,
4390                                 &curr_failing_rules);
4391                         num_failing_rules += curr_failing_rules;
4392                 }
4393
4394                 input_offset += cond_hdr->data_size;
4395         }
4396
4397         /* Overwrite num_rules parameter */
4398         if (dump)
4399                 qed_dump_num_param(dump_buf + num_failing_rules_offset,
4400                                    dump, "num_rules", num_failing_rules);
4401
4402         /* Dump last section */
4403         offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump);
4404
4405         return offset;
4406 }
4407
4408 /* Finds the meta data image in NVRAM */
4409 static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
4410                                             struct qed_ptt *p_ptt,
4411                                             u32 image_type,
4412                                             u32 *nvram_offset_bytes,
4413                                             u32 *nvram_size_bytes)
4414 {
4415         u32 ret_mcp_resp, ret_mcp_param, ret_txn_size;
4416         struct mcp_file_att file_att;
4417         int nvm_result;
4418
4419         /* Call NVRAM get file command */
4420         nvm_result = qed_mcp_nvm_rd_cmd(p_hwfn,
4421                                         p_ptt,
4422                                         DRV_MSG_CODE_NVM_GET_FILE_ATT,
4423                                         image_type,
4424                                         &ret_mcp_resp,
4425                                         &ret_mcp_param,
4426                                         &ret_txn_size, (u32 *)&file_att);
4427
4428         /* Check response */
4429         if (nvm_result ||
4430             (ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
4431                 return DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
4432
4433         /* Update return values */
4434         *nvram_offset_bytes = file_att.nvm_start_addr;
4435         *nvram_size_bytes = file_att.len;
4436
4437         DP_VERBOSE(p_hwfn,
4438                    QED_MSG_DEBUG,
4439                    "find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\n",
4440                    image_type, *nvram_offset_bytes, *nvram_size_bytes);
4441
4442         /* Check alignment */
4443         if (*nvram_size_bytes & 0x3)
4444                 return DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE;
4445
4446         return DBG_STATUS_OK;
4447 }
4448
4449 /* Reads data from NVRAM */
4450 static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
4451                                       struct qed_ptt *p_ptt,
4452                                       u32 nvram_offset_bytes,
4453                                       u32 nvram_size_bytes, u32 *ret_buf)
4454 {
4455         u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy;
4456         s32 bytes_left = nvram_size_bytes;
4457         u32 read_offset = 0;
4458
4459         DP_VERBOSE(p_hwfn,
4460                    QED_MSG_DEBUG,
4461                    "nvram_read: reading image of size %d bytes from NVRAM\n",
4462                    nvram_size_bytes);
4463
4464         do {
4465                 bytes_to_copy =
4466                     (bytes_left >
4467                      MCP_DRV_NVM_BUF_LEN) ? MCP_DRV_NVM_BUF_LEN : bytes_left;
4468
4469                 /* Call NVRAM read command */
4470                 if (qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt,
4471                                        DRV_MSG_CODE_NVM_READ_NVRAM,
4472                                        (nvram_offset_bytes +
4473                                         read_offset) |
4474                                        (bytes_to_copy <<
4475                                         DRV_MB_PARAM_NVM_LEN_SHIFT),
4476                                        &ret_mcp_resp, &ret_mcp_param,
4477                                        &ret_read_size,
4478                                        (u32 *)((u8 *)ret_buf + read_offset)))
4479                         return DBG_STATUS_NVRAM_READ_FAILED;
4480
4481                 /* Check response */
4482                 if ((ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
4483                         return DBG_STATUS_NVRAM_READ_FAILED;
4484
4485                 /* Update read offset */
4486                 read_offset += ret_read_size;
4487                 bytes_left -= ret_read_size;
4488         } while (bytes_left > 0);
4489
4490         return DBG_STATUS_OK;
4491 }
4492
4493 /* Get info on the MCP Trace data in the scratchpad:
4494  * - trace_data_grc_addr (OUT): trace data GRC address in bytes
4495  * - trace_data_size (OUT): trace data size in bytes (without the header)
4496  */
4497 static enum dbg_status qed_mcp_trace_get_data_info(struct qed_hwfn *p_hwfn,
4498                                                    struct qed_ptt *p_ptt,
4499                                                    u32 *trace_data_grc_addr,
4500                                                    u32 *trace_data_size)
4501 {
4502         u32 spad_trace_offsize, signature;
4503
4504         /* Read trace section offsize structure from MCP scratchpad */
4505         spad_trace_offsize = qed_rd(p_hwfn, p_ptt, MCP_SPAD_TRACE_OFFSIZE_ADDR);
4506
4507         /* Extract trace section address from offsize (in scratchpad) */
4508         *trace_data_grc_addr =
4509                 MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize);
4510
4511         /* Read signature from MCP trace section */
4512         signature = qed_rd(p_hwfn, p_ptt,
4513                            *trace_data_grc_addr +
4514                            offsetof(struct mcp_trace, signature));
4515
4516         if (signature != MFW_TRACE_SIGNATURE)
4517                 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4518
4519         /* Read trace size from MCP trace section */
4520         *trace_data_size = qed_rd(p_hwfn,
4521                                   p_ptt,
4522                                   *trace_data_grc_addr +
4523                                   offsetof(struct mcp_trace, size));
4524
4525         return DBG_STATUS_OK;
4526 }
4527
4528 /* Reads MCP trace meta data image from NVRAM
4529  * - running_bundle_id (OUT): running bundle ID (invalid when loaded from file)
4530  * - trace_meta_offset (OUT): trace meta offset in NVRAM in bytes (invalid when
4531  *                            loaded from file).
4532  * - trace_meta_size (OUT):   size in bytes of the trace meta data.
4533  */
4534 static enum dbg_status qed_mcp_trace_get_meta_info(struct qed_hwfn *p_hwfn,
4535                                                    struct qed_ptt *p_ptt,
4536                                                    u32 trace_data_size_bytes,
4537                                                    u32 *running_bundle_id,
4538                                                    u32 *trace_meta_offset,
4539                                                    u32 *trace_meta_size)
4540 {
4541         u32 spad_trace_offsize, nvram_image_type, running_mfw_addr;
4542
4543         /* Read MCP trace section offsize structure from MCP scratchpad */
4544         spad_trace_offsize = qed_rd(p_hwfn, p_ptt, MCP_SPAD_TRACE_OFFSIZE_ADDR);
4545
4546         /* Find running bundle ID */
4547         running_mfw_addr =
4548                 MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize) +
4549                 QED_SECTION_SIZE(spad_trace_offsize) + trace_data_size_bytes;
4550         *running_bundle_id = qed_rd(p_hwfn, p_ptt, running_mfw_addr);
4551         if (*running_bundle_id > 1)
4552                 return DBG_STATUS_INVALID_NVRAM_BUNDLE;
4553
4554         /* Find image in NVRAM */
4555         nvram_image_type =
4556             (*running_bundle_id ==
4557              DIR_ID_1) ? NVM_TYPE_MFW_TRACE1 : NVM_TYPE_MFW_TRACE2;
4558         return qed_find_nvram_image(p_hwfn,
4559                                     p_ptt,
4560                                     nvram_image_type,
4561                                     trace_meta_offset, trace_meta_size);
4562 }
4563
4564 /* Reads the MCP Trace meta data from NVRAM into the specified buffer */
4565 static enum dbg_status qed_mcp_trace_read_meta(struct qed_hwfn *p_hwfn,
4566                                                struct qed_ptt *p_ptt,
4567                                                u32 nvram_offset_in_bytes,
4568                                                u32 size_in_bytes, u32 *buf)
4569 {
4570         u8 modules_num, module_len, i, *byte_buf = (u8 *)buf;
4571         enum dbg_status status;
4572         u32 signature;
4573
4574         /* Read meta data from NVRAM */
4575         status = qed_nvram_read(p_hwfn,
4576                                 p_ptt,
4577                                 nvram_offset_in_bytes, size_in_bytes, buf);
4578         if (status != DBG_STATUS_OK)
4579                 return status;
4580
4581         /* Extract and check first signature */
4582         signature = qed_read_unaligned_dword(byte_buf);
4583         byte_buf += sizeof(signature);
4584         if (signature != NVM_MAGIC_VALUE)
4585                 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4586
4587         /* Extract number of modules */
4588         modules_num = *(byte_buf++);
4589
4590         /* Skip all modules */
4591         for (i = 0; i < modules_num; i++) {
4592                 module_len = *(byte_buf++);
4593                 byte_buf += module_len;
4594         }
4595
4596         /* Extract and check second signature */
4597         signature = qed_read_unaligned_dword(byte_buf);
4598         byte_buf += sizeof(signature);
4599         if (signature != NVM_MAGIC_VALUE)
4600                 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4601
4602         return DBG_STATUS_OK;
4603 }
4604
4605 /* Dump MCP Trace */
4606 static enum dbg_status qed_mcp_trace_dump(struct qed_hwfn *p_hwfn,
4607                                           struct qed_ptt *p_ptt,
4608                                           u32 *dump_buf,
4609                                           bool dump, u32 *num_dumped_dwords)
4610 {
4611         u32 trace_data_grc_addr, trace_data_size_bytes, trace_data_size_dwords;
4612         u32 trace_meta_size_dwords = 0, running_bundle_id, offset = 0;
4613         u32 trace_meta_offset_bytes = 0, trace_meta_size_bytes = 0;
4614         enum dbg_status status;
4615         bool mcp_access;
4616         int halted = 0;
4617
4618         *num_dumped_dwords = 0;
4619
4620         mcp_access = !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP);
4621
4622         /* Get trace data info */
4623         status = qed_mcp_trace_get_data_info(p_hwfn,
4624                                              p_ptt,
4625                                              &trace_data_grc_addr,
4626                                              &trace_data_size_bytes);
4627         if (status != DBG_STATUS_OK)
4628                 return status;
4629
4630         /* Dump global params */
4631         offset += qed_dump_common_global_params(p_hwfn,
4632                                                 p_ptt,
4633                                                 dump_buf + offset, dump, 1);
4634         offset += qed_dump_str_param(dump_buf + offset,
4635                                      dump, "dump-type", "mcp-trace");
4636
4637         /* Halt MCP while reading from scratchpad so the read data will be
4638          * consistent. if halt fails, MCP trace is taken anyway, with a small
4639          * risk that it may be corrupt.
4640          */
4641         if (dump && mcp_access) {
4642                 halted = !qed_mcp_halt(p_hwfn, p_ptt);
4643                 if (!halted)
4644                         DP_NOTICE(p_hwfn, "MCP halt failed!\n");
4645         }
4646
4647         /* Find trace data size */
4648         trace_data_size_dwords =
4649             DIV_ROUND_UP(trace_data_size_bytes + sizeof(struct mcp_trace),
4650                          BYTES_IN_DWORD);
4651
4652         /* Dump trace data section header and param */
4653         offset += qed_dump_section_hdr(dump_buf + offset,
4654                                        dump, "mcp_trace_data", 1);
4655         offset += qed_dump_num_param(dump_buf + offset,
4656                                      dump, "size", trace_data_size_dwords);
4657
4658         /* Read trace data from scratchpad into dump buffer */
4659         offset += qed_grc_dump_addr_range(p_hwfn,
4660                                           p_ptt,
4661                                           dump_buf + offset,
4662                                           dump,
4663                                           BYTES_TO_DWORDS(trace_data_grc_addr),
4664                                           trace_data_size_dwords, false);
4665
4666         /* Resume MCP (only if halt succeeded) */
4667         if (halted && qed_mcp_resume(p_hwfn, p_ptt))
4668                 DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n");
4669
4670         /* Dump trace meta section header */
4671         offset += qed_dump_section_hdr(dump_buf + offset,
4672                                        dump, "mcp_trace_meta", 1);
4673
4674         /* Read trace meta info (trace_meta_size_bytes is dword-aligned) */
4675         if (mcp_access) {
4676                 status = qed_mcp_trace_get_meta_info(p_hwfn,
4677                                                      p_ptt,
4678                                                      trace_data_size_bytes,
4679                                                      &running_bundle_id,
4680                                                      &trace_meta_offset_bytes,
4681                                                      &trace_meta_size_bytes);
4682                 if (status == DBG_STATUS_OK)
4683                         trace_meta_size_dwords =
4684                                 BYTES_TO_DWORDS(trace_meta_size_bytes);
4685         }
4686
4687         /* Dump trace meta size param */
4688         offset += qed_dump_num_param(dump_buf + offset,
4689                                      dump, "size", trace_meta_size_dwords);
4690
4691         /* Read trace meta image into dump buffer */
4692         if (dump && trace_meta_size_dwords)
4693                 status = qed_mcp_trace_read_meta(p_hwfn,
4694                                                  p_ptt,
4695                                                  trace_meta_offset_bytes,
4696                                                  trace_meta_size_bytes,
4697                                                  dump_buf + offset);
4698         if (status == DBG_STATUS_OK)
4699                 offset += trace_meta_size_dwords;
4700
4701         /* Dump last section */
4702         offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump);
4703
4704         *num_dumped_dwords = offset;
4705
4706         /* If no mcp access, indicate that the dump doesn't contain the meta
4707          * data from NVRAM.
4708          */
4709         return mcp_access ? status : DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
4710 }
4711
4712 /* Dump GRC FIFO */
4713 static enum dbg_status qed_reg_fifo_dump(struct qed_hwfn *p_hwfn,
4714                                          struct qed_ptt *p_ptt,
4715                                          u32 *dump_buf,
4716                                          bool dump, u32 *num_dumped_dwords)
4717 {
4718         u32 dwords_read, size_param_offset, offset = 0;
4719         bool fifo_has_data;
4720
4721         *num_dumped_dwords = 0;
4722
4723         /* Dump global params */
4724         offset += qed_dump_common_global_params(p_hwfn,
4725                                                 p_ptt,
4726                                                 dump_buf + offset, dump, 1);
4727         offset += qed_dump_str_param(dump_buf + offset,
4728                                      dump, "dump-type", "reg-fifo");
4729
4730         /* Dump fifo data section header and param. The size param is 0 for
4731          * now, and is overwritten after reading the FIFO.
4732          */
4733         offset += qed_dump_section_hdr(dump_buf + offset,
4734                                        dump, "reg_fifo_data", 1);
4735         size_param_offset = offset;
4736         offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4737
4738         if (!dump) {
4739                 /* FIFO max size is REG_FIFO_DEPTH_DWORDS. There is no way to
4740                  * test how much data is available, except for reading it.
4741                  */
4742                 offset += REG_FIFO_DEPTH_DWORDS;
4743                 goto out;
4744         }
4745
4746         fifo_has_data = qed_rd(p_hwfn, p_ptt,
4747                                GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
4748
4749         /* Pull available data from fifo. Use DMAE since this is widebus memory
4750          * and must be accessed atomically. Test for dwords_read not passing
4751          * buffer size since more entries could be added to the buffer as we are
4752          * emptying it.
4753          */
4754         for (dwords_read = 0;
4755              fifo_has_data && dwords_read < REG_FIFO_DEPTH_DWORDS;
4756              dwords_read += REG_FIFO_ELEMENT_DWORDS, offset +=
4757              REG_FIFO_ELEMENT_DWORDS) {
4758                 if (qed_dmae_grc2host(p_hwfn, p_ptt, GRC_REG_TRACE_FIFO,
4759                                       (u64)(uintptr_t)(&dump_buf[offset]),
4760                                       REG_FIFO_ELEMENT_DWORDS, 0))
4761                         return DBG_STATUS_DMAE_FAILED;
4762                 fifo_has_data = qed_rd(p_hwfn, p_ptt,
4763                                        GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
4764         }
4765
4766         qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4767                            dwords_read);
4768 out:
4769         /* Dump last section */
4770         offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump);
4771
4772         *num_dumped_dwords = offset;
4773
4774         return DBG_STATUS_OK;
4775 }
4776
4777 /* Dump IGU FIFO */
4778 static enum dbg_status qed_igu_fifo_dump(struct qed_hwfn *p_hwfn,
4779                                          struct qed_ptt *p_ptt,
4780                                          u32 *dump_buf,
4781                                          bool dump, u32 *num_dumped_dwords)
4782 {
4783         u32 dwords_read, size_param_offset, offset = 0;
4784         bool fifo_has_data;
4785
4786         *num_dumped_dwords = 0;
4787
4788         /* Dump global params */
4789         offset += qed_dump_common_global_params(p_hwfn,
4790                                                 p_ptt,
4791                                                 dump_buf + offset, dump, 1);
4792         offset += qed_dump_str_param(dump_buf + offset,
4793                                      dump, "dump-type", "igu-fifo");
4794
4795         /* Dump fifo data section header and param. The size param is 0 for
4796          * now, and is overwritten after reading the FIFO.
4797          */
4798         offset += qed_dump_section_hdr(dump_buf + offset,
4799                                        dump, "igu_fifo_data", 1);
4800         size_param_offset = offset;
4801         offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4802
4803         if (!dump) {
4804                 /* FIFO max size is IGU_FIFO_DEPTH_DWORDS. There is no way to
4805                  * test how much data is available, except for reading it.
4806                  */
4807                 offset += IGU_FIFO_DEPTH_DWORDS;
4808                 goto out;
4809         }
4810
4811         fifo_has_data = qed_rd(p_hwfn, p_ptt,
4812                                IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
4813
4814         /* Pull available data from fifo. Use DMAE since this is widebus memory
4815          * and must be accessed atomically. Test for dwords_read not passing
4816          * buffer size since more entries could be added to the buffer as we are
4817          * emptying it.
4818          */
4819         for (dwords_read = 0;
4820              fifo_has_data && dwords_read < IGU_FIFO_DEPTH_DWORDS;
4821              dwords_read += IGU_FIFO_ELEMENT_DWORDS, offset +=
4822              IGU_FIFO_ELEMENT_DWORDS) {
4823                 if (qed_dmae_grc2host(p_hwfn, p_ptt,
4824                                       IGU_REG_ERROR_HANDLING_MEMORY,
4825                                       (u64)(uintptr_t)(&dump_buf[offset]),
4826                                       IGU_FIFO_ELEMENT_DWORDS, 0))
4827                         return DBG_STATUS_DMAE_FAILED;
4828                 fifo_has_data = qed_rd(p_hwfn, p_ptt,
4829                                        IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
4830         }
4831
4832         qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4833                            dwords_read);
4834 out:
4835         /* Dump last section */
4836         offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump);
4837
4838         *num_dumped_dwords = offset;
4839
4840         return DBG_STATUS_OK;
4841 }
4842
4843 /* Protection Override dump */
4844 static enum dbg_status qed_protection_override_dump(struct qed_hwfn *p_hwfn,
4845                                                     struct qed_ptt *p_ptt,
4846                                                     u32 *dump_buf,
4847                                                     bool dump,
4848                                                     u32 *num_dumped_dwords)
4849 {
4850         u32 size_param_offset, override_window_dwords, offset = 0;
4851
4852         *num_dumped_dwords = 0;
4853
4854         /* Dump global params */
4855         offset += qed_dump_common_global_params(p_hwfn,
4856                                                 p_ptt,
4857                                                 dump_buf + offset, dump, 1);
4858         offset += qed_dump_str_param(dump_buf + offset,
4859                                      dump, "dump-type", "protection-override");
4860
4861         /* Dump data section header and param. The size param is 0 for now,
4862          * and is overwritten after reading the data.
4863          */
4864         offset += qed_dump_section_hdr(dump_buf + offset,
4865                                        dump, "protection_override_data", 1);
4866         size_param_offset = offset;
4867         offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4868
4869         if (!dump) {
4870                 offset += PROTECTION_OVERRIDE_DEPTH_DWORDS;
4871                 goto out;
4872         }
4873
4874         /* Add override window info to buffer */
4875         override_window_dwords =
4876                 qed_rd(p_hwfn, p_ptt,
4877                        GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW) *
4878                        PROTECTION_OVERRIDE_ELEMENT_DWORDS;
4879         if (qed_dmae_grc2host(p_hwfn, p_ptt,
4880                               GRC_REG_PROTECTION_OVERRIDE_WINDOW,
4881                               (u64)(uintptr_t)(dump_buf + offset),
4882                               override_window_dwords, 0))
4883                 return DBG_STATUS_DMAE_FAILED;
4884         offset += override_window_dwords;
4885         qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4886                            override_window_dwords);
4887 out:
4888         /* Dump last section */
4889         offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump);
4890
4891         *num_dumped_dwords = offset;
4892
4893         return DBG_STATUS_OK;
4894 }
4895
4896 /* Performs FW Asserts Dump to the specified buffer.
4897  * Returns the dumped size in dwords.
4898  */
4899 static u32 qed_fw_asserts_dump(struct qed_hwfn *p_hwfn,
4900                                struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
4901 {
4902         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4903         struct fw_asserts_ram_section *asserts;
4904         char storm_letter_str[2] = "?";
4905         struct fw_info fw_info;
4906         u32 offset = 0;
4907         u8 storm_id;
4908
4909         /* Dump global params */
4910         offset += qed_dump_common_global_params(p_hwfn,
4911                                                 p_ptt,
4912                                                 dump_buf + offset, dump, 1);
4913         offset += qed_dump_str_param(dump_buf + offset,
4914                                      dump, "dump-type", "fw-asserts");
4915
4916         /* Find Storm dump size */
4917         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
4918                 u32 fw_asserts_section_addr, next_list_idx_addr, next_list_idx;
4919                 struct storm_defs *storm = &s_storm_defs[storm_id];
4920                 u32 last_list_idx, addr;
4921
4922                 if (dev_data->block_in_reset[storm->block_id])
4923                         continue;
4924
4925                 /* Read FW info for the current Storm */
4926                 qed_read_fw_info(p_hwfn, p_ptt, storm_id, &fw_info);
4927
4928                 asserts = &fw_info.fw_asserts_section;
4929
4930                 /* Dump FW Asserts section header and params */
4931                 storm_letter_str[0] = storm->letter;
4932                 offset += qed_dump_section_hdr(dump_buf + offset,
4933                                                dump, "fw_asserts", 2);
4934                 offset += qed_dump_str_param(dump_buf + offset,
4935                                              dump, "storm", storm_letter_str);
4936                 offset += qed_dump_num_param(dump_buf + offset,
4937                                              dump,
4938                                              "size",
4939                                              asserts->list_element_dword_size);
4940
4941                 /* Read and dump FW Asserts data */
4942                 if (!dump) {
4943                         offset += asserts->list_element_dword_size;
4944                         continue;
4945                 }
4946
4947                 fw_asserts_section_addr = storm->sem_fast_mem_addr +
4948                         SEM_FAST_REG_INT_RAM +
4949                         RAM_LINES_TO_BYTES(asserts->section_ram_line_offset);
4950                 next_list_idx_addr = fw_asserts_section_addr +
4951                         DWORDS_TO_BYTES(asserts->list_next_index_dword_offset);
4952                 next_list_idx = qed_rd(p_hwfn, p_ptt, next_list_idx_addr);
4953                 last_list_idx = (next_list_idx > 0
4954                                  ? next_list_idx
4955                                  : asserts->list_num_elements) - 1;
4956                 addr = BYTES_TO_DWORDS(fw_asserts_section_addr) +
4957                        asserts->list_dword_offset +
4958                        last_list_idx * asserts->list_element_dword_size;
4959                 offset +=
4960                     qed_grc_dump_addr_range(p_hwfn, p_ptt,
4961                                             dump_buf + offset,
4962                                             dump, addr,
4963                                             asserts->list_element_dword_size,
4964                                             false);
4965         }
4966
4967         /* Dump last section */
4968         offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump);
4969
4970         return offset;
4971 }
4972
4973 /***************************** Public Functions *******************************/
4974
4975 enum dbg_status qed_dbg_set_bin_ptr(const u8 * const bin_ptr)
4976 {
4977         struct bin_buffer_hdr *buf_array = (struct bin_buffer_hdr *)bin_ptr;
4978         u8 buf_id;
4979
4980         /* convert binary data to debug arrays */
4981         for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++) {
4982                 s_dbg_arrays[buf_id].ptr =
4983                     (u32 *)(bin_ptr + buf_array[buf_id].offset);
4984                 s_dbg_arrays[buf_id].size_in_dwords =
4985                     BYTES_TO_DWORDS(buf_array[buf_id].length);
4986         }
4987
4988         return DBG_STATUS_OK;
4989 }
4990
4991 /* Assign default GRC param values */
4992 void qed_dbg_grc_set_params_default(struct qed_hwfn *p_hwfn)
4993 {
4994         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4995         u32 i;
4996
4997         for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
4998                 dev_data->grc.param_val[i] =
4999                     s_grc_param_defs[i].default_val[dev_data->chip_id];
5000 }
5001
5002 enum dbg_status qed_dbg_grc_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5003                                               struct qed_ptt *p_ptt,
5004                                               u32 *buf_size)
5005 {
5006         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5007
5008         *buf_size = 0;
5009
5010         if (status != DBG_STATUS_OK)
5011                 return status;
5012
5013         if (!s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
5014             !s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr ||
5015             !s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr ||
5016             !s_dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||
5017             !s_dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)
5018                 return DBG_STATUS_DBG_ARRAY_NOT_SET;
5019
5020         return qed_grc_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5021 }
5022
5023 enum dbg_status qed_dbg_grc_dump(struct qed_hwfn *p_hwfn,
5024                                  struct qed_ptt *p_ptt,
5025                                  u32 *dump_buf,
5026                                  u32 buf_size_in_dwords,
5027                                  u32 *num_dumped_dwords)
5028 {
5029         u32 needed_buf_size_in_dwords;
5030         enum dbg_status status;
5031
5032         *num_dumped_dwords = 0;
5033
5034         status = qed_dbg_grc_get_dump_buf_size(p_hwfn,
5035                                                p_ptt,
5036                                                &needed_buf_size_in_dwords);
5037         if (status != DBG_STATUS_OK)
5038                 return status;
5039
5040         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5041                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5042
5043         /* GRC Dump */
5044         status = qed_grc_dump(p_hwfn, p_ptt, dump_buf, true, num_dumped_dwords);
5045
5046         /* Revert GRC params to their default */
5047         qed_dbg_grc_set_params_default(p_hwfn);
5048
5049         return status;
5050 }
5051
5052 enum dbg_status qed_dbg_idle_chk_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5053                                                    struct qed_ptt *p_ptt,
5054                                                    u32 *buf_size)
5055 {
5056         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5057         struct idle_chk_data *idle_chk;
5058         enum dbg_status status;
5059
5060         idle_chk = &dev_data->idle_chk;
5061         *buf_size = 0;
5062
5063         status = qed_dbg_dev_init(p_hwfn, p_ptt);
5064         if (status != DBG_STATUS_OK)
5065                 return status;
5066
5067         if (!s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
5068             !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr ||
5069             !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr ||
5070             !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr)
5071                 return DBG_STATUS_DBG_ARRAY_NOT_SET;
5072
5073         if (!idle_chk->buf_size_set) {
5074                 idle_chk->buf_size = qed_idle_chk_dump(p_hwfn,
5075                                                        p_ptt, NULL, false);
5076                 idle_chk->buf_size_set = true;
5077         }
5078
5079         *buf_size = idle_chk->buf_size;
5080
5081         return DBG_STATUS_OK;
5082 }
5083
5084 enum dbg_status qed_dbg_idle_chk_dump(struct qed_hwfn *p_hwfn,
5085                                       struct qed_ptt *p_ptt,
5086                                       u32 *dump_buf,
5087                                       u32 buf_size_in_dwords,
5088                                       u32 *num_dumped_dwords)
5089 {
5090         u32 needed_buf_size_in_dwords;
5091         enum dbg_status status;
5092
5093         *num_dumped_dwords = 0;
5094
5095         status = qed_dbg_idle_chk_get_dump_buf_size(p_hwfn,
5096                                                     p_ptt,
5097                                                     &needed_buf_size_in_dwords);
5098         if (status != DBG_STATUS_OK)
5099                 return status;
5100
5101         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5102                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5103
5104         /* Update reset state */
5105         qed_update_blocks_reset_state(p_hwfn, p_ptt);
5106
5107         /* Idle Check Dump */
5108         *num_dumped_dwords = qed_idle_chk_dump(p_hwfn, p_ptt, dump_buf, true);
5109
5110         /* Revert GRC params to their default */
5111         qed_dbg_grc_set_params_default(p_hwfn);
5112
5113         return DBG_STATUS_OK;
5114 }
5115
5116 enum dbg_status qed_dbg_mcp_trace_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5117                                                     struct qed_ptt *p_ptt,
5118                                                     u32 *buf_size)
5119 {
5120         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5121
5122         *buf_size = 0;
5123
5124         if (status != DBG_STATUS_OK)
5125                 return status;
5126
5127         return qed_mcp_trace_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5128 }
5129
5130 enum dbg_status qed_dbg_mcp_trace_dump(struct qed_hwfn *p_hwfn,
5131                                        struct qed_ptt *p_ptt,
5132                                        u32 *dump_buf,
5133                                        u32 buf_size_in_dwords,
5134                                        u32 *num_dumped_dwords)
5135 {
5136         u32 needed_buf_size_in_dwords;
5137         enum dbg_status status;
5138
5139         status =
5140                 qed_dbg_mcp_trace_get_dump_buf_size(p_hwfn,
5141                                                     p_ptt,
5142                                                     &needed_buf_size_in_dwords);
5143         if (status != DBG_STATUS_OK && status !=
5144             DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
5145                 return status;
5146
5147         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5148                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5149
5150         /* Update reset state */
5151         qed_update_blocks_reset_state(p_hwfn, p_ptt);
5152
5153         /* Perform dump */
5154         status = qed_mcp_trace_dump(p_hwfn,
5155                                     p_ptt, dump_buf, true, num_dumped_dwords);
5156
5157         /* Revert GRC params to their default */
5158         qed_dbg_grc_set_params_default(p_hwfn);
5159
5160         return status;
5161 }
5162
5163 enum dbg_status qed_dbg_reg_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5164                                                    struct qed_ptt *p_ptt,
5165                                                    u32 *buf_size)
5166 {
5167         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5168
5169         *buf_size = 0;
5170
5171         if (status != DBG_STATUS_OK)
5172                 return status;
5173
5174         return qed_reg_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5175 }
5176
5177 enum dbg_status qed_dbg_reg_fifo_dump(struct qed_hwfn *p_hwfn,
5178                                       struct qed_ptt *p_ptt,
5179                                       u32 *dump_buf,
5180                                       u32 buf_size_in_dwords,
5181                                       u32 *num_dumped_dwords)
5182 {
5183         u32 needed_buf_size_in_dwords;
5184         enum dbg_status status;
5185
5186         *num_dumped_dwords = 0;
5187
5188         status = qed_dbg_reg_fifo_get_dump_buf_size(p_hwfn,
5189                                                     p_ptt,
5190                                                     &needed_buf_size_in_dwords);
5191         if (status != DBG_STATUS_OK)
5192                 return status;
5193
5194         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5195                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5196
5197         /* Update reset state */
5198         qed_update_blocks_reset_state(p_hwfn, p_ptt);
5199
5200         status = qed_reg_fifo_dump(p_hwfn,
5201                                    p_ptt, dump_buf, true, num_dumped_dwords);
5202
5203         /* Revert GRC params to their default */
5204         qed_dbg_grc_set_params_default(p_hwfn);
5205
5206         return status;
5207 }
5208
5209 enum dbg_status qed_dbg_igu_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5210                                                    struct qed_ptt *p_ptt,
5211                                                    u32 *buf_size)
5212 {
5213         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5214
5215         *buf_size = 0;
5216
5217         if (status != DBG_STATUS_OK)
5218                 return status;
5219
5220         return qed_igu_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5221 }
5222
5223 enum dbg_status qed_dbg_igu_fifo_dump(struct qed_hwfn *p_hwfn,
5224                                       struct qed_ptt *p_ptt,
5225                                       u32 *dump_buf,
5226                                       u32 buf_size_in_dwords,
5227                                       u32 *num_dumped_dwords)
5228 {
5229         u32 needed_buf_size_in_dwords;
5230         enum dbg_status status;
5231
5232         *num_dumped_dwords = 0;
5233
5234         status = qed_dbg_igu_fifo_get_dump_buf_size(p_hwfn,
5235                                                     p_ptt,
5236                                                     &needed_buf_size_in_dwords);
5237         if (status != DBG_STATUS_OK)
5238                 return status;
5239
5240         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5241                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5242
5243         /* Update reset state */
5244         qed_update_blocks_reset_state(p_hwfn, p_ptt);
5245
5246         status = qed_igu_fifo_dump(p_hwfn,
5247                                    p_ptt, dump_buf, true, num_dumped_dwords);
5248         /* Revert GRC params to their default */
5249         qed_dbg_grc_set_params_default(p_hwfn);
5250
5251         return status;
5252 }
5253
5254 enum dbg_status
5255 qed_dbg_protection_override_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5256                                               struct qed_ptt *p_ptt,
5257                                               u32 *buf_size)
5258 {
5259         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5260
5261         *buf_size = 0;
5262
5263         if (status != DBG_STATUS_OK)
5264                 return status;
5265
5266         return qed_protection_override_dump(p_hwfn,
5267                                             p_ptt, NULL, false, buf_size);
5268 }
5269
5270 enum dbg_status qed_dbg_protection_override_dump(struct qed_hwfn *p_hwfn,
5271                                                  struct qed_ptt *p_ptt,
5272                                                  u32 *dump_buf,
5273                                                  u32 buf_size_in_dwords,
5274                                                  u32 *num_dumped_dwords)
5275 {
5276         u32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords;
5277         enum dbg_status status;
5278
5279         *num_dumped_dwords = 0;
5280
5281         status =
5282                 qed_dbg_protection_override_get_dump_buf_size(p_hwfn,
5283                                                               p_ptt,
5284                                                               p_size);
5285         if (status != DBG_STATUS_OK)
5286                 return status;
5287
5288         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5289                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5290
5291         /* Update reset state */
5292         qed_update_blocks_reset_state(p_hwfn, p_ptt);
5293
5294         status = qed_protection_override_dump(p_hwfn,
5295                                               p_ptt,
5296                                               dump_buf,
5297                                               true, num_dumped_dwords);
5298
5299         /* Revert GRC params to their default */
5300         qed_dbg_grc_set_params_default(p_hwfn);
5301
5302         return status;
5303 }
5304
5305 enum dbg_status qed_dbg_fw_asserts_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5306                                                      struct qed_ptt *p_ptt,
5307                                                      u32 *buf_size)
5308 {
5309         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5310
5311         *buf_size = 0;
5312
5313         if (status != DBG_STATUS_OK)
5314                 return status;
5315
5316         /* Update reset state */
5317         qed_update_blocks_reset_state(p_hwfn, p_ptt);
5318
5319         *buf_size = qed_fw_asserts_dump(p_hwfn, p_ptt, NULL, false);
5320
5321         return DBG_STATUS_OK;
5322 }
5323
5324 enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn *p_hwfn,
5325                                         struct qed_ptt *p_ptt,
5326                                         u32 *dump_buf,
5327                                         u32 buf_size_in_dwords,
5328                                         u32 *num_dumped_dwords)
5329 {
5330         u32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords;
5331         enum dbg_status status;
5332
5333         *num_dumped_dwords = 0;
5334
5335         status =
5336                 qed_dbg_fw_asserts_get_dump_buf_size(p_hwfn,
5337                                                      p_ptt,
5338                                                      p_size);
5339         if (status != DBG_STATUS_OK)
5340                 return status;
5341
5342         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5343                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5344
5345         *num_dumped_dwords = qed_fw_asserts_dump(p_hwfn, p_ptt, dump_buf, true);
5346
5347         /* Revert GRC params to their default */
5348         qed_dbg_grc_set_params_default(p_hwfn);
5349
5350         return DBG_STATUS_OK;
5351 }
5352
5353 enum dbg_status qed_dbg_read_attn(struct qed_hwfn *p_hwfn,
5354                                   struct qed_ptt *p_ptt,
5355                                   enum block_id block_id,
5356                                   enum dbg_attn_type attn_type,
5357                                   bool clear_status,
5358                                   struct dbg_attn_block_result *results)
5359 {
5360         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5361         u8 reg_idx, num_attn_regs, num_result_regs = 0;
5362         const struct dbg_attn_reg *attn_reg_arr;
5363
5364         if (status != DBG_STATUS_OK)
5365                 return status;
5366
5367         if (!s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
5368             !s_dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||
5369             !s_dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)
5370                 return DBG_STATUS_DBG_ARRAY_NOT_SET;
5371
5372         attn_reg_arr = qed_get_block_attn_regs(block_id,
5373                                                attn_type, &num_attn_regs);
5374
5375         for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
5376                 const struct dbg_attn_reg *reg_data = &attn_reg_arr[reg_idx];
5377                 struct dbg_attn_reg_result *reg_result;
5378                 u32 sts_addr, sts_val;
5379                 u16 modes_buf_offset;
5380                 bool eval_mode;
5381
5382                 /* Check mode */
5383                 eval_mode = GET_FIELD(reg_data->mode.data,
5384                                       DBG_MODE_HDR_EVAL_MODE) > 0;
5385                 modes_buf_offset = GET_FIELD(reg_data->mode.data,
5386                                              DBG_MODE_HDR_MODES_BUF_OFFSET);
5387                 if (eval_mode && !qed_is_mode_match(p_hwfn, &modes_buf_offset))
5388                         continue;
5389
5390                 /* Mode match - read attention status register */
5391                 sts_addr = DWORDS_TO_BYTES(clear_status ?
5392                                            reg_data->sts_clr_address :
5393                                            GET_FIELD(reg_data->data,
5394                                                      DBG_ATTN_REG_STS_ADDRESS));
5395                 sts_val = qed_rd(p_hwfn, p_ptt, sts_addr);
5396                 if (!sts_val)
5397                         continue;
5398
5399                 /* Non-zero attention status - add to results */
5400                 reg_result = &results->reg_results[num_result_regs];
5401                 SET_FIELD(reg_result->data,
5402                           DBG_ATTN_REG_RESULT_STS_ADDRESS, sts_addr);
5403                 SET_FIELD(reg_result->data,
5404                           DBG_ATTN_REG_RESULT_NUM_REG_ATTN,
5405                           GET_FIELD(reg_data->data, DBG_ATTN_REG_NUM_REG_ATTN));
5406                 reg_result->block_attn_offset = reg_data->block_attn_offset;
5407                 reg_result->sts_val = sts_val;
5408                 reg_result->mask_val = qed_rd(p_hwfn,
5409                                               p_ptt,
5410                                               DWORDS_TO_BYTES
5411                                               (reg_data->mask_address));
5412                 num_result_regs++;
5413         }
5414
5415         results->block_id = (u8)block_id;
5416         results->names_offset =
5417             qed_get_block_attn_data(block_id, attn_type)->names_offset;
5418         SET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE, attn_type);
5419         SET_FIELD(results->data,
5420                   DBG_ATTN_BLOCK_RESULT_NUM_REGS, num_result_regs);
5421
5422         return DBG_STATUS_OK;
5423 }
5424
5425 /******************************* Data Types **********************************/
5426
5427 struct block_info {
5428         const char *name;
5429         enum block_id id;
5430 };
5431
5432 struct mcp_trace_format {
5433         u32 data;
5434 #define MCP_TRACE_FORMAT_MODULE_MASK    0x0000ffff
5435 #define MCP_TRACE_FORMAT_MODULE_SHIFT   0
5436 #define MCP_TRACE_FORMAT_LEVEL_MASK     0x00030000
5437 #define MCP_TRACE_FORMAT_LEVEL_SHIFT    16
5438 #define MCP_TRACE_FORMAT_P1_SIZE_MASK   0x000c0000
5439 #define MCP_TRACE_FORMAT_P1_SIZE_SHIFT  18
5440 #define MCP_TRACE_FORMAT_P2_SIZE_MASK   0x00300000
5441 #define MCP_TRACE_FORMAT_P2_SIZE_SHIFT  20
5442 #define MCP_TRACE_FORMAT_P3_SIZE_MASK   0x00c00000
5443 #define MCP_TRACE_FORMAT_P3_SIZE_SHIFT  22
5444 #define MCP_TRACE_FORMAT_LEN_MASK       0xff000000
5445 #define MCP_TRACE_FORMAT_LEN_SHIFT      24
5446
5447         char *format_str;
5448 };
5449
5450 /* Meta data structure, generated by a perl script during MFW build. therefore,
5451  * the structs mcp_trace_meta and mcp_trace_format are duplicated in the perl
5452  * script.
5453  */
5454 struct mcp_trace_meta {
5455         u32 modules_num;
5456         char **modules;
5457         u32 formats_num;
5458         struct mcp_trace_format *formats;
5459 };
5460
5461 /* REG fifo element */
5462 struct reg_fifo_element {
5463         u64 data;
5464 #define REG_FIFO_ELEMENT_ADDRESS_SHIFT          0
5465 #define REG_FIFO_ELEMENT_ADDRESS_MASK           0x7fffff
5466 #define REG_FIFO_ELEMENT_ACCESS_SHIFT           23
5467 #define REG_FIFO_ELEMENT_ACCESS_MASK            0x1
5468 #define REG_FIFO_ELEMENT_PF_SHIFT               24
5469 #define REG_FIFO_ELEMENT_PF_MASK                0xf
5470 #define REG_FIFO_ELEMENT_VF_SHIFT               28
5471 #define REG_FIFO_ELEMENT_VF_MASK                0xff
5472 #define REG_FIFO_ELEMENT_PORT_SHIFT             36
5473 #define REG_FIFO_ELEMENT_PORT_MASK              0x3
5474 #define REG_FIFO_ELEMENT_PRIVILEGE_SHIFT        38
5475 #define REG_FIFO_ELEMENT_PRIVILEGE_MASK         0x3
5476 #define REG_FIFO_ELEMENT_PROTECTION_SHIFT       40
5477 #define REG_FIFO_ELEMENT_PROTECTION_MASK        0x7
5478 #define REG_FIFO_ELEMENT_MASTER_SHIFT           43
5479 #define REG_FIFO_ELEMENT_MASTER_MASK            0xf
5480 #define REG_FIFO_ELEMENT_ERROR_SHIFT            47
5481 #define REG_FIFO_ELEMENT_ERROR_MASK             0x1f
5482 };
5483
5484 /* IGU fifo element */
5485 struct igu_fifo_element {
5486         u32 dword0;
5487 #define IGU_FIFO_ELEMENT_DWORD0_FID_SHIFT               0
5488 #define IGU_FIFO_ELEMENT_DWORD0_FID_MASK                0xff
5489 #define IGU_FIFO_ELEMENT_DWORD0_IS_PF_SHIFT             8
5490 #define IGU_FIFO_ELEMENT_DWORD0_IS_PF_MASK              0x1
5491 #define IGU_FIFO_ELEMENT_DWORD0_SOURCE_SHIFT            9
5492 #define IGU_FIFO_ELEMENT_DWORD0_SOURCE_MASK             0xf
5493 #define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_SHIFT          13
5494 #define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_MASK           0xf
5495 #define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_SHIFT          17
5496 #define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_MASK           0x7fff
5497         u32 dword1;
5498         u32 dword2;
5499 #define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_SHIFT        0
5500 #define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_MASK         0x1
5501 #define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_SHIFT          1
5502 #define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_MASK           0xffffffff
5503         u32 reserved;
5504 };
5505
5506 struct igu_fifo_wr_data {
5507         u32 data;
5508 #define IGU_FIFO_WR_DATA_PROD_CONS_SHIFT                0
5509 #define IGU_FIFO_WR_DATA_PROD_CONS_MASK                 0xffffff
5510 #define IGU_FIFO_WR_DATA_UPDATE_FLAG_SHIFT              24
5511 #define IGU_FIFO_WR_DATA_UPDATE_FLAG_MASK               0x1
5512 #define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_SHIFT        25
5513 #define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_MASK         0x3
5514 #define IGU_FIFO_WR_DATA_SEGMENT_SHIFT                  27
5515 #define IGU_FIFO_WR_DATA_SEGMENT_MASK                   0x1
5516 #define IGU_FIFO_WR_DATA_TIMER_MASK_SHIFT               28
5517 #define IGU_FIFO_WR_DATA_TIMER_MASK_MASK                0x1
5518 #define IGU_FIFO_WR_DATA_CMD_TYPE_SHIFT                 31
5519 #define IGU_FIFO_WR_DATA_CMD_TYPE_MASK                  0x1
5520 };
5521
5522 struct igu_fifo_cleanup_wr_data {
5523         u32 data;
5524 #define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_SHIFT         0
5525 #define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_MASK          0x7ffffff
5526 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_SHIFT      27
5527 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_MASK       0x1
5528 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_SHIFT     28
5529 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_MASK      0x7
5530 #define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_SHIFT         31
5531 #define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_MASK          0x1
5532 };
5533
5534 /* Protection override element */
5535 struct protection_override_element {
5536         u64 data;
5537 #define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_SHIFT               0
5538 #define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_MASK                0x7fffff
5539 #define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_SHIFT           23
5540 #define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_MASK            0xffffff
5541 #define PROTECTION_OVERRIDE_ELEMENT_READ_SHIFT                  47
5542 #define PROTECTION_OVERRIDE_ELEMENT_READ_MASK                   0x1
5543 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_SHIFT                 48
5544 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_MASK                  0x1
5545 #define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_SHIFT       49
5546 #define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_MASK        0x7
5547 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_SHIFT      52
5548 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_MASK       0x7
5549 };
5550
5551 enum igu_fifo_sources {
5552         IGU_SRC_PXP0,
5553         IGU_SRC_PXP1,
5554         IGU_SRC_PXP2,
5555         IGU_SRC_PXP3,
5556         IGU_SRC_PXP4,
5557         IGU_SRC_PXP5,
5558         IGU_SRC_PXP6,
5559         IGU_SRC_PXP7,
5560         IGU_SRC_CAU,
5561         IGU_SRC_ATTN,
5562         IGU_SRC_GRC
5563 };
5564
5565 enum igu_fifo_addr_types {
5566         IGU_ADDR_TYPE_MSIX_MEM,
5567         IGU_ADDR_TYPE_WRITE_PBA,
5568         IGU_ADDR_TYPE_WRITE_INT_ACK,
5569         IGU_ADDR_TYPE_WRITE_ATTN_BITS,
5570         IGU_ADDR_TYPE_READ_INT,
5571         IGU_ADDR_TYPE_WRITE_PROD_UPDATE,
5572         IGU_ADDR_TYPE_RESERVED
5573 };
5574
5575 struct igu_fifo_addr_data {
5576         u16 start_addr;
5577         u16 end_addr;
5578         char *desc;
5579         char *vf_desc;
5580         enum igu_fifo_addr_types type;
5581 };
5582
5583 /******************************** Constants **********************************/
5584
5585 #define MAX_MSG_LEN                             1024
5586
5587 #define MCP_TRACE_MAX_MODULE_LEN                8
5588 #define MCP_TRACE_FORMAT_MAX_PARAMS             3
5589 #define MCP_TRACE_FORMAT_PARAM_WIDTH \
5590         (MCP_TRACE_FORMAT_P2_SIZE_SHIFT - MCP_TRACE_FORMAT_P1_SIZE_SHIFT)
5591
5592 #define REG_FIFO_ELEMENT_ADDR_FACTOR            4
5593 #define REG_FIFO_ELEMENT_IS_PF_VF_VAL           127
5594
5595 #define PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR 4
5596
5597 /********************************* Macros ************************************/
5598
5599 #define BYTES_TO_DWORDS(bytes)                  ((bytes) / BYTES_IN_DWORD)
5600
5601 /***************************** Constant Arrays *******************************/
5602
5603 struct user_dbg_array {
5604         const u32 *ptr;
5605         u32 size_in_dwords;
5606 };
5607
5608 /* Debug arrays */
5609 static struct user_dbg_array
5610 s_user_dbg_arrays[MAX_BIN_DBG_BUFFER_TYPE] = { {NULL} };
5611
5612 /* Block names array */
5613 static struct block_info s_block_info_arr[] = {
5614         {"grc", BLOCK_GRC},
5615         {"miscs", BLOCK_MISCS},
5616         {"misc", BLOCK_MISC},
5617         {"dbu", BLOCK_DBU},
5618         {"pglue_b", BLOCK_PGLUE_B},
5619         {"cnig", BLOCK_CNIG},
5620         {"cpmu", BLOCK_CPMU},
5621         {"ncsi", BLOCK_NCSI},
5622         {"opte", BLOCK_OPTE},
5623         {"bmb", BLOCK_BMB},
5624         {"pcie", BLOCK_PCIE},
5625         {"mcp", BLOCK_MCP},
5626         {"mcp2", BLOCK_MCP2},
5627         {"pswhst", BLOCK_PSWHST},
5628         {"pswhst2", BLOCK_PSWHST2},
5629         {"pswrd", BLOCK_PSWRD},
5630         {"pswrd2", BLOCK_PSWRD2},
5631         {"pswwr", BLOCK_PSWWR},
5632         {"pswwr2", BLOCK_PSWWR2},
5633         {"pswrq", BLOCK_PSWRQ},
5634         {"pswrq2", BLOCK_PSWRQ2},
5635         {"pglcs", BLOCK_PGLCS},
5636         {"ptu", BLOCK_PTU},
5637         {"dmae", BLOCK_DMAE},
5638         {"tcm", BLOCK_TCM},
5639         {"mcm", BLOCK_MCM},
5640         {"ucm", BLOCK_UCM},
5641         {"xcm", BLOCK_XCM},
5642         {"ycm", BLOCK_YCM},
5643         {"pcm", BLOCK_PCM},
5644         {"qm", BLOCK_QM},
5645         {"tm", BLOCK_TM},
5646         {"dorq", BLOCK_DORQ},
5647         {"brb", BLOCK_BRB},
5648         {"src", BLOCK_SRC},
5649         {"prs", BLOCK_PRS},
5650         {"tsdm", BLOCK_TSDM},
5651         {"msdm", BLOCK_MSDM},
5652         {"usdm", BLOCK_USDM},
5653         {"xsdm", BLOCK_XSDM},
5654         {"ysdm", BLOCK_YSDM},
5655         {"psdm", BLOCK_PSDM},
5656         {"tsem", BLOCK_TSEM},
5657         {"msem", BLOCK_MSEM},
5658         {"usem", BLOCK_USEM},
5659         {"xsem", BLOCK_XSEM},
5660         {"ysem", BLOCK_YSEM},
5661         {"psem", BLOCK_PSEM},
5662         {"rss", BLOCK_RSS},
5663         {"tmld", BLOCK_TMLD},
5664         {"muld", BLOCK_MULD},
5665         {"yuld", BLOCK_YULD},
5666         {"xyld", BLOCK_XYLD},
5667         {"ptld", BLOCK_PTLD},
5668         {"ypld", BLOCK_YPLD},
5669         {"prm", BLOCK_PRM},
5670         {"pbf_pb1", BLOCK_PBF_PB1},
5671         {"pbf_pb2", BLOCK_PBF_PB2},
5672         {"rpb", BLOCK_RPB},
5673         {"btb", BLOCK_BTB},
5674         {"pbf", BLOCK_PBF},
5675         {"rdif", BLOCK_RDIF},
5676         {"tdif", BLOCK_TDIF},
5677         {"cdu", BLOCK_CDU},
5678         {"ccfc", BLOCK_CCFC},
5679         {"tcfc", BLOCK_TCFC},
5680         {"igu", BLOCK_IGU},
5681         {"cau", BLOCK_CAU},
5682         {"rgfs", BLOCK_RGFS},
5683         {"rgsrc", BLOCK_RGSRC},
5684         {"tgfs", BLOCK_TGFS},
5685         {"tgsrc", BLOCK_TGSRC},
5686         {"umac", BLOCK_UMAC},
5687         {"xmac", BLOCK_XMAC},
5688         {"dbg", BLOCK_DBG},
5689         {"nig", BLOCK_NIG},
5690         {"wol", BLOCK_WOL},
5691         {"bmbn", BLOCK_BMBN},
5692         {"ipc", BLOCK_IPC},
5693         {"nwm", BLOCK_NWM},
5694         {"nws", BLOCK_NWS},
5695         {"ms", BLOCK_MS},
5696         {"phy_pcie", BLOCK_PHY_PCIE},
5697         {"led", BLOCK_LED},
5698         {"avs_wrap", BLOCK_AVS_WRAP},
5699         {"misc_aeu", BLOCK_MISC_AEU},
5700         {"bar0_map", BLOCK_BAR0_MAP}
5701 };
5702
5703 /* Status string array */
5704 static const char * const s_status_str[] = {
5705         /* DBG_STATUS_OK */
5706         "Operation completed successfully",
5707
5708         /* DBG_STATUS_APP_VERSION_NOT_SET */
5709         "Debug application version wasn't set",
5710
5711         /* DBG_STATUS_UNSUPPORTED_APP_VERSION */
5712         "Unsupported debug application version",
5713
5714         /* DBG_STATUS_DBG_BLOCK_NOT_RESET */
5715         "The debug block wasn't reset since the last recording",
5716
5717         /* DBG_STATUS_INVALID_ARGS */
5718         "Invalid arguments",
5719
5720         /* DBG_STATUS_OUTPUT_ALREADY_SET */
5721         "The debug output was already set",
5722
5723         /* DBG_STATUS_INVALID_PCI_BUF_SIZE */
5724         "Invalid PCI buffer size",
5725
5726         /* DBG_STATUS_PCI_BUF_ALLOC_FAILED */
5727         "PCI buffer allocation failed",
5728
5729         /* DBG_STATUS_PCI_BUF_NOT_ALLOCATED */
5730         "A PCI buffer wasn't allocated",
5731
5732         /* DBG_STATUS_TOO_MANY_INPUTS */
5733         "Too many inputs were enabled. Enabled less inputs, or set 'unifyInputs' to true",
5734
5735         /* DBG_STATUS_INPUT_OVERLAP */
5736         "Overlapping debug bus inputs",
5737
5738         /* DBG_STATUS_HW_ONLY_RECORDING */
5739         "Cannot record Storm data since the entire recording cycle is used by HW",
5740
5741         /* DBG_STATUS_STORM_ALREADY_ENABLED */
5742         "The Storm was already enabled",
5743
5744         /* DBG_STATUS_STORM_NOT_ENABLED */
5745         "The specified Storm wasn't enabled",
5746
5747         /* DBG_STATUS_BLOCK_ALREADY_ENABLED */
5748         "The block was already enabled",
5749
5750         /* DBG_STATUS_BLOCK_NOT_ENABLED */
5751         "The specified block wasn't enabled",
5752
5753         /* DBG_STATUS_NO_INPUT_ENABLED */
5754         "No input was enabled for recording",
5755
5756         /* DBG_STATUS_NO_FILTER_TRIGGER_64B */
5757         "Filters and triggers are not allowed when recording in 64b units",
5758
5759         /* DBG_STATUS_FILTER_ALREADY_ENABLED */
5760         "The filter was already enabled",
5761
5762         /* DBG_STATUS_TRIGGER_ALREADY_ENABLED */
5763         "The trigger was already enabled",
5764
5765         /* DBG_STATUS_TRIGGER_NOT_ENABLED */
5766         "The trigger wasn't enabled",
5767
5768         /* DBG_STATUS_CANT_ADD_CONSTRAINT */
5769         "A constraint can be added only after a filter was enabled or a trigger state was added",
5770
5771         /* DBG_STATUS_TOO_MANY_TRIGGER_STATES */
5772         "Cannot add more than 3 trigger states",
5773
5774         /* DBG_STATUS_TOO_MANY_CONSTRAINTS */
5775         "Cannot add more than 4 constraints per filter or trigger state",
5776
5777         /* DBG_STATUS_RECORDING_NOT_STARTED */
5778         "The recording wasn't started",
5779
5780         /* DBG_STATUS_DATA_DIDNT_TRIGGER */
5781         "A trigger was configured, but it didn't trigger",
5782
5783         /* DBG_STATUS_NO_DATA_RECORDED */
5784         "No data was recorded",
5785
5786         /* DBG_STATUS_DUMP_BUF_TOO_SMALL */
5787         "Dump buffer is too small",
5788
5789         /* DBG_STATUS_DUMP_NOT_CHUNK_ALIGNED */
5790         "Dumped data is not aligned to chunks",
5791
5792         /* DBG_STATUS_UNKNOWN_CHIP */
5793         "Unknown chip",
5794
5795         /* DBG_STATUS_VIRT_MEM_ALLOC_FAILED */
5796         "Failed allocating virtual memory",
5797
5798         /* DBG_STATUS_BLOCK_IN_RESET */
5799         "The input block is in reset",
5800
5801         /* DBG_STATUS_INVALID_TRACE_SIGNATURE */
5802         "Invalid MCP trace signature found in NVRAM",
5803
5804         /* DBG_STATUS_INVALID_NVRAM_BUNDLE */
5805         "Invalid bundle ID found in NVRAM",
5806
5807         /* DBG_STATUS_NVRAM_GET_IMAGE_FAILED */
5808         "Failed getting NVRAM image",
5809
5810         /* DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE */
5811         "NVRAM image is not dword-aligned",
5812
5813         /* DBG_STATUS_NVRAM_READ_FAILED */
5814         "Failed reading from NVRAM",
5815
5816         /* DBG_STATUS_IDLE_CHK_PARSE_FAILED */
5817         "Idle check parsing failed",
5818
5819         /* DBG_STATUS_MCP_TRACE_BAD_DATA */
5820         "MCP Trace data is corrupt",
5821
5822         /* DBG_STATUS_MCP_TRACE_NO_META */
5823         "Dump doesn't contain meta data - it must be provided in image file",
5824
5825         /* DBG_STATUS_MCP_COULD_NOT_HALT */
5826         "Failed to halt MCP",
5827
5828         /* DBG_STATUS_MCP_COULD_NOT_RESUME */
5829         "Failed to resume MCP after halt",
5830
5831         /* DBG_STATUS_DMAE_FAILED */
5832         "DMAE transaction failed",
5833
5834         /* DBG_STATUS_SEMI_FIFO_NOT_EMPTY */
5835         "Failed to empty SEMI sync FIFO",
5836
5837         /* DBG_STATUS_IGU_FIFO_BAD_DATA */
5838         "IGU FIFO data is corrupt",
5839
5840         /* DBG_STATUS_MCP_COULD_NOT_MASK_PRTY */
5841         "MCP failed to mask parities",
5842
5843         /* DBG_STATUS_FW_ASSERTS_PARSE_FAILED */
5844         "FW Asserts parsing failed",
5845
5846         /* DBG_STATUS_REG_FIFO_BAD_DATA */
5847         "GRC FIFO data is corrupt",
5848
5849         /* DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA */
5850         "Protection Override data is corrupt",
5851
5852         /* DBG_STATUS_DBG_ARRAY_NOT_SET */
5853         "Debug arrays were not set (when using binary files, dbg_set_bin_ptr must be called)",
5854
5855         /* DBG_STATUS_FILTER_BUG */
5856         "Debug Bus filtering requires the -unifyInputs option (due to a HW bug)",
5857
5858         /* DBG_STATUS_NON_MATCHING_LINES */
5859         "Non-matching debug lines - all lines must be of the same type (either 128b or 256b)",
5860
5861         /* DBG_STATUS_INVALID_TRIGGER_DWORD_OFFSET */
5862         "The selected trigger dword offset wasn't enabled in the recorded HW block",
5863
5864         /* DBG_STATUS_DBG_BUS_IN_USE */
5865         "The debug bus is in use"
5866 };
5867
5868 /* Idle check severity names array */
5869 static const char * const s_idle_chk_severity_str[] = {
5870         "Error",
5871         "Error if no traffic",
5872         "Warning"
5873 };
5874
5875 /* MCP Trace level names array */
5876 static const char * const s_mcp_trace_level_str[] = {
5877         "ERROR",
5878         "TRACE",
5879         "DEBUG"
5880 };
5881
5882 /* Access type names array */
5883 static const char * const s_access_strs[] = {
5884         "read",
5885         "write"
5886 };
5887
5888 /* Privilege type names array */
5889 static const char * const s_privilege_strs[] = {
5890         "VF",
5891         "PDA",
5892         "HV",
5893         "UA"
5894 };
5895
5896 /* Protection type names array */
5897 static const char * const s_protection_strs[] = {
5898         "(default)",
5899         "(default)",
5900         "(default)",
5901         "(default)",
5902         "override VF",
5903         "override PDA",
5904         "override HV",
5905         "override UA"
5906 };
5907
5908 /* Master type names array */
5909 static const char * const s_master_strs[] = {
5910         "???",
5911         "pxp",
5912         "mcp",
5913         "msdm",
5914         "psdm",
5915         "ysdm",
5916         "usdm",
5917         "tsdm",
5918         "xsdm",
5919         "dbu",
5920         "dmae",
5921         "???",
5922         "???",
5923         "???",
5924         "???",
5925         "???"
5926 };
5927
5928 /* REG FIFO error messages array */
5929 static const char * const s_reg_fifo_error_strs[] = {
5930         "grc timeout",
5931         "address doesn't belong to any block",
5932         "reserved address in block or write to read-only address",
5933         "privilege/protection mismatch",
5934         "path isolation error"
5935 };
5936
5937 /* IGU FIFO sources array */
5938 static const char * const s_igu_fifo_source_strs[] = {
5939         "TSTORM",
5940         "MSTORM",
5941         "USTORM",
5942         "XSTORM",
5943         "YSTORM",
5944         "PSTORM",
5945         "PCIE",
5946         "NIG_QM_PBF",
5947         "CAU",
5948         "ATTN",
5949         "GRC",
5950 };
5951
5952 /* IGU FIFO error messages */
5953 static const char * const s_igu_fifo_error_strs[] = {
5954         "no error",
5955         "length error",
5956         "function disabled",
5957         "VF sent command to attnetion address",
5958         "host sent prod update command",
5959         "read of during interrupt register while in MIMD mode",
5960         "access to PXP BAR reserved address",
5961         "producer update command to attention index",
5962         "unknown error",
5963         "SB index not valid",
5964         "SB relative index and FID not found",
5965         "FID not match",
5966         "command with error flag asserted (PCI error or CAU discard)",
5967         "VF sent cleanup and RF cleanup is disabled",
5968         "cleanup command on type bigger than 4"
5969 };
5970
5971 /* IGU FIFO address data */
5972 static const struct igu_fifo_addr_data s_igu_fifo_addr_data[] = {
5973         {0x0, 0x101, "MSI-X Memory", NULL,
5974          IGU_ADDR_TYPE_MSIX_MEM},
5975         {0x102, 0x1ff, "reserved", NULL,
5976          IGU_ADDR_TYPE_RESERVED},
5977         {0x200, 0x200, "Write PBA[0:63]", NULL,
5978          IGU_ADDR_TYPE_WRITE_PBA},
5979         {0x201, 0x201, "Write PBA[64:127]", "reserved",
5980          IGU_ADDR_TYPE_WRITE_PBA},
5981         {0x202, 0x202, "Write PBA[128]", "reserved",
5982          IGU_ADDR_TYPE_WRITE_PBA},
5983         {0x203, 0x3ff, "reserved", NULL,
5984          IGU_ADDR_TYPE_RESERVED},
5985         {0x400, 0x5ef, "Write interrupt acknowledgment", NULL,
5986          IGU_ADDR_TYPE_WRITE_INT_ACK},
5987         {0x5f0, 0x5f0, "Attention bits update", NULL,
5988          IGU_ADDR_TYPE_WRITE_ATTN_BITS},
5989         {0x5f1, 0x5f1, "Attention bits set", NULL,
5990          IGU_ADDR_TYPE_WRITE_ATTN_BITS},
5991         {0x5f2, 0x5f2, "Attention bits clear", NULL,
5992          IGU_ADDR_TYPE_WRITE_ATTN_BITS},
5993         {0x5f3, 0x5f3, "Read interrupt 0:63 with mask", NULL,
5994          IGU_ADDR_TYPE_READ_INT},
5995         {0x5f4, 0x5f4, "Read interrupt 0:31 with mask", NULL,
5996          IGU_ADDR_TYPE_READ_INT},
5997         {0x5f5, 0x5f5, "Read interrupt 32:63 with mask", NULL,
5998          IGU_ADDR_TYPE_READ_INT},
5999         {0x5f6, 0x5f6, "Read interrupt 0:63 without mask", NULL,
6000          IGU_ADDR_TYPE_READ_INT},
6001         {0x5f7, 0x5ff, "reserved", NULL,
6002          IGU_ADDR_TYPE_RESERVED},
6003         {0x600, 0x7ff, "Producer update", NULL,
6004          IGU_ADDR_TYPE_WRITE_PROD_UPDATE}
6005 };
6006
6007 /******************************** Variables **********************************/
6008
6009 /* MCP Trace meta data - used in case the dump doesn't contain the meta data
6010  * (e.g. due to no NVRAM access).
6011  */
6012 static struct user_dbg_array s_mcp_trace_meta = { NULL, 0 };
6013
6014 /* Temporary buffer, used for print size calculations */
6015 static char s_temp_buf[MAX_MSG_LEN];
6016
6017 /**************************** Private Functions ******************************/
6018
6019 static u32 qed_cyclic_add(u32 a, u32 b, u32 size)
6020 {
6021         return (a + b) % size;
6022 }
6023
6024 static u32 qed_cyclic_sub(u32 a, u32 b, u32 size)
6025 {
6026         return (size + a - b) % size;
6027 }
6028
6029 /* Reads the specified number of bytes from the specified cyclic buffer (up to 4
6030  * bytes) and returns them as a dword value. the specified buffer offset is
6031  * updated.
6032  */
6033 static u32 qed_read_from_cyclic_buf(void *buf,
6034                                     u32 *offset,
6035                                     u32 buf_size, u8 num_bytes_to_read)
6036 {
6037         u8 i, *val_ptr, *bytes_buf = (u8 *)buf;
6038         u32 val = 0;
6039
6040         val_ptr = (u8 *)&val;
6041
6042         for (i = 0; i < num_bytes_to_read; i++) {
6043                 val_ptr[i] = bytes_buf[*offset];
6044                 *offset = qed_cyclic_add(*offset, 1, buf_size);
6045         }
6046
6047         return val;
6048 }
6049
6050 /* Reads and returns the next byte from the specified buffer.
6051  * The specified buffer offset is updated.
6052  */
6053 static u8 qed_read_byte_from_buf(void *buf, u32 *offset)
6054 {
6055         return ((u8 *)buf)[(*offset)++];
6056 }
6057
6058 /* Reads and returns the next dword from the specified buffer.
6059  * The specified buffer offset is updated.
6060  */
6061 static u32 qed_read_dword_from_buf(void *buf, u32 *offset)
6062 {
6063         u32 dword_val = *(u32 *)&((u8 *)buf)[*offset];
6064
6065         *offset += 4;
6066
6067         return dword_val;
6068 }
6069
6070 /* Reads the next string from the specified buffer, and copies it to the
6071  * specified pointer. The specified buffer offset is updated.
6072  */
6073 static void qed_read_str_from_buf(void *buf, u32 *offset, u32 size, char *dest)
6074 {
6075         const char *source_str = &((const char *)buf)[*offset];
6076
6077         strncpy(dest, source_str, size);
6078         dest[size - 1] = '\0';
6079         *offset += size;
6080 }
6081
6082 /* Returns a pointer to the specified offset (in bytes) of the specified buffer.
6083  * If the specified buffer in NULL, a temporary buffer pointer is returned.
6084  */
6085 static char *qed_get_buf_ptr(void *buf, u32 offset)
6086 {
6087         return buf ? (char *)buf + offset : s_temp_buf;
6088 }
6089
6090 /* Reads a param from the specified buffer. Returns the number of dwords read.
6091  * If the returned str_param is NULL, the param is numeric and its value is
6092  * returned in num_param.
6093  * Otheriwise, the param is a string and its pointer is returned in str_param.
6094  */
6095 static u32 qed_read_param(u32 *dump_buf,
6096                           const char **param_name,
6097                           const char **param_str_val, u32 *param_num_val)
6098 {
6099         char *char_buf = (char *)dump_buf;
6100         size_t offset = 0;
6101
6102         /* Extract param name */
6103         *param_name = char_buf;
6104         offset += strlen(*param_name) + 1;
6105
6106         /* Check param type */
6107         if (*(char_buf + offset++)) {
6108                 /* String param */
6109                 *param_str_val = char_buf + offset;
6110                 offset += strlen(*param_str_val) + 1;
6111                 if (offset & 0x3)
6112                         offset += (4 - (offset & 0x3));
6113         } else {
6114                 /* Numeric param */
6115                 *param_str_val = NULL;
6116                 if (offset & 0x3)
6117                         offset += (4 - (offset & 0x3));
6118                 *param_num_val = *(u32 *)(char_buf + offset);
6119                 offset += 4;
6120         }
6121
6122         return offset / 4;
6123 }
6124
6125 /* Reads a section header from the specified buffer.
6126  * Returns the number of dwords read.
6127  */
6128 static u32 qed_read_section_hdr(u32 *dump_buf,
6129                                 const char **section_name,
6130                                 u32 *num_section_params)
6131 {
6132         const char *param_str_val;
6133
6134         return qed_read_param(dump_buf,
6135                               section_name, &param_str_val, num_section_params);
6136 }
6137
6138 /* Reads section params from the specified buffer and prints them to the results
6139  * buffer. Returns the number of dwords read.
6140  */
6141 static u32 qed_print_section_params(u32 *dump_buf,
6142                                     u32 num_section_params,
6143                                     char *results_buf, u32 *num_chars_printed)
6144 {
6145         u32 i, dump_offset = 0, results_offset = 0;
6146
6147         for (i = 0; i < num_section_params; i++) {
6148                 const char *param_name, *param_str_val;
6149                 u32 param_num_val = 0;
6150
6151                 dump_offset += qed_read_param(dump_buf + dump_offset,
6152                                               &param_name,
6153                                               &param_str_val, &param_num_val);
6154
6155                 if (param_str_val)
6156                         results_offset +=
6157                                 sprintf(qed_get_buf_ptr(results_buf,
6158                                                         results_offset),
6159                                         "%s: %s\n", param_name, param_str_val);
6160                 else if (strcmp(param_name, "fw-timestamp"))
6161                         results_offset +=
6162                                 sprintf(qed_get_buf_ptr(results_buf,
6163                                                         results_offset),
6164                                         "%s: %d\n", param_name, param_num_val);
6165         }
6166
6167         results_offset += sprintf(qed_get_buf_ptr(results_buf, results_offset),
6168                                   "\n");
6169
6170         *num_chars_printed = results_offset;
6171
6172         return dump_offset;
6173 }
6174
6175 /* Parses the idle check rules and returns the number of characters printed.
6176  * In case of parsing error, returns 0.
6177  */
6178 static u32 qed_parse_idle_chk_dump_rules(struct qed_hwfn *p_hwfn,
6179                                          u32 *dump_buf,
6180                                          u32 *dump_buf_end,
6181                                          u32 num_rules,
6182                                          bool print_fw_idle_chk,
6183                                          char *results_buf,
6184                                          u32 *num_errors, u32 *num_warnings)
6185 {
6186         /* Offset in results_buf in bytes */
6187         u32 results_offset = 0;
6188
6189         u32 rule_idx;
6190         u16 i, j;
6191
6192         *num_errors = 0;
6193         *num_warnings = 0;
6194
6195         /* Go over dumped results */
6196         for (rule_idx = 0; rule_idx < num_rules && dump_buf < dump_buf_end;
6197              rule_idx++) {
6198                 const struct dbg_idle_chk_rule_parsing_data *rule_parsing_data;
6199                 struct dbg_idle_chk_result_hdr *hdr;
6200                 const char *parsing_str, *lsi_msg;
6201                 u32 parsing_str_offset;
6202                 bool has_fw_msg;
6203                 u8 curr_reg_id;
6204
6205                 hdr = (struct dbg_idle_chk_result_hdr *)dump_buf;
6206                 rule_parsing_data =
6207                         (const struct dbg_idle_chk_rule_parsing_data *)
6208                         &s_user_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].
6209                         ptr[hdr->rule_id];
6210                 parsing_str_offset =
6211                         GET_FIELD(rule_parsing_data->data,
6212                                   DBG_IDLE_CHK_RULE_PARSING_DATA_STR_OFFSET);
6213                 has_fw_msg =
6214                         GET_FIELD(rule_parsing_data->data,
6215                                 DBG_IDLE_CHK_RULE_PARSING_DATA_HAS_FW_MSG) > 0;
6216                 parsing_str =
6217                         &((const char *)
6218                         s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr)
6219                         [parsing_str_offset];
6220                 lsi_msg = parsing_str;
6221                 curr_reg_id = 0;
6222
6223                 if (hdr->severity >= MAX_DBG_IDLE_CHK_SEVERITY_TYPES)
6224                         return 0;
6225
6226                 /* Skip rule header */
6227                 dump_buf += BYTES_TO_DWORDS(sizeof(*hdr));
6228
6229                 /* Update errors/warnings count */
6230                 if (hdr->severity == IDLE_CHK_SEVERITY_ERROR ||
6231                     hdr->severity == IDLE_CHK_SEVERITY_ERROR_NO_TRAFFIC)
6232                         (*num_errors)++;
6233                 else
6234                         (*num_warnings)++;
6235
6236                 /* Print rule severity */
6237                 results_offset +=
6238                     sprintf(qed_get_buf_ptr(results_buf,
6239                                             results_offset), "%s: ",
6240                             s_idle_chk_severity_str[hdr->severity]);
6241
6242                 /* Print rule message */
6243                 if (has_fw_msg)
6244                         parsing_str += strlen(parsing_str) + 1;
6245                 results_offset +=
6246                     sprintf(qed_get_buf_ptr(results_buf,
6247                                             results_offset), "%s.",
6248                             has_fw_msg &&
6249                             print_fw_idle_chk ? parsing_str : lsi_msg);
6250                 parsing_str += strlen(parsing_str) + 1;
6251
6252                 /* Print register values */
6253                 results_offset +=
6254                     sprintf(qed_get_buf_ptr(results_buf,
6255                                             results_offset), " Registers:");
6256                 for (i = 0;
6257                      i < hdr->num_dumped_cond_regs + hdr->num_dumped_info_regs;
6258                      i++) {
6259                         struct dbg_idle_chk_result_reg_hdr *reg_hdr;
6260                         bool is_mem;
6261                         u8 reg_id;
6262
6263                         reg_hdr =
6264                                 (struct dbg_idle_chk_result_reg_hdr *)dump_buf;
6265                         is_mem = GET_FIELD(reg_hdr->data,
6266                                            DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM);
6267                         reg_id = GET_FIELD(reg_hdr->data,
6268                                            DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID);
6269
6270                         /* Skip reg header */
6271                         dump_buf += BYTES_TO_DWORDS(sizeof(*reg_hdr));
6272
6273                         /* Skip register names until the required reg_id is
6274                          * reached.
6275                          */
6276                         for (; reg_id > curr_reg_id;
6277                              curr_reg_id++,
6278                              parsing_str += strlen(parsing_str) + 1);
6279
6280                         results_offset +=
6281                             sprintf(qed_get_buf_ptr(results_buf,
6282                                                     results_offset), " %s",
6283                                     parsing_str);
6284                         if (i < hdr->num_dumped_cond_regs && is_mem)
6285                                 results_offset +=
6286                                     sprintf(qed_get_buf_ptr(results_buf,
6287                                                             results_offset),
6288                                             "[%d]", hdr->mem_entry_id +
6289                                             reg_hdr->start_entry);
6290                         results_offset +=
6291                             sprintf(qed_get_buf_ptr(results_buf,
6292                                                     results_offset), "=");
6293                         for (j = 0; j < reg_hdr->size; j++, dump_buf++) {
6294                                 results_offset +=
6295                                     sprintf(qed_get_buf_ptr(results_buf,
6296                                                             results_offset),
6297                                             "0x%x", *dump_buf);
6298                                 if (j < reg_hdr->size - 1)
6299                                         results_offset +=
6300                                             sprintf(qed_get_buf_ptr
6301                                                     (results_buf,
6302                                                      results_offset), ",");
6303                         }
6304                 }
6305
6306                 results_offset +=
6307                     sprintf(qed_get_buf_ptr(results_buf, results_offset), "\n");
6308         }
6309
6310         /* Check if end of dump buffer was exceeded */
6311         if (dump_buf > dump_buf_end)
6312                 return 0;
6313
6314         return results_offset;
6315 }
6316
6317 /* Parses an idle check dump buffer.
6318  * If result_buf is not NULL, the idle check results are printed to it.
6319  * In any case, the required results buffer size is assigned to
6320  * parsed_results_bytes.
6321  * The parsing status is returned.
6322  */
6323 static enum dbg_status qed_parse_idle_chk_dump(struct qed_hwfn *p_hwfn,
6324                                                u32 *dump_buf,
6325                                                u32 num_dumped_dwords,
6326                                                char *results_buf,
6327                                                u32 *parsed_results_bytes,
6328                                                u32 *num_errors,
6329                                                u32 *num_warnings)
6330 {
6331         const char *section_name, *param_name, *param_str_val;
6332         u32 *dump_buf_end = dump_buf + num_dumped_dwords;
6333         u32 num_section_params = 0, num_rules;
6334
6335         /* Offset in results_buf in bytes */
6336         u32 results_offset = 0;
6337
6338         *parsed_results_bytes = 0;
6339         *num_errors = 0;
6340         *num_warnings = 0;
6341
6342         if (!s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr ||
6343             !s_user_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr)
6344                 return DBG_STATUS_DBG_ARRAY_NOT_SET;
6345
6346         /* Read global_params section */
6347         dump_buf += qed_read_section_hdr(dump_buf,
6348                                          &section_name, &num_section_params);
6349         if (strcmp(section_name, "global_params"))
6350                 return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6351
6352         /* Print global params */
6353         dump_buf += qed_print_section_params(dump_buf,
6354                                              num_section_params,
6355                                              results_buf, &results_offset);
6356
6357         /* Read idle_chk section */
6358         dump_buf += qed_read_section_hdr(dump_buf,
6359                                          &section_name, &num_section_params);
6360         if (strcmp(section_name, "idle_chk") || num_section_params != 1)
6361                 return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6362         dump_buf += qed_read_param(dump_buf,
6363                                    &param_name, &param_str_val, &num_rules);
6364         if (strcmp(param_name, "num_rules"))
6365                 return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6366
6367         if (num_rules) {
6368                 u32 rules_print_size;
6369
6370                 /* Print FW output */
6371                 results_offset +=
6372                     sprintf(qed_get_buf_ptr(results_buf,
6373                                             results_offset),
6374                             "FW_IDLE_CHECK:\n");
6375                 rules_print_size =
6376                         qed_parse_idle_chk_dump_rules(p_hwfn, dump_buf,
6377                                                       dump_buf_end, num_rules,
6378                                                       true,
6379                                                       results_buf ?
6380                                                       results_buf +
6381                                                       results_offset : NULL,
6382                                                       num_errors, num_warnings);
6383                 results_offset += rules_print_size;
6384                 if (!rules_print_size)
6385                         return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6386
6387                 /* Print LSI output */
6388                 results_offset +=
6389                     sprintf(qed_get_buf_ptr(results_buf,
6390                                             results_offset),
6391                             "\nLSI_IDLE_CHECK:\n");
6392                 rules_print_size =
6393                         qed_parse_idle_chk_dump_rules(p_hwfn, dump_buf,
6394                                                       dump_buf_end, num_rules,
6395                                                       false,
6396                                                       results_buf ?
6397                                                       results_buf +
6398                                                       results_offset : NULL,
6399                                                       num_errors, num_warnings);
6400                 results_offset += rules_print_size;
6401                 if (!rules_print_size)
6402                         return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6403         }
6404
6405         /* Print errors/warnings count */
6406         if (*num_errors)
6407                 results_offset +=
6408                     sprintf(qed_get_buf_ptr(results_buf,
6409                                             results_offset),
6410                             "\nIdle Check failed!!! (with %d errors and %d warnings)\n",
6411                             *num_errors, *num_warnings);
6412         else if (*num_warnings)
6413                 results_offset +=
6414                     sprintf(qed_get_buf_ptr(results_buf,
6415                                             results_offset),
6416                             "\nIdle Check completed successfully (with %d warnings)\n",
6417                             *num_warnings);
6418         else
6419                 results_offset +=
6420                     sprintf(qed_get_buf_ptr(results_buf,
6421                                             results_offset),
6422                             "\nIdle Check completed successfully\n");
6423
6424         /* Add 1 for string NULL termination */
6425         *parsed_results_bytes = results_offset + 1;
6426
6427         return DBG_STATUS_OK;
6428 }
6429
6430 /* Frees the specified MCP Trace meta data */
6431 static void qed_mcp_trace_free_meta(struct qed_hwfn *p_hwfn,
6432                                     struct mcp_trace_meta *meta)
6433 {
6434         u32 i;
6435
6436         /* Release modules */
6437         if (meta->modules) {
6438                 for (i = 0; i < meta->modules_num; i++)
6439                         kfree(meta->modules[i]);
6440                 kfree(meta->modules);
6441         }
6442
6443         /* Release formats */
6444         if (meta->formats) {
6445                 for (i = 0; i < meta->formats_num; i++)
6446                         kfree(meta->formats[i].format_str);
6447                 kfree(meta->formats);
6448         }
6449 }
6450
6451 /* Allocates and fills MCP Trace meta data based on the specified meta data
6452  * dump buffer.
6453  * Returns debug status code.
6454  */
6455 static enum dbg_status qed_mcp_trace_alloc_meta(struct qed_hwfn *p_hwfn,
6456                                                 const u32 *meta_buf,
6457                                                 struct mcp_trace_meta *meta)
6458 {
6459         u8 *meta_buf_bytes = (u8 *)meta_buf;
6460         u32 offset = 0, signature, i;
6461
6462         memset(meta, 0, sizeof(*meta));
6463
6464         /* Read first signature */
6465         signature = qed_read_dword_from_buf(meta_buf_bytes, &offset);
6466         if (signature != NVM_MAGIC_VALUE)
6467                 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
6468
6469         /* Read no. of modules and allocate memory for their pointers */
6470         meta->modules_num = qed_read_byte_from_buf(meta_buf_bytes, &offset);
6471         meta->modules = kzalloc(meta->modules_num * sizeof(char *), GFP_KERNEL);
6472         if (!meta->modules)
6473                 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6474
6475         /* Allocate and read all module strings */
6476         for (i = 0; i < meta->modules_num; i++) {
6477                 u8 module_len = qed_read_byte_from_buf(meta_buf_bytes, &offset);
6478
6479                 *(meta->modules + i) = kzalloc(module_len, GFP_KERNEL);
6480                 if (!(*(meta->modules + i))) {
6481                         /* Update number of modules to be released */
6482                         meta->modules_num = i ? i - 1 : 0;
6483                         return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6484                 }
6485
6486                 qed_read_str_from_buf(meta_buf_bytes, &offset, module_len,
6487                                       *(meta->modules + i));
6488                 if (module_len > MCP_TRACE_MAX_MODULE_LEN)
6489                         (*(meta->modules + i))[MCP_TRACE_MAX_MODULE_LEN] = '\0';
6490         }
6491
6492         /* Read second signature */
6493         signature = qed_read_dword_from_buf(meta_buf_bytes, &offset);
6494         if (signature != NVM_MAGIC_VALUE)
6495                 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
6496
6497         /* Read number of formats and allocate memory for all formats */
6498         meta->formats_num = qed_read_dword_from_buf(meta_buf_bytes, &offset);
6499         meta->formats = kzalloc(meta->formats_num *
6500                                 sizeof(struct mcp_trace_format),
6501                                 GFP_KERNEL);
6502         if (!meta->formats)
6503                 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6504
6505         /* Allocate and read all strings */
6506         for (i = 0; i < meta->formats_num; i++) {
6507                 struct mcp_trace_format *format_ptr = &meta->formats[i];
6508                 u8 format_len;
6509
6510                 format_ptr->data = qed_read_dword_from_buf(meta_buf_bytes,
6511                                                            &offset);
6512                 format_len =
6513                     (format_ptr->data &
6514                      MCP_TRACE_FORMAT_LEN_MASK) >> MCP_TRACE_FORMAT_LEN_SHIFT;
6515                 format_ptr->format_str = kzalloc(format_len, GFP_KERNEL);
6516                 if (!format_ptr->format_str) {
6517                         /* Update number of modules to be released */
6518                         meta->formats_num = i ? i - 1 : 0;
6519                         return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6520                 }
6521
6522                 qed_read_str_from_buf(meta_buf_bytes,
6523                                       &offset,
6524                                       format_len, format_ptr->format_str);
6525         }
6526
6527         return DBG_STATUS_OK;
6528 }
6529
6530 /* Parses an MCP Trace dump buffer.
6531  * If result_buf is not NULL, the MCP Trace results are printed to it.
6532  * In any case, the required results buffer size is assigned to
6533  * parsed_results_bytes.
6534  * The parsing status is returned.
6535  */
6536 static enum dbg_status qed_parse_mcp_trace_dump(struct qed_hwfn *p_hwfn,
6537                                                 u32 *dump_buf,
6538                                                 u32 num_dumped_dwords,
6539                                                 char *results_buf,
6540                                                 u32 *parsed_results_bytes)
6541 {
6542         u32 end_offset, bytes_left, trace_data_dwords, trace_meta_dwords;
6543         u32 param_mask, param_shift, param_num_val, num_section_params;
6544         const char *section_name, *param_name, *param_str_val;
6545         u32 offset, results_offset = 0;
6546         struct mcp_trace_meta meta;
6547         struct mcp_trace *trace;
6548         enum dbg_status status;
6549         const u32 *meta_buf;
6550         u8 *trace_buf;
6551
6552         *parsed_results_bytes = 0;
6553
6554         /* Read global_params section */
6555         dump_buf += qed_read_section_hdr(dump_buf,
6556                                          &section_name, &num_section_params);
6557         if (strcmp(section_name, "global_params"))
6558                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6559
6560         /* Print global params */
6561         dump_buf += qed_print_section_params(dump_buf,
6562                                              num_section_params,
6563                                              results_buf, &results_offset);
6564
6565         /* Read trace_data section */
6566         dump_buf += qed_read_section_hdr(dump_buf,
6567                                          &section_name, &num_section_params);
6568         if (strcmp(section_name, "mcp_trace_data") || num_section_params != 1)
6569                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6570         dump_buf += qed_read_param(dump_buf,
6571                                    &param_name, &param_str_val, &param_num_val);
6572         if (strcmp(param_name, "size"))
6573                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6574         trace_data_dwords = param_num_val;
6575
6576         /* Prepare trace info */
6577         trace = (struct mcp_trace *)dump_buf;
6578         trace_buf = (u8 *)dump_buf + sizeof(*trace);
6579         offset = trace->trace_oldest;
6580         end_offset = trace->trace_prod;
6581         bytes_left = qed_cyclic_sub(end_offset, offset, trace->size);
6582         dump_buf += trace_data_dwords;
6583
6584         /* Read meta_data section */
6585         dump_buf += qed_read_section_hdr(dump_buf,
6586                                          &section_name, &num_section_params);
6587         if (strcmp(section_name, "mcp_trace_meta"))
6588                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6589         dump_buf += qed_read_param(dump_buf,
6590                                    &param_name, &param_str_val, &param_num_val);
6591         if (strcmp(param_name, "size"))
6592                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6593         trace_meta_dwords = param_num_val;
6594
6595         /* Choose meta data buffer */
6596         if (!trace_meta_dwords) {
6597                 /* Dump doesn't include meta data */
6598                 if (!s_mcp_trace_meta.ptr)
6599                         return DBG_STATUS_MCP_TRACE_NO_META;
6600                 meta_buf = s_mcp_trace_meta.ptr;
6601         } else {
6602                 /* Dump includes meta data */
6603                 meta_buf = dump_buf;
6604         }
6605
6606         /* Allocate meta data memory */
6607         status = qed_mcp_trace_alloc_meta(p_hwfn, meta_buf, &meta);
6608         if (status != DBG_STATUS_OK)
6609                 goto free_mem;
6610
6611         /* Ignore the level and modules masks - just print everything that is
6612          * already in the buffer.
6613          */
6614         while (bytes_left) {
6615                 struct mcp_trace_format *format_ptr;
6616                 u8 format_level, format_module;
6617                 u32 params[3] = { 0, 0, 0 };
6618                 u32 header, format_idx, i;
6619
6620                 if (bytes_left < MFW_TRACE_ENTRY_SIZE) {
6621                         status = DBG_STATUS_MCP_TRACE_BAD_DATA;
6622                         goto free_mem;
6623                 }
6624
6625                 header = qed_read_from_cyclic_buf(trace_buf,
6626                                                   &offset,
6627                                                   trace->size,
6628                                                   MFW_TRACE_ENTRY_SIZE);
6629                 bytes_left -= MFW_TRACE_ENTRY_SIZE;
6630                 format_idx = header & MFW_TRACE_EVENTID_MASK;
6631
6632                 /* Skip message if its  index doesn't exist in the meta data */
6633                 if (format_idx > meta.formats_num) {
6634                         u8 format_size =
6635                             (u8)((header &
6636                                   MFW_TRACE_PRM_SIZE_MASK) >>
6637                                  MFW_TRACE_PRM_SIZE_SHIFT);
6638
6639                         if (bytes_left < format_size) {
6640                                 status = DBG_STATUS_MCP_TRACE_BAD_DATA;
6641                                 goto free_mem;
6642                         }
6643
6644                         offset = qed_cyclic_add(offset,
6645                                                 format_size, trace->size);
6646                         bytes_left -= format_size;
6647                         continue;
6648                 }
6649
6650                 format_ptr = &meta.formats[format_idx];
6651
6652                 for (i = 0,
6653                      param_mask = MCP_TRACE_FORMAT_P1_SIZE_MASK, param_shift =
6654                      MCP_TRACE_FORMAT_P1_SIZE_SHIFT;
6655                      i < MCP_TRACE_FORMAT_MAX_PARAMS;
6656                      i++, param_mask <<= MCP_TRACE_FORMAT_PARAM_WIDTH,
6657                      param_shift += MCP_TRACE_FORMAT_PARAM_WIDTH) {
6658                         /* Extract param size (0..3) */
6659                         u8 param_size =
6660                             (u8)((format_ptr->data &
6661                                   param_mask) >> param_shift);
6662
6663                         /* If the param size is zero, there are no other
6664                          * parameters.
6665                          */
6666                         if (!param_size)
6667                                 break;
6668
6669                         /* Size is encoded using 2 bits, where 3 is used to
6670                          * encode 4.
6671                          */
6672                         if (param_size == 3)
6673                                 param_size = 4;
6674
6675                         if (bytes_left < param_size) {
6676                                 status = DBG_STATUS_MCP_TRACE_BAD_DATA;
6677                                 goto free_mem;
6678                         }
6679
6680                         params[i] = qed_read_from_cyclic_buf(trace_buf,
6681                                                              &offset,
6682                                                              trace->size,
6683                                                              param_size);
6684
6685                         bytes_left -= param_size;
6686                 }
6687
6688                 format_level =
6689                     (u8)((format_ptr->data &
6690                           MCP_TRACE_FORMAT_LEVEL_MASK) >>
6691                          MCP_TRACE_FORMAT_LEVEL_SHIFT);
6692                 format_module =
6693                     (u8)((format_ptr->data &
6694                           MCP_TRACE_FORMAT_MODULE_MASK) >>
6695                          MCP_TRACE_FORMAT_MODULE_SHIFT);
6696                 if (format_level >= ARRAY_SIZE(s_mcp_trace_level_str)) {
6697                         status = DBG_STATUS_MCP_TRACE_BAD_DATA;
6698                         goto free_mem;
6699                 }
6700
6701                 /* Print current message to results buffer */
6702                 results_offset +=
6703                     sprintf(qed_get_buf_ptr(results_buf,
6704                                             results_offset), "%s %-8s: ",
6705                             s_mcp_trace_level_str[format_level],
6706                             meta.modules[format_module]);
6707                 results_offset +=
6708                     sprintf(qed_get_buf_ptr(results_buf,
6709                                             results_offset),
6710                             format_ptr->format_str, params[0], params[1],
6711                             params[2]);
6712         }
6713
6714 free_mem:
6715         *parsed_results_bytes = results_offset + 1;
6716         qed_mcp_trace_free_meta(p_hwfn, &meta);
6717         return status;
6718 }
6719
6720 /* Parses a Reg FIFO dump buffer.
6721  * If result_buf is not NULL, the Reg FIFO results are printed to it.
6722  * In any case, the required results buffer size is assigned to
6723  * parsed_results_bytes.
6724  * The parsing status is returned.
6725  */
6726 static enum dbg_status qed_parse_reg_fifo_dump(struct qed_hwfn *p_hwfn,
6727                                                u32 *dump_buf,
6728                                                u32 num_dumped_dwords,
6729                                                char *results_buf,
6730                                                u32 *parsed_results_bytes)
6731 {
6732         const char *section_name, *param_name, *param_str_val;
6733         u32 param_num_val, num_section_params, num_elements;
6734         struct reg_fifo_element *elements;
6735         u8 i, j, err_val, vf_val;
6736         u32 results_offset = 0;
6737         char vf_str[4];
6738
6739         /* Read global_params section */
6740         dump_buf += qed_read_section_hdr(dump_buf,
6741                                          &section_name, &num_section_params);
6742         if (strcmp(section_name, "global_params"))
6743                 return DBG_STATUS_REG_FIFO_BAD_DATA;
6744
6745         /* Print global params */
6746         dump_buf += qed_print_section_params(dump_buf,
6747                                              num_section_params,
6748                                              results_buf, &results_offset);
6749
6750         /* Read reg_fifo_data section */
6751         dump_buf += qed_read_section_hdr(dump_buf,
6752                                          &section_name, &num_section_params);
6753         if (strcmp(section_name, "reg_fifo_data"))
6754                 return DBG_STATUS_REG_FIFO_BAD_DATA;
6755         dump_buf += qed_read_param(dump_buf,
6756                                    &param_name, &param_str_val, &param_num_val);
6757         if (strcmp(param_name, "size"))
6758                 return DBG_STATUS_REG_FIFO_BAD_DATA;
6759         if (param_num_val % REG_FIFO_ELEMENT_DWORDS)
6760                 return DBG_STATUS_REG_FIFO_BAD_DATA;
6761         num_elements = param_num_val / REG_FIFO_ELEMENT_DWORDS;
6762         elements = (struct reg_fifo_element *)dump_buf;
6763
6764         /* Decode elements */
6765         for (i = 0; i < num_elements; i++) {
6766                 bool err_printed = false;
6767
6768                 /* Discover if element belongs to a VF or a PF */
6769                 vf_val = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_VF);
6770                 if (vf_val == REG_FIFO_ELEMENT_IS_PF_VF_VAL)
6771                         sprintf(vf_str, "%s", "N/A");
6772                 else
6773                         sprintf(vf_str, "%d", vf_val);
6774
6775                 /* Add parsed element to parsed buffer */
6776                 results_offset +=
6777                     sprintf(qed_get_buf_ptr(results_buf,
6778                                             results_offset),
6779                             "raw: 0x%016llx, address: 0x%07x, access: %-5s, pf: %2d, vf: %s, port: %d, privilege: %-3s, protection: %-12s, master: %-4s, errors: ",
6780                             elements[i].data,
6781                             (u32)GET_FIELD(elements[i].data,
6782                                            REG_FIFO_ELEMENT_ADDRESS) *
6783                             REG_FIFO_ELEMENT_ADDR_FACTOR,
6784                             s_access_strs[GET_FIELD(elements[i].data,
6785                                                     REG_FIFO_ELEMENT_ACCESS)],
6786                             (u32)GET_FIELD(elements[i].data,
6787                                            REG_FIFO_ELEMENT_PF),
6788                             vf_str,
6789                             (u32)GET_FIELD(elements[i].data,
6790                                            REG_FIFO_ELEMENT_PORT),
6791                             s_privilege_strs[GET_FIELD(elements[i].data,
6792                                                 REG_FIFO_ELEMENT_PRIVILEGE)],
6793                             s_protection_strs[GET_FIELD(elements[i].data,
6794                                                 REG_FIFO_ELEMENT_PROTECTION)],
6795                             s_master_strs[GET_FIELD(elements[i].data,
6796                                                 REG_FIFO_ELEMENT_MASTER)]);
6797
6798                 /* Print errors */
6799                 for (j = 0,
6800                      err_val = GET_FIELD(elements[i].data,
6801                                          REG_FIFO_ELEMENT_ERROR);
6802                      j < ARRAY_SIZE(s_reg_fifo_error_strs);
6803                      j++, err_val >>= 1) {
6804                         if (err_val & 0x1) {
6805                                 if (err_printed)
6806                                         results_offset +=
6807                                             sprintf(qed_get_buf_ptr
6808                                                     (results_buf,
6809                                                      results_offset), ", ");
6810                                 results_offset +=
6811                                     sprintf(qed_get_buf_ptr
6812                                             (results_buf, results_offset), "%s",
6813                                             s_reg_fifo_error_strs[j]);
6814                                 err_printed = true;
6815                         }
6816                 }
6817
6818                 results_offset +=
6819                     sprintf(qed_get_buf_ptr(results_buf, results_offset), "\n");
6820         }
6821
6822         results_offset += sprintf(qed_get_buf_ptr(results_buf,
6823                                                   results_offset),
6824                                   "fifo contained %d elements", num_elements);
6825
6826         /* Add 1 for string NULL termination */
6827         *parsed_results_bytes = results_offset + 1;
6828
6829         return DBG_STATUS_OK;
6830 }
6831
6832 static enum dbg_status qed_parse_igu_fifo_element(struct igu_fifo_element
6833                                                   *element, char
6834                                                   *results_buf,
6835                                                   u32 *results_offset,
6836                                                   u32 *parsed_results_bytes)
6837 {
6838         const struct igu_fifo_addr_data *found_addr = NULL;
6839         u8 source, err_type, i, is_cleanup;
6840         char parsed_addr_data[32];
6841         char parsed_wr_data[256];
6842         u32 wr_data, prod_cons;
6843         bool is_wr_cmd, is_pf;
6844         u16 cmd_addr;
6845         u64 dword12;
6846
6847         /* Dword12 (dword index 1 and 2) contains bits 32..95 of the
6848          * FIFO element.
6849          */
6850         dword12 = ((u64)element->dword2 << 32) | element->dword1;
6851         is_wr_cmd = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD);
6852         is_pf = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_IS_PF);
6853         cmd_addr = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR);
6854         source = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_SOURCE);
6855         err_type = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE);
6856
6857         if (source >= ARRAY_SIZE(s_igu_fifo_source_strs))
6858                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
6859         if (err_type >= ARRAY_SIZE(s_igu_fifo_error_strs))
6860                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
6861
6862         /* Find address data */
6863         for (i = 0; i < ARRAY_SIZE(s_igu_fifo_addr_data) && !found_addr; i++) {
6864                 const struct igu_fifo_addr_data *curr_addr =
6865                         &s_igu_fifo_addr_data[i];
6866
6867                 if (cmd_addr >= curr_addr->start_addr && cmd_addr <=
6868                     curr_addr->end_addr)
6869                         found_addr = curr_addr;
6870         }
6871
6872         if (!found_addr)
6873                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
6874
6875         /* Prepare parsed address data */
6876         switch (found_addr->type) {
6877         case IGU_ADDR_TYPE_MSIX_MEM:
6878                 sprintf(parsed_addr_data, " vector_num = 0x%x", cmd_addr / 2);
6879                 break;
6880         case IGU_ADDR_TYPE_WRITE_INT_ACK:
6881         case IGU_ADDR_TYPE_WRITE_PROD_UPDATE:
6882                 sprintf(parsed_addr_data,
6883                         " SB = 0x%x", cmd_addr - found_addr->start_addr);
6884                 break;
6885         default:
6886                 parsed_addr_data[0] = '\0';
6887         }
6888
6889         if (!is_wr_cmd) {
6890                 parsed_wr_data[0] = '\0';
6891                 goto out;
6892         }
6893
6894         /* Prepare parsed write data */
6895         wr_data = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_WR_DATA);
6896         prod_cons = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_PROD_CONS);
6897         is_cleanup = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_CMD_TYPE);
6898
6899         if (source == IGU_SRC_ATTN) {
6900                 sprintf(parsed_wr_data, "prod: 0x%x, ", prod_cons);
6901         } else {
6902                 if (is_cleanup) {
6903                         u8 cleanup_val, cleanup_type;
6904
6905                         cleanup_val =
6906                                 GET_FIELD(wr_data,
6907                                           IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL);
6908                         cleanup_type =
6909                             GET_FIELD(wr_data,
6910                                       IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE);
6911
6912                         sprintf(parsed_wr_data,
6913                                 "cmd_type: cleanup, cleanup_val: %s, cleanup_type : %d, ",
6914                                 cleanup_val ? "set" : "clear",
6915                                 cleanup_type);
6916                 } else {
6917                         u8 update_flag, en_dis_int_for_sb, segment;
6918                         u8 timer_mask;
6919
6920                         update_flag = GET_FIELD(wr_data,
6921                                                 IGU_FIFO_WR_DATA_UPDATE_FLAG);
6922                         en_dis_int_for_sb =
6923                                 GET_FIELD(wr_data,
6924                                           IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB);
6925                         segment = GET_FIELD(wr_data,
6926                                             IGU_FIFO_WR_DATA_SEGMENT);
6927                         timer_mask = GET_FIELD(wr_data,
6928                                                IGU_FIFO_WR_DATA_TIMER_MASK);
6929
6930                         sprintf(parsed_wr_data,
6931                                 "cmd_type: prod/cons update, prod/cons: 0x%x, update_flag: %s, en_dis_int_for_sb : %s, segment : %s, timer_mask = %d, ",
6932                                 prod_cons,
6933                                 update_flag ? "update" : "nop",
6934                                 en_dis_int_for_sb
6935                                 ? (en_dis_int_for_sb == 1 ? "disable" : "nop")
6936                                 : "enable",
6937                                 segment ? "attn" : "regular",
6938                                 timer_mask);
6939                 }
6940         }
6941 out:
6942         /* Add parsed element to parsed buffer */
6943         *results_offset += sprintf(qed_get_buf_ptr(results_buf,
6944                                                    *results_offset),
6945                                    "raw: 0x%01x%08x%08x, %s: %d, source : %s, type : %s, cmd_addr : 0x%x(%s%s), %serror: %s\n",
6946                                    element->dword2, element->dword1,
6947                                    element->dword0,
6948                                    is_pf ? "pf" : "vf",
6949                                    GET_FIELD(element->dword0,
6950                                              IGU_FIFO_ELEMENT_DWORD0_FID),
6951                                    s_igu_fifo_source_strs[source],
6952                                    is_wr_cmd ? "wr" : "rd",
6953                                    cmd_addr,
6954                                    (!is_pf && found_addr->vf_desc)
6955                                    ? found_addr->vf_desc
6956                                    : found_addr->desc,
6957                                    parsed_addr_data,
6958                                    parsed_wr_data,
6959                                    s_igu_fifo_error_strs[err_type]);
6960
6961         return DBG_STATUS_OK;
6962 }
6963
6964 /* Parses an IGU FIFO dump buffer.
6965  * If result_buf is not NULL, the IGU FIFO results are printed to it.
6966  * In any case, the required results buffer size is assigned to
6967  * parsed_results_bytes.
6968  * The parsing status is returned.
6969  */
6970 static enum dbg_status qed_parse_igu_fifo_dump(struct qed_hwfn *p_hwfn,
6971                                                u32 *dump_buf,
6972                                                u32 num_dumped_dwords,
6973                                                char *results_buf,
6974                                                u32 *parsed_results_bytes)
6975 {
6976         const char *section_name, *param_name, *param_str_val;
6977         u32 param_num_val, num_section_params, num_elements;
6978         struct igu_fifo_element *elements;
6979         enum dbg_status status;
6980         u32 results_offset = 0;
6981         u8 i;
6982
6983         /* Read global_params section */
6984         dump_buf += qed_read_section_hdr(dump_buf,
6985                                          &section_name, &num_section_params);
6986         if (strcmp(section_name, "global_params"))
6987                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
6988
6989         /* Print global params */
6990         dump_buf += qed_print_section_params(dump_buf,
6991                                              num_section_params,
6992                                              results_buf, &results_offset);
6993
6994         /* Read igu_fifo_data section */
6995         dump_buf += qed_read_section_hdr(dump_buf,
6996                                          &section_name, &num_section_params);
6997         if (strcmp(section_name, "igu_fifo_data"))
6998                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
6999         dump_buf += qed_read_param(dump_buf,
7000                                    &param_name, &param_str_val, &param_num_val);
7001         if (strcmp(param_name, "size"))
7002                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
7003         if (param_num_val % IGU_FIFO_ELEMENT_DWORDS)
7004                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
7005         num_elements = param_num_val / IGU_FIFO_ELEMENT_DWORDS;
7006         elements = (struct igu_fifo_element *)dump_buf;
7007
7008         /* Decode elements */
7009         for (i = 0; i < num_elements; i++) {
7010                 status = qed_parse_igu_fifo_element(&elements[i],
7011                                                     results_buf,
7012                                                     &results_offset,
7013                                                     parsed_results_bytes);
7014                 if (status != DBG_STATUS_OK)
7015                         return status;
7016         }
7017
7018         results_offset += sprintf(qed_get_buf_ptr(results_buf,
7019                                                   results_offset),
7020                                   "fifo contained %d elements", num_elements);
7021
7022         /* Add 1 for string NULL termination */
7023         *parsed_results_bytes = results_offset + 1;
7024
7025         return DBG_STATUS_OK;
7026 }
7027
7028 static enum dbg_status
7029 qed_parse_protection_override_dump(struct qed_hwfn *p_hwfn,
7030                                    u32 *dump_buf,
7031                                    u32 num_dumped_dwords,
7032                                    char *results_buf,
7033                                    u32 *parsed_results_bytes)
7034 {
7035         const char *section_name, *param_name, *param_str_val;
7036         u32 param_num_val, num_section_params, num_elements;
7037         struct protection_override_element *elements;
7038         u32 results_offset = 0;
7039         u8 i;
7040
7041         /* Read global_params section */
7042         dump_buf += qed_read_section_hdr(dump_buf,
7043                                          &section_name, &num_section_params);
7044         if (strcmp(section_name, "global_params"))
7045                 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7046
7047         /* Print global params */
7048         dump_buf += qed_print_section_params(dump_buf,
7049                                              num_section_params,
7050                                              results_buf, &results_offset);
7051
7052         /* Read protection_override_data section */
7053         dump_buf += qed_read_section_hdr(dump_buf,
7054                                          &section_name, &num_section_params);
7055         if (strcmp(section_name, "protection_override_data"))
7056                 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7057         dump_buf += qed_read_param(dump_buf,
7058                                    &param_name, &param_str_val, &param_num_val);
7059         if (strcmp(param_name, "size"))
7060                 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7061         if (param_num_val % PROTECTION_OVERRIDE_ELEMENT_DWORDS)
7062                 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7063         num_elements = param_num_val / PROTECTION_OVERRIDE_ELEMENT_DWORDS;
7064         elements = (struct protection_override_element *)dump_buf;
7065
7066         /* Decode elements */
7067         for (i = 0; i < num_elements; i++) {
7068                 u32 address = GET_FIELD(elements[i].data,
7069                                         PROTECTION_OVERRIDE_ELEMENT_ADDRESS) *
7070                               PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR;
7071
7072                 results_offset +=
7073                     sprintf(qed_get_buf_ptr(results_buf,
7074                                             results_offset),
7075                             "window %2d, address: 0x%07x, size: %7d regs, read: %d, write: %d, read protection: %-12s, write protection: %-12s\n",
7076                             i, address,
7077                             (u32)GET_FIELD(elements[i].data,
7078                                       PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE),
7079                             (u32)GET_FIELD(elements[i].data,
7080                                       PROTECTION_OVERRIDE_ELEMENT_READ),
7081                             (u32)GET_FIELD(elements[i].data,
7082                                       PROTECTION_OVERRIDE_ELEMENT_WRITE),
7083                             s_protection_strs[GET_FIELD(elements[i].data,
7084                                 PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION)],
7085                             s_protection_strs[GET_FIELD(elements[i].data,
7086                                 PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION)]);
7087         }
7088
7089         results_offset += sprintf(qed_get_buf_ptr(results_buf,
7090                                                   results_offset),
7091                                   "protection override contained %d elements",
7092                                   num_elements);
7093
7094         /* Add 1 for string NULL termination */
7095         *parsed_results_bytes = results_offset + 1;
7096
7097         return DBG_STATUS_OK;
7098 }
7099
7100 /* Parses a FW Asserts dump buffer.
7101  * If result_buf is not NULL, the FW Asserts results are printed to it.
7102  * In any case, the required results buffer size is assigned to
7103  * parsed_results_bytes.
7104  * The parsing status is returned.
7105  */
7106 static enum dbg_status qed_parse_fw_asserts_dump(struct qed_hwfn *p_hwfn,
7107                                                  u32 *dump_buf,
7108                                                  u32 num_dumped_dwords,
7109                                                  char *results_buf,
7110                                                  u32 *parsed_results_bytes)
7111 {
7112         u32 num_section_params, param_num_val, i, results_offset = 0;
7113         const char *param_name, *param_str_val, *section_name;
7114         bool last_section_found = false;
7115
7116         *parsed_results_bytes = 0;
7117
7118         /* Read global_params section */
7119         dump_buf += qed_read_section_hdr(dump_buf,
7120                                          &section_name, &num_section_params);
7121         if (strcmp(section_name, "global_params"))
7122                 return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7123
7124         /* Print global params */
7125         dump_buf += qed_print_section_params(dump_buf,
7126                                              num_section_params,
7127                                              results_buf, &results_offset);
7128
7129         while (!last_section_found) {
7130                 dump_buf += qed_read_section_hdr(dump_buf,
7131                                                  &section_name,
7132                                                  &num_section_params);
7133                 if (!strcmp(section_name, "fw_asserts")) {
7134                         /* Extract params */
7135                         const char *storm_letter = NULL;
7136                         u32 storm_dump_size = 0;
7137
7138                         for (i = 0; i < num_section_params; i++) {
7139                                 dump_buf += qed_read_param(dump_buf,
7140                                                            &param_name,
7141                                                            &param_str_val,
7142                                                            &param_num_val);
7143                                 if (!strcmp(param_name, "storm"))
7144                                         storm_letter = param_str_val;
7145                                 else if (!strcmp(param_name, "size"))
7146                                         storm_dump_size = param_num_val;
7147                                 else
7148                                         return
7149                                             DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7150                         }
7151
7152                         if (!storm_letter || !storm_dump_size)
7153                                 return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7154
7155                         /* Print data */
7156                         results_offset +=
7157                             sprintf(qed_get_buf_ptr(results_buf,
7158                                                     results_offset),
7159                                     "\n%sSTORM_ASSERT: size=%d\n",
7160                                     storm_letter, storm_dump_size);
7161                         for (i = 0; i < storm_dump_size; i++, dump_buf++)
7162                                 results_offset +=
7163                                     sprintf(qed_get_buf_ptr(results_buf,
7164                                                             results_offset),
7165                                             "%08x\n", *dump_buf);
7166                 } else if (!strcmp(section_name, "last")) {
7167                         last_section_found = true;
7168                 } else {
7169                         return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7170                 }
7171         }
7172
7173         /* Add 1 for string NULL termination */
7174         *parsed_results_bytes = results_offset + 1;
7175
7176         return DBG_STATUS_OK;
7177 }
7178
7179 /***************************** Public Functions *******************************/
7180
7181 enum dbg_status qed_dbg_user_set_bin_ptr(const u8 * const bin_ptr)
7182 {
7183         struct bin_buffer_hdr *buf_array = (struct bin_buffer_hdr *)bin_ptr;
7184         u8 buf_id;
7185
7186         /* Convert binary data to debug arrays */
7187         for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++) {
7188                 s_user_dbg_arrays[buf_id].ptr =
7189                         (u32 *)(bin_ptr + buf_array[buf_id].offset);
7190                 s_user_dbg_arrays[buf_id].size_in_dwords =
7191                         BYTES_TO_DWORDS(buf_array[buf_id].length);
7192         }
7193
7194         return DBG_STATUS_OK;
7195 }
7196
7197 const char *qed_dbg_get_status_str(enum dbg_status status)
7198 {
7199         return (status <
7200                 MAX_DBG_STATUS) ? s_status_str[status] : "Invalid debug status";
7201 }
7202
7203 enum dbg_status qed_get_idle_chk_results_buf_size(struct qed_hwfn *p_hwfn,
7204                                                   u32 *dump_buf,
7205                                                   u32 num_dumped_dwords,
7206                                                   u32 *results_buf_size)
7207 {
7208         u32 num_errors, num_warnings;
7209
7210         return qed_parse_idle_chk_dump(p_hwfn,
7211                                        dump_buf,
7212                                        num_dumped_dwords,
7213                                        NULL,
7214                                        results_buf_size,
7215                                        &num_errors, &num_warnings);
7216 }
7217
7218 enum dbg_status qed_print_idle_chk_results(struct qed_hwfn *p_hwfn,
7219                                            u32 *dump_buf,
7220                                            u32 num_dumped_dwords,
7221                                            char *results_buf,
7222                                            u32 *num_errors, u32 *num_warnings)
7223 {
7224         u32 parsed_buf_size;
7225
7226         return qed_parse_idle_chk_dump(p_hwfn,
7227                                        dump_buf,
7228                                        num_dumped_dwords,
7229                                        results_buf,
7230                                        &parsed_buf_size,
7231                                        num_errors, num_warnings);
7232 }
7233
7234 void qed_dbg_mcp_trace_set_meta_data(u32 *data, u32 size)
7235 {
7236         s_mcp_trace_meta.ptr = data;
7237         s_mcp_trace_meta.size_in_dwords = size;
7238 }
7239
7240 enum dbg_status qed_get_mcp_trace_results_buf_size(struct qed_hwfn *p_hwfn,
7241                                                    u32 *dump_buf,
7242                                                    u32 num_dumped_dwords,
7243                                                    u32 *results_buf_size)
7244 {
7245         return qed_parse_mcp_trace_dump(p_hwfn,
7246                                         dump_buf,
7247                                         num_dumped_dwords,
7248                                         NULL, results_buf_size);
7249 }
7250
7251 enum dbg_status qed_print_mcp_trace_results(struct qed_hwfn *p_hwfn,
7252                                             u32 *dump_buf,
7253                                             u32 num_dumped_dwords,
7254                                             char *results_buf)
7255 {
7256         u32 parsed_buf_size;
7257
7258         return qed_parse_mcp_trace_dump(p_hwfn,
7259                                         dump_buf,
7260                                         num_dumped_dwords,
7261                                         results_buf, &parsed_buf_size);
7262 }
7263
7264 enum dbg_status qed_get_reg_fifo_results_buf_size(struct qed_hwfn *p_hwfn,
7265                                                   u32 *dump_buf,
7266                                                   u32 num_dumped_dwords,
7267                                                   u32 *results_buf_size)
7268 {
7269         return qed_parse_reg_fifo_dump(p_hwfn,
7270                                        dump_buf,
7271                                        num_dumped_dwords,
7272                                        NULL, results_buf_size);
7273 }
7274
7275 enum dbg_status qed_print_reg_fifo_results(struct qed_hwfn *p_hwfn,
7276                                            u32 *dump_buf,
7277                                            u32 num_dumped_dwords,
7278                                            char *results_buf)
7279 {
7280         u32 parsed_buf_size;
7281
7282         return qed_parse_reg_fifo_dump(p_hwfn,
7283                                        dump_buf,
7284                                        num_dumped_dwords,
7285                                        results_buf, &parsed_buf_size);
7286 }
7287
7288 enum dbg_status qed_get_igu_fifo_results_buf_size(struct qed_hwfn *p_hwfn,
7289                                                   u32 *dump_buf,
7290                                                   u32 num_dumped_dwords,
7291                                                   u32 *results_buf_size)
7292 {
7293         return qed_parse_igu_fifo_dump(p_hwfn,
7294                                        dump_buf,
7295                                        num_dumped_dwords,
7296                                        NULL, results_buf_size);
7297 }
7298
7299 enum dbg_status qed_print_igu_fifo_results(struct qed_hwfn *p_hwfn,
7300                                            u32 *dump_buf,
7301                                            u32 num_dumped_dwords,
7302                                            char *results_buf)
7303 {
7304         u32 parsed_buf_size;
7305
7306         return qed_parse_igu_fifo_dump(p_hwfn,
7307                                        dump_buf,
7308                                        num_dumped_dwords,
7309                                        results_buf, &parsed_buf_size);
7310 }
7311
7312 enum dbg_status
7313 qed_get_protection_override_results_buf_size(struct qed_hwfn *p_hwfn,
7314                                              u32 *dump_buf,
7315                                              u32 num_dumped_dwords,
7316                                              u32 *results_buf_size)
7317 {
7318         return qed_parse_protection_override_dump(p_hwfn,
7319                                                   dump_buf,
7320                                                   num_dumped_dwords,
7321                                                   NULL, results_buf_size);
7322 }
7323
7324 enum dbg_status qed_print_protection_override_results(struct qed_hwfn *p_hwfn,
7325                                                       u32 *dump_buf,
7326                                                       u32 num_dumped_dwords,
7327                                                       char *results_buf)
7328 {
7329         u32 parsed_buf_size;
7330
7331         return qed_parse_protection_override_dump(p_hwfn,
7332                                                   dump_buf,
7333                                                   num_dumped_dwords,
7334                                                   results_buf,
7335                                                   &parsed_buf_size);
7336 }
7337
7338 enum dbg_status qed_get_fw_asserts_results_buf_size(struct qed_hwfn *p_hwfn,
7339                                                     u32 *dump_buf,
7340                                                     u32 num_dumped_dwords,
7341                                                     u32 *results_buf_size)
7342 {
7343         return qed_parse_fw_asserts_dump(p_hwfn,
7344                                          dump_buf,
7345                                          num_dumped_dwords,
7346                                          NULL, results_buf_size);
7347 }
7348
7349 enum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn,
7350                                              u32 *dump_buf,
7351                                              u32 num_dumped_dwords,
7352                                              char *results_buf)
7353 {
7354         u32 parsed_buf_size;
7355
7356         return qed_parse_fw_asserts_dump(p_hwfn,
7357                                          dump_buf,
7358                                          num_dumped_dwords,
7359                                          results_buf, &parsed_buf_size);
7360 }
7361
7362 enum dbg_status qed_dbg_parse_attn(struct qed_hwfn *p_hwfn,
7363                                    struct dbg_attn_block_result *results)
7364 {
7365         struct user_dbg_array *block_attn, *pstrings;
7366         const u32 *block_attn_name_offsets;
7367         enum dbg_attn_type attn_type;
7368         const char *block_name;
7369         u8 num_regs, i, j;
7370
7371         num_regs = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_NUM_REGS);
7372         attn_type = (enum dbg_attn_type)
7373                     GET_FIELD(results->data,
7374                               DBG_ATTN_BLOCK_RESULT_ATTN_TYPE);
7375         block_name = s_block_info_arr[results->block_id].name;
7376
7377         if (!s_user_dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr ||
7378             !s_user_dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr ||
7379             !s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr)
7380                 return DBG_STATUS_DBG_ARRAY_NOT_SET;
7381
7382         block_attn = &s_user_dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS];
7383         block_attn_name_offsets = &block_attn->ptr[results->names_offset];
7384
7385         /* Go over registers with a non-zero attention status */
7386         for (i = 0; i < num_regs; i++) {
7387                 struct dbg_attn_reg_result *reg_result;
7388                 struct dbg_attn_bit_mapping *mapping;
7389                 u8 num_reg_attn, bit_idx = 0;
7390
7391                 reg_result = &results->reg_results[i];
7392                 num_reg_attn = GET_FIELD(reg_result->data,
7393                                          DBG_ATTN_REG_RESULT_NUM_REG_ATTN);
7394                 block_attn = &s_user_dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES];
7395                 mapping = &((struct dbg_attn_bit_mapping *)
7396                             block_attn->ptr)[reg_result->block_attn_offset];
7397
7398                 pstrings = &s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS];
7399
7400                 /* Go over attention status bits */
7401                 for (j = 0; j < num_reg_attn; j++) {
7402                         u16 attn_idx_val = GET_FIELD(mapping[j].data,
7403                                                      DBG_ATTN_BIT_MAPPING_VAL);
7404                         const char *attn_name, *attn_type_str, *masked_str;
7405                         u32 name_offset, sts_addr;
7406
7407                         /* Check if bit mask should be advanced (due to unused
7408                          * bits).
7409                          */
7410                         if (GET_FIELD(mapping[j].data,
7411                                       DBG_ATTN_BIT_MAPPING_IS_UNUSED_BIT_CNT)) {
7412                                 bit_idx += (u8)attn_idx_val;
7413                                 continue;
7414                         }
7415
7416                         /* Check current bit index */
7417                         if (!(reg_result->sts_val & BIT(bit_idx))) {
7418                                 bit_idx++;
7419                                 continue;
7420                         }
7421
7422                         /* Find attention name */
7423                         name_offset = block_attn_name_offsets[attn_idx_val];
7424                         attn_name = &((const char *)
7425                                       pstrings->ptr)[name_offset];
7426                         attn_type_str = attn_type == ATTN_TYPE_INTERRUPT ?
7427                                         "Interrupt" : "Parity";
7428                         masked_str = reg_result->mask_val & BIT(bit_idx) ?
7429                                      " [masked]" : "";
7430                         sts_addr = GET_FIELD(reg_result->data,
7431                                              DBG_ATTN_REG_RESULT_STS_ADDRESS);
7432                         DP_NOTICE(p_hwfn,
7433                                   "%s (%s) : %s [address 0x%08x, bit %d]%s\n",
7434                                   block_name, attn_type_str, attn_name,
7435                                   sts_addr, bit_idx, masked_str);
7436
7437                         bit_idx++;
7438                 }
7439         }
7440
7441         return DBG_STATUS_OK;
7442 }
7443
7444 /* Wrapper for unifying the idle_chk and mcp_trace api */
7445 static enum dbg_status
7446 qed_print_idle_chk_results_wrapper(struct qed_hwfn *p_hwfn,
7447                                    u32 *dump_buf,
7448                                    u32 num_dumped_dwords,
7449                                    char *results_buf)
7450 {
7451         u32 num_errors, num_warnnings;
7452
7453         return qed_print_idle_chk_results(p_hwfn, dump_buf, num_dumped_dwords,
7454                                           results_buf, &num_errors,
7455                                           &num_warnnings);
7456 }
7457
7458 /* Feature meta data lookup table */
7459 static struct {
7460         char *name;
7461         enum dbg_status (*get_size)(struct qed_hwfn *p_hwfn,
7462                                     struct qed_ptt *p_ptt, u32 *size);
7463         enum dbg_status (*perform_dump)(struct qed_hwfn *p_hwfn,
7464                                         struct qed_ptt *p_ptt, u32 *dump_buf,
7465                                         u32 buf_size, u32 *dumped_dwords);
7466         enum dbg_status (*print_results)(struct qed_hwfn *p_hwfn,
7467                                          u32 *dump_buf, u32 num_dumped_dwords,
7468                                          char *results_buf);
7469         enum dbg_status (*results_buf_size)(struct qed_hwfn *p_hwfn,
7470                                             u32 *dump_buf,
7471                                             u32 num_dumped_dwords,
7472                                             u32 *results_buf_size);
7473 } qed_features_lookup[] = {
7474         {
7475         "grc", qed_dbg_grc_get_dump_buf_size,
7476                     qed_dbg_grc_dump, NULL, NULL}, {
7477         "idle_chk",
7478                     qed_dbg_idle_chk_get_dump_buf_size,
7479                     qed_dbg_idle_chk_dump,
7480                     qed_print_idle_chk_results_wrapper,
7481                     qed_get_idle_chk_results_buf_size}, {
7482         "mcp_trace",
7483                     qed_dbg_mcp_trace_get_dump_buf_size,
7484                     qed_dbg_mcp_trace_dump, qed_print_mcp_trace_results,
7485                     qed_get_mcp_trace_results_buf_size}, {
7486         "reg_fifo",
7487                     qed_dbg_reg_fifo_get_dump_buf_size,
7488                     qed_dbg_reg_fifo_dump, qed_print_reg_fifo_results,
7489                     qed_get_reg_fifo_results_buf_size}, {
7490         "igu_fifo",
7491                     qed_dbg_igu_fifo_get_dump_buf_size,
7492                     qed_dbg_igu_fifo_dump, qed_print_igu_fifo_results,
7493                     qed_get_igu_fifo_results_buf_size}, {
7494         "protection_override",
7495                     qed_dbg_protection_override_get_dump_buf_size,
7496                     qed_dbg_protection_override_dump,
7497                     qed_print_protection_override_results,
7498                     qed_get_protection_override_results_buf_size}, {
7499         "fw_asserts",
7500                     qed_dbg_fw_asserts_get_dump_buf_size,
7501                     qed_dbg_fw_asserts_dump,
7502                     qed_print_fw_asserts_results,
7503                     qed_get_fw_asserts_results_buf_size},};
7504
7505 static void qed_dbg_print_feature(u8 *p_text_buf, u32 text_size)
7506 {
7507         u32 i, precision = 80;
7508
7509         if (!p_text_buf)
7510                 return;
7511
7512         pr_notice("\n%.*s", precision, p_text_buf);
7513         for (i = precision; i < text_size; i += precision)
7514                 pr_cont("%.*s", precision, p_text_buf + i);
7515         pr_cont("\n");
7516 }
7517
7518 #define QED_RESULTS_BUF_MIN_SIZE 16
7519 /* Generic function for decoding debug feature info */
7520 static enum dbg_status format_feature(struct qed_hwfn *p_hwfn,
7521                                       enum qed_dbg_features feature_idx)
7522 {
7523         struct qed_dbg_feature *feature =
7524             &p_hwfn->cdev->dbg_params.features[feature_idx];
7525         u32 text_size_bytes, null_char_pos, i;
7526         enum dbg_status rc;
7527         char *text_buf;
7528
7529         /* Check if feature supports formatting capability */
7530         if (!qed_features_lookup[feature_idx].results_buf_size)
7531                 return DBG_STATUS_OK;
7532
7533         /* Obtain size of formatted output */
7534         rc = qed_features_lookup[feature_idx].
7535                 results_buf_size(p_hwfn, (u32 *)feature->dump_buf,
7536                                  feature->dumped_dwords, &text_size_bytes);
7537         if (rc != DBG_STATUS_OK)
7538                 return rc;
7539
7540         /* Make sure that the allocated size is a multiple of dword (4 bytes) */
7541         null_char_pos = text_size_bytes - 1;
7542         text_size_bytes = (text_size_bytes + 3) & ~0x3;
7543
7544         if (text_size_bytes < QED_RESULTS_BUF_MIN_SIZE) {
7545                 DP_NOTICE(p_hwfn->cdev,
7546                           "formatted size of feature was too small %d. Aborting\n",
7547                           text_size_bytes);
7548                 return DBG_STATUS_INVALID_ARGS;
7549         }
7550
7551         /* Allocate temp text buf */
7552         text_buf = vzalloc(text_size_bytes);
7553         if (!text_buf)
7554                 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
7555
7556         /* Decode feature opcodes to string on temp buf */
7557         rc = qed_features_lookup[feature_idx].
7558                 print_results(p_hwfn, (u32 *)feature->dump_buf,
7559                               feature->dumped_dwords, text_buf);
7560         if (rc != DBG_STATUS_OK) {
7561                 vfree(text_buf);
7562                 return rc;
7563         }
7564
7565         /* Replace the original null character with a '\n' character.
7566          * The bytes that were added as a result of the dword alignment are also
7567          * padded with '\n' characters.
7568          */
7569         for (i = null_char_pos; i < text_size_bytes; i++)
7570                 text_buf[i] = '\n';
7571
7572         /* Dump printable feature to log */
7573         if (p_hwfn->cdev->dbg_params.print_data)
7574                 qed_dbg_print_feature(text_buf, text_size_bytes);
7575
7576         /* Free the old dump_buf and point the dump_buf to the newly allocagted
7577          * and formatted text buffer.
7578          */
7579         vfree(feature->dump_buf);
7580         feature->dump_buf = text_buf;
7581         feature->buf_size = text_size_bytes;
7582         feature->dumped_dwords = text_size_bytes / 4;
7583         return rc;
7584 }
7585
7586 /* Generic function for performing the dump of a debug feature. */
7587 static enum dbg_status qed_dbg_dump(struct qed_hwfn *p_hwfn,
7588                                     struct qed_ptt *p_ptt,
7589                                     enum qed_dbg_features feature_idx)
7590 {
7591         struct qed_dbg_feature *feature =
7592             &p_hwfn->cdev->dbg_params.features[feature_idx];
7593         u32 buf_size_dwords;
7594         enum dbg_status rc;
7595
7596         DP_NOTICE(p_hwfn->cdev, "Collecting a debug feature [\"%s\"]\n",
7597                   qed_features_lookup[feature_idx].name);
7598
7599         /* Dump_buf was already allocated need to free (this can happen if dump
7600          * was called but file was never read).
7601          * We can't use the buffer as is since size may have changed.
7602          */
7603         if (feature->dump_buf) {
7604                 vfree(feature->dump_buf);
7605                 feature->dump_buf = NULL;
7606         }
7607
7608         /* Get buffer size from hsi, allocate accordingly, and perform the
7609          * dump.
7610          */
7611         rc = qed_features_lookup[feature_idx].get_size(p_hwfn, p_ptt,
7612                                                        &buf_size_dwords);
7613         if (rc != DBG_STATUS_OK && rc != DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
7614                 return rc;
7615         feature->buf_size = buf_size_dwords * sizeof(u32);
7616         feature->dump_buf = vmalloc(feature->buf_size);
7617         if (!feature->dump_buf)
7618                 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
7619
7620         rc = qed_features_lookup[feature_idx].
7621                 perform_dump(p_hwfn, p_ptt, (u32 *)feature->dump_buf,
7622                              feature->buf_size / sizeof(u32),
7623                              &feature->dumped_dwords);
7624
7625         /* If mcp is stuck we get DBG_STATUS_NVRAM_GET_IMAGE_FAILED error.
7626          * In this case the buffer holds valid binary data, but we wont able
7627          * to parse it (since parsing relies on data in NVRAM which is only
7628          * accessible when MFW is responsive). skip the formatting but return
7629          * success so that binary data is provided.
7630          */
7631         if (rc == DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
7632                 return DBG_STATUS_OK;
7633
7634         if (rc != DBG_STATUS_OK)
7635                 return rc;
7636
7637         /* Format output */
7638         rc = format_feature(p_hwfn, feature_idx);
7639         return rc;
7640 }
7641
7642 int qed_dbg_grc(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
7643 {
7644         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_GRC, num_dumped_bytes);
7645 }
7646
7647 int qed_dbg_grc_size(struct qed_dev *cdev)
7648 {
7649         return qed_dbg_feature_size(cdev, DBG_FEATURE_GRC);
7650 }
7651
7652 int qed_dbg_idle_chk(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
7653 {
7654         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IDLE_CHK,
7655                                num_dumped_bytes);
7656 }
7657
7658 int qed_dbg_idle_chk_size(struct qed_dev *cdev)
7659 {
7660         return qed_dbg_feature_size(cdev, DBG_FEATURE_IDLE_CHK);
7661 }
7662
7663 int qed_dbg_reg_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
7664 {
7665         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_REG_FIFO,
7666                                num_dumped_bytes);
7667 }
7668
7669 int qed_dbg_reg_fifo_size(struct qed_dev *cdev)
7670 {
7671         return qed_dbg_feature_size(cdev, DBG_FEATURE_REG_FIFO);
7672 }
7673
7674 int qed_dbg_igu_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
7675 {
7676         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IGU_FIFO,
7677                                num_dumped_bytes);
7678 }
7679
7680 int qed_dbg_igu_fifo_size(struct qed_dev *cdev)
7681 {
7682         return qed_dbg_feature_size(cdev, DBG_FEATURE_IGU_FIFO);
7683 }
7684
7685 int qed_dbg_protection_override(struct qed_dev *cdev, void *buffer,
7686                                 u32 *num_dumped_bytes)
7687 {
7688         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_PROTECTION_OVERRIDE,
7689                                num_dumped_bytes);
7690 }
7691
7692 int qed_dbg_protection_override_size(struct qed_dev *cdev)
7693 {
7694         return qed_dbg_feature_size(cdev, DBG_FEATURE_PROTECTION_OVERRIDE);
7695 }
7696
7697 int qed_dbg_fw_asserts(struct qed_dev *cdev, void *buffer,
7698                        u32 *num_dumped_bytes)
7699 {
7700         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_FW_ASSERTS,
7701                                num_dumped_bytes);
7702 }
7703
7704 int qed_dbg_fw_asserts_size(struct qed_dev *cdev)
7705 {
7706         return qed_dbg_feature_size(cdev, DBG_FEATURE_FW_ASSERTS);
7707 }
7708
7709 int qed_dbg_mcp_trace(struct qed_dev *cdev, void *buffer,
7710                       u32 *num_dumped_bytes)
7711 {
7712         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_MCP_TRACE,
7713                                num_dumped_bytes);
7714 }
7715
7716 int qed_dbg_mcp_trace_size(struct qed_dev *cdev)
7717 {
7718         return qed_dbg_feature_size(cdev, DBG_FEATURE_MCP_TRACE);
7719 }
7720
7721 /* Defines the amount of bytes allocated for recording the length of debugfs
7722  * feature buffer.
7723  */
7724 #define REGDUMP_HEADER_SIZE                     sizeof(u32)
7725 #define REGDUMP_HEADER_FEATURE_SHIFT            24
7726 #define REGDUMP_HEADER_ENGINE_SHIFT             31
7727 #define REGDUMP_HEADER_OMIT_ENGINE_SHIFT        30
7728 enum debug_print_features {
7729         OLD_MODE = 0,
7730         IDLE_CHK = 1,
7731         GRC_DUMP = 2,
7732         MCP_TRACE = 3,
7733         REG_FIFO = 4,
7734         PROTECTION_OVERRIDE = 5,
7735         IGU_FIFO = 6,
7736         PHY = 7,
7737         FW_ASSERTS = 8,
7738 };
7739
7740 static u32 qed_calc_regdump_header(enum debug_print_features feature,
7741                                    int engine, u32 feature_size, u8 omit_engine)
7742 {
7743         /* Insert the engine, feature and mode inside the header and combine it
7744          * with feature size.
7745          */
7746         return feature_size | (feature << REGDUMP_HEADER_FEATURE_SHIFT) |
7747                (omit_engine << REGDUMP_HEADER_OMIT_ENGINE_SHIFT) |
7748                (engine << REGDUMP_HEADER_ENGINE_SHIFT);
7749 }
7750
7751 int qed_dbg_all_data(struct qed_dev *cdev, void *buffer)
7752 {
7753         u8 cur_engine, omit_engine = 0, org_engine;
7754         u32 offset = 0, feature_size;
7755         int rc;
7756
7757         if (cdev->num_hwfns == 1)
7758                 omit_engine = 1;
7759
7760         org_engine = qed_get_debug_engine(cdev);
7761         for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
7762                 /* Collect idle_chks and grcDump for each hw function */
7763                 DP_VERBOSE(cdev, QED_MSG_DEBUG,
7764                            "obtaining idle_chk and grcdump for current engine\n");
7765                 qed_set_debug_engine(cdev, cur_engine);
7766
7767                 /* First idle_chk */
7768                 rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset +
7769                                       REGDUMP_HEADER_SIZE, &feature_size);
7770                 if (!rc) {
7771                         *(u32 *)((u8 *)buffer + offset) =
7772                             qed_calc_regdump_header(IDLE_CHK, cur_engine,
7773                                                     feature_size, omit_engine);
7774                         offset += (feature_size + REGDUMP_HEADER_SIZE);
7775                 } else {
7776                         DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
7777                 }
7778
7779                 /* Second idle_chk */
7780                 rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset +
7781                                       REGDUMP_HEADER_SIZE, &feature_size);
7782                 if (!rc) {
7783                         *(u32 *)((u8 *)buffer + offset) =
7784                             qed_calc_regdump_header(IDLE_CHK, cur_engine,
7785                                                     feature_size, omit_engine);
7786                         offset += (feature_size + REGDUMP_HEADER_SIZE);
7787                 } else {
7788                         DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
7789                 }
7790
7791                 /* reg_fifo dump */
7792                 rc = qed_dbg_reg_fifo(cdev, (u8 *)buffer + offset +
7793                                       REGDUMP_HEADER_SIZE, &feature_size);
7794                 if (!rc) {
7795                         *(u32 *)((u8 *)buffer + offset) =
7796                             qed_calc_regdump_header(REG_FIFO, cur_engine,
7797                                                     feature_size, omit_engine);
7798                         offset += (feature_size + REGDUMP_HEADER_SIZE);
7799                 } else {
7800                         DP_ERR(cdev, "qed_dbg_reg_fifo failed. rc = %d\n", rc);
7801                 }
7802
7803                 /* igu_fifo dump */
7804                 rc = qed_dbg_igu_fifo(cdev, (u8 *)buffer + offset +
7805                                       REGDUMP_HEADER_SIZE, &feature_size);
7806                 if (!rc) {
7807                         *(u32 *)((u8 *)buffer + offset) =
7808                             qed_calc_regdump_header(IGU_FIFO, cur_engine,
7809                                                     feature_size, omit_engine);
7810                         offset += (feature_size + REGDUMP_HEADER_SIZE);
7811                 } else {
7812                         DP_ERR(cdev, "qed_dbg_igu_fifo failed. rc = %d", rc);
7813                 }
7814
7815                 /* protection_override dump */
7816                 rc = qed_dbg_protection_override(cdev, (u8 *)buffer + offset +
7817                                                  REGDUMP_HEADER_SIZE,
7818                                                  &feature_size);
7819                 if (!rc) {
7820                         *(u32 *)((u8 *)buffer + offset) =
7821                             qed_calc_regdump_header(PROTECTION_OVERRIDE,
7822                                                     cur_engine,
7823                                                     feature_size, omit_engine);
7824                         offset += (feature_size + REGDUMP_HEADER_SIZE);
7825                 } else {
7826                         DP_ERR(cdev,
7827                                "qed_dbg_protection_override failed. rc = %d\n",
7828                                rc);
7829                 }
7830
7831                 /* fw_asserts dump */
7832                 rc = qed_dbg_fw_asserts(cdev, (u8 *)buffer + offset +
7833                                         REGDUMP_HEADER_SIZE, &feature_size);
7834                 if (!rc) {
7835                         *(u32 *)((u8 *)buffer + offset) =
7836                             qed_calc_regdump_header(FW_ASSERTS, cur_engine,
7837                                                     feature_size, omit_engine);
7838                         offset += (feature_size + REGDUMP_HEADER_SIZE);
7839                 } else {
7840                         DP_ERR(cdev, "qed_dbg_fw_asserts failed. rc = %d\n",
7841                                rc);
7842                 }
7843
7844                 /* GRC dump - must be last because when mcp stuck it will
7845                  * clutter idle_chk, reg_fifo, ...
7846                  */
7847                 rc = qed_dbg_grc(cdev, (u8 *)buffer + offset +
7848                                  REGDUMP_HEADER_SIZE, &feature_size);
7849                 if (!rc) {
7850                         *(u32 *)((u8 *)buffer + offset) =
7851                             qed_calc_regdump_header(GRC_DUMP, cur_engine,
7852                                                     feature_size, omit_engine);
7853                         offset += (feature_size + REGDUMP_HEADER_SIZE);
7854                 } else {
7855                         DP_ERR(cdev, "qed_dbg_grc failed. rc = %d", rc);
7856                 }
7857         }
7858
7859         /* mcp_trace */
7860         rc = qed_dbg_mcp_trace(cdev, (u8 *)buffer + offset +
7861                                REGDUMP_HEADER_SIZE, &feature_size);
7862         if (!rc) {
7863                 *(u32 *)((u8 *)buffer + offset) =
7864                     qed_calc_regdump_header(MCP_TRACE, cur_engine,
7865                                             feature_size, omit_engine);
7866                 offset += (feature_size + REGDUMP_HEADER_SIZE);
7867         } else {
7868                 DP_ERR(cdev, "qed_dbg_mcp_trace failed. rc = %d\n", rc);
7869         }
7870
7871         qed_set_debug_engine(cdev, org_engine);
7872
7873         return 0;
7874 }
7875
7876 int qed_dbg_all_data_size(struct qed_dev *cdev)
7877 {
7878         u8 cur_engine, org_engine;
7879         u32 regs_len = 0;
7880
7881         org_engine = qed_get_debug_engine(cdev);
7882         for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
7883                 /* Engine specific */
7884                 DP_VERBOSE(cdev, QED_MSG_DEBUG,
7885                            "calculating idle_chk and grcdump register length for current engine\n");
7886                 qed_set_debug_engine(cdev, cur_engine);
7887                 regs_len += REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
7888                             REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
7889                             REGDUMP_HEADER_SIZE + qed_dbg_grc_size(cdev) +
7890                             REGDUMP_HEADER_SIZE + qed_dbg_reg_fifo_size(cdev) +
7891                             REGDUMP_HEADER_SIZE + qed_dbg_igu_fifo_size(cdev) +
7892                             REGDUMP_HEADER_SIZE +
7893                             qed_dbg_protection_override_size(cdev) +
7894                             REGDUMP_HEADER_SIZE + qed_dbg_fw_asserts_size(cdev);
7895         }
7896
7897         /* Engine common */
7898         regs_len += REGDUMP_HEADER_SIZE + qed_dbg_mcp_trace_size(cdev);
7899         qed_set_debug_engine(cdev, org_engine);
7900
7901         return regs_len;
7902 }
7903
7904 int qed_dbg_feature(struct qed_dev *cdev, void *buffer,
7905                     enum qed_dbg_features feature, u32 *num_dumped_bytes)
7906 {
7907         struct qed_hwfn *p_hwfn =
7908                 &cdev->hwfns[cdev->dbg_params.engine_for_debug];
7909         struct qed_dbg_feature *qed_feature =
7910                 &cdev->dbg_params.features[feature];
7911         enum dbg_status dbg_rc;
7912         struct qed_ptt *p_ptt;
7913         int rc = 0;
7914
7915         /* Acquire ptt */
7916         p_ptt = qed_ptt_acquire(p_hwfn);
7917         if (!p_ptt)
7918                 return -EINVAL;
7919
7920         /* Get dump */
7921         dbg_rc = qed_dbg_dump(p_hwfn, p_ptt, feature);
7922         if (dbg_rc != DBG_STATUS_OK) {
7923                 DP_VERBOSE(cdev, QED_MSG_DEBUG, "%s\n",
7924                            qed_dbg_get_status_str(dbg_rc));
7925                 *num_dumped_bytes = 0;
7926                 rc = -EINVAL;
7927                 goto out;
7928         }
7929
7930         DP_VERBOSE(cdev, QED_MSG_DEBUG,
7931                    "copying debugfs feature to external buffer\n");
7932         memcpy(buffer, qed_feature->dump_buf, qed_feature->buf_size);
7933         *num_dumped_bytes = cdev->dbg_params.features[feature].dumped_dwords *
7934                             4;
7935
7936 out:
7937         qed_ptt_release(p_hwfn, p_ptt);
7938         return rc;
7939 }
7940
7941 int qed_dbg_feature_size(struct qed_dev *cdev, enum qed_dbg_features feature)
7942 {
7943         struct qed_hwfn *p_hwfn =
7944                 &cdev->hwfns[cdev->dbg_params.engine_for_debug];
7945         struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
7946         struct qed_dbg_feature *qed_feature =
7947                 &cdev->dbg_params.features[feature];
7948         u32 buf_size_dwords;
7949         enum dbg_status rc;
7950
7951         if (!p_ptt)
7952                 return -EINVAL;
7953
7954         rc = qed_features_lookup[feature].get_size(p_hwfn, p_ptt,
7955                                                    &buf_size_dwords);
7956         if (rc != DBG_STATUS_OK)
7957                 buf_size_dwords = 0;
7958
7959         qed_ptt_release(p_hwfn, p_ptt);
7960         qed_feature->buf_size = buf_size_dwords * sizeof(u32);
7961         return qed_feature->buf_size;
7962 }
7963
7964 u8 qed_get_debug_engine(struct qed_dev *cdev)
7965 {
7966         return cdev->dbg_params.engine_for_debug;
7967 }
7968
7969 void qed_set_debug_engine(struct qed_dev *cdev, int engine_number)
7970 {
7971         DP_VERBOSE(cdev, QED_MSG_DEBUG, "set debug engine to %d\n",
7972                    engine_number);
7973         cdev->dbg_params.engine_for_debug = engine_number;
7974 }
7975
7976 void qed_dbg_pf_init(struct qed_dev *cdev)
7977 {
7978         const u8 *dbg_values;
7979
7980         /* Debug values are after init values.
7981          * The offset is the first dword of the file.
7982          */
7983         dbg_values = cdev->firmware->data + *(u32 *)cdev->firmware->data;
7984         qed_dbg_set_bin_ptr((u8 *)dbg_values);
7985         qed_dbg_user_set_bin_ptr((u8 *)dbg_values);
7986 }
7987
7988 void qed_dbg_pf_exit(struct qed_dev *cdev)
7989 {
7990         struct qed_dbg_feature *feature = NULL;
7991         enum qed_dbg_features feature_idx;
7992
7993         /* Debug features' buffers may be allocated if debug feature was used
7994          * but dump wasn't called.
7995          */
7996         for (feature_idx = 0; feature_idx < DBG_FEATURE_NUM; feature_idx++) {
7997                 feature = &cdev->dbg_params.features[feature_idx];
7998                 if (feature->dump_buf) {
7999                         vfree(feature->dump_buf);
8000                         feature->dump_buf = NULL;
8001                 }
8002         }
8003 }