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