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