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