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