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