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