1ab81e23cSAlexander Lobakin // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2c965db44STomer Tayar /* QLogic qed NIC Driver
3c965db44STomer Tayar  * Copyright (c) 2015 QLogic Corporation
4c965db44STomer Tayar  */
5c965db44STomer Tayar 
6c965db44STomer Tayar #include <linux/module.h>
7c965db44STomer Tayar #include <linux/vmalloc.h>
8c965db44STomer Tayar #include <linux/crc32.h>
9c965db44STomer Tayar #include "qed.h"
108a52bbabSMichal Kalderon #include "qed_cxt.h"
11c965db44STomer Tayar #include "qed_hsi.h"
12c965db44STomer Tayar #include "qed_hw.h"
13c965db44STomer Tayar #include "qed_mcp.h"
14c965db44STomer Tayar #include "qed_reg_addr.h"
15c965db44STomer Tayar 
16c965db44STomer Tayar /* Memory groups enum */
17c965db44STomer Tayar enum mem_groups {
18c965db44STomer Tayar 	MEM_GROUP_PXP_MEM,
19c965db44STomer Tayar 	MEM_GROUP_DMAE_MEM,
20c965db44STomer Tayar 	MEM_GROUP_CM_MEM,
21c965db44STomer Tayar 	MEM_GROUP_QM_MEM,
22da090917STomer Tayar 	MEM_GROUP_DORQ_MEM,
23c965db44STomer Tayar 	MEM_GROUP_BRB_RAM,
24c965db44STomer Tayar 	MEM_GROUP_BRB_MEM,
25c965db44STomer Tayar 	MEM_GROUP_PRS_MEM,
26da090917STomer Tayar 	MEM_GROUP_SDM_MEM,
277b6859fbSMintz, Yuval 	MEM_GROUP_PBUF,
282d22bc83SMichal Kalderon 	MEM_GROUP_IOR,
29da090917STomer Tayar 	MEM_GROUP_RAM,
302d22bc83SMichal Kalderon 	MEM_GROUP_BTB_RAM,
31da090917STomer Tayar 	MEM_GROUP_RDIF_CTX,
32da090917STomer Tayar 	MEM_GROUP_TDIF_CTX,
33da090917STomer Tayar 	MEM_GROUP_CFC_MEM,
342d22bc83SMichal Kalderon 	MEM_GROUP_CONN_CFC_MEM,
352d22bc83SMichal Kalderon 	MEM_GROUP_CAU_PI,
362d22bc83SMichal Kalderon 	MEM_GROUP_CAU_MEM,
372d22bc83SMichal Kalderon 	MEM_GROUP_CAU_MEM_EXT,
382d22bc83SMichal Kalderon 	MEM_GROUP_PXP_ILT,
392d22bc83SMichal Kalderon 	MEM_GROUP_MULD_MEM,
402d22bc83SMichal Kalderon 	MEM_GROUP_BTB_MEM,
41c965db44STomer Tayar 	MEM_GROUP_IGU_MEM,
42c965db44STomer Tayar 	MEM_GROUP_IGU_MSIX,
43c965db44STomer Tayar 	MEM_GROUP_CAU_SB,
44c965db44STomer Tayar 	MEM_GROUP_BMB_RAM,
45c965db44STomer Tayar 	MEM_GROUP_BMB_MEM,
462d22bc83SMichal Kalderon 	MEM_GROUP_TM_MEM,
472d22bc83SMichal Kalderon 	MEM_GROUP_TASK_CFC_MEM,
48c965db44STomer Tayar 	MEM_GROUPS_NUM
49c965db44STomer Tayar };
50c965db44STomer Tayar 
51c965db44STomer Tayar /* Memory groups names */
52c965db44STomer Tayar static const char * const s_mem_group_names[] = {
53c965db44STomer Tayar 	"PXP_MEM",
54c965db44STomer Tayar 	"DMAE_MEM",
55c965db44STomer Tayar 	"CM_MEM",
56c965db44STomer Tayar 	"QM_MEM",
57da090917STomer Tayar 	"DORQ_MEM",
58c965db44STomer Tayar 	"BRB_RAM",
59c965db44STomer Tayar 	"BRB_MEM",
60c965db44STomer Tayar 	"PRS_MEM",
61da090917STomer Tayar 	"SDM_MEM",
627b6859fbSMintz, Yuval 	"PBUF",
632d22bc83SMichal Kalderon 	"IOR",
64da090917STomer Tayar 	"RAM",
652d22bc83SMichal Kalderon 	"BTB_RAM",
66da090917STomer Tayar 	"RDIF_CTX",
67da090917STomer Tayar 	"TDIF_CTX",
68da090917STomer Tayar 	"CFC_MEM",
692d22bc83SMichal Kalderon 	"CONN_CFC_MEM",
702d22bc83SMichal Kalderon 	"CAU_PI",
712d22bc83SMichal Kalderon 	"CAU_MEM",
722d22bc83SMichal Kalderon 	"CAU_MEM_EXT",
732d22bc83SMichal Kalderon 	"PXP_ILT",
742d22bc83SMichal Kalderon 	"MULD_MEM",
752d22bc83SMichal Kalderon 	"BTB_MEM",
76c965db44STomer Tayar 	"IGU_MEM",
77c965db44STomer Tayar 	"IGU_MSIX",
78c965db44STomer Tayar 	"CAU_SB",
79c965db44STomer Tayar 	"BMB_RAM",
80c965db44STomer Tayar 	"BMB_MEM",
812d22bc83SMichal Kalderon 	"TM_MEM",
822d22bc83SMichal Kalderon 	"TASK_CFC_MEM",
83c965db44STomer Tayar };
84c965db44STomer Tayar 
85c965db44STomer Tayar /* Idle check conditions */
867b6859fbSMintz, Yuval 
877b6859fbSMintz, Yuval static u32 cond5(const u32 *r, const u32 *imm)
88c965db44STomer Tayar {
89c965db44STomer Tayar 	return ((r[0] & imm[0]) != imm[1]) && ((r[1] & imm[2]) != imm[3]);
90c965db44STomer Tayar }
91c965db44STomer Tayar 
927b6859fbSMintz, Yuval static u32 cond7(const u32 *r, const u32 *imm)
93c965db44STomer Tayar {
94c965db44STomer Tayar 	return ((r[0] >> imm[0]) & imm[1]) != imm[2];
95c965db44STomer Tayar }
96c965db44STomer Tayar 
977b6859fbSMintz, Yuval static u32 cond6(const u32 *r, const u32 *imm)
98c965db44STomer Tayar {
99c965db44STomer Tayar 	return (r[0] & imm[0]) != imm[1];
100c965db44STomer Tayar }
101c965db44STomer Tayar 
1027b6859fbSMintz, Yuval static u32 cond9(const u32 *r, const u32 *imm)
103c965db44STomer Tayar {
104c965db44STomer Tayar 	return ((r[0] & imm[0]) >> imm[1]) !=
105c965db44STomer Tayar 	    (((r[0] & imm[2]) >> imm[3]) | ((r[1] & imm[4]) << imm[5]));
106c965db44STomer Tayar }
107c965db44STomer Tayar 
1087b6859fbSMintz, Yuval static u32 cond10(const u32 *r, const u32 *imm)
109c965db44STomer Tayar {
110c965db44STomer Tayar 	return ((r[0] & imm[0]) >> imm[1]) != (r[0] & imm[2]);
111c965db44STomer Tayar }
112c965db44STomer Tayar 
1137b6859fbSMintz, Yuval static u32 cond4(const u32 *r, const u32 *imm)
114c965db44STomer Tayar {
115c965db44STomer Tayar 	return (r[0] & ~imm[0]) != imm[1];
116c965db44STomer Tayar }
117c965db44STomer Tayar 
118c965db44STomer Tayar static u32 cond0(const u32 *r, const u32 *imm)
119c965db44STomer Tayar {
1207b6859fbSMintz, Yuval 	return (r[0] & ~r[1]) != imm[0];
1217b6859fbSMintz, Yuval }
1227b6859fbSMintz, Yuval 
1237b6859fbSMintz, Yuval static u32 cond1(const u32 *r, const u32 *imm)
1247b6859fbSMintz, Yuval {
125c965db44STomer Tayar 	return r[0] != imm[0];
126c965db44STomer Tayar }
127c965db44STomer Tayar 
1287b6859fbSMintz, Yuval static u32 cond11(const u32 *r, const u32 *imm)
129c965db44STomer Tayar {
130c965db44STomer Tayar 	return r[0] != r[1] && r[2] == imm[0];
131c965db44STomer Tayar }
132c965db44STomer Tayar 
1337b6859fbSMintz, Yuval static u32 cond12(const u32 *r, const u32 *imm)
134c965db44STomer Tayar {
135c965db44STomer Tayar 	return r[0] != r[1] && r[2] > imm[0];
136c965db44STomer Tayar }
137c965db44STomer Tayar 
138c965db44STomer Tayar static u32 cond3(const u32 *r, const u32 *imm)
139c965db44STomer Tayar {
140c965db44STomer Tayar 	return r[0] != r[1];
141c965db44STomer Tayar }
142c965db44STomer Tayar 
1437b6859fbSMintz, Yuval static u32 cond13(const u32 *r, const u32 *imm)
144c965db44STomer Tayar {
145c965db44STomer Tayar 	return r[0] & imm[0];
146c965db44STomer Tayar }
147c965db44STomer Tayar 
1487b6859fbSMintz, Yuval static u32 cond8(const u32 *r, const u32 *imm)
149c965db44STomer Tayar {
150c965db44STomer Tayar 	return r[0] < (r[1] - imm[0]);
151c965db44STomer Tayar }
152c965db44STomer Tayar 
153c965db44STomer Tayar static u32 cond2(const u32 *r, const u32 *imm)
154c965db44STomer Tayar {
155c965db44STomer Tayar 	return r[0] > imm[0];
156c965db44STomer Tayar }
157c965db44STomer Tayar 
158c965db44STomer Tayar /* Array of Idle Check conditions */
159c965db44STomer Tayar static u32(*cond_arr[]) (const u32 *r, const u32 *imm) = {
160c965db44STomer Tayar 	cond0,
161c965db44STomer Tayar 	cond1,
162c965db44STomer Tayar 	cond2,
163c965db44STomer Tayar 	cond3,
164c965db44STomer Tayar 	cond4,
165c965db44STomer Tayar 	cond5,
166c965db44STomer Tayar 	cond6,
167c965db44STomer Tayar 	cond7,
168c965db44STomer Tayar 	cond8,
169c965db44STomer Tayar 	cond9,
170c965db44STomer Tayar 	cond10,
171c965db44STomer Tayar 	cond11,
172c965db44STomer Tayar 	cond12,
1737b6859fbSMintz, Yuval 	cond13,
174c965db44STomer Tayar };
175c965db44STomer Tayar 
1762d22bc83SMichal Kalderon #define NUM_PHYS_BLOCKS 84
1772d22bc83SMichal Kalderon 
1782d22bc83SMichal Kalderon #define NUM_DBG_RESET_REGS 8
1792d22bc83SMichal Kalderon 
180c965db44STomer Tayar /******************************* Data Types **********************************/
181c965db44STomer Tayar 
1822d22bc83SMichal Kalderon enum hw_types {
1832d22bc83SMichal Kalderon 	HW_TYPE_ASIC,
184c965db44STomer Tayar 	PLATFORM_RESERVED,
185c965db44STomer Tayar 	PLATFORM_RESERVED2,
186c965db44STomer Tayar 	PLATFORM_RESERVED3,
1872d22bc83SMichal Kalderon 	PLATFORM_RESERVED4,
1882d22bc83SMichal Kalderon 	MAX_HW_TYPES
1892d22bc83SMichal Kalderon };
1902d22bc83SMichal Kalderon 
1912d22bc83SMichal Kalderon /* CM context types */
1922d22bc83SMichal Kalderon enum cm_ctx_types {
1932d22bc83SMichal Kalderon 	CM_CTX_CONN_AG,
1942d22bc83SMichal Kalderon 	CM_CTX_CONN_ST,
1952d22bc83SMichal Kalderon 	CM_CTX_TASK_AG,
1962d22bc83SMichal Kalderon 	CM_CTX_TASK_ST,
1972d22bc83SMichal Kalderon 	NUM_CM_CTX_TYPES
1982d22bc83SMichal Kalderon };
1992d22bc83SMichal Kalderon 
2002d22bc83SMichal Kalderon /* Debug bus frame modes */
2012d22bc83SMichal Kalderon enum dbg_bus_frame_modes {
2022d22bc83SMichal Kalderon 	DBG_BUS_FRAME_MODE_4ST = 0,	/* 4 Storm dwords (no HW) */
2032d22bc83SMichal Kalderon 	DBG_BUS_FRAME_MODE_2ST_2HW = 1,	/* 2 Storm dwords, 2 HW dwords */
2042d22bc83SMichal Kalderon 	DBG_BUS_FRAME_MODE_1ST_3HW = 2,	/* 1 Storm dwords, 3 HW dwords */
2052d22bc83SMichal Kalderon 	DBG_BUS_FRAME_MODE_4HW = 3,	/* 4 HW dwords (no Storms) */
2062d22bc83SMichal Kalderon 	DBG_BUS_FRAME_MODE_8HW = 4,	/* 8 HW dwords (no Storms) */
2072d22bc83SMichal Kalderon 	DBG_BUS_NUM_FRAME_MODES
208c965db44STomer Tayar };
209c965db44STomer Tayar 
210c965db44STomer Tayar /* Chip constant definitions */
211c965db44STomer Tayar struct chip_defs {
212c965db44STomer Tayar 	const char *name;
2138a52bbabSMichal Kalderon 	u32 num_ilt_pages;
214c965db44STomer Tayar };
215c965db44STomer Tayar 
2162d22bc83SMichal Kalderon /* HW type constant definitions */
2172d22bc83SMichal Kalderon struct hw_type_defs {
218c965db44STomer Tayar 	const char *name;
219c965db44STomer Tayar 	u32 delay_factor;
220da090917STomer Tayar 	u32 dmae_thresh;
221da090917STomer Tayar 	u32 log_thresh;
222c965db44STomer Tayar };
223c965db44STomer Tayar 
2242d22bc83SMichal Kalderon /* RBC reset definitions */
2252d22bc83SMichal Kalderon struct rbc_reset_defs {
2262d22bc83SMichal Kalderon 	u32 reset_reg_addr;
2272d22bc83SMichal Kalderon 	u32 reset_val[MAX_CHIP_IDS];
2282d22bc83SMichal Kalderon };
2292d22bc83SMichal Kalderon 
2307b6859fbSMintz, Yuval /* Storm constant definitions.
2317b6859fbSMintz, Yuval  * Addresses are in bytes, sizes are in quad-regs.
2327b6859fbSMintz, Yuval  */
233c965db44STomer Tayar struct storm_defs {
234c965db44STomer Tayar 	char letter;
2352d22bc83SMichal Kalderon 	enum block_id sem_block_id;
236c965db44STomer Tayar 	enum dbg_bus_clients dbg_client_id[MAX_CHIP_IDS];
237c965db44STomer Tayar 	bool has_vfc;
238c965db44STomer Tayar 	u32 sem_fast_mem_addr;
239c965db44STomer Tayar 	u32 sem_frame_mode_addr;
240c965db44STomer Tayar 	u32 sem_slow_enable_addr;
241c965db44STomer Tayar 	u32 sem_slow_mode_addr;
242c965db44STomer Tayar 	u32 sem_slow_mode1_conf_addr;
243c965db44STomer Tayar 	u32 sem_sync_dbg_empty_addr;
2442d22bc83SMichal Kalderon 	u32 sem_gpre_vect_addr;
245c965db44STomer Tayar 	u32 cm_ctx_wr_addr;
2462d22bc83SMichal Kalderon 	u32 cm_ctx_rd_addr[NUM_CM_CTX_TYPES];
2472d22bc83SMichal Kalderon 	u32 cm_ctx_lid_sizes[MAX_CHIP_IDS][NUM_CM_CTX_TYPES];
248c965db44STomer Tayar };
249c965db44STomer Tayar 
2502d22bc83SMichal Kalderon /* Debug Bus Constraint operation constant definitions */
2512d22bc83SMichal Kalderon struct dbg_bus_constraint_op_defs {
2522d22bc83SMichal Kalderon 	u8 hw_op_val;
2532d22bc83SMichal Kalderon 	bool is_cyclic;
2542d22bc83SMichal Kalderon };
2552d22bc83SMichal Kalderon 
2562d22bc83SMichal Kalderon /* Storm Mode definitions */
2572d22bc83SMichal Kalderon struct storm_mode_defs {
258c965db44STomer Tayar 	const char *name;
2592d22bc83SMichal Kalderon 	bool is_fast_dbg;
2602d22bc83SMichal Kalderon 	u8 id_in_hw;
2612d22bc83SMichal Kalderon 	u32 src_disable_reg_addr;
2622d22bc83SMichal Kalderon 	u32 src_enable_val;
263da090917STomer Tayar 	bool exists[MAX_CHIP_IDS];
264c965db44STomer Tayar };
265c965db44STomer Tayar 
266c965db44STomer Tayar struct grc_param_defs {
267c965db44STomer Tayar 	u32 default_val[MAX_CHIP_IDS];
268c965db44STomer Tayar 	u32 min;
269c965db44STomer Tayar 	u32 max;
270c965db44STomer Tayar 	bool is_preset;
27150bc60cbSMichal Kalderon 	bool is_persistent;
272c965db44STomer Tayar 	u32 exclude_all_preset_val;
2732d22bc83SMichal Kalderon 	u32 crash_preset_val[MAX_CHIP_IDS];
274c965db44STomer Tayar };
275c965db44STomer Tayar 
2767b6859fbSMintz, Yuval /* Address is in 128b units. Width is in bits. */
277c965db44STomer Tayar struct rss_mem_defs {
278c965db44STomer Tayar 	const char *mem_name;
279c965db44STomer Tayar 	const char *type_name;
2807b6859fbSMintz, Yuval 	u32 addr;
281da090917STomer Tayar 	u32 entry_width;
282c965db44STomer Tayar 	u32 num_entries[MAX_CHIP_IDS];
283c965db44STomer Tayar };
284c965db44STomer Tayar 
285c965db44STomer Tayar struct vfc_ram_defs {
286c965db44STomer Tayar 	const char *mem_name;
287c965db44STomer Tayar 	const char *type_name;
288c965db44STomer Tayar 	u32 base_row;
289c965db44STomer Tayar 	u32 num_rows;
290c965db44STomer Tayar };
291c965db44STomer Tayar 
292c965db44STomer Tayar struct big_ram_defs {
293c965db44STomer Tayar 	const char *instance_name;
294c965db44STomer Tayar 	enum mem_groups mem_group_id;
295c965db44STomer Tayar 	enum mem_groups ram_mem_group_id;
296c965db44STomer Tayar 	enum dbg_grc_params grc_param;
297c965db44STomer Tayar 	u32 addr_reg_addr;
298c965db44STomer Tayar 	u32 data_reg_addr;
299da090917STomer Tayar 	u32 is_256b_reg_addr;
300da090917STomer Tayar 	u32 is_256b_bit_offset[MAX_CHIP_IDS];
301da090917STomer Tayar 	u32 ram_size[MAX_CHIP_IDS]; /* In dwords */
302c965db44STomer Tayar };
303c965db44STomer Tayar 
304c965db44STomer Tayar struct phy_defs {
305c965db44STomer Tayar 	const char *phy_name;
3067b6859fbSMintz, Yuval 
3077b6859fbSMintz, Yuval 	/* PHY base GRC address */
308c965db44STomer Tayar 	u32 base_addr;
3097b6859fbSMintz, Yuval 
3107b6859fbSMintz, Yuval 	/* Relative address of indirect TBUS address register (bits 0..7) */
311c965db44STomer Tayar 	u32 tbus_addr_lo_addr;
3127b6859fbSMintz, Yuval 
3137b6859fbSMintz, Yuval 	/* Relative address of indirect TBUS address register (bits 8..10) */
314c965db44STomer Tayar 	u32 tbus_addr_hi_addr;
3157b6859fbSMintz, Yuval 
3167b6859fbSMintz, Yuval 	/* Relative address of indirect TBUS data register (bits 0..7) */
317c965db44STomer Tayar 	u32 tbus_data_lo_addr;
3187b6859fbSMintz, Yuval 
3197b6859fbSMintz, Yuval 	/* Relative address of indirect TBUS data register (bits 8..11) */
320c965db44STomer Tayar 	u32 tbus_data_hi_addr;
321c965db44STomer Tayar };
322c965db44STomer Tayar 
323d52c89f1SMichal Kalderon /* Split type definitions */
324d52c89f1SMichal Kalderon struct split_type_defs {
325d52c89f1SMichal Kalderon 	const char *name;
326d52c89f1SMichal Kalderon };
327d52c89f1SMichal Kalderon 
328c965db44STomer Tayar /******************************** Constants **********************************/
329c965db44STomer Tayar 
330c965db44STomer Tayar #define BYTES_IN_DWORD			sizeof(u32)
331c965db44STomer Tayar /* In the macros below, size and offset are specified in bits */
332c965db44STomer Tayar #define CEIL_DWORDS(size)		DIV_ROUND_UP(size, 32)
333c965db44STomer Tayar #define FIELD_BIT_OFFSET(type, field)	type ## _ ## field ## _ ## OFFSET
334c965db44STomer Tayar #define FIELD_BIT_SIZE(type, field)	type ## _ ## field ## _ ## SIZE
335c965db44STomer Tayar #define FIELD_DWORD_OFFSET(type, field) \
336c965db44STomer Tayar 	 (int)(FIELD_BIT_OFFSET(type, field) / 32)
337c965db44STomer Tayar #define FIELD_DWORD_SHIFT(type, field)	(FIELD_BIT_OFFSET(type, field) % 32)
338c965db44STomer Tayar #define FIELD_BIT_MASK(type, field) \
339c965db44STomer Tayar 	(((1 << FIELD_BIT_SIZE(type, field)) - 1) << \
340c965db44STomer Tayar 	 FIELD_DWORD_SHIFT(type, field))
3417b6859fbSMintz, Yuval 
342c965db44STomer Tayar #define SET_VAR_FIELD(var, type, field, val) \
343c965db44STomer Tayar 	do { \
344c965db44STomer Tayar 		var[FIELD_DWORD_OFFSET(type, field)] &=	\
345c965db44STomer Tayar 		(~FIELD_BIT_MASK(type, field));	\
346c965db44STomer Tayar 		var[FIELD_DWORD_OFFSET(type, field)] |= \
347c965db44STomer Tayar 		(val) << FIELD_DWORD_SHIFT(type, field); \
348c965db44STomer Tayar 	} while (0)
3497b6859fbSMintz, Yuval 
350c965db44STomer Tayar #define ARR_REG_WR(dev, ptt, addr, arr, arr_size) \
351c965db44STomer Tayar 	do { \
352c965db44STomer Tayar 		for (i = 0; i < (arr_size); i++) \
353c965db44STomer Tayar 			qed_wr(dev, ptt, addr,	(arr)[i]); \
354c965db44STomer Tayar 	} while (0)
3557b6859fbSMintz, Yuval 
356c965db44STomer Tayar #define DWORDS_TO_BYTES(dwords)		((dwords) * BYTES_IN_DWORD)
357c965db44STomer Tayar #define BYTES_TO_DWORDS(bytes)		((bytes) / BYTES_IN_DWORD)
3587b6859fbSMintz, Yuval 
3592d22bc83SMichal Kalderon /* extra lines include a signature line + optional latency events line */
3602d22bc83SMichal Kalderon #define NUM_EXTRA_DBG_LINES(block) \
3612d22bc83SMichal Kalderon 	(GET_FIELD((block)->flags, DBG_BLOCK_CHIP_HAS_LATENCY_EVENTS) ? 2 : 1)
3622d22bc83SMichal Kalderon #define NUM_DBG_LINES(block) \
3632d22bc83SMichal Kalderon 	((block)->num_of_dbg_bus_lines + NUM_EXTRA_DBG_LINES(block))
3642d22bc83SMichal Kalderon 
3652d22bc83SMichal Kalderon #define USE_DMAE			true
3662d22bc83SMichal Kalderon #define PROTECT_WIDE_BUS		true
3677b6859fbSMintz, Yuval 
368c965db44STomer Tayar #define RAM_LINES_TO_DWORDS(lines)	((lines) * 2)
369c965db44STomer Tayar #define RAM_LINES_TO_BYTES(lines) \
370c965db44STomer Tayar 	DWORDS_TO_BYTES(RAM_LINES_TO_DWORDS(lines))
3717b6859fbSMintz, Yuval 
372c965db44STomer Tayar #define REG_DUMP_LEN_SHIFT		24
373c965db44STomer Tayar #define MEM_DUMP_ENTRY_SIZE_DWORDS \
374c965db44STomer Tayar 	BYTES_TO_DWORDS(sizeof(struct dbg_dump_mem))
3757b6859fbSMintz, Yuval 
376c965db44STomer Tayar #define IDLE_CHK_RULE_SIZE_DWORDS \
377c965db44STomer Tayar 	BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_rule))
3787b6859fbSMintz, Yuval 
379c965db44STomer Tayar #define IDLE_CHK_RESULT_HDR_DWORDS \
380c965db44STomer Tayar 	BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_hdr))
3817b6859fbSMintz, Yuval 
382c965db44STomer Tayar #define IDLE_CHK_RESULT_REG_HDR_DWORDS \
383c965db44STomer Tayar 	BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_reg_hdr))
3847b6859fbSMintz, Yuval 
3858a52bbabSMichal Kalderon #define PAGE_MEM_DESC_SIZE_DWORDS \
3868a52bbabSMichal Kalderon 	BYTES_TO_DWORDS(sizeof(struct phys_mem_desc))
3878a52bbabSMichal Kalderon 
388c965db44STomer Tayar #define IDLE_CHK_MAX_ENTRIES_SIZE	32
389c965db44STomer Tayar 
390c965db44STomer Tayar /* The sizes and offsets below are specified in bits */
391c965db44STomer Tayar #define VFC_CAM_CMD_STRUCT_SIZE		64
392c965db44STomer Tayar #define VFC_CAM_CMD_ROW_OFFSET		48
393c965db44STomer Tayar #define VFC_CAM_CMD_ROW_SIZE		9
394c965db44STomer Tayar #define VFC_CAM_ADDR_STRUCT_SIZE	16
395c965db44STomer Tayar #define VFC_CAM_ADDR_OP_OFFSET		0
396c965db44STomer Tayar #define VFC_CAM_ADDR_OP_SIZE		4
397c965db44STomer Tayar #define VFC_CAM_RESP_STRUCT_SIZE	256
398c965db44STomer Tayar #define VFC_RAM_ADDR_STRUCT_SIZE	16
399c965db44STomer Tayar #define VFC_RAM_ADDR_OP_OFFSET		0
400c965db44STomer Tayar #define VFC_RAM_ADDR_OP_SIZE		2
401c965db44STomer Tayar #define VFC_RAM_ADDR_ROW_OFFSET		2
402c965db44STomer Tayar #define VFC_RAM_ADDR_ROW_SIZE		10
403c965db44STomer Tayar #define VFC_RAM_RESP_STRUCT_SIZE	256
4047b6859fbSMintz, Yuval 
405c965db44STomer Tayar #define VFC_CAM_CMD_DWORDS		CEIL_DWORDS(VFC_CAM_CMD_STRUCT_SIZE)
406c965db44STomer Tayar #define VFC_CAM_ADDR_DWORDS		CEIL_DWORDS(VFC_CAM_ADDR_STRUCT_SIZE)
407c965db44STomer Tayar #define VFC_CAM_RESP_DWORDS		CEIL_DWORDS(VFC_CAM_RESP_STRUCT_SIZE)
408c965db44STomer Tayar #define VFC_RAM_CMD_DWORDS		VFC_CAM_CMD_DWORDS
409c965db44STomer Tayar #define VFC_RAM_ADDR_DWORDS		CEIL_DWORDS(VFC_RAM_ADDR_STRUCT_SIZE)
410c965db44STomer Tayar #define VFC_RAM_RESP_DWORDS		CEIL_DWORDS(VFC_RAM_RESP_STRUCT_SIZE)
4117b6859fbSMintz, Yuval 
412c965db44STomer Tayar #define NUM_VFC_RAM_TYPES		4
4137b6859fbSMintz, Yuval 
414c965db44STomer Tayar #define VFC_CAM_NUM_ROWS		512
4157b6859fbSMintz, Yuval 
416c965db44STomer Tayar #define VFC_OPCODE_CAM_RD		14
417c965db44STomer Tayar #define VFC_OPCODE_RAM_RD		0
4187b6859fbSMintz, Yuval 
419c965db44STomer Tayar #define NUM_RSS_MEM_TYPES		5
4207b6859fbSMintz, Yuval 
421c965db44STomer Tayar #define NUM_BIG_RAM_TYPES		3
422c7d852e3SDenis Bolotin #define BIG_RAM_NAME_LEN		3
4237b6859fbSMintz, Yuval 
424c965db44STomer Tayar #define NUM_PHY_TBUS_ADDRESSES		2048
425c965db44STomer Tayar #define PHY_DUMP_SIZE_DWORDS		(NUM_PHY_TBUS_ADDRESSES / 2)
4267b6859fbSMintz, Yuval 
427c965db44STomer Tayar #define RESET_REG_UNRESET_OFFSET	4
4287b6859fbSMintz, Yuval 
429c965db44STomer Tayar #define STALL_DELAY_MS			500
4307b6859fbSMintz, Yuval 
431c965db44STomer Tayar #define STATIC_DEBUG_LINE_DWORDS	9
4327b6859fbSMintz, Yuval 
4332d22bc83SMichal Kalderon #define NUM_COMMON_GLOBAL_PARAMS	9
4342d22bc83SMichal Kalderon 
4352d22bc83SMichal Kalderon #define MAX_RECURSION_DEPTH		10
4367b6859fbSMintz, Yuval 
437c965db44STomer Tayar #define FW_IMG_MAIN			1
4387b6859fbSMintz, Yuval 
439c965db44STomer Tayar #define REG_FIFO_ELEMENT_DWORDS		2
4407b6859fbSMintz, Yuval #define REG_FIFO_DEPTH_ELEMENTS		32
441c965db44STomer Tayar #define REG_FIFO_DEPTH_DWORDS \
442c965db44STomer Tayar 	(REG_FIFO_ELEMENT_DWORDS * REG_FIFO_DEPTH_ELEMENTS)
4437b6859fbSMintz, Yuval 
444c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORDS		4
4457b6859fbSMintz, Yuval #define IGU_FIFO_DEPTH_ELEMENTS		64
446c965db44STomer Tayar #define IGU_FIFO_DEPTH_DWORDS \
447c965db44STomer Tayar 	(IGU_FIFO_ELEMENT_DWORDS * IGU_FIFO_DEPTH_ELEMENTS)
4487b6859fbSMintz, Yuval 
449c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_DWORDS	2
4507b6859fbSMintz, Yuval #define PROTECTION_OVERRIDE_DEPTH_ELEMENTS	20
451c965db44STomer Tayar #define PROTECTION_OVERRIDE_DEPTH_DWORDS \
452c965db44STomer Tayar 	(PROTECTION_OVERRIDE_DEPTH_ELEMENTS * \
453c965db44STomer Tayar 	 PROTECTION_OVERRIDE_ELEMENT_DWORDS)
4547b6859fbSMintz, Yuval 
455c965db44STomer Tayar #define MCP_SPAD_TRACE_OFFSIZE_ADDR \
456c965db44STomer Tayar 	(MCP_REG_SCRATCH + \
457c965db44STomer Tayar 	 offsetof(struct static_init, sections[SPAD_SECTION_TRACE]))
4587b6859fbSMintz, Yuval 
4592d22bc83SMichal Kalderon #define MAX_SW_PLTAFORM_STR_SIZE	64
4602d22bc83SMichal Kalderon 
461c965db44STomer Tayar #define EMPTY_FW_VERSION_STR		"???_???_???_???"
462c965db44STomer Tayar #define EMPTY_FW_IMAGE_STR		"???????????????"
463c965db44STomer Tayar 
464c965db44STomer Tayar /***************************** Constant Arrays *******************************/
465c965db44STomer Tayar 
466c965db44STomer Tayar /* Chip constant definitions array */
467c965db44STomer Tayar static struct chip_defs s_chip_defs[MAX_CHIP_IDS] = {
4688a52bbabSMichal Kalderon 	{"bb", PSWRQ2_REG_ILT_MEMORY_SIZE_BB / 2},
4698a52bbabSMichal Kalderon 	{"ah", PSWRQ2_REG_ILT_MEMORY_SIZE_K2 / 2}
470c965db44STomer Tayar };
471c965db44STomer Tayar 
472c965db44STomer Tayar /* Storm constant definitions array */
473c965db44STomer Tayar static struct storm_defs s_storm_defs[] = {
474c965db44STomer Tayar 	/* Tstorm */
475c965db44STomer Tayar 	{'T', BLOCK_TSEM,
4762d22bc83SMichal Kalderon 		{DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
4772d22bc83SMichal Kalderon 		true,
478c965db44STomer Tayar 		TSEM_REG_FAST_MEMORY,
4797b6859fbSMintz, Yuval 		TSEM_REG_DBG_FRAME_MODE_BB_K2, TSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
4807b6859fbSMintz, Yuval 		TSEM_REG_SLOW_DBG_MODE_BB_K2, TSEM_REG_DBG_MODE1_CFG_BB_K2,
4812d22bc83SMichal Kalderon 		TSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_DBG_GPRE_VECT,
482c965db44STomer Tayar 		TCM_REG_CTX_RBC_ACCS,
4832d22bc83SMichal Kalderon 		{TCM_REG_AGG_CON_CTX, TCM_REG_SM_CON_CTX, TCM_REG_AGG_TASK_CTX,
4842d22bc83SMichal Kalderon 		 TCM_REG_SM_TASK_CTX},
4852d22bc83SMichal Kalderon 		{{4, 16, 2, 4}, {4, 16, 2, 4}} /* {bb} {k2} */
4862d22bc83SMichal Kalderon 	},
4877b6859fbSMintz, Yuval 
488c965db44STomer Tayar 	/* Mstorm */
489c965db44STomer Tayar 	{'M', BLOCK_MSEM,
4902d22bc83SMichal Kalderon 		{DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
4912d22bc83SMichal Kalderon 		false,
492c965db44STomer Tayar 		MSEM_REG_FAST_MEMORY,
4932d22bc83SMichal Kalderon 		MSEM_REG_DBG_FRAME_MODE_BB_K2,
4942d22bc83SMichal Kalderon 		MSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
4952d22bc83SMichal Kalderon 		MSEM_REG_SLOW_DBG_MODE_BB_K2,
4962d22bc83SMichal Kalderon 		MSEM_REG_DBG_MODE1_CFG_BB_K2,
4972d22bc83SMichal Kalderon 		MSEM_REG_SYNC_DBG_EMPTY,
4982d22bc83SMichal Kalderon 		MSEM_REG_DBG_GPRE_VECT,
499c965db44STomer Tayar 		MCM_REG_CTX_RBC_ACCS,
5002d22bc83SMichal Kalderon 		{MCM_REG_AGG_CON_CTX, MCM_REG_SM_CON_CTX, MCM_REG_AGG_TASK_CTX,
5012d22bc83SMichal Kalderon 		 MCM_REG_SM_TASK_CTX },
5022d22bc83SMichal Kalderon 		{{1, 10, 2, 7}, {1, 10, 2, 7}} /* {bb} {k2}*/
5032d22bc83SMichal Kalderon 	},
5047b6859fbSMintz, Yuval 
505c965db44STomer Tayar 	/* Ustorm */
506c965db44STomer Tayar 	{'U', BLOCK_USEM,
5072d22bc83SMichal Kalderon 		{DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
5082d22bc83SMichal Kalderon 		false,
509c965db44STomer Tayar 		USEM_REG_FAST_MEMORY,
5102d22bc83SMichal Kalderon 		USEM_REG_DBG_FRAME_MODE_BB_K2,
5112d22bc83SMichal Kalderon 		USEM_REG_SLOW_DBG_ACTIVE_BB_K2,
5122d22bc83SMichal Kalderon 		USEM_REG_SLOW_DBG_MODE_BB_K2,
5132d22bc83SMichal Kalderon 		USEM_REG_DBG_MODE1_CFG_BB_K2,
5142d22bc83SMichal Kalderon 		USEM_REG_SYNC_DBG_EMPTY,
5152d22bc83SMichal Kalderon 		USEM_REG_DBG_GPRE_VECT,
516c965db44STomer Tayar 		UCM_REG_CTX_RBC_ACCS,
5172d22bc83SMichal Kalderon 		{UCM_REG_AGG_CON_CTX, UCM_REG_SM_CON_CTX, UCM_REG_AGG_TASK_CTX,
5182d22bc83SMichal Kalderon 		 UCM_REG_SM_TASK_CTX},
5192d22bc83SMichal Kalderon 		{{2, 13, 3, 3}, {2, 13, 3, 3}} /* {bb} {k2} */
5202d22bc83SMichal Kalderon 	},
5217b6859fbSMintz, Yuval 
522c965db44STomer Tayar 	/* Xstorm */
523c965db44STomer Tayar 	{'X', BLOCK_XSEM,
5242d22bc83SMichal Kalderon 		{DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
5252d22bc83SMichal Kalderon 		false,
526c965db44STomer Tayar 		XSEM_REG_FAST_MEMORY,
5272d22bc83SMichal Kalderon 		XSEM_REG_DBG_FRAME_MODE_BB_K2,
5282d22bc83SMichal Kalderon 		XSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
5292d22bc83SMichal Kalderon 		XSEM_REG_SLOW_DBG_MODE_BB_K2,
5302d22bc83SMichal Kalderon 		XSEM_REG_DBG_MODE1_CFG_BB_K2,
5312d22bc83SMichal Kalderon 		XSEM_REG_SYNC_DBG_EMPTY,
5322d22bc83SMichal Kalderon 		XSEM_REG_DBG_GPRE_VECT,
533c965db44STomer Tayar 		XCM_REG_CTX_RBC_ACCS,
5342d22bc83SMichal Kalderon 		{XCM_REG_AGG_CON_CTX, XCM_REG_SM_CON_CTX, 0, 0},
5352d22bc83SMichal Kalderon 		{{9, 15, 0, 0}, {9, 15,	0, 0}} /* {bb} {k2} */
5362d22bc83SMichal Kalderon 	},
5377b6859fbSMintz, Yuval 
538c965db44STomer Tayar 	/* Ystorm */
539c965db44STomer Tayar 	{'Y', BLOCK_YSEM,
5402d22bc83SMichal Kalderon 		{DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY},
5412d22bc83SMichal Kalderon 		false,
542c965db44STomer Tayar 		YSEM_REG_FAST_MEMORY,
5432d22bc83SMichal Kalderon 		YSEM_REG_DBG_FRAME_MODE_BB_K2,
5442d22bc83SMichal Kalderon 		YSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
5452d22bc83SMichal Kalderon 		YSEM_REG_SLOW_DBG_MODE_BB_K2,
5462d22bc83SMichal Kalderon 		YSEM_REG_DBG_MODE1_CFG_BB_K2,
5472d22bc83SMichal Kalderon 		YSEM_REG_SYNC_DBG_EMPTY,
5482d22bc83SMichal Kalderon 		YSEM_REG_DBG_GPRE_VECT,
549c965db44STomer Tayar 		YCM_REG_CTX_RBC_ACCS,
5502d22bc83SMichal Kalderon 		{YCM_REG_AGG_CON_CTX, YCM_REG_SM_CON_CTX, YCM_REG_AGG_TASK_CTX,
5512d22bc83SMichal Kalderon 		 YCM_REG_SM_TASK_CTX},
5522d22bc83SMichal Kalderon 		{{2, 3, 2, 12}, {2, 3, 2, 12}} /* {bb} {k2} */
5532d22bc83SMichal Kalderon 	},
5547b6859fbSMintz, Yuval 
555c965db44STomer Tayar 	/* Pstorm */
556c965db44STomer Tayar 	{'P', BLOCK_PSEM,
5572d22bc83SMichal Kalderon 		{DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
5582d22bc83SMichal Kalderon 		true,
559c965db44STomer Tayar 		PSEM_REG_FAST_MEMORY,
5602d22bc83SMichal Kalderon 		PSEM_REG_DBG_FRAME_MODE_BB_K2,
5612d22bc83SMichal Kalderon 		PSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
5622d22bc83SMichal Kalderon 		PSEM_REG_SLOW_DBG_MODE_BB_K2,
5632d22bc83SMichal Kalderon 		PSEM_REG_DBG_MODE1_CFG_BB_K2,
5642d22bc83SMichal Kalderon 		PSEM_REG_SYNC_DBG_EMPTY,
5652d22bc83SMichal Kalderon 		PSEM_REG_DBG_GPRE_VECT,
566c965db44STomer Tayar 		PCM_REG_CTX_RBC_ACCS,
5672d22bc83SMichal Kalderon 		{0, PCM_REG_SM_CON_CTX, 0, 0},
5682d22bc83SMichal Kalderon 		{{0, 10, 0, 0}, {0, 10, 0, 0}} /* {bb} {k2} */
5692d22bc83SMichal Kalderon 	},
570c965db44STomer Tayar };
571c965db44STomer Tayar 
5722d22bc83SMichal Kalderon static struct hw_type_defs s_hw_type_defs[] = {
5732d22bc83SMichal Kalderon 	/* HW_TYPE_ASIC */
574da090917STomer Tayar 	{"asic", 1, 256, 32768},
575da090917STomer Tayar 	{"reserved", 0, 0, 0},
576da090917STomer Tayar 	{"reserved2", 0, 0, 0},
577da090917STomer Tayar 	{"reserved3", 0, 0, 0}
578c965db44STomer Tayar };
579c965db44STomer Tayar 
580c965db44STomer Tayar static struct grc_param_defs s_grc_param_defs[] = {
5817b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_TSTORM */
5822d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 1, {1, 1}},
5837b6859fbSMintz, Yuval 
5847b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_MSTORM */
5852d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 1, {1, 1}},
5867b6859fbSMintz, Yuval 
5877b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_USTORM */
5882d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 1, {1, 1}},
5897b6859fbSMintz, Yuval 
5907b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_XSTORM */
5912d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 1, {1, 1}},
5927b6859fbSMintz, Yuval 
5937b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_YSTORM */
5942d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 1, {1, 1}},
5957b6859fbSMintz, Yuval 
5967b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_PSTORM */
5972d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 1, {1, 1}},
5987b6859fbSMintz, Yuval 
5997b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_REGS */
6002d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6017b6859fbSMintz, Yuval 
6027b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_RAM */
6032d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6047b6859fbSMintz, Yuval 
6057b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_PBUF */
6062d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6077b6859fbSMintz, Yuval 
6087b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_IOR */
6092d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {1, 1}},
6107b6859fbSMintz, Yuval 
6117b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_VFC */
6122d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {1, 1}},
6137b6859fbSMintz, Yuval 
6147b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_CM_CTX */
6152d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6167b6859fbSMintz, Yuval 
6177b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_ILT */
6182d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6197b6859fbSMintz, Yuval 
6207b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_RSS */
6212d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6227b6859fbSMintz, Yuval 
6237b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_CAU */
6242d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6257b6859fbSMintz, Yuval 
6267b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_QM */
6272d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6287b6859fbSMintz, Yuval 
6297b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_MCP */
6302d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6317b6859fbSMintz, Yuval 
6322d22bc83SMichal Kalderon 	/* DBG_GRC_PARAM_DUMP_DORQ */
6332d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6347b6859fbSMintz, Yuval 
6357b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_CFC */
6362d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6377b6859fbSMintz, Yuval 
6387b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_IGU */
6392d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6407b6859fbSMintz, Yuval 
6417b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_BRB */
6422d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {1, 1}},
6437b6859fbSMintz, Yuval 
6447b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_BTB */
6452d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {1, 1}},
6467b6859fbSMintz, Yuval 
6477b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_BMB */
6482d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {0, 0}},
6497b6859fbSMintz, Yuval 
6502d22bc83SMichal Kalderon 	/* DBG_GRC_PARAM_RESERVED1 */
6512d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {0, 0}},
6527b6859fbSMintz, Yuval 
6537b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_MULD */
6542d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6557b6859fbSMintz, Yuval 
6567b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_PRS */
6572d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6587b6859fbSMintz, Yuval 
6597b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_DMAE */
6602d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6617b6859fbSMintz, Yuval 
6627b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_TM */
6632d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6647b6859fbSMintz, Yuval 
6657b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_SDM */
6662d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6677b6859fbSMintz, Yuval 
6687b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_DIF */
6692d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6707b6859fbSMintz, Yuval 
6717b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_STATIC */
6722d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6737b6859fbSMintz, Yuval 
6747b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_UNSTALL */
6752d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {0, 0}},
6767b6859fbSMintz, Yuval 
6772d22bc83SMichal Kalderon 	/* DBG_GRC_PARAM_RESERVED2 */
6782d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {0, 0}},
6797b6859fbSMintz, Yuval 
6802d22bc83SMichal Kalderon 	/* DBG_GRC_PARAM_MCP_TRACE_META_SIZE */
6812d22bc83SMichal Kalderon 	{{0, 0}, 1, 0xffffffff, false, true, 0, {0, 0}},
6827b6859fbSMintz, Yuval 
6837b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_EXCLUDE_ALL */
6842d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, true, false, 0, {0, 0}},
6857b6859fbSMintz, Yuval 
6867b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_CRASH */
6872d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, true, false, 0, {0, 0}},
6887b6859fbSMintz, Yuval 
6897b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_PARITY_SAFE */
6902d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {0, 0}},
6917b6859fbSMintz, Yuval 
6927b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_CM */
6932d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {1, 1}},
6947b6859fbSMintz, Yuval 
6957b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_DUMP_PHY */
6962d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {0, 0}},
6977b6859fbSMintz, Yuval 
6987b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_NO_MCP */
6992d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {0, 0}},
7007b6859fbSMintz, Yuval 
7017b6859fbSMintz, Yuval 	/* DBG_GRC_PARAM_NO_FW_VER */
7022d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {0, 0}},
7038a52bbabSMichal Kalderon 
7048a52bbabSMichal Kalderon 	/* DBG_GRC_PARAM_RESERVED3 */
7052d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {0, 0}},
7068a52bbabSMichal Kalderon 
7078a52bbabSMichal Kalderon 	/* DBG_GRC_PARAM_DUMP_MCP_HW_DUMP */
7082d22bc83SMichal Kalderon 	{{0, 1}, 0, 1, false, false, 0, {0, 1}},
7098a52bbabSMichal Kalderon 
7108a52bbabSMichal Kalderon 	/* DBG_GRC_PARAM_DUMP_ILT_CDUC */
7112d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {0, 0}},
7128a52bbabSMichal Kalderon 
7138a52bbabSMichal Kalderon 	/* DBG_GRC_PARAM_DUMP_ILT_CDUT */
7142d22bc83SMichal Kalderon 	{{1, 1}, 0, 1, false, false, 0, {0, 0}},
7158a52bbabSMichal Kalderon 
7168a52bbabSMichal Kalderon 	/* DBG_GRC_PARAM_DUMP_CAU_EXT */
7172d22bc83SMichal Kalderon 	{{0, 0}, 0, 1, false, false, 0, {1, 1}}
718c965db44STomer Tayar };
719c965db44STomer Tayar 
720c965db44STomer Tayar static struct rss_mem_defs s_rss_mem_defs[] = {
721da090917STomer Tayar 	{"rss_mem_cid", "rss_cid", 0, 32,
7222d22bc83SMichal Kalderon 	 {256, 320}},
7237b6859fbSMintz, Yuval 
724da090917STomer Tayar 	{"rss_mem_key_msb", "rss_key", 1024, 256,
7252d22bc83SMichal Kalderon 	 {128, 208}},
7267b6859fbSMintz, Yuval 
727da090917STomer Tayar 	{"rss_mem_key_lsb", "rss_key", 2048, 64,
7282d22bc83SMichal Kalderon 	 {128, 208}},
7297b6859fbSMintz, Yuval 
730da090917STomer Tayar 	{"rss_mem_info", "rss_info", 3072, 16,
7312d22bc83SMichal Kalderon 	 {128, 208}},
7327b6859fbSMintz, Yuval 
733da090917STomer Tayar 	{"rss_mem_ind", "rss_ind", 4096, 16,
7342d22bc83SMichal Kalderon 	 {16384, 26624}}
735c965db44STomer Tayar };
736c965db44STomer Tayar 
737c965db44STomer Tayar static struct vfc_ram_defs s_vfc_ram_defs[] = {
738c965db44STomer Tayar 	{"vfc_ram_tt1", "vfc_ram", 0, 512},
739c965db44STomer Tayar 	{"vfc_ram_mtt2", "vfc_ram", 512, 128},
740c965db44STomer Tayar 	{"vfc_ram_stt2", "vfc_ram", 640, 32},
741c965db44STomer Tayar 	{"vfc_ram_ro_vect", "vfc_ram", 672, 32}
742c965db44STomer Tayar };
743c965db44STomer Tayar 
744c965db44STomer Tayar static struct big_ram_defs s_big_ram_defs[] = {
745c965db44STomer Tayar 	{"BRB", MEM_GROUP_BRB_MEM, MEM_GROUP_BRB_RAM, DBG_GRC_PARAM_DUMP_BRB,
746c965db44STomer Tayar 	 BRB_REG_BIG_RAM_ADDRESS, BRB_REG_BIG_RAM_DATA,
7472d22bc83SMichal Kalderon 	 MISC_REG_BLOCK_256B_EN, {0, 0},
7482d22bc83SMichal Kalderon 	 {153600, 180224}},
7497b6859fbSMintz, Yuval 
750c965db44STomer Tayar 	{"BTB", MEM_GROUP_BTB_MEM, MEM_GROUP_BTB_RAM, DBG_GRC_PARAM_DUMP_BTB,
751c965db44STomer Tayar 	 BTB_REG_BIG_RAM_ADDRESS, BTB_REG_BIG_RAM_DATA,
7522d22bc83SMichal Kalderon 	 MISC_REG_BLOCK_256B_EN, {0, 1},
7532d22bc83SMichal Kalderon 	 {92160, 117760}},
7547b6859fbSMintz, Yuval 
755c965db44STomer Tayar 	{"BMB", MEM_GROUP_BMB_MEM, MEM_GROUP_BMB_RAM, DBG_GRC_PARAM_DUMP_BMB,
756c965db44STomer Tayar 	 BMB_REG_BIG_RAM_ADDRESS, BMB_REG_BIG_RAM_DATA,
7572d22bc83SMichal Kalderon 	 MISCS_REG_BLOCK_256B_EN, {0, 0},
7582d22bc83SMichal Kalderon 	 {36864, 36864}}
759c965db44STomer Tayar };
760c965db44STomer Tayar 
7612d22bc83SMichal Kalderon static struct rbc_reset_defs s_rbc_reset_defs[] = {
762da090917STomer Tayar 	{MISCS_REG_RESET_PL_HV,
7632d22bc83SMichal Kalderon 	 {0x0, 0x400}},
764da090917STomer Tayar 	{MISC_REG_RESET_PL_PDA_VMAIN_1,
7652d22bc83SMichal Kalderon 	 {0x4404040, 0x4404040}},
766da090917STomer Tayar 	{MISC_REG_RESET_PL_PDA_VMAIN_2,
7672d22bc83SMichal Kalderon 	 {0x7, 0x7c00007}},
768da090917STomer Tayar 	{MISC_REG_RESET_PL_PDA_VAUX,
7692d22bc83SMichal Kalderon 	 {0x2, 0x2}},
770c965db44STomer Tayar };
771c965db44STomer Tayar 
772c965db44STomer Tayar static struct phy_defs s_phy_defs[] = {
7737b6859fbSMintz, Yuval 	{"nw_phy", NWS_REG_NWS_CMU_K2,
77421dd79e8STomer Tayar 	 PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_7_0_K2_E5,
77521dd79e8STomer Tayar 	 PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_15_8_K2_E5,
77621dd79e8STomer Tayar 	 PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_7_0_K2_E5,
77721dd79e8STomer Tayar 	 PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_11_8_K2_E5},
77821dd79e8STomer Tayar 	{"sgmii_phy", MS_REG_MS_CMU_K2_E5,
77921dd79e8STomer Tayar 	 PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X132_K2_E5,
78021dd79e8STomer Tayar 	 PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X133_K2_E5,
78121dd79e8STomer Tayar 	 PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X130_K2_E5,
78221dd79e8STomer Tayar 	 PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X131_K2_E5},
78321dd79e8STomer Tayar 	{"pcie_phy0", PHY_PCIE_REG_PHY0_K2_E5,
78421dd79e8STomer Tayar 	 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2_E5,
78521dd79e8STomer Tayar 	 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2_E5,
78621dd79e8STomer Tayar 	 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2_E5,
78721dd79e8STomer Tayar 	 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2_E5},
78821dd79e8STomer Tayar 	{"pcie_phy1", PHY_PCIE_REG_PHY1_K2_E5,
78921dd79e8STomer Tayar 	 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2_E5,
79021dd79e8STomer Tayar 	 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2_E5,
79121dd79e8STomer Tayar 	 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2_E5,
79221dd79e8STomer Tayar 	 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2_E5},
793c965db44STomer Tayar };
794c965db44STomer Tayar 
795d52c89f1SMichal Kalderon static struct split_type_defs s_split_type_defs[] = {
796d52c89f1SMichal Kalderon 	/* SPLIT_TYPE_NONE */
797d52c89f1SMichal Kalderon 	{"eng"},
798d52c89f1SMichal Kalderon 
799d52c89f1SMichal Kalderon 	/* SPLIT_TYPE_PORT */
800d52c89f1SMichal Kalderon 	{"port"},
801d52c89f1SMichal Kalderon 
802d52c89f1SMichal Kalderon 	/* SPLIT_TYPE_PF */
803d52c89f1SMichal Kalderon 	{"pf"},
804d52c89f1SMichal Kalderon 
805d52c89f1SMichal Kalderon 	/* SPLIT_TYPE_PORT_PF */
806d52c89f1SMichal Kalderon 	{"port"},
807d52c89f1SMichal Kalderon 
808d52c89f1SMichal Kalderon 	/* SPLIT_TYPE_VF */
809d52c89f1SMichal Kalderon 	{"vf"}
810d52c89f1SMichal Kalderon };
811d52c89f1SMichal Kalderon 
812c965db44STomer Tayar /**************************** Private Functions ******************************/
813c965db44STomer Tayar 
814c965db44STomer Tayar /* Reads and returns a single dword from the specified unaligned buffer */
815c965db44STomer Tayar static u32 qed_read_unaligned_dword(u8 *buf)
816c965db44STomer Tayar {
817c965db44STomer Tayar 	u32 dword;
818c965db44STomer Tayar 
819c965db44STomer Tayar 	memcpy((u8 *)&dword, buf, sizeof(dword));
820c965db44STomer Tayar 	return dword;
821c965db44STomer Tayar }
822c965db44STomer Tayar 
8233b86bd07SSudarsana Reddy Kalluru /* Sets the value of the specified GRC param */
8243b86bd07SSudarsana Reddy Kalluru static void qed_grc_set_param(struct qed_hwfn *p_hwfn,
8253b86bd07SSudarsana Reddy Kalluru 			      enum dbg_grc_params grc_param, u32 val)
8263b86bd07SSudarsana Reddy Kalluru {
8273b86bd07SSudarsana Reddy Kalluru 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
8283b86bd07SSudarsana Reddy Kalluru 
8293b86bd07SSudarsana Reddy Kalluru 	dev_data->grc.param_val[grc_param] = val;
8303b86bd07SSudarsana Reddy Kalluru }
8313b86bd07SSudarsana Reddy Kalluru 
832be086e7cSMintz, Yuval /* Returns the value of the specified GRC param */
833be086e7cSMintz, Yuval static u32 qed_grc_get_param(struct qed_hwfn *p_hwfn,
834be086e7cSMintz, Yuval 			     enum dbg_grc_params grc_param)
835be086e7cSMintz, Yuval {
836be086e7cSMintz, Yuval 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
837be086e7cSMintz, Yuval 
838be086e7cSMintz, Yuval 	return dev_data->grc.param_val[grc_param];
839be086e7cSMintz, Yuval }
840be086e7cSMintz, Yuval 
841be086e7cSMintz, Yuval /* Initializes the GRC parameters */
842be086e7cSMintz, Yuval static void qed_dbg_grc_init_params(struct qed_hwfn *p_hwfn)
843be086e7cSMintz, Yuval {
844be086e7cSMintz, Yuval 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
845be086e7cSMintz, Yuval 
846be086e7cSMintz, Yuval 	if (!dev_data->grc.params_initialized) {
847be086e7cSMintz, Yuval 		qed_dbg_grc_set_params_default(p_hwfn);
848be086e7cSMintz, Yuval 		dev_data->grc.params_initialized = 1;
849be086e7cSMintz, Yuval 	}
850be086e7cSMintz, Yuval }
851be086e7cSMintz, Yuval 
8522d22bc83SMichal Kalderon /* Sets pointer and size for the specified binary buffer type */
8532d22bc83SMichal Kalderon static void qed_set_dbg_bin_buf(struct qed_hwfn *p_hwfn,
8542d22bc83SMichal Kalderon 				enum bin_dbg_buffer_type buf_type,
8552d22bc83SMichal Kalderon 				const u32 *ptr, u32 size)
8562d22bc83SMichal Kalderon {
8572d22bc83SMichal Kalderon 	struct virt_mem_desc *buf = &p_hwfn->dbg_arrays[buf_type];
8582d22bc83SMichal Kalderon 
8592d22bc83SMichal Kalderon 	buf->ptr = (void *)ptr;
8602d22bc83SMichal Kalderon 	buf->size = size;
8612d22bc83SMichal Kalderon }
8622d22bc83SMichal Kalderon 
863c965db44STomer Tayar /* Initializes debug data for the specified device */
8642d22bc83SMichal Kalderon static enum dbg_status qed_dbg_dev_init(struct qed_hwfn *p_hwfn)
865c965db44STomer Tayar {
866c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
867d52c89f1SMichal Kalderon 	u8 num_pfs = 0, max_pfs_per_port = 0;
868c965db44STomer Tayar 
869c965db44STomer Tayar 	if (dev_data->initialized)
870c965db44STomer Tayar 		return DBG_STATUS_OK;
871c965db44STomer Tayar 
872d52c89f1SMichal Kalderon 	/* Set chip */
873c965db44STomer Tayar 	if (QED_IS_K2(p_hwfn->cdev)) {
874c965db44STomer Tayar 		dev_data->chip_id = CHIP_K2;
875c965db44STomer Tayar 		dev_data->mode_enable[MODE_K2] = 1;
876d52c89f1SMichal Kalderon 		dev_data->num_vfs = MAX_NUM_VFS_K2;
877d52c89f1SMichal Kalderon 		num_pfs = MAX_NUM_PFS_K2;
878d52c89f1SMichal Kalderon 		max_pfs_per_port = MAX_NUM_PFS_K2 / 2;
879c965db44STomer Tayar 	} else if (QED_IS_BB_B0(p_hwfn->cdev)) {
8807b6859fbSMintz, Yuval 		dev_data->chip_id = CHIP_BB;
8819c79ddaaSMintz, Yuval 		dev_data->mode_enable[MODE_BB] = 1;
882d52c89f1SMichal Kalderon 		dev_data->num_vfs = MAX_NUM_VFS_BB;
883d52c89f1SMichal Kalderon 		num_pfs = MAX_NUM_PFS_BB;
884d52c89f1SMichal Kalderon 		max_pfs_per_port = MAX_NUM_PFS_BB;
885c965db44STomer Tayar 	} else {
886c965db44STomer Tayar 		return DBG_STATUS_UNKNOWN_CHIP;
887c965db44STomer Tayar 	}
888c965db44STomer Tayar 
8892d22bc83SMichal Kalderon 	/* Set HW type */
8902d22bc83SMichal Kalderon 	dev_data->hw_type = HW_TYPE_ASIC;
891c965db44STomer Tayar 	dev_data->mode_enable[MODE_ASIC] = 1;
892be086e7cSMintz, Yuval 
893d52c89f1SMichal Kalderon 	/* Set port mode */
8942d22bc83SMichal Kalderon 	switch (p_hwfn->cdev->num_ports_in_engine) {
8952d22bc83SMichal Kalderon 	case 1:
896d52c89f1SMichal Kalderon 		dev_data->mode_enable[MODE_PORTS_PER_ENG_1] = 1;
897d52c89f1SMichal Kalderon 		break;
8982d22bc83SMichal Kalderon 	case 2:
899d52c89f1SMichal Kalderon 		dev_data->mode_enable[MODE_PORTS_PER_ENG_2] = 1;
900d52c89f1SMichal Kalderon 		break;
9012d22bc83SMichal Kalderon 	case 4:
902d52c89f1SMichal Kalderon 		dev_data->mode_enable[MODE_PORTS_PER_ENG_4] = 1;
903d52c89f1SMichal Kalderon 		break;
904d52c89f1SMichal Kalderon 	}
905d52c89f1SMichal Kalderon 
906d52c89f1SMichal Kalderon 	/* Set 100G mode */
9072d22bc83SMichal Kalderon 	if (QED_IS_CMT(p_hwfn->cdev))
908d52c89f1SMichal Kalderon 		dev_data->mode_enable[MODE_100G] = 1;
909d52c89f1SMichal Kalderon 
910d52c89f1SMichal Kalderon 	/* Set number of ports */
911d52c89f1SMichal Kalderon 	if (dev_data->mode_enable[MODE_PORTS_PER_ENG_1] ||
912d52c89f1SMichal Kalderon 	    dev_data->mode_enable[MODE_100G])
913d52c89f1SMichal Kalderon 		dev_data->num_ports = 1;
914d52c89f1SMichal Kalderon 	else if (dev_data->mode_enable[MODE_PORTS_PER_ENG_2])
915d52c89f1SMichal Kalderon 		dev_data->num_ports = 2;
916d52c89f1SMichal Kalderon 	else if (dev_data->mode_enable[MODE_PORTS_PER_ENG_4])
917d52c89f1SMichal Kalderon 		dev_data->num_ports = 4;
918d52c89f1SMichal Kalderon 
919d52c89f1SMichal Kalderon 	/* Set number of PFs per port */
920d52c89f1SMichal Kalderon 	dev_data->num_pfs_per_port = min_t(u32,
921d52c89f1SMichal Kalderon 					   num_pfs / dev_data->num_ports,
922d52c89f1SMichal Kalderon 					   max_pfs_per_port);
923d52c89f1SMichal Kalderon 
924be086e7cSMintz, Yuval 	/* Initializes the GRC parameters */
925be086e7cSMintz, Yuval 	qed_dbg_grc_init_params(p_hwfn);
926be086e7cSMintz, Yuval 
927da090917STomer Tayar 	dev_data->use_dmae = true;
928da090917STomer Tayar 	dev_data->initialized = 1;
9297b6859fbSMintz, Yuval 
930c965db44STomer Tayar 	return DBG_STATUS_OK;
931c965db44STomer Tayar }
932c965db44STomer Tayar 
9332d22bc83SMichal Kalderon static const struct dbg_block *get_dbg_block(struct qed_hwfn *p_hwfn,
9347b6859fbSMintz, Yuval 					     enum block_id block_id)
9357b6859fbSMintz, Yuval {
9362d22bc83SMichal Kalderon 	const struct dbg_block *dbg_block;
9372d22bc83SMichal Kalderon 
9382d22bc83SMichal Kalderon 	dbg_block = p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS].ptr;
9392d22bc83SMichal Kalderon 	return dbg_block + block_id;
9402d22bc83SMichal Kalderon }
9412d22bc83SMichal Kalderon 
9422d22bc83SMichal Kalderon static const struct dbg_block_chip *qed_get_dbg_block_per_chip(struct qed_hwfn
9432d22bc83SMichal Kalderon 							       *p_hwfn,
9442d22bc83SMichal Kalderon 							       enum block_id
9452d22bc83SMichal Kalderon 							       block_id)
9462d22bc83SMichal Kalderon {
9477b6859fbSMintz, Yuval 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
9487b6859fbSMintz, Yuval 
9492d22bc83SMichal Kalderon 	return (const struct dbg_block_chip *)
9502d22bc83SMichal Kalderon 	    p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS_CHIP_DATA].ptr +
9512d22bc83SMichal Kalderon 	    block_id * MAX_CHIP_IDS + dev_data->chip_id;
9522d22bc83SMichal Kalderon }
9532d22bc83SMichal Kalderon 
9542d22bc83SMichal Kalderon static const struct dbg_reset_reg *qed_get_dbg_reset_reg(struct qed_hwfn
9552d22bc83SMichal Kalderon 							 *p_hwfn,
9562d22bc83SMichal Kalderon 							 u8 reset_reg_id)
9572d22bc83SMichal Kalderon {
9582d22bc83SMichal Kalderon 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
9592d22bc83SMichal Kalderon 
9602d22bc83SMichal Kalderon 	return (const struct dbg_reset_reg *)
9612d22bc83SMichal Kalderon 	    p_hwfn->dbg_arrays[BIN_BUF_DBG_RESET_REGS].ptr +
9622d22bc83SMichal Kalderon 	    reset_reg_id * MAX_CHIP_IDS + dev_data->chip_id;
9637b6859fbSMintz, Yuval }
9647b6859fbSMintz, Yuval 
965c965db44STomer Tayar /* Reads the FW info structure for the specified Storm from the chip,
966c965db44STomer Tayar  * and writes it to the specified fw_info pointer.
967c965db44STomer Tayar  */
968d52c89f1SMichal Kalderon static void qed_read_storm_fw_info(struct qed_hwfn *p_hwfn,
969c965db44STomer Tayar 				   struct qed_ptt *p_ptt,
970c965db44STomer Tayar 				   u8 storm_id, struct fw_info *fw_info)
971c965db44STomer Tayar {
9727b6859fbSMintz, Yuval 	struct storm_defs *storm = &s_storm_defs[storm_id];
973c965db44STomer Tayar 	struct fw_info_location fw_info_location;
9747b6859fbSMintz, Yuval 	u32 addr, i, *dest;
975c965db44STomer Tayar 
976c965db44STomer Tayar 	memset(&fw_info_location, 0, sizeof(fw_info_location));
977c965db44STomer Tayar 	memset(fw_info, 0, sizeof(*fw_info));
9787b6859fbSMintz, Yuval 
9797b6859fbSMintz, Yuval 	/* Read first the address that points to fw_info location.
9807b6859fbSMintz, Yuval 	 * The address is located in the last line of the Storm RAM.
9817b6859fbSMintz, Yuval 	 */
9827b6859fbSMintz, Yuval 	addr = storm->sem_fast_mem_addr + SEM_FAST_REG_INT_RAM +
9832d22bc83SMichal Kalderon 	    DWORDS_TO_BYTES(SEM_FAST_REG_INT_RAM_SIZE) -
9847b6859fbSMintz, Yuval 	    sizeof(fw_info_location);
9852d22bc83SMichal Kalderon 
9867b6859fbSMintz, Yuval 	dest = (u32 *)&fw_info_location;
9877b6859fbSMintz, Yuval 
988c965db44STomer Tayar 	for (i = 0; i < BYTES_TO_DWORDS(sizeof(fw_info_location));
989c965db44STomer Tayar 	     i++, addr += BYTES_IN_DWORD)
990c965db44STomer Tayar 		dest[i] = qed_rd(p_hwfn, p_ptt, addr);
9917b6859fbSMintz, Yuval 
9927b6859fbSMintz, Yuval 	/* Read FW version info from Storm RAM */
993c965db44STomer Tayar 	if (fw_info_location.size > 0 && fw_info_location.size <=
994c965db44STomer Tayar 	    sizeof(*fw_info)) {
995c965db44STomer Tayar 		addr = fw_info_location.grc_addr;
996c965db44STomer Tayar 		dest = (u32 *)fw_info;
997c965db44STomer Tayar 		for (i = 0; i < BYTES_TO_DWORDS(fw_info_location.size);
998c965db44STomer Tayar 		     i++, addr += BYTES_IN_DWORD)
999c965db44STomer Tayar 			dest[i] = qed_rd(p_hwfn, p_ptt, addr);
1000c965db44STomer Tayar 	}
1001c965db44STomer Tayar }
1002c965db44STomer Tayar 
10037b6859fbSMintz, Yuval /* Dumps the specified string to the specified buffer.
10047b6859fbSMintz, Yuval  * Returns the dumped size in bytes.
1005c965db44STomer Tayar  */
1006c965db44STomer Tayar static u32 qed_dump_str(char *dump_buf, bool dump, const char *str)
1007c965db44STomer Tayar {
1008c965db44STomer Tayar 	if (dump)
1009c965db44STomer Tayar 		strcpy(dump_buf, str);
10107b6859fbSMintz, Yuval 
1011c965db44STomer Tayar 	return (u32)strlen(str) + 1;
1012c965db44STomer Tayar }
1013c965db44STomer Tayar 
10147b6859fbSMintz, Yuval /* Dumps zeros to align the specified buffer to dwords.
10157b6859fbSMintz, Yuval  * Returns the dumped size in bytes.
1016c965db44STomer Tayar  */
1017c965db44STomer Tayar static u32 qed_dump_align(char *dump_buf, bool dump, u32 byte_offset)
1018c965db44STomer Tayar {
10197b6859fbSMintz, Yuval 	u8 offset_in_dword, align_size;
1020c965db44STomer Tayar 
10217b6859fbSMintz, Yuval 	offset_in_dword = (u8)(byte_offset & 0x3);
1022c965db44STomer Tayar 	align_size = offset_in_dword ? BYTES_IN_DWORD - offset_in_dword : 0;
1023c965db44STomer Tayar 
1024c965db44STomer Tayar 	if (dump && align_size)
1025c965db44STomer Tayar 		memset(dump_buf, 0, align_size);
10267b6859fbSMintz, Yuval 
1027c965db44STomer Tayar 	return align_size;
1028c965db44STomer Tayar }
1029c965db44STomer Tayar 
1030c965db44STomer Tayar /* Writes the specified string param to the specified buffer.
1031c965db44STomer Tayar  * Returns the dumped size in dwords.
1032c965db44STomer Tayar  */
1033c965db44STomer Tayar static u32 qed_dump_str_param(u32 *dump_buf,
1034c965db44STomer Tayar 			      bool dump,
1035c965db44STomer Tayar 			      const char *param_name, const char *param_val)
1036c965db44STomer Tayar {
1037c965db44STomer Tayar 	char *char_buf = (char *)dump_buf;
1038c965db44STomer Tayar 	u32 offset = 0;
1039c965db44STomer Tayar 
1040c965db44STomer Tayar 	/* Dump param name */
1041c965db44STomer Tayar 	offset += qed_dump_str(char_buf + offset, dump, param_name);
1042c965db44STomer Tayar 
1043c965db44STomer Tayar 	/* Indicate a string param value */
1044c965db44STomer Tayar 	if (dump)
1045c965db44STomer Tayar 		*(char_buf + offset) = 1;
1046c965db44STomer Tayar 	offset++;
1047c965db44STomer Tayar 
1048c965db44STomer Tayar 	/* Dump param value */
1049c965db44STomer Tayar 	offset += qed_dump_str(char_buf + offset, dump, param_val);
1050c965db44STomer Tayar 
1051c965db44STomer Tayar 	/* Align buffer to next dword */
1052c965db44STomer Tayar 	offset += qed_dump_align(char_buf + offset, dump, offset);
10537b6859fbSMintz, Yuval 
1054c965db44STomer Tayar 	return BYTES_TO_DWORDS(offset);
1055c965db44STomer Tayar }
1056c965db44STomer Tayar 
1057c965db44STomer Tayar /* Writes the specified numeric param to the specified buffer.
1058c965db44STomer Tayar  * Returns the dumped size in dwords.
1059c965db44STomer Tayar  */
1060c965db44STomer Tayar static u32 qed_dump_num_param(u32 *dump_buf,
1061c965db44STomer Tayar 			      bool dump, const char *param_name, u32 param_val)
1062c965db44STomer Tayar {
1063c965db44STomer Tayar 	char *char_buf = (char *)dump_buf;
1064c965db44STomer Tayar 	u32 offset = 0;
1065c965db44STomer Tayar 
1066c965db44STomer Tayar 	/* Dump param name */
1067c965db44STomer Tayar 	offset += qed_dump_str(char_buf + offset, dump, param_name);
1068c965db44STomer Tayar 
1069c965db44STomer Tayar 	/* Indicate a numeric param value */
1070c965db44STomer Tayar 	if (dump)
1071c965db44STomer Tayar 		*(char_buf + offset) = 0;
1072c965db44STomer Tayar 	offset++;
1073c965db44STomer Tayar 
1074c965db44STomer Tayar 	/* Align buffer to next dword */
1075c965db44STomer Tayar 	offset += qed_dump_align(char_buf + offset, dump, offset);
1076c965db44STomer Tayar 
1077c965db44STomer Tayar 	/* Dump param value (and change offset from bytes to dwords) */
1078c965db44STomer Tayar 	offset = BYTES_TO_DWORDS(offset);
1079c965db44STomer Tayar 	if (dump)
1080c965db44STomer Tayar 		*(dump_buf + offset) = param_val;
1081c965db44STomer Tayar 	offset++;
10827b6859fbSMintz, Yuval 
1083c965db44STomer Tayar 	return offset;
1084c965db44STomer Tayar }
1085c965db44STomer Tayar 
1086c965db44STomer Tayar /* Reads the FW version and writes it as a param to the specified buffer.
1087c965db44STomer Tayar  * Returns the dumped size in dwords.
1088c965db44STomer Tayar  */
1089c965db44STomer Tayar static u32 qed_dump_fw_ver_param(struct qed_hwfn *p_hwfn,
1090c965db44STomer Tayar 				 struct qed_ptt *p_ptt,
1091c965db44STomer Tayar 				 u32 *dump_buf, bool dump)
1092c965db44STomer Tayar {
1093c965db44STomer Tayar 	char fw_ver_str[16] = EMPTY_FW_VERSION_STR;
1094c965db44STomer Tayar 	char fw_img_str[16] = EMPTY_FW_IMAGE_STR;
1095c965db44STomer Tayar 	struct fw_info fw_info = { {0}, {0} };
1096c965db44STomer Tayar 	u32 offset = 0;
1097c965db44STomer Tayar 
1098be086e7cSMintz, Yuval 	if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {
1099d52c89f1SMichal Kalderon 		/* Read FW info from chip */
1100d52c89f1SMichal Kalderon 		qed_read_fw_info(p_hwfn, p_ptt, &fw_info);
1101c965db44STomer Tayar 
1102c965db44STomer Tayar 		/* Create FW version/image strings */
11037b6859fbSMintz, Yuval 		if (snprintf(fw_ver_str, sizeof(fw_ver_str),
11047b6859fbSMintz, Yuval 			     "%d_%d_%d_%d", fw_info.ver.num.major,
11057b6859fbSMintz, Yuval 			     fw_info.ver.num.minor, fw_info.ver.num.rev,
11067b6859fbSMintz, Yuval 			     fw_info.ver.num.eng) < 0)
1107c965db44STomer Tayar 			DP_NOTICE(p_hwfn,
1108c965db44STomer Tayar 				  "Unexpected debug error: invalid FW version string\n");
1109c965db44STomer Tayar 		switch (fw_info.ver.image_id) {
1110c965db44STomer Tayar 		case FW_IMG_MAIN:
1111c965db44STomer Tayar 			strcpy(fw_img_str, "main");
1112c965db44STomer Tayar 			break;
1113c965db44STomer Tayar 		default:
1114c965db44STomer Tayar 			strcpy(fw_img_str, "unknown");
1115c965db44STomer Tayar 			break;
1116c965db44STomer Tayar 		}
1117c965db44STomer Tayar 	}
1118c965db44STomer Tayar 
1119c965db44STomer Tayar 	/* Dump FW version, image and timestamp */
1120c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset,
1121c965db44STomer Tayar 				     dump, "fw-version", fw_ver_str);
1122c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset,
1123c965db44STomer Tayar 				     dump, "fw-image", fw_img_str);
1124c965db44STomer Tayar 	offset += qed_dump_num_param(dump_buf + offset,
1125c965db44STomer Tayar 				     dump,
1126c965db44STomer Tayar 				     "fw-timestamp", fw_info.ver.timestamp);
11277b6859fbSMintz, Yuval 
1128c965db44STomer Tayar 	return offset;
1129c965db44STomer Tayar }
1130c965db44STomer Tayar 
1131c965db44STomer Tayar /* Reads the MFW version and writes it as a param to the specified buffer.
1132c965db44STomer Tayar  * Returns the dumped size in dwords.
1133c965db44STomer Tayar  */
1134c965db44STomer Tayar static u32 qed_dump_mfw_ver_param(struct qed_hwfn *p_hwfn,
1135c965db44STomer Tayar 				  struct qed_ptt *p_ptt,
1136c965db44STomer Tayar 				  u32 *dump_buf, bool dump)
1137c965db44STomer Tayar {
1138c965db44STomer Tayar 	char mfw_ver_str[16] = EMPTY_FW_VERSION_STR;
1139c965db44STomer Tayar 
11407b6859fbSMintz, Yuval 	if (dump &&
11417b6859fbSMintz, Yuval 	    !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {
1142c965db44STomer Tayar 		u32 global_section_offsize, global_section_addr, mfw_ver;
1143c965db44STomer Tayar 		u32 public_data_addr, global_section_offsize_addr;
1144c965db44STomer Tayar 
11457b6859fbSMintz, Yuval 		/* Find MCP public data GRC address. Needs to be ORed with
11467b6859fbSMintz, Yuval 		 * MCP_REG_SCRATCH due to a HW bug.
1147c965db44STomer Tayar 		 */
11487b6859fbSMintz, Yuval 		public_data_addr = qed_rd(p_hwfn,
11497b6859fbSMintz, Yuval 					  p_ptt,
1150c965db44STomer Tayar 					  MISC_REG_SHARED_MEM_ADDR) |
1151c965db44STomer Tayar 				   MCP_REG_SCRATCH;
1152c965db44STomer Tayar 
1153c965db44STomer Tayar 		/* Find MCP public global section offset */
1154c965db44STomer Tayar 		global_section_offsize_addr = public_data_addr +
1155c965db44STomer Tayar 					      offsetof(struct mcp_public_data,
1156c965db44STomer Tayar 						       sections) +
1157c965db44STomer Tayar 					      sizeof(offsize_t) * PUBLIC_GLOBAL;
1158c965db44STomer Tayar 		global_section_offsize = qed_rd(p_hwfn, p_ptt,
1159c965db44STomer Tayar 						global_section_offsize_addr);
11607b6859fbSMintz, Yuval 		global_section_addr =
11617b6859fbSMintz, Yuval 			MCP_REG_SCRATCH +
11627b6859fbSMintz, Yuval 			(global_section_offsize & OFFSIZE_OFFSET_MASK) * 4;
1163c965db44STomer Tayar 
1164c965db44STomer Tayar 		/* Read MFW version from MCP public global section */
1165c965db44STomer Tayar 		mfw_ver = qed_rd(p_hwfn, p_ptt,
1166c965db44STomer Tayar 				 global_section_addr +
1167c965db44STomer Tayar 				 offsetof(struct public_global, mfw_ver));
1168c965db44STomer Tayar 
1169c965db44STomer Tayar 		/* Dump MFW version param */
11707b6859fbSMintz, Yuval 		if (snprintf(mfw_ver_str, sizeof(mfw_ver_str), "%d_%d_%d_%d",
11717b6859fbSMintz, Yuval 			     (u8)(mfw_ver >> 24), (u8)(mfw_ver >> 16),
11727b6859fbSMintz, Yuval 			     (u8)(mfw_ver >> 8), (u8)mfw_ver) < 0)
1173c965db44STomer Tayar 			DP_NOTICE(p_hwfn,
1174c965db44STomer Tayar 				  "Unexpected debug error: invalid MFW version string\n");
1175c965db44STomer Tayar 	}
1176c965db44STomer Tayar 
1177c965db44STomer Tayar 	return qed_dump_str_param(dump_buf, dump, "mfw-version", mfw_ver_str);
1178c965db44STomer Tayar }
1179c965db44STomer Tayar 
11802d22bc83SMichal Kalderon /* Reads the chip revision from the chip and writes it as a param to the
11812d22bc83SMichal Kalderon  * specified buffer. Returns the dumped size in dwords.
11822d22bc83SMichal Kalderon  */
11832d22bc83SMichal Kalderon static u32 qed_dump_chip_revision_param(struct qed_hwfn *p_hwfn,
11842d22bc83SMichal Kalderon 					struct qed_ptt *p_ptt,
11852d22bc83SMichal Kalderon 					u32 *dump_buf, bool dump)
11862d22bc83SMichal Kalderon {
11872d22bc83SMichal Kalderon 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
11882d22bc83SMichal Kalderon 	char param_str[3] = "??";
11892d22bc83SMichal Kalderon 
11902d22bc83SMichal Kalderon 	if (dev_data->hw_type == HW_TYPE_ASIC) {
11912d22bc83SMichal Kalderon 		u32 chip_rev, chip_metal;
11922d22bc83SMichal Kalderon 
11932d22bc83SMichal Kalderon 		chip_rev = qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_REV);
11942d22bc83SMichal Kalderon 		chip_metal = qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_METAL);
11952d22bc83SMichal Kalderon 
11962d22bc83SMichal Kalderon 		param_str[0] = 'a' + (u8)chip_rev;
11972d22bc83SMichal Kalderon 		param_str[1] = '0' + (u8)chip_metal;
11982d22bc83SMichal Kalderon 	}
11992d22bc83SMichal Kalderon 
12002d22bc83SMichal Kalderon 	return qed_dump_str_param(dump_buf, dump, "chip-revision", param_str);
12012d22bc83SMichal Kalderon }
12022d22bc83SMichal Kalderon 
1203c965db44STomer Tayar /* Writes a section header to the specified buffer.
1204c965db44STomer Tayar  * Returns the dumped size in dwords.
1205c965db44STomer Tayar  */
1206c965db44STomer Tayar static u32 qed_dump_section_hdr(u32 *dump_buf,
1207c965db44STomer Tayar 				bool dump, const char *name, u32 num_params)
1208c965db44STomer Tayar {
1209c965db44STomer Tayar 	return qed_dump_num_param(dump_buf, dump, name, num_params);
1210c965db44STomer Tayar }
1211c965db44STomer Tayar 
1212c965db44STomer Tayar /* Writes the common global params to the specified buffer.
1213c965db44STomer Tayar  * Returns the dumped size in dwords.
1214c965db44STomer Tayar  */
1215c965db44STomer Tayar static u32 qed_dump_common_global_params(struct qed_hwfn *p_hwfn,
1216c965db44STomer Tayar 					 struct qed_ptt *p_ptt,
1217c965db44STomer Tayar 					 u32 *dump_buf,
1218c965db44STomer Tayar 					 bool dump,
1219c965db44STomer Tayar 					 u8 num_specific_global_params)
1220c965db44STomer Tayar {
1221c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1222c965db44STomer Tayar 	u32 offset = 0;
12237b6859fbSMintz, Yuval 	u8 num_params;
1224c965db44STomer Tayar 
12257b6859fbSMintz, Yuval 	/* Dump global params section header */
12262d22bc83SMichal Kalderon 	num_params = NUM_COMMON_GLOBAL_PARAMS + num_specific_global_params +
12272d22bc83SMichal Kalderon 		(dev_data->chip_id == CHIP_BB ? 1 : 0);
1228c965db44STomer Tayar 	offset += qed_dump_section_hdr(dump_buf + offset,
1229be086e7cSMintz, Yuval 				       dump, "global_params", num_params);
1230c965db44STomer Tayar 
1231c965db44STomer Tayar 	/* Store params */
1232c965db44STomer Tayar 	offset += qed_dump_fw_ver_param(p_hwfn, p_ptt, dump_buf + offset, dump);
1233c965db44STomer Tayar 	offset += qed_dump_mfw_ver_param(p_hwfn,
1234c965db44STomer Tayar 					 p_ptt, dump_buf + offset, dump);
12352d22bc83SMichal Kalderon 	offset += qed_dump_chip_revision_param(p_hwfn,
12362d22bc83SMichal Kalderon 					       p_ptt, dump_buf + offset, dump);
1237c965db44STomer Tayar 	offset += qed_dump_num_param(dump_buf + offset,
1238c965db44STomer Tayar 				     dump, "tools-version", TOOLS_VERSION);
1239c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset,
1240c965db44STomer Tayar 				     dump,
1241c965db44STomer Tayar 				     "chip",
1242c965db44STomer Tayar 				     s_chip_defs[dev_data->chip_id].name);
1243c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset,
1244c965db44STomer Tayar 				     dump,
1245c965db44STomer Tayar 				     "platform",
12462d22bc83SMichal Kalderon 				     s_hw_type_defs[dev_data->hw_type].name);
12472d22bc83SMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
12482d22bc83SMichal Kalderon 				     dump, "pci-func", p_hwfn->abs_pf_id);
12492d22bc83SMichal Kalderon 	if (dev_data->chip_id == CHIP_BB)
12502d22bc83SMichal Kalderon 		offset += qed_dump_num_param(dump_buf + offset,
12512d22bc83SMichal Kalderon 					     dump, "path", QED_PATH_ID(p_hwfn));
12527b6859fbSMintz, Yuval 
1253c965db44STomer Tayar 	return offset;
1254c965db44STomer Tayar }
1255c965db44STomer Tayar 
12567b6859fbSMintz, Yuval /* Writes the "last" section (including CRC) to the specified buffer at the
12577b6859fbSMintz, Yuval  * given offset. Returns the dumped size in dwords.
1258c965db44STomer Tayar  */
1259da090917STomer Tayar static u32 qed_dump_last_section(u32 *dump_buf, u32 offset, bool dump)
1260c965db44STomer Tayar {
12617b6859fbSMintz, Yuval 	u32 start_offset = offset;
1262c965db44STomer Tayar 
1263c965db44STomer Tayar 	/* Dump CRC section header */
1264c965db44STomer Tayar 	offset += qed_dump_section_hdr(dump_buf + offset, dump, "last", 0);
1265c965db44STomer Tayar 
12667b6859fbSMintz, Yuval 	/* Calculate CRC32 and add it to the dword after the "last" section */
1267c965db44STomer Tayar 	if (dump)
12687b6859fbSMintz, Yuval 		*(dump_buf + offset) = ~crc32(0xffffffff,
12697b6859fbSMintz, Yuval 					      (u8 *)dump_buf,
1270c965db44STomer Tayar 					      DWORDS_TO_BYTES(offset));
12717b6859fbSMintz, Yuval 
1272c965db44STomer Tayar 	offset++;
12737b6859fbSMintz, Yuval 
1274c965db44STomer Tayar 	return offset - start_offset;
1275c965db44STomer Tayar }
1276c965db44STomer Tayar 
1277c965db44STomer Tayar /* Update blocks reset state  */
1278c965db44STomer Tayar static void qed_update_blocks_reset_state(struct qed_hwfn *p_hwfn,
1279c965db44STomer Tayar 					  struct qed_ptt *p_ptt)
1280c965db44STomer Tayar {
1281c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
12822d22bc83SMichal Kalderon 	u32 reg_val[NUM_DBG_RESET_REGS] = { 0 };
12832d22bc83SMichal Kalderon 	u8 rst_reg_id;
12842d22bc83SMichal Kalderon 	u32 blk_id;
1285c965db44STomer Tayar 
1286c965db44STomer Tayar 	/* Read reset registers */
12872d22bc83SMichal Kalderon 	for (rst_reg_id = 0; rst_reg_id < NUM_DBG_RESET_REGS; rst_reg_id++) {
12882d22bc83SMichal Kalderon 		const struct dbg_reset_reg *rst_reg;
12892d22bc83SMichal Kalderon 		bool rst_reg_removed;
12902d22bc83SMichal Kalderon 		u32 rst_reg_addr;
12912d22bc83SMichal Kalderon 
12922d22bc83SMichal Kalderon 		rst_reg = qed_get_dbg_reset_reg(p_hwfn, rst_reg_id);
12932d22bc83SMichal Kalderon 		rst_reg_removed = GET_FIELD(rst_reg->data,
12942d22bc83SMichal Kalderon 					    DBG_RESET_REG_IS_REMOVED);
12952d22bc83SMichal Kalderon 		rst_reg_addr = DWORDS_TO_BYTES(GET_FIELD(rst_reg->data,
12962d22bc83SMichal Kalderon 							 DBG_RESET_REG_ADDR));
12972d22bc83SMichal Kalderon 
12982d22bc83SMichal Kalderon 		if (!rst_reg_removed)
12992d22bc83SMichal Kalderon 			reg_val[rst_reg_id] = qed_rd(p_hwfn, p_ptt,
13002d22bc83SMichal Kalderon 						     rst_reg_addr);
13012d22bc83SMichal Kalderon 	}
1302c965db44STomer Tayar 
1303c965db44STomer Tayar 	/* Check if blocks are in reset */
13042d22bc83SMichal Kalderon 	for (blk_id = 0; blk_id < NUM_PHYS_BLOCKS; blk_id++) {
13052d22bc83SMichal Kalderon 		const struct dbg_block_chip *blk;
13062d22bc83SMichal Kalderon 		bool has_rst_reg;
13072d22bc83SMichal Kalderon 		bool is_removed;
13087b6859fbSMintz, Yuval 
13092d22bc83SMichal Kalderon 		blk = qed_get_dbg_block_per_chip(p_hwfn, (enum block_id)blk_id);
13102d22bc83SMichal Kalderon 		is_removed = GET_FIELD(blk->flags, DBG_BLOCK_CHIP_IS_REMOVED);
13112d22bc83SMichal Kalderon 		has_rst_reg = GET_FIELD(blk->flags,
13122d22bc83SMichal Kalderon 					DBG_BLOCK_CHIP_HAS_RESET_REG);
13132d22bc83SMichal Kalderon 
13142d22bc83SMichal Kalderon 		if (!is_removed && has_rst_reg)
13152d22bc83SMichal Kalderon 			dev_data->block_in_reset[blk_id] =
13162d22bc83SMichal Kalderon 			    !(reg_val[blk->reset_reg_id] &
13172d22bc83SMichal Kalderon 			      BIT(blk->reset_reg_bit_offset));
13187b6859fbSMintz, Yuval 	}
1319c965db44STomer Tayar }
1320c965db44STomer Tayar 
13212d22bc83SMichal Kalderon /* is_mode_match recursive function */
13222d22bc83SMichal Kalderon static bool qed_is_mode_match_rec(struct qed_hwfn *p_hwfn,
13232d22bc83SMichal Kalderon 				  u16 *modes_buf_offset, u8 rec_depth)
13242d22bc83SMichal Kalderon {
13252d22bc83SMichal Kalderon 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
13262d22bc83SMichal Kalderon 	u8 *dbg_array;
13272d22bc83SMichal Kalderon 	bool arg1, arg2;
13282d22bc83SMichal Kalderon 	u8 tree_val;
13292d22bc83SMichal Kalderon 
13302d22bc83SMichal Kalderon 	if (rec_depth > MAX_RECURSION_DEPTH) {
13312d22bc83SMichal Kalderon 		DP_NOTICE(p_hwfn,
13322d22bc83SMichal Kalderon 			  "Unexpected error: is_mode_match_rec exceeded the max recursion depth. This is probably due to a corrupt init/debug buffer.\n");
13332d22bc83SMichal Kalderon 		return false;
13342d22bc83SMichal Kalderon 	}
13352d22bc83SMichal Kalderon 
13362d22bc83SMichal Kalderon 	/* Get next element from modes tree buffer */
13372d22bc83SMichal Kalderon 	dbg_array = p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr;
13382d22bc83SMichal Kalderon 	tree_val = dbg_array[(*modes_buf_offset)++];
13392d22bc83SMichal Kalderon 
13402d22bc83SMichal Kalderon 	switch (tree_val) {
13412d22bc83SMichal Kalderon 	case INIT_MODE_OP_NOT:
13422d22bc83SMichal Kalderon 		return !qed_is_mode_match_rec(p_hwfn,
13432d22bc83SMichal Kalderon 					      modes_buf_offset, rec_depth + 1);
13442d22bc83SMichal Kalderon 	case INIT_MODE_OP_OR:
13452d22bc83SMichal Kalderon 	case INIT_MODE_OP_AND:
13462d22bc83SMichal Kalderon 		arg1 = qed_is_mode_match_rec(p_hwfn,
13472d22bc83SMichal Kalderon 					     modes_buf_offset, rec_depth + 1);
13482d22bc83SMichal Kalderon 		arg2 = qed_is_mode_match_rec(p_hwfn,
13492d22bc83SMichal Kalderon 					     modes_buf_offset, rec_depth + 1);
13502d22bc83SMichal Kalderon 		return (tree_val == INIT_MODE_OP_OR) ? (arg1 ||
13512d22bc83SMichal Kalderon 							arg2) : (arg1 && arg2);
13522d22bc83SMichal Kalderon 	default:
13532d22bc83SMichal Kalderon 		return dev_data->mode_enable[tree_val - MAX_INIT_MODE_OPS] > 0;
13542d22bc83SMichal Kalderon 	}
13552d22bc83SMichal Kalderon }
13562d22bc83SMichal Kalderon 
13572d22bc83SMichal Kalderon /* Returns true if the mode (specified using modes_buf_offset) is enabled */
13582d22bc83SMichal Kalderon static bool qed_is_mode_match(struct qed_hwfn *p_hwfn, u16 *modes_buf_offset)
13592d22bc83SMichal Kalderon {
13602d22bc83SMichal Kalderon 	return qed_is_mode_match_rec(p_hwfn, modes_buf_offset, 0);
13612d22bc83SMichal Kalderon }
13622d22bc83SMichal Kalderon 
1363c965db44STomer Tayar /* Enable / disable the Debug block */
1364c965db44STomer Tayar static void qed_bus_enable_dbg_block(struct qed_hwfn *p_hwfn,
1365c965db44STomer Tayar 				     struct qed_ptt *p_ptt, bool enable)
1366c965db44STomer Tayar {
1367c965db44STomer Tayar 	qed_wr(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON, enable ? 1 : 0);
1368c965db44STomer Tayar }
1369c965db44STomer Tayar 
1370c965db44STomer Tayar /* Resets the Debug block */
1371c965db44STomer Tayar static void qed_bus_reset_dbg_block(struct qed_hwfn *p_hwfn,
1372c965db44STomer Tayar 				    struct qed_ptt *p_ptt)
1373c965db44STomer Tayar {
13742d22bc83SMichal Kalderon 	u32 reset_reg_addr, old_reset_reg_val, new_reset_reg_val;
13752d22bc83SMichal Kalderon 	const struct dbg_reset_reg *reset_reg;
13762d22bc83SMichal Kalderon 	const struct dbg_block_chip *block;
1377c965db44STomer Tayar 
13782d22bc83SMichal Kalderon 	block = qed_get_dbg_block_per_chip(p_hwfn, BLOCK_DBG);
13792d22bc83SMichal Kalderon 	reset_reg = qed_get_dbg_reset_reg(p_hwfn, block->reset_reg_id);
13802d22bc83SMichal Kalderon 	reset_reg_addr =
13812d22bc83SMichal Kalderon 	    DWORDS_TO_BYTES(GET_FIELD(reset_reg->data, DBG_RESET_REG_ADDR));
13822d22bc83SMichal Kalderon 
13832d22bc83SMichal Kalderon 	old_reset_reg_val = qed_rd(p_hwfn, p_ptt, reset_reg_addr);
13847b6859fbSMintz, Yuval 	new_reset_reg_val =
13852d22bc83SMichal Kalderon 	    old_reset_reg_val & ~BIT(block->reset_reg_bit_offset);
1386c965db44STomer Tayar 
13872d22bc83SMichal Kalderon 	qed_wr(p_hwfn, p_ptt, reset_reg_addr, new_reset_reg_val);
13882d22bc83SMichal Kalderon 	qed_wr(p_hwfn, p_ptt, reset_reg_addr, old_reset_reg_val);
1389c965db44STomer Tayar }
1390c965db44STomer Tayar 
13917b6859fbSMintz, Yuval /* Enable / disable Debug Bus clients according to the specified mask
13927b6859fbSMintz, Yuval  * (1 = enable, 0 = disable).
1393c965db44STomer Tayar  */
1394c965db44STomer Tayar static void qed_bus_enable_clients(struct qed_hwfn *p_hwfn,
1395c965db44STomer Tayar 				   struct qed_ptt *p_ptt, u32 client_mask)
1396c965db44STomer Tayar {
1397c965db44STomer Tayar 	qed_wr(p_hwfn, p_ptt, DBG_REG_CLIENT_ENABLE, client_mask);
1398c965db44STomer Tayar }
1399c965db44STomer Tayar 
14002d22bc83SMichal Kalderon static void qed_bus_config_dbg_line(struct qed_hwfn *p_hwfn,
14012d22bc83SMichal Kalderon 				    struct qed_ptt *p_ptt,
14022d22bc83SMichal Kalderon 				    enum block_id block_id,
14032d22bc83SMichal Kalderon 				    u8 line_id,
14042d22bc83SMichal Kalderon 				    u8 enable_mask,
14052d22bc83SMichal Kalderon 				    u8 right_shift,
14062d22bc83SMichal Kalderon 				    u8 force_valid_mask, u8 force_frame_mask)
14072d22bc83SMichal Kalderon {
14082d22bc83SMichal Kalderon 	const struct dbg_block_chip *block =
14092d22bc83SMichal Kalderon 		qed_get_dbg_block_per_chip(p_hwfn, block_id);
14102d22bc83SMichal Kalderon 
14112d22bc83SMichal Kalderon 	qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_select_reg_addr),
14122d22bc83SMichal Kalderon 	       line_id);
14132d22bc83SMichal Kalderon 	qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_dword_enable_reg_addr),
14142d22bc83SMichal Kalderon 	       enable_mask);
14152d22bc83SMichal Kalderon 	qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_shift_reg_addr),
14162d22bc83SMichal Kalderon 	       right_shift);
14172d22bc83SMichal Kalderon 	qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_force_valid_reg_addr),
14182d22bc83SMichal Kalderon 	       force_valid_mask);
14192d22bc83SMichal Kalderon 	qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_force_frame_reg_addr),
14202d22bc83SMichal Kalderon 	       force_frame_mask);
14212d22bc83SMichal Kalderon }
14222d22bc83SMichal Kalderon 
14232d22bc83SMichal Kalderon /* Disable debug bus in all blocks */
14242d22bc83SMichal Kalderon static void qed_bus_disable_blocks(struct qed_hwfn *p_hwfn,
14252d22bc83SMichal Kalderon 				   struct qed_ptt *p_ptt)
1426c965db44STomer Tayar {
1427c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
14282d22bc83SMichal Kalderon 	u32 block_id;
14297b6859fbSMintz, Yuval 
14302d22bc83SMichal Kalderon 	/* Disable all blocks */
14312d22bc83SMichal Kalderon 	for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
14322d22bc83SMichal Kalderon 		const struct dbg_block_chip *block_per_chip =
14332d22bc83SMichal Kalderon 		    qed_get_dbg_block_per_chip(p_hwfn,
14342d22bc83SMichal Kalderon 					       (enum block_id)block_id);
1435c965db44STomer Tayar 
14362d22bc83SMichal Kalderon 		if (GET_FIELD(block_per_chip->flags,
14372d22bc83SMichal Kalderon 			      DBG_BLOCK_CHIP_IS_REMOVED) ||
14382d22bc83SMichal Kalderon 		    dev_data->block_in_reset[block_id])
14392d22bc83SMichal Kalderon 			continue;
14402d22bc83SMichal Kalderon 
14412d22bc83SMichal Kalderon 		/* Disable debug bus */
14422d22bc83SMichal Kalderon 		if (GET_FIELD(block_per_chip->flags,
14432d22bc83SMichal Kalderon 			      DBG_BLOCK_CHIP_HAS_DBG_BUS)) {
14442d22bc83SMichal Kalderon 			u32 dbg_en_addr =
14452d22bc83SMichal Kalderon 				block_per_chip->dbg_dword_enable_reg_addr;
14462d22bc83SMichal Kalderon 			u16 modes_buf_offset =
14472d22bc83SMichal Kalderon 			    GET_FIELD(block_per_chip->dbg_bus_mode.data,
14482d22bc83SMichal Kalderon 				      DBG_MODE_HDR_MODES_BUF_OFFSET);
14492d22bc83SMichal Kalderon 			bool eval_mode =
14502d22bc83SMichal Kalderon 			    GET_FIELD(block_per_chip->dbg_bus_mode.data,
14512d22bc83SMichal Kalderon 				      DBG_MODE_HDR_EVAL_MODE) > 0;
14522d22bc83SMichal Kalderon 
14532d22bc83SMichal Kalderon 			if (!eval_mode ||
14542d22bc83SMichal Kalderon 			    qed_is_mode_match(p_hwfn, &modes_buf_offset))
14552d22bc83SMichal Kalderon 				qed_wr(p_hwfn, p_ptt,
14562d22bc83SMichal Kalderon 				       DWORDS_TO_BYTES(dbg_en_addr),
14572d22bc83SMichal Kalderon 				       0);
14582d22bc83SMichal Kalderon 		}
1459c965db44STomer Tayar 	}
1460c965db44STomer Tayar }
1461c965db44STomer Tayar 
1462c965db44STomer Tayar /* Returns true if the specified entity (indicated by GRC param) should be
1463c965db44STomer Tayar  * included in the dump, false otherwise.
1464c965db44STomer Tayar  */
1465c965db44STomer Tayar static bool qed_grc_is_included(struct qed_hwfn *p_hwfn,
1466c965db44STomer Tayar 				enum dbg_grc_params grc_param)
1467c965db44STomer Tayar {
1468c965db44STomer Tayar 	return qed_grc_get_param(p_hwfn, grc_param) > 0;
1469c965db44STomer Tayar }
1470c965db44STomer Tayar 
14712d22bc83SMichal Kalderon /* Returns the storm_id that matches the specified Storm letter,
14722d22bc83SMichal Kalderon  * or MAX_DBG_STORMS if invalid storm letter.
14732d22bc83SMichal Kalderon  */
14742d22bc83SMichal Kalderon static enum dbg_storms qed_get_id_from_letter(char storm_letter)
14752d22bc83SMichal Kalderon {
14762d22bc83SMichal Kalderon 	u8 storm_id;
14772d22bc83SMichal Kalderon 
14782d22bc83SMichal Kalderon 	for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++)
14792d22bc83SMichal Kalderon 		if (s_storm_defs[storm_id].letter == storm_letter)
14802d22bc83SMichal Kalderon 			return (enum dbg_storms)storm_id;
14812d22bc83SMichal Kalderon 
14822d22bc83SMichal Kalderon 	return MAX_DBG_STORMS;
14832d22bc83SMichal Kalderon }
14842d22bc83SMichal Kalderon 
1485c965db44STomer Tayar /* Returns true of the specified Storm should be included in the dump, false
1486c965db44STomer Tayar  * otherwise.
1487c965db44STomer Tayar  */
1488c965db44STomer Tayar static bool qed_grc_is_storm_included(struct qed_hwfn *p_hwfn,
1489c965db44STomer Tayar 				      enum dbg_storms storm)
1490c965db44STomer Tayar {
1491c965db44STomer Tayar 	return qed_grc_get_param(p_hwfn, (enum dbg_grc_params)storm) > 0;
1492c965db44STomer Tayar }
1493c965db44STomer Tayar 
1494c965db44STomer Tayar /* Returns true if the specified memory should be included in the dump, false
1495c965db44STomer Tayar  * otherwise.
1496c965db44STomer Tayar  */
1497c965db44STomer Tayar static bool qed_grc_is_mem_included(struct qed_hwfn *p_hwfn,
1498c965db44STomer Tayar 				    enum block_id block_id, u8 mem_group_id)
1499c965db44STomer Tayar {
15002d22bc83SMichal Kalderon 	const struct dbg_block *block;
1501c965db44STomer Tayar 	u8 i;
1502c965db44STomer Tayar 
15032d22bc83SMichal Kalderon 	block = get_dbg_block(p_hwfn, block_id);
15042d22bc83SMichal Kalderon 
15052d22bc83SMichal Kalderon 	/* If the block is associated with a Storm, check Storm match */
15062d22bc83SMichal Kalderon 	if (block->associated_storm_letter) {
15072d22bc83SMichal Kalderon 		enum dbg_storms associated_storm_id =
15082d22bc83SMichal Kalderon 		    qed_get_id_from_letter(block->associated_storm_letter);
15092d22bc83SMichal Kalderon 
15102d22bc83SMichal Kalderon 		if (associated_storm_id == MAX_DBG_STORMS ||
15112d22bc83SMichal Kalderon 		    !qed_grc_is_storm_included(p_hwfn, associated_storm_id))
1512c965db44STomer Tayar 			return false;
15132d22bc83SMichal Kalderon 	}
1514c965db44STomer Tayar 
15157b6859fbSMintz, Yuval 	for (i = 0; i < NUM_BIG_RAM_TYPES; i++) {
15167b6859fbSMintz, Yuval 		struct big_ram_defs *big_ram = &s_big_ram_defs[i];
1517c965db44STomer Tayar 
15187b6859fbSMintz, Yuval 		if (mem_group_id == big_ram->mem_group_id ||
15197b6859fbSMintz, Yuval 		    mem_group_id == big_ram->ram_mem_group_id)
15207b6859fbSMintz, Yuval 			return qed_grc_is_included(p_hwfn, big_ram->grc_param);
15217b6859fbSMintz, Yuval 	}
15227b6859fbSMintz, Yuval 
15237b6859fbSMintz, Yuval 	switch (mem_group_id) {
15247b6859fbSMintz, Yuval 	case MEM_GROUP_PXP_ILT:
15257b6859fbSMintz, Yuval 	case MEM_GROUP_PXP_MEM:
15267b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PXP);
15277b6859fbSMintz, Yuval 	case MEM_GROUP_RAM:
15287b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RAM);
15297b6859fbSMintz, Yuval 	case MEM_GROUP_PBUF:
15307b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PBUF);
15317b6859fbSMintz, Yuval 	case MEM_GROUP_CAU_MEM:
15327b6859fbSMintz, Yuval 	case MEM_GROUP_CAU_SB:
15337b6859fbSMintz, Yuval 	case MEM_GROUP_CAU_PI:
15347b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU);
15352d22bc83SMichal Kalderon 	case MEM_GROUP_CAU_MEM_EXT:
15362d22bc83SMichal Kalderon 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU_EXT);
15377b6859fbSMintz, Yuval 	case MEM_GROUP_QM_MEM:
15387b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_QM);
15397b6859fbSMintz, Yuval 	case MEM_GROUP_CFC_MEM:
15407b6859fbSMintz, Yuval 	case MEM_GROUP_CONN_CFC_MEM:
15417b6859fbSMintz, Yuval 	case MEM_GROUP_TASK_CFC_MEM:
1542da090917STomer Tayar 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CFC) ||
1543da090917STomer Tayar 		       qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX);
15442d22bc83SMichal Kalderon 	case MEM_GROUP_DORQ_MEM:
15452d22bc83SMichal Kalderon 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DORQ);
15467b6859fbSMintz, Yuval 	case MEM_GROUP_IGU_MEM:
15477b6859fbSMintz, Yuval 	case MEM_GROUP_IGU_MSIX:
15487b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IGU);
15497b6859fbSMintz, Yuval 	case MEM_GROUP_MULD_MEM:
15507b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MULD);
15517b6859fbSMintz, Yuval 	case MEM_GROUP_PRS_MEM:
15527b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PRS);
15537b6859fbSMintz, Yuval 	case MEM_GROUP_DMAE_MEM:
15547b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DMAE);
15557b6859fbSMintz, Yuval 	case MEM_GROUP_TM_MEM:
15567b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_TM);
15577b6859fbSMintz, Yuval 	case MEM_GROUP_SDM_MEM:
15587b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_SDM);
15597b6859fbSMintz, Yuval 	case MEM_GROUP_TDIF_CTX:
15607b6859fbSMintz, Yuval 	case MEM_GROUP_RDIF_CTX:
15617b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DIF);
15627b6859fbSMintz, Yuval 	case MEM_GROUP_CM_MEM:
15637b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM);
15647b6859fbSMintz, Yuval 	case MEM_GROUP_IOR:
15657b6859fbSMintz, Yuval 		return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IOR);
15667b6859fbSMintz, Yuval 	default:
1567c965db44STomer Tayar 		return true;
1568c965db44STomer Tayar 	}
15697b6859fbSMintz, Yuval }
1570c965db44STomer Tayar 
1571c965db44STomer Tayar /* Stalls all Storms */
1572c965db44STomer Tayar static void qed_grc_stall_storms(struct qed_hwfn *p_hwfn,
1573c965db44STomer Tayar 				 struct qed_ptt *p_ptt, bool stall)
1574c965db44STomer Tayar {
15757b6859fbSMintz, Yuval 	u32 reg_addr;
1576c965db44STomer Tayar 	u8 storm_id;
1577c965db44STomer Tayar 
1578c965db44STomer Tayar 	for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
15797b6859fbSMintz, Yuval 		if (!qed_grc_is_storm_included(p_hwfn,
15807b6859fbSMintz, Yuval 					       (enum dbg_storms)storm_id))
15817b6859fbSMintz, Yuval 			continue;
1582c965db44STomer Tayar 
15837b6859fbSMintz, Yuval 		reg_addr = s_storm_defs[storm_id].sem_fast_mem_addr +
15847b6859fbSMintz, Yuval 		    SEM_FAST_REG_STALL_0_BB_K2;
15857b6859fbSMintz, Yuval 		qed_wr(p_hwfn, p_ptt, reg_addr, stall ? 1 : 0);
1586c965db44STomer Tayar 	}
1587c965db44STomer Tayar 
1588c965db44STomer Tayar 	msleep(STALL_DELAY_MS);
1589c965db44STomer Tayar }
1590c965db44STomer Tayar 
15912d22bc83SMichal Kalderon /* Takes all blocks out of reset. If rbc_only is true, only RBC clients are
15922d22bc83SMichal Kalderon  * taken out of reset.
15932d22bc83SMichal Kalderon  */
1594c965db44STomer Tayar static void qed_grc_unreset_blocks(struct qed_hwfn *p_hwfn,
15952d22bc83SMichal Kalderon 				   struct qed_ptt *p_ptt, bool rbc_only)
1596c965db44STomer Tayar {
1597c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
15982d22bc83SMichal Kalderon 	u8 chip_id = dev_data->chip_id;
15992d22bc83SMichal Kalderon 	u32 i;
16002d22bc83SMichal Kalderon 
16012d22bc83SMichal Kalderon 	/* Take RBCs out of reset */
16022d22bc83SMichal Kalderon 	for (i = 0; i < ARRAY_SIZE(s_rbc_reset_defs); i++)
16032d22bc83SMichal Kalderon 		if (s_rbc_reset_defs[i].reset_val[dev_data->chip_id])
16042d22bc83SMichal Kalderon 			qed_wr(p_hwfn,
16052d22bc83SMichal Kalderon 			       p_ptt,
16062d22bc83SMichal Kalderon 			       s_rbc_reset_defs[i].reset_reg_addr +
16072d22bc83SMichal Kalderon 			       RESET_REG_UNRESET_OFFSET,
16082d22bc83SMichal Kalderon 			       s_rbc_reset_defs[i].reset_val[chip_id]);
16092d22bc83SMichal Kalderon 
16102d22bc83SMichal Kalderon 	if (!rbc_only) {
16112d22bc83SMichal Kalderon 		u32 reg_val[NUM_DBG_RESET_REGS] = { 0 };
16122d22bc83SMichal Kalderon 		u8 reset_reg_id;
16132d22bc83SMichal Kalderon 		u32 block_id;
1614c965db44STomer Tayar 
1615c965db44STomer Tayar 		/* Fill reset regs values */
16162d22bc83SMichal Kalderon 		for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) {
16172d22bc83SMichal Kalderon 			bool is_removed, has_reset_reg, unreset_before_dump;
16182d22bc83SMichal Kalderon 			const struct dbg_block_chip *block;
16197b6859fbSMintz, Yuval 
16202d22bc83SMichal Kalderon 			block = qed_get_dbg_block_per_chip(p_hwfn,
16212d22bc83SMichal Kalderon 							   (enum block_id)
16222d22bc83SMichal Kalderon 							   block_id);
16232d22bc83SMichal Kalderon 			is_removed =
16242d22bc83SMichal Kalderon 			    GET_FIELD(block->flags, DBG_BLOCK_CHIP_IS_REMOVED);
16252d22bc83SMichal Kalderon 			has_reset_reg =
16262d22bc83SMichal Kalderon 			    GET_FIELD(block->flags,
16272d22bc83SMichal Kalderon 				      DBG_BLOCK_CHIP_HAS_RESET_REG);
16282d22bc83SMichal Kalderon 			unreset_before_dump =
16292d22bc83SMichal Kalderon 			    GET_FIELD(block->flags,
16302d22bc83SMichal Kalderon 				      DBG_BLOCK_CHIP_UNRESET_BEFORE_DUMP);
16312d22bc83SMichal Kalderon 
16322d22bc83SMichal Kalderon 			if (!is_removed && has_reset_reg && unreset_before_dump)
16332d22bc83SMichal Kalderon 				reg_val[block->reset_reg_id] |=
16342d22bc83SMichal Kalderon 				    BIT(block->reset_reg_bit_offset);
16357b6859fbSMintz, Yuval 		}
1636c965db44STomer Tayar 
1637c965db44STomer Tayar 		/* Write reset registers */
16382d22bc83SMichal Kalderon 		for (reset_reg_id = 0; reset_reg_id < NUM_DBG_RESET_REGS;
16392d22bc83SMichal Kalderon 		     reset_reg_id++) {
16402d22bc83SMichal Kalderon 			const struct dbg_reset_reg *reset_reg;
16412d22bc83SMichal Kalderon 			u32 reset_reg_addr;
16422d22bc83SMichal Kalderon 
16432d22bc83SMichal Kalderon 			reset_reg = qed_get_dbg_reset_reg(p_hwfn, reset_reg_id);
16442d22bc83SMichal Kalderon 
16452d22bc83SMichal Kalderon 			if (GET_FIELD
16462d22bc83SMichal Kalderon 			    (reset_reg->data, DBG_RESET_REG_IS_REMOVED))
16477b6859fbSMintz, Yuval 				continue;
16487b6859fbSMintz, Yuval 
16492d22bc83SMichal Kalderon 			if (reg_val[reset_reg_id]) {
16502d22bc83SMichal Kalderon 				reset_reg_addr =
16512d22bc83SMichal Kalderon 				    GET_FIELD(reset_reg->data,
16522d22bc83SMichal Kalderon 					      DBG_RESET_REG_ADDR);
1653c965db44STomer Tayar 				qed_wr(p_hwfn,
1654c965db44STomer Tayar 				       p_ptt,
16552d22bc83SMichal Kalderon 				       DWORDS_TO_BYTES(reset_reg_addr) +
16562d22bc83SMichal Kalderon 				       RESET_REG_UNRESET_OFFSET,
16572d22bc83SMichal Kalderon 				       reg_val[reset_reg_id]);
16582d22bc83SMichal Kalderon 			}
16592d22bc83SMichal Kalderon 		}
1660c965db44STomer Tayar 	}
1661c965db44STomer Tayar }
1662c965db44STomer Tayar 
1663be086e7cSMintz, Yuval /* Returns the attention block data of the specified block */
1664c965db44STomer Tayar static const struct dbg_attn_block_type_data *
16652d22bc83SMichal Kalderon qed_get_block_attn_data(struct qed_hwfn *p_hwfn,
16662d22bc83SMichal Kalderon 			enum block_id block_id, enum dbg_attn_type attn_type)
1667c965db44STomer Tayar {
1668c965db44STomer Tayar 	const struct dbg_attn_block *base_attn_block_arr =
1669c965db44STomer Tayar 	    (const struct dbg_attn_block *)
16702d22bc83SMichal Kalderon 	    p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr;
1671c965db44STomer Tayar 
1672c965db44STomer Tayar 	return &base_attn_block_arr[block_id].per_type_data[attn_type];
1673c965db44STomer Tayar }
1674c965db44STomer Tayar 
1675c965db44STomer Tayar /* Returns the attention registers of the specified block */
1676c965db44STomer Tayar static const struct dbg_attn_reg *
16772d22bc83SMichal Kalderon qed_get_block_attn_regs(struct qed_hwfn *p_hwfn,
16782d22bc83SMichal Kalderon 			enum block_id block_id, enum dbg_attn_type attn_type,
1679c965db44STomer Tayar 			u8 *num_attn_regs)
1680c965db44STomer Tayar {
1681c965db44STomer Tayar 	const struct dbg_attn_block_type_data *block_type_data =
16822d22bc83SMichal Kalderon 	    qed_get_block_attn_data(p_hwfn, block_id, attn_type);
1683c965db44STomer Tayar 
1684c965db44STomer Tayar 	*num_attn_regs = block_type_data->num_regs;
16857b6859fbSMintz, Yuval 
16862d22bc83SMichal Kalderon 	return (const struct dbg_attn_reg *)
16872d22bc83SMichal Kalderon 		p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr +
16882d22bc83SMichal Kalderon 		block_type_data->regs_offset;
1689c965db44STomer Tayar }
1690c965db44STomer Tayar 
1691c965db44STomer Tayar /* For each block, clear the status of all parities */
1692c965db44STomer Tayar static void qed_grc_clear_all_prty(struct qed_hwfn *p_hwfn,
1693c965db44STomer Tayar 				   struct qed_ptt *p_ptt)
1694c965db44STomer Tayar {
1695c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
16967b6859fbSMintz, Yuval 	const struct dbg_attn_reg *attn_reg_arr;
1697c965db44STomer Tayar 	u8 reg_idx, num_attn_regs;
1698c965db44STomer Tayar 	u32 block_id;
1699c965db44STomer Tayar 
17002d22bc83SMichal Kalderon 	for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) {
1701c965db44STomer Tayar 		if (dev_data->block_in_reset[block_id])
1702c965db44STomer Tayar 			continue;
1703c965db44STomer Tayar 
17042d22bc83SMichal Kalderon 		attn_reg_arr = qed_get_block_attn_regs(p_hwfn,
17052d22bc83SMichal Kalderon 						       (enum block_id)block_id,
1706c965db44STomer Tayar 						       ATTN_TYPE_PARITY,
1707c965db44STomer Tayar 						       &num_attn_regs);
17087b6859fbSMintz, Yuval 
1709c965db44STomer Tayar 		for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
1710c965db44STomer Tayar 			const struct dbg_attn_reg *reg_data =
1711c965db44STomer Tayar 				&attn_reg_arr[reg_idx];
17127b6859fbSMintz, Yuval 			u16 modes_buf_offset;
17137b6859fbSMintz, Yuval 			bool eval_mode;
1714c965db44STomer Tayar 
1715c965db44STomer Tayar 			/* Check mode */
17167b6859fbSMintz, Yuval 			eval_mode = GET_FIELD(reg_data->mode.data,
1717c965db44STomer Tayar 					      DBG_MODE_HDR_EVAL_MODE) > 0;
17187b6859fbSMintz, Yuval 			modes_buf_offset =
1719c965db44STomer Tayar 				GET_FIELD(reg_data->mode.data,
1720c965db44STomer Tayar 					  DBG_MODE_HDR_MODES_BUF_OFFSET);
1721c965db44STomer Tayar 
17227b6859fbSMintz, Yuval 			/* If Mode match: clear parity status */
1723c965db44STomer Tayar 			if (!eval_mode ||
1724c965db44STomer Tayar 			    qed_is_mode_match(p_hwfn, &modes_buf_offset))
1725c965db44STomer Tayar 				qed_rd(p_hwfn, p_ptt,
1726c965db44STomer Tayar 				       DWORDS_TO_BYTES(reg_data->
1727c965db44STomer Tayar 						       sts_clr_address));
1728c965db44STomer Tayar 		}
1729c965db44STomer Tayar 	}
1730c965db44STomer Tayar }
1731c965db44STomer Tayar 
1732c965db44STomer Tayar /* Dumps GRC registers section header. Returns the dumped size in dwords.
17332d22bc83SMichal Kalderon  * the following parameters are dumped:
17347b6859fbSMintz, Yuval  * - count: no. of dumped entries
1735d52c89f1SMichal Kalderon  * - split_type: split type
1736d52c89f1SMichal Kalderon  * - split_id: split ID (dumped only if split_id != SPLIT_TYPE_NONE)
17372d22bc83SMichal Kalderon  * - reg_type_name: register type name (dumped only if reg_type_name != NULL)
1738c965db44STomer Tayar  */
1739c965db44STomer Tayar static u32 qed_grc_dump_regs_hdr(u32 *dump_buf,
1740c965db44STomer Tayar 				 bool dump,
1741c965db44STomer Tayar 				 u32 num_reg_entries,
1742d52c89f1SMichal Kalderon 				 enum init_split_types split_type,
17432d22bc83SMichal Kalderon 				 u8 split_id, const char *reg_type_name)
1744c965db44STomer Tayar {
1745d52c89f1SMichal Kalderon 	u8 num_params = 2 +
17462d22bc83SMichal Kalderon 	    (split_type != SPLIT_TYPE_NONE ? 1 : 0) + (reg_type_name ? 1 : 0);
1747c965db44STomer Tayar 	u32 offset = 0;
1748c965db44STomer Tayar 
1749c965db44STomer Tayar 	offset += qed_dump_section_hdr(dump_buf + offset,
1750c965db44STomer Tayar 				       dump, "grc_regs", num_params);
1751c965db44STomer Tayar 	offset += qed_dump_num_param(dump_buf + offset,
1752c965db44STomer Tayar 				     dump, "count", num_reg_entries);
1753c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset,
1754d52c89f1SMichal Kalderon 				     dump, "split",
1755d52c89f1SMichal Kalderon 				     s_split_type_defs[split_type].name);
1756d52c89f1SMichal Kalderon 	if (split_type != SPLIT_TYPE_NONE)
1757c965db44STomer Tayar 		offset += qed_dump_num_param(dump_buf + offset,
1758c965db44STomer Tayar 					     dump, "id", split_id);
17592d22bc83SMichal Kalderon 	if (reg_type_name)
1760c965db44STomer Tayar 		offset += qed_dump_str_param(dump_buf + offset,
17612d22bc83SMichal Kalderon 					     dump, "type", reg_type_name);
17627b6859fbSMintz, Yuval 
1763c965db44STomer Tayar 	return offset;
1764c965db44STomer Tayar }
1765c965db44STomer Tayar 
1766da090917STomer Tayar /* Reads the specified registers into the specified buffer.
1767da090917STomer Tayar  * The addr and len arguments are specified in dwords.
1768da090917STomer Tayar  */
1769da090917STomer Tayar void qed_read_regs(struct qed_hwfn *p_hwfn,
1770da090917STomer Tayar 		   struct qed_ptt *p_ptt, u32 *buf, u32 addr, u32 len)
1771da090917STomer Tayar {
1772da090917STomer Tayar 	u32 i;
1773da090917STomer Tayar 
1774da090917STomer Tayar 	for (i = 0; i < len; i++)
1775da090917STomer Tayar 		buf[i] = qed_rd(p_hwfn, p_ptt, DWORDS_TO_BYTES(addr + i));
1776da090917STomer Tayar }
1777da090917STomer Tayar 
1778be086e7cSMintz, Yuval /* Dumps the GRC registers in the specified address range.
1779be086e7cSMintz, Yuval  * Returns the dumped size in dwords.
17807b6859fbSMintz, Yuval  * The addr and len arguments are specified in dwords.
1781be086e7cSMintz, Yuval  */
1782be086e7cSMintz, Yuval static u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn,
17837b6859fbSMintz, Yuval 				   struct qed_ptt *p_ptt,
17847b6859fbSMintz, Yuval 				   u32 *dump_buf,
1785d52c89f1SMichal Kalderon 				   bool dump, u32 addr, u32 len, bool wide_bus,
1786d52c89f1SMichal Kalderon 				   enum init_split_types split_type,
1787d52c89f1SMichal Kalderon 				   u8 split_id)
1788be086e7cSMintz, Yuval {
1789da090917STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1790d52c89f1SMichal Kalderon 	u8 port_id = 0, pf_id = 0, vf_id = 0, fid = 0;
17912d22bc83SMichal Kalderon 	bool read_using_dmae = false;
17922d22bc83SMichal Kalderon 	u32 thresh;
1793be086e7cSMintz, Yuval 
17947b6859fbSMintz, Yuval 	if (!dump)
17957b6859fbSMintz, Yuval 		return len;
17967b6859fbSMintz, Yuval 
1797d52c89f1SMichal Kalderon 	switch (split_type) {
1798d52c89f1SMichal Kalderon 	case SPLIT_TYPE_PORT:
1799d52c89f1SMichal Kalderon 		port_id = split_id;
1800d52c89f1SMichal Kalderon 		break;
1801d52c89f1SMichal Kalderon 	case SPLIT_TYPE_PF:
1802d52c89f1SMichal Kalderon 		pf_id = split_id;
1803d52c89f1SMichal Kalderon 		break;
1804d52c89f1SMichal Kalderon 	case SPLIT_TYPE_PORT_PF:
1805d52c89f1SMichal Kalderon 		port_id = split_id / dev_data->num_pfs_per_port;
1806d52c89f1SMichal Kalderon 		pf_id = port_id + dev_data->num_ports *
1807d52c89f1SMichal Kalderon 		    (split_id % dev_data->num_pfs_per_port);
1808d52c89f1SMichal Kalderon 		break;
1809d52c89f1SMichal Kalderon 	case SPLIT_TYPE_VF:
1810d52c89f1SMichal Kalderon 		vf_id = split_id;
1811d52c89f1SMichal Kalderon 		break;
1812d52c89f1SMichal Kalderon 	default:
1813d52c89f1SMichal Kalderon 		break;
1814d52c89f1SMichal Kalderon 	}
1815d52c89f1SMichal Kalderon 
1816da090917STomer Tayar 	/* Try reading using DMAE */
18172d22bc83SMichal Kalderon 	if (dev_data->use_dmae && split_type != SPLIT_TYPE_VF &&
18182d22bc83SMichal Kalderon 	    (len >= s_hw_type_defs[dev_data->hw_type].dmae_thresh ||
18192d22bc83SMichal Kalderon 	     (PROTECT_WIDE_BUS && wide_bus))) {
18202d22bc83SMichal Kalderon 		struct qed_dmae_params dmae_params;
18212d22bc83SMichal Kalderon 
18222d22bc83SMichal Kalderon 		/* Set DMAE params */
18232d22bc83SMichal Kalderon 		memset(&dmae_params, 0, sizeof(dmae_params));
18242d22bc83SMichal Kalderon 		SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_COMPLETION_DST, 1);
18252d22bc83SMichal Kalderon 		switch (split_type) {
18262d22bc83SMichal Kalderon 		case SPLIT_TYPE_PORT:
18272d22bc83SMichal Kalderon 			SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_PORT_VALID,
18282d22bc83SMichal Kalderon 				  1);
18292d22bc83SMichal Kalderon 			dmae_params.port_id = port_id;
18302d22bc83SMichal Kalderon 			break;
18312d22bc83SMichal Kalderon 		case SPLIT_TYPE_PF:
18322d22bc83SMichal Kalderon 			SET_FIELD(dmae_params.flags,
18332d22bc83SMichal Kalderon 				  QED_DMAE_PARAMS_SRC_PF_VALID, 1);
18342d22bc83SMichal Kalderon 			dmae_params.src_pfid = pf_id;
18352d22bc83SMichal Kalderon 			break;
18362d22bc83SMichal Kalderon 		case SPLIT_TYPE_PORT_PF:
18372d22bc83SMichal Kalderon 			SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_PORT_VALID,
18382d22bc83SMichal Kalderon 				  1);
18392d22bc83SMichal Kalderon 			SET_FIELD(dmae_params.flags,
18402d22bc83SMichal Kalderon 				  QED_DMAE_PARAMS_SRC_PF_VALID, 1);
18412d22bc83SMichal Kalderon 			dmae_params.port_id = port_id;
18422d22bc83SMichal Kalderon 			dmae_params.src_pfid = pf_id;
18432d22bc83SMichal Kalderon 			break;
18442d22bc83SMichal Kalderon 		default:
18452d22bc83SMichal Kalderon 			break;
18462d22bc83SMichal Kalderon 		}
18472d22bc83SMichal Kalderon 
18482d22bc83SMichal Kalderon 		/* Execute DMAE command */
18492d22bc83SMichal Kalderon 		read_using_dmae = !qed_dmae_grc2host(p_hwfn,
18502d22bc83SMichal Kalderon 						     p_ptt,
18512d22bc83SMichal Kalderon 						     DWORDS_TO_BYTES(addr),
18522d22bc83SMichal Kalderon 						     (u64)(uintptr_t)(dump_buf),
18532d22bc83SMichal Kalderon 						     len, &dmae_params);
18542d22bc83SMichal Kalderon 		if (!read_using_dmae) {
1855da090917STomer Tayar 			dev_data->use_dmae = 0;
1856da090917STomer Tayar 			DP_VERBOSE(p_hwfn,
1857da090917STomer Tayar 				   QED_MSG_DEBUG,
1858da090917STomer Tayar 				   "Failed reading from chip using DMAE, using GRC instead\n");
1859da090917STomer Tayar 		}
18602d22bc83SMichal Kalderon 	}
18612d22bc83SMichal Kalderon 
18622d22bc83SMichal Kalderon 	if (read_using_dmae)
18632d22bc83SMichal Kalderon 		goto print_log;
1864da090917STomer Tayar 
1865d52c89f1SMichal Kalderon 	/* If not read using DMAE, read using GRC */
1866d52c89f1SMichal Kalderon 
1867d52c89f1SMichal Kalderon 	/* Set pretend */
18682d22bc83SMichal Kalderon 	if (split_type != dev_data->pretend.split_type ||
18692d22bc83SMichal Kalderon 	    split_id != dev_data->pretend.split_id) {
1870d52c89f1SMichal Kalderon 		switch (split_type) {
1871d52c89f1SMichal Kalderon 		case SPLIT_TYPE_PORT:
1872d52c89f1SMichal Kalderon 			qed_port_pretend(p_hwfn, p_ptt, port_id);
1873d52c89f1SMichal Kalderon 			break;
1874d52c89f1SMichal Kalderon 		case SPLIT_TYPE_PF:
18752d22bc83SMichal Kalderon 			fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID,
18762d22bc83SMichal Kalderon 					  pf_id);
1877d52c89f1SMichal Kalderon 			qed_fid_pretend(p_hwfn, p_ptt, fid);
1878d52c89f1SMichal Kalderon 			break;
1879d52c89f1SMichal Kalderon 		case SPLIT_TYPE_PORT_PF:
18802d22bc83SMichal Kalderon 			fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID,
18812d22bc83SMichal Kalderon 					  pf_id);
1882d52c89f1SMichal Kalderon 			qed_port_fid_pretend(p_hwfn, p_ptt, port_id, fid);
1883d52c89f1SMichal Kalderon 			break;
1884d52c89f1SMichal Kalderon 		case SPLIT_TYPE_VF:
18852d22bc83SMichal Kalderon 			fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFVALID, 1)
18862d22bc83SMichal Kalderon 			      | FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFID,
18872d22bc83SMichal Kalderon 					  vf_id);
1888d52c89f1SMichal Kalderon 			qed_fid_pretend(p_hwfn, p_ptt, fid);
1889d52c89f1SMichal Kalderon 			break;
1890d52c89f1SMichal Kalderon 		default:
1891d52c89f1SMichal Kalderon 			break;
1892d52c89f1SMichal Kalderon 		}
1893d52c89f1SMichal Kalderon 
1894d52c89f1SMichal Kalderon 		dev_data->pretend.split_type = (u8)split_type;
1895d52c89f1SMichal Kalderon 		dev_data->pretend.split_id = split_id;
1896d52c89f1SMichal Kalderon 	}
1897d52c89f1SMichal Kalderon 
1898d52c89f1SMichal Kalderon 	/* Read registers using GRC */
1899da090917STomer Tayar 	qed_read_regs(p_hwfn, p_ptt, dump_buf, addr, len);
1900da090917STomer Tayar 
19012d22bc83SMichal Kalderon print_log:
19022d22bc83SMichal Kalderon 	/* Print log */
19032d22bc83SMichal Kalderon 	dev_data->num_regs_read += len;
19042d22bc83SMichal Kalderon 	thresh = s_hw_type_defs[dev_data->hw_type].log_thresh;
19052d22bc83SMichal Kalderon 	if ((dev_data->num_regs_read / thresh) >
19062d22bc83SMichal Kalderon 	    ((dev_data->num_regs_read - len) / thresh))
19072d22bc83SMichal Kalderon 		DP_VERBOSE(p_hwfn,
19082d22bc83SMichal Kalderon 			   QED_MSG_DEBUG,
19092d22bc83SMichal Kalderon 			   "Dumped %d registers...\n", dev_data->num_regs_read);
19102d22bc83SMichal Kalderon 
1911da090917STomer Tayar 	return len;
1912be086e7cSMintz, Yuval }
1913be086e7cSMintz, Yuval 
19147b6859fbSMintz, Yuval /* Dumps GRC registers sequence header. Returns the dumped size in dwords.
19157b6859fbSMintz, Yuval  * The addr and len arguments are specified in dwords.
19167b6859fbSMintz, Yuval  */
19177b6859fbSMintz, Yuval static u32 qed_grc_dump_reg_entry_hdr(u32 *dump_buf,
19187b6859fbSMintz, Yuval 				      bool dump, u32 addr, u32 len)
1919be086e7cSMintz, Yuval {
1920be086e7cSMintz, Yuval 	if (dump)
1921be086e7cSMintz, Yuval 		*dump_buf = addr | (len << REG_DUMP_LEN_SHIFT);
19227b6859fbSMintz, Yuval 
1923be086e7cSMintz, Yuval 	return 1;
1924be086e7cSMintz, Yuval }
1925be086e7cSMintz, Yuval 
19267b6859fbSMintz, Yuval /* Dumps GRC registers sequence. Returns the dumped size in dwords.
19277b6859fbSMintz, Yuval  * The addr and len arguments are specified in dwords.
19287b6859fbSMintz, Yuval  */
1929c965db44STomer Tayar static u32 qed_grc_dump_reg_entry(struct qed_hwfn *p_hwfn,
19307b6859fbSMintz, Yuval 				  struct qed_ptt *p_ptt,
19317b6859fbSMintz, Yuval 				  u32 *dump_buf,
1932d52c89f1SMichal Kalderon 				  bool dump, u32 addr, u32 len, bool wide_bus,
1933d52c89f1SMichal Kalderon 				  enum init_split_types split_type, u8 split_id)
1934c965db44STomer Tayar {
1935be086e7cSMintz, Yuval 	u32 offset = 0;
1936c965db44STomer Tayar 
1937be086e7cSMintz, Yuval 	offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, len);
1938be086e7cSMintz, Yuval 	offset += qed_grc_dump_addr_range(p_hwfn,
1939c965db44STomer Tayar 					  p_ptt,
19407b6859fbSMintz, Yuval 					  dump_buf + offset,
1941d52c89f1SMichal Kalderon 					  dump, addr, len, wide_bus,
1942d52c89f1SMichal Kalderon 					  split_type, split_id);
19437b6859fbSMintz, Yuval 
1944be086e7cSMintz, Yuval 	return offset;
1945be086e7cSMintz, Yuval }
1946be086e7cSMintz, Yuval 
1947be086e7cSMintz, Yuval /* Dumps GRC registers sequence with skip cycle.
1948be086e7cSMintz, Yuval  * Returns the dumped size in dwords.
19497b6859fbSMintz, Yuval  * - addr:	start GRC address in dwords
19507b6859fbSMintz, Yuval  * - total_len:	total no. of dwords to dump
19517b6859fbSMintz, Yuval  * - read_len:	no. consecutive dwords to read
19527b6859fbSMintz, Yuval  * - skip_len:	no. of dwords to skip (and fill with zeros)
1953be086e7cSMintz, Yuval  */
1954be086e7cSMintz, Yuval static u32 qed_grc_dump_reg_entry_skip(struct qed_hwfn *p_hwfn,
19557b6859fbSMintz, Yuval 				       struct qed_ptt *p_ptt,
19567b6859fbSMintz, Yuval 				       u32 *dump_buf,
19577b6859fbSMintz, Yuval 				       bool dump,
19587b6859fbSMintz, Yuval 				       u32 addr,
19597b6859fbSMintz, Yuval 				       u32 total_len,
1960be086e7cSMintz, Yuval 				       u32 read_len, u32 skip_len)
1961be086e7cSMintz, Yuval {
1962be086e7cSMintz, Yuval 	u32 offset = 0, reg_offset = 0;
1963be086e7cSMintz, Yuval 
1964be086e7cSMintz, Yuval 	offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, total_len);
19657b6859fbSMintz, Yuval 
19667b6859fbSMintz, Yuval 	if (!dump)
19677b6859fbSMintz, Yuval 		return offset + total_len;
19687b6859fbSMintz, Yuval 
1969be086e7cSMintz, Yuval 	while (reg_offset < total_len) {
19707b6859fbSMintz, Yuval 		u32 curr_len = min_t(u32, read_len, total_len - reg_offset);
19717b6859fbSMintz, Yuval 
1972be086e7cSMintz, Yuval 		offset += qed_grc_dump_addr_range(p_hwfn,
1973be086e7cSMintz, Yuval 						  p_ptt,
1974be086e7cSMintz, Yuval 						  dump_buf + offset,
1975d52c89f1SMichal Kalderon 						  dump,  addr, curr_len, false,
1976d52c89f1SMichal Kalderon 						  SPLIT_TYPE_NONE, 0);
1977be086e7cSMintz, Yuval 		reg_offset += curr_len;
1978be086e7cSMintz, Yuval 		addr += curr_len;
19797b6859fbSMintz, Yuval 
1980be086e7cSMintz, Yuval 		if (reg_offset < total_len) {
19817b6859fbSMintz, Yuval 			curr_len = min_t(u32, skip_len, total_len - skip_len);
19827b6859fbSMintz, Yuval 			memset(dump_buf + offset, 0, DWORDS_TO_BYTES(curr_len));
1983be086e7cSMintz, Yuval 			offset += curr_len;
1984be086e7cSMintz, Yuval 			reg_offset += curr_len;
1985be086e7cSMintz, Yuval 			addr += curr_len;
1986be086e7cSMintz, Yuval 		}
1987be086e7cSMintz, Yuval 	}
1988c965db44STomer Tayar 
1989c965db44STomer Tayar 	return offset;
1990c965db44STomer Tayar }
1991c965db44STomer Tayar 
1992c965db44STomer Tayar /* Dumps GRC registers entries. Returns the dumped size in dwords. */
1993c965db44STomer Tayar static u32 qed_grc_dump_regs_entries(struct qed_hwfn *p_hwfn,
1994c965db44STomer Tayar 				     struct qed_ptt *p_ptt,
19952d22bc83SMichal Kalderon 				     struct virt_mem_desc input_regs_arr,
1996c965db44STomer Tayar 				     u32 *dump_buf,
1997c965db44STomer Tayar 				     bool dump,
1998d52c89f1SMichal Kalderon 				     enum init_split_types split_type,
1999d52c89f1SMichal Kalderon 				     u8 split_id,
2000c965db44STomer Tayar 				     bool block_enable[MAX_BLOCK_ID],
2001c965db44STomer Tayar 				     u32 *num_dumped_reg_entries)
2002c965db44STomer Tayar {
2003c965db44STomer Tayar 	u32 i, offset = 0, input_offset = 0;
2004c965db44STomer Tayar 	bool mode_match = true;
2005c965db44STomer Tayar 
2006c965db44STomer Tayar 	*num_dumped_reg_entries = 0;
20077b6859fbSMintz, Yuval 
20082d22bc83SMichal Kalderon 	while (input_offset < BYTES_TO_DWORDS(input_regs_arr.size)) {
2009c965db44STomer Tayar 		const struct dbg_dump_cond_hdr *cond_hdr =
2010c965db44STomer Tayar 		    (const struct dbg_dump_cond_hdr *)
20112d22bc83SMichal Kalderon 		    input_regs_arr.ptr + input_offset++;
20127b6859fbSMintz, Yuval 		u16 modes_buf_offset;
20137b6859fbSMintz, Yuval 		bool eval_mode;
2014c965db44STomer Tayar 
2015c965db44STomer Tayar 		/* Check mode/block */
20167b6859fbSMintz, Yuval 		eval_mode = GET_FIELD(cond_hdr->mode.data,
20177b6859fbSMintz, Yuval 				      DBG_MODE_HDR_EVAL_MODE) > 0;
2018c965db44STomer Tayar 		if (eval_mode) {
20197b6859fbSMintz, Yuval 			modes_buf_offset =
2020c965db44STomer Tayar 				GET_FIELD(cond_hdr->mode.data,
2021c965db44STomer Tayar 					  DBG_MODE_HDR_MODES_BUF_OFFSET);
2022c965db44STomer Tayar 			mode_match = qed_is_mode_match(p_hwfn,
2023c965db44STomer Tayar 						       &modes_buf_offset);
2024c965db44STomer Tayar 		}
2025c965db44STomer Tayar 
20267b6859fbSMintz, Yuval 		if (!mode_match || !block_enable[cond_hdr->block_id]) {
20277b6859fbSMintz, Yuval 			input_offset += cond_hdr->data_size;
20287b6859fbSMintz, Yuval 			continue;
20297b6859fbSMintz, Yuval 		}
20307b6859fbSMintz, Yuval 
20317b6859fbSMintz, Yuval 		for (i = 0; i < cond_hdr->data_size; i++, input_offset++) {
2032c965db44STomer Tayar 			const struct dbg_dump_reg *reg =
2033c965db44STomer Tayar 			    (const struct dbg_dump_reg *)
20342d22bc83SMichal Kalderon 			    input_regs_arr.ptr + input_offset;
2035be086e7cSMintz, Yuval 			u32 addr, len;
20367b6859fbSMintz, Yuval 			bool wide_bus;
2037c965db44STomer Tayar 
20387b6859fbSMintz, Yuval 			addr = GET_FIELD(reg->data, DBG_DUMP_REG_ADDRESS);
2039be086e7cSMintz, Yuval 			len = GET_FIELD(reg->data, DBG_DUMP_REG_LENGTH);
20407b6859fbSMintz, Yuval 			wide_bus = GET_FIELD(reg->data, DBG_DUMP_REG_WIDE_BUS);
20417b6859fbSMintz, Yuval 			offset += qed_grc_dump_reg_entry(p_hwfn,
20427b6859fbSMintz, Yuval 							 p_ptt,
2043be086e7cSMintz, Yuval 							 dump_buf + offset,
2044be086e7cSMintz, Yuval 							 dump,
2045be086e7cSMintz, Yuval 							 addr,
20467b6859fbSMintz, Yuval 							 len,
2047d52c89f1SMichal Kalderon 							 wide_bus,
2048d52c89f1SMichal Kalderon 							 split_type, split_id);
2049c965db44STomer Tayar 			(*num_dumped_reg_entries)++;
2050c965db44STomer Tayar 		}
2051c965db44STomer Tayar 	}
2052c965db44STomer Tayar 
2053c965db44STomer Tayar 	return offset;
2054c965db44STomer Tayar }
2055c965db44STomer Tayar 
2056c965db44STomer Tayar /* Dumps GRC registers entries. Returns the dumped size in dwords. */
2057c965db44STomer Tayar static u32 qed_grc_dump_split_data(struct qed_hwfn *p_hwfn,
2058c965db44STomer Tayar 				   struct qed_ptt *p_ptt,
20592d22bc83SMichal Kalderon 				   struct virt_mem_desc input_regs_arr,
2060c965db44STomer Tayar 				   u32 *dump_buf,
2061c965db44STomer Tayar 				   bool dump,
2062c965db44STomer Tayar 				   bool block_enable[MAX_BLOCK_ID],
2063d52c89f1SMichal Kalderon 				   enum init_split_types split_type,
20642d22bc83SMichal Kalderon 				   u8 split_id, const char *reg_type_name)
2065c965db44STomer Tayar {
2066d52c89f1SMichal Kalderon 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2067d52c89f1SMichal Kalderon 	enum init_split_types hdr_split_type = split_type;
2068c965db44STomer Tayar 	u32 num_dumped_reg_entries, offset;
2069d52c89f1SMichal Kalderon 	u8 hdr_split_id = split_id;
2070d52c89f1SMichal Kalderon 
2071d52c89f1SMichal Kalderon 	/* In PORT_PF split type, print a port split header */
2072d52c89f1SMichal Kalderon 	if (split_type == SPLIT_TYPE_PORT_PF) {
2073d52c89f1SMichal Kalderon 		hdr_split_type = SPLIT_TYPE_PORT;
2074d52c89f1SMichal Kalderon 		hdr_split_id = split_id / dev_data->num_pfs_per_port;
2075d52c89f1SMichal Kalderon 	}
2076c965db44STomer Tayar 
2077c965db44STomer Tayar 	/* Calculate register dump header size (and skip it for now) */
2078c965db44STomer Tayar 	offset = qed_grc_dump_regs_hdr(dump_buf,
2079c965db44STomer Tayar 				       false,
2080c965db44STomer Tayar 				       0,
2081d52c89f1SMichal Kalderon 				       hdr_split_type,
20822d22bc83SMichal Kalderon 				       hdr_split_id, reg_type_name);
2083c965db44STomer Tayar 
2084c965db44STomer Tayar 	/* Dump registers */
2085c965db44STomer Tayar 	offset += qed_grc_dump_regs_entries(p_hwfn,
2086c965db44STomer Tayar 					    p_ptt,
2087c965db44STomer Tayar 					    input_regs_arr,
2088c965db44STomer Tayar 					    dump_buf + offset,
2089c965db44STomer Tayar 					    dump,
2090d52c89f1SMichal Kalderon 					    split_type,
2091d52c89f1SMichal Kalderon 					    split_id,
2092c965db44STomer Tayar 					    block_enable,
2093c965db44STomer Tayar 					    &num_dumped_reg_entries);
2094c965db44STomer Tayar 
2095c965db44STomer Tayar 	/* Write register dump header */
2096c965db44STomer Tayar 	if (dump && num_dumped_reg_entries > 0)
2097c965db44STomer Tayar 		qed_grc_dump_regs_hdr(dump_buf,
2098c965db44STomer Tayar 				      dump,
2099c965db44STomer Tayar 				      num_dumped_reg_entries,
2100d52c89f1SMichal Kalderon 				      hdr_split_type,
21012d22bc83SMichal Kalderon 				      hdr_split_id, reg_type_name);
2102c965db44STomer Tayar 
2103c965db44STomer Tayar 	return num_dumped_reg_entries > 0 ? offset : 0;
2104c965db44STomer Tayar }
2105c965db44STomer Tayar 
21067b6859fbSMintz, Yuval /* Dumps registers according to the input registers array. Returns the dumped
21077b6859fbSMintz, Yuval  * size in dwords.
2108c965db44STomer Tayar  */
2109c965db44STomer Tayar static u32 qed_grc_dump_registers(struct qed_hwfn *p_hwfn,
2110c965db44STomer Tayar 				  struct qed_ptt *p_ptt,
2111c965db44STomer Tayar 				  u32 *dump_buf,
2112c965db44STomer Tayar 				  bool dump,
2113c965db44STomer Tayar 				  bool block_enable[MAX_BLOCK_ID],
21142d22bc83SMichal Kalderon 				  const char *reg_type_name)
2115c965db44STomer Tayar {
21162d22bc83SMichal Kalderon 	struct virt_mem_desc *dbg_buf =
21172d22bc83SMichal Kalderon 	    &p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG];
2118c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2119c965db44STomer Tayar 	u32 offset = 0, input_offset = 0;
21202d22bc83SMichal Kalderon 
21212d22bc83SMichal Kalderon 	while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) {
21227b6859fbSMintz, Yuval 		const struct dbg_dump_split_hdr *split_hdr;
21232d22bc83SMichal Kalderon 		struct virt_mem_desc curr_input_regs_arr;
2124d52c89f1SMichal Kalderon 		enum init_split_types split_type;
2125d52c89f1SMichal Kalderon 		u16 split_count = 0;
21267b6859fbSMintz, Yuval 		u32 split_data_size;
2127d52c89f1SMichal Kalderon 		u8 split_id;
21287b6859fbSMintz, Yuval 
21297b6859fbSMintz, Yuval 		split_hdr =
2130c965db44STomer Tayar 		    (const struct dbg_dump_split_hdr *)
21312d22bc83SMichal Kalderon 		    dbg_buf->ptr + input_offset++;
2132d52c89f1SMichal Kalderon 		split_type =
21337b6859fbSMintz, Yuval 		    GET_FIELD(split_hdr->hdr,
2134c965db44STomer Tayar 			      DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
21352d22bc83SMichal Kalderon 		split_data_size = GET_FIELD(split_hdr->hdr,
2136c965db44STomer Tayar 					    DBG_DUMP_SPLIT_HDR_DATA_SIZE);
21377b6859fbSMintz, Yuval 		curr_input_regs_arr.ptr =
21382d22bc83SMichal Kalderon 		    (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr +
21392d22bc83SMichal Kalderon 		    input_offset;
21402d22bc83SMichal Kalderon 		curr_input_regs_arr.size = DWORDS_TO_BYTES(split_data_size);
2141c965db44STomer Tayar 
2142d52c89f1SMichal Kalderon 		switch (split_type) {
2143c965db44STomer Tayar 		case SPLIT_TYPE_NONE:
2144d52c89f1SMichal Kalderon 			split_count = 1;
2145c965db44STomer Tayar 			break;
2146c965db44STomer Tayar 		case SPLIT_TYPE_PORT:
2147d52c89f1SMichal Kalderon 			split_count = dev_data->num_ports;
2148c965db44STomer Tayar 			break;
2149c965db44STomer Tayar 		case SPLIT_TYPE_PF:
2150c965db44STomer Tayar 		case SPLIT_TYPE_PORT_PF:
2151d52c89f1SMichal Kalderon 			split_count = dev_data->num_ports *
2152d52c89f1SMichal Kalderon 			    dev_data->num_pfs_per_port;
2153be086e7cSMintz, Yuval 			break;
2154be086e7cSMintz, Yuval 		case SPLIT_TYPE_VF:
2155d52c89f1SMichal Kalderon 			split_count = dev_data->num_vfs;
2156d52c89f1SMichal Kalderon 			break;
2157d52c89f1SMichal Kalderon 		default:
2158d52c89f1SMichal Kalderon 			return 0;
2159be086e7cSMintz, Yuval 		}
2160be086e7cSMintz, Yuval 
2161d52c89f1SMichal Kalderon 		for (split_id = 0; split_id < split_count; split_id++)
2162d52c89f1SMichal Kalderon 			offset += qed_grc_dump_split_data(p_hwfn, p_ptt,
2163be086e7cSMintz, Yuval 							  curr_input_regs_arr,
2164be086e7cSMintz, Yuval 							  dump_buf + offset,
2165be086e7cSMintz, Yuval 							  dump, block_enable,
2166d52c89f1SMichal Kalderon 							  split_type,
2167d52c89f1SMichal Kalderon 							  split_id,
21682d22bc83SMichal Kalderon 							  reg_type_name);
2169c965db44STomer Tayar 
2170c965db44STomer Tayar 		input_offset += split_data_size;
2171c965db44STomer Tayar 	}
2172c965db44STomer Tayar 
2173d52c89f1SMichal Kalderon 	/* Cancel pretends (pretend to original PF) */
2174be086e7cSMintz, Yuval 	if (dump) {
21752d22bc83SMichal Kalderon 		qed_fid_pretend(p_hwfn, p_ptt,
21762d22bc83SMichal Kalderon 				FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID,
21772d22bc83SMichal Kalderon 					    p_hwfn->rel_pf_id));
2178d52c89f1SMichal Kalderon 		dev_data->pretend.split_type = SPLIT_TYPE_NONE;
2179d52c89f1SMichal Kalderon 		dev_data->pretend.split_id = 0;
2180be086e7cSMintz, Yuval 	}
2181be086e7cSMintz, Yuval 
2182c965db44STomer Tayar 	return offset;
2183c965db44STomer Tayar }
2184c965db44STomer Tayar 
2185c965db44STomer Tayar /* Dump reset registers. Returns the dumped size in dwords. */
2186c965db44STomer Tayar static u32 qed_grc_dump_reset_regs(struct qed_hwfn *p_hwfn,
2187c965db44STomer Tayar 				   struct qed_ptt *p_ptt,
2188c965db44STomer Tayar 				   u32 *dump_buf, bool dump)
2189c965db44STomer Tayar {
21902d22bc83SMichal Kalderon 	u32 offset = 0, num_regs = 0;
21912d22bc83SMichal Kalderon 	u8 reset_reg_id;
2192c965db44STomer Tayar 
2193c965db44STomer Tayar 	/* Calculate header size */
2194c965db44STomer Tayar 	offset += qed_grc_dump_regs_hdr(dump_buf,
21952d22bc83SMichal Kalderon 					false,
21962d22bc83SMichal Kalderon 					0, SPLIT_TYPE_NONE, 0, "RESET_REGS");
2197c965db44STomer Tayar 
2198c965db44STomer Tayar 	/* Write reset registers */
21992d22bc83SMichal Kalderon 	for (reset_reg_id = 0; reset_reg_id < NUM_DBG_RESET_REGS;
22002d22bc83SMichal Kalderon 	     reset_reg_id++) {
22012d22bc83SMichal Kalderon 		const struct dbg_reset_reg *reset_reg;
22022d22bc83SMichal Kalderon 		u32 reset_reg_addr;
22032d22bc83SMichal Kalderon 
22042d22bc83SMichal Kalderon 		reset_reg = qed_get_dbg_reset_reg(p_hwfn, reset_reg_id);
22052d22bc83SMichal Kalderon 
22062d22bc83SMichal Kalderon 		if (GET_FIELD(reset_reg->data, DBG_RESET_REG_IS_REMOVED))
22077b6859fbSMintz, Yuval 			continue;
2208be086e7cSMintz, Yuval 
22092d22bc83SMichal Kalderon 		reset_reg_addr = GET_FIELD(reset_reg->data, DBG_RESET_REG_ADDR);
2210c965db44STomer Tayar 		offset += qed_grc_dump_reg_entry(p_hwfn,
2211c965db44STomer Tayar 						 p_ptt,
2212c965db44STomer Tayar 						 dump_buf + offset,
2213c965db44STomer Tayar 						 dump,
22142d22bc83SMichal Kalderon 						 reset_reg_addr,
22152d22bc83SMichal Kalderon 						 1, false, SPLIT_TYPE_NONE, 0);
2216c965db44STomer Tayar 		num_regs++;
2217c965db44STomer Tayar 	}
2218c965db44STomer Tayar 
2219c965db44STomer Tayar 	/* Write header */
2220c965db44STomer Tayar 	if (dump)
2221c965db44STomer Tayar 		qed_grc_dump_regs_hdr(dump_buf,
2222d52c89f1SMichal Kalderon 				      true, num_regs, SPLIT_TYPE_NONE,
22232d22bc83SMichal Kalderon 				      0, "RESET_REGS");
22247b6859fbSMintz, Yuval 
2225c965db44STomer Tayar 	return offset;
2226c965db44STomer Tayar }
2227c965db44STomer Tayar 
22287b6859fbSMintz, Yuval /* Dump registers that are modified during GRC Dump and therefore must be
22297b6859fbSMintz, Yuval  * dumped first. Returns the dumped size in dwords.
2230c965db44STomer Tayar  */
2231c965db44STomer Tayar static u32 qed_grc_dump_modified_regs(struct qed_hwfn *p_hwfn,
2232c965db44STomer Tayar 				      struct qed_ptt *p_ptt,
2233c965db44STomer Tayar 				      u32 *dump_buf, bool dump)
2234c965db44STomer Tayar {
2235c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
22362d22bc83SMichal Kalderon 	u32 block_id, offset = 0, stall_regs_offset;
22377b6859fbSMintz, Yuval 	const struct dbg_attn_reg *attn_reg_arr;
2238c965db44STomer Tayar 	u8 storm_id, reg_idx, num_attn_regs;
22392d22bc83SMichal Kalderon 	u32 num_reg_entries = 0;
2240c965db44STomer Tayar 
22412d22bc83SMichal Kalderon 	/* Write empty header for attention registers */
2242c965db44STomer Tayar 	offset += qed_grc_dump_regs_hdr(dump_buf,
22432d22bc83SMichal Kalderon 					false,
22442d22bc83SMichal Kalderon 					0, SPLIT_TYPE_NONE, 0, "ATTN_REGS");
2245c965db44STomer Tayar 
2246c965db44STomer Tayar 	/* Write parity registers */
22472d22bc83SMichal Kalderon 	for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) {
2248c965db44STomer Tayar 		if (dev_data->block_in_reset[block_id] && dump)
2249c965db44STomer Tayar 			continue;
2250c965db44STomer Tayar 
22512d22bc83SMichal Kalderon 		attn_reg_arr = qed_get_block_attn_regs(p_hwfn,
22522d22bc83SMichal Kalderon 						       (enum block_id)block_id,
2253c965db44STomer Tayar 						       ATTN_TYPE_PARITY,
2254c965db44STomer Tayar 						       &num_attn_regs);
22557b6859fbSMintz, Yuval 
2256c965db44STomer Tayar 		for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
2257c965db44STomer Tayar 			const struct dbg_attn_reg *reg_data =
2258c965db44STomer Tayar 				&attn_reg_arr[reg_idx];
2259c965db44STomer Tayar 			u16 modes_buf_offset;
2260c965db44STomer Tayar 			bool eval_mode;
2261be086e7cSMintz, Yuval 			u32 addr;
2262c965db44STomer Tayar 
2263c965db44STomer Tayar 			/* Check mode */
2264c965db44STomer Tayar 			eval_mode = GET_FIELD(reg_data->mode.data,
2265c965db44STomer Tayar 					      DBG_MODE_HDR_EVAL_MODE) > 0;
2266c965db44STomer Tayar 			modes_buf_offset =
2267c965db44STomer Tayar 				GET_FIELD(reg_data->mode.data,
2268c965db44STomer Tayar 					  DBG_MODE_HDR_MODES_BUF_OFFSET);
22697b6859fbSMintz, Yuval 			if (eval_mode &&
22707b6859fbSMintz, Yuval 			    !qed_is_mode_match(p_hwfn, &modes_buf_offset))
22717b6859fbSMintz, Yuval 				continue;
22727b6859fbSMintz, Yuval 
22737b6859fbSMintz, Yuval 			/* Mode match: read & dump registers */
2274be086e7cSMintz, Yuval 			addr = reg_data->mask_address;
22757b6859fbSMintz, Yuval 			offset += qed_grc_dump_reg_entry(p_hwfn,
2276c965db44STomer Tayar 							 p_ptt,
2277c965db44STomer Tayar 							 dump_buf + offset,
2278c965db44STomer Tayar 							 dump,
2279be086e7cSMintz, Yuval 							 addr,
2280d52c89f1SMichal Kalderon 							 1, false,
2281d52c89f1SMichal Kalderon 							 SPLIT_TYPE_NONE, 0);
2282be086e7cSMintz, Yuval 			addr = GET_FIELD(reg_data->data,
2283be086e7cSMintz, Yuval 					 DBG_ATTN_REG_STS_ADDRESS);
22847b6859fbSMintz, Yuval 			offset += qed_grc_dump_reg_entry(p_hwfn,
2285c965db44STomer Tayar 							 p_ptt,
2286c965db44STomer Tayar 							 dump_buf + offset,
2287c965db44STomer Tayar 							 dump,
2288be086e7cSMintz, Yuval 							 addr,
2289d52c89f1SMichal Kalderon 							 1, false,
2290d52c89f1SMichal Kalderon 							 SPLIT_TYPE_NONE, 0);
2291c965db44STomer Tayar 			num_reg_entries += 2;
2292c965db44STomer Tayar 		}
2293c965db44STomer Tayar 	}
2294c965db44STomer Tayar 
22952d22bc83SMichal Kalderon 	/* Overwrite header for attention registers */
22962d22bc83SMichal Kalderon 	if (dump)
22972d22bc83SMichal Kalderon 		qed_grc_dump_regs_hdr(dump_buf,
22982d22bc83SMichal Kalderon 				      true,
22992d22bc83SMichal Kalderon 				      num_reg_entries,
23002d22bc83SMichal Kalderon 				      SPLIT_TYPE_NONE, 0, "ATTN_REGS");
23012d22bc83SMichal Kalderon 
23022d22bc83SMichal Kalderon 	/* Write empty header for stall registers */
23032d22bc83SMichal Kalderon 	stall_regs_offset = offset;
23042d22bc83SMichal Kalderon 	offset += qed_grc_dump_regs_hdr(dump_buf,
23052d22bc83SMichal Kalderon 					false, 0, SPLIT_TYPE_NONE, 0, "REGS");
23062d22bc83SMichal Kalderon 
23077b6859fbSMintz, Yuval 	/* Write Storm stall status registers */
23082d22bc83SMichal Kalderon 	for (storm_id = 0, num_reg_entries = 0; storm_id < MAX_DBG_STORMS;
23092d22bc83SMichal Kalderon 	     storm_id++) {
23107b6859fbSMintz, Yuval 		struct storm_defs *storm = &s_storm_defs[storm_id];
2311be086e7cSMintz, Yuval 		u32 addr;
2312be086e7cSMintz, Yuval 
23132d22bc83SMichal Kalderon 		if (dev_data->block_in_reset[storm->sem_block_id] && dump)
2314c965db44STomer Tayar 			continue;
2315c965db44STomer Tayar 
2316be086e7cSMintz, Yuval 		addr =
23172d22bc83SMichal Kalderon 		    BYTES_TO_DWORDS(storm->sem_fast_mem_addr +
2318be086e7cSMintz, Yuval 				    SEM_FAST_REG_STALLED);
2319c965db44STomer Tayar 		offset += qed_grc_dump_reg_entry(p_hwfn,
2320c965db44STomer Tayar 						 p_ptt,
2321c965db44STomer Tayar 						 dump_buf + offset,
2322c965db44STomer Tayar 						 dump,
2323be086e7cSMintz, Yuval 						 addr,
23247b6859fbSMintz, Yuval 						 1,
2325d52c89f1SMichal Kalderon 						 false, SPLIT_TYPE_NONE, 0);
2326c965db44STomer Tayar 		num_reg_entries++;
2327c965db44STomer Tayar 	}
2328c965db44STomer Tayar 
23292d22bc83SMichal Kalderon 	/* Overwrite header for stall registers */
2330c965db44STomer Tayar 	if (dump)
23312d22bc83SMichal Kalderon 		qed_grc_dump_regs_hdr(dump_buf + stall_regs_offset,
2332c965db44STomer Tayar 				      true,
23332d22bc83SMichal Kalderon 				      num_reg_entries,
23342d22bc83SMichal Kalderon 				      SPLIT_TYPE_NONE, 0, "REGS");
23357b6859fbSMintz, Yuval 
2336c965db44STomer Tayar 	return offset;
2337c965db44STomer Tayar }
2338c965db44STomer Tayar 
2339be086e7cSMintz, Yuval /* Dumps registers that can't be represented in the debug arrays */
2340be086e7cSMintz, Yuval static u32 qed_grc_dump_special_regs(struct qed_hwfn *p_hwfn,
2341be086e7cSMintz, Yuval 				     struct qed_ptt *p_ptt,
2342be086e7cSMintz, Yuval 				     u32 *dump_buf, bool dump)
2343be086e7cSMintz, Yuval {
2344be086e7cSMintz, Yuval 	u32 offset = 0, addr;
2345be086e7cSMintz, Yuval 
2346be086e7cSMintz, Yuval 	offset += qed_grc_dump_regs_hdr(dump_buf,
23472d22bc83SMichal Kalderon 					dump, 2, SPLIT_TYPE_NONE, 0, "REGS");
2348be086e7cSMintz, Yuval 
2349be086e7cSMintz, Yuval 	/* Dump R/TDIF_REG_DEBUG_ERROR_INFO_SIZE (every 8'th register should be
2350be086e7cSMintz, Yuval 	 * skipped).
2351be086e7cSMintz, Yuval 	 */
2352be086e7cSMintz, Yuval 	addr = BYTES_TO_DWORDS(RDIF_REG_DEBUG_ERROR_INFO);
2353be086e7cSMintz, Yuval 	offset += qed_grc_dump_reg_entry_skip(p_hwfn,
2354be086e7cSMintz, Yuval 					      p_ptt,
2355be086e7cSMintz, Yuval 					      dump_buf + offset,
2356be086e7cSMintz, Yuval 					      dump,
2357be086e7cSMintz, Yuval 					      addr,
2358be086e7cSMintz, Yuval 					      RDIF_REG_DEBUG_ERROR_INFO_SIZE,
2359be086e7cSMintz, Yuval 					      7,
2360be086e7cSMintz, Yuval 					      1);
2361be086e7cSMintz, Yuval 	addr = BYTES_TO_DWORDS(TDIF_REG_DEBUG_ERROR_INFO);
2362be086e7cSMintz, Yuval 	offset +=
2363be086e7cSMintz, Yuval 	    qed_grc_dump_reg_entry_skip(p_hwfn,
2364be086e7cSMintz, Yuval 					p_ptt,
2365be086e7cSMintz, Yuval 					dump_buf + offset,
2366be086e7cSMintz, Yuval 					dump,
2367be086e7cSMintz, Yuval 					addr,
2368be086e7cSMintz, Yuval 					TDIF_REG_DEBUG_ERROR_INFO_SIZE,
2369be086e7cSMintz, Yuval 					7,
2370be086e7cSMintz, Yuval 					1);
2371be086e7cSMintz, Yuval 
2372be086e7cSMintz, Yuval 	return offset;
2373be086e7cSMintz, Yuval }
2374be086e7cSMintz, Yuval 
23757b6859fbSMintz, Yuval /* Dumps a GRC memory header (section and params). Returns the dumped size in
23767b6859fbSMintz, Yuval  * dwords. The following parameters are dumped:
23777b6859fbSMintz, Yuval  * - name:	   dumped only if it's not NULL.
23787b6859fbSMintz, Yuval  * - addr:	   in dwords, dumped only if name is NULL.
23797b6859fbSMintz, Yuval  * - len:	   in dwords, always dumped.
23807b6859fbSMintz, Yuval  * - width:	   dumped if it's not zero.
23817b6859fbSMintz, Yuval  * - packed:	   dumped only if it's not false.
23827b6859fbSMintz, Yuval  * - mem_group:	   always dumped.
23837b6859fbSMintz, Yuval  * - is_storm:	   true only if the memory is related to a Storm.
23847b6859fbSMintz, Yuval  * - storm_letter: valid only if is_storm is true.
23857b6859fbSMintz, Yuval  *
2386c965db44STomer Tayar  */
2387c965db44STomer Tayar static u32 qed_grc_dump_mem_hdr(struct qed_hwfn *p_hwfn,
2388c965db44STomer Tayar 				u32 *dump_buf,
2389c965db44STomer Tayar 				bool dump,
2390c965db44STomer Tayar 				const char *name,
2391be086e7cSMintz, Yuval 				u32 addr,
2392be086e7cSMintz, Yuval 				u32 len,
2393c965db44STomer Tayar 				u32 bit_width,
2394c965db44STomer Tayar 				bool packed,
23952d22bc83SMichal Kalderon 				const char *mem_group, char storm_letter)
2396c965db44STomer Tayar {
2397c965db44STomer Tayar 	u8 num_params = 3;
2398c965db44STomer Tayar 	u32 offset = 0;
2399c965db44STomer Tayar 	char buf[64];
2400c965db44STomer Tayar 
2401be086e7cSMintz, Yuval 	if (!len)
2402c965db44STomer Tayar 		DP_NOTICE(p_hwfn,
2403c965db44STomer Tayar 			  "Unexpected GRC Dump error: dumped memory size must be non-zero\n");
24047b6859fbSMintz, Yuval 
2405c965db44STomer Tayar 	if (bit_width)
2406c965db44STomer Tayar 		num_params++;
2407c965db44STomer Tayar 	if (packed)
2408c965db44STomer Tayar 		num_params++;
2409c965db44STomer Tayar 
2410c965db44STomer Tayar 	/* Dump section header */
2411c965db44STomer Tayar 	offset += qed_dump_section_hdr(dump_buf + offset,
2412c965db44STomer Tayar 				       dump, "grc_mem", num_params);
24137b6859fbSMintz, Yuval 
2414c965db44STomer Tayar 	if (name) {
2415c965db44STomer Tayar 		/* Dump name */
24162d22bc83SMichal Kalderon 		if (storm_letter) {
2417c965db44STomer Tayar 			strcpy(buf, "?STORM_");
2418c965db44STomer Tayar 			buf[0] = storm_letter;
2419c965db44STomer Tayar 			strcpy(buf + strlen(buf), name);
2420c965db44STomer Tayar 		} else {
2421c965db44STomer Tayar 			strcpy(buf, name);
2422c965db44STomer Tayar 		}
2423c965db44STomer Tayar 
2424c965db44STomer Tayar 		offset += qed_dump_str_param(dump_buf + offset,
2425c965db44STomer Tayar 					     dump, "name", buf);
2426c965db44STomer Tayar 	} else {
2427c965db44STomer Tayar 		/* Dump address */
24287b6859fbSMintz, Yuval 		u32 addr_in_bytes = DWORDS_TO_BYTES(addr);
24297b6859fbSMintz, Yuval 
2430c965db44STomer Tayar 		offset += qed_dump_num_param(dump_buf + offset,
24317b6859fbSMintz, Yuval 					     dump, "addr", addr_in_bytes);
2432c965db44STomer Tayar 	}
2433c965db44STomer Tayar 
2434c965db44STomer Tayar 	/* Dump len */
2435be086e7cSMintz, Yuval 	offset += qed_dump_num_param(dump_buf + offset, dump, "len", len);
2436c965db44STomer Tayar 
2437c965db44STomer Tayar 	/* Dump bit width */
2438c965db44STomer Tayar 	if (bit_width)
2439c965db44STomer Tayar 		offset += qed_dump_num_param(dump_buf + offset,
2440c965db44STomer Tayar 					     dump, "width", bit_width);
2441c965db44STomer Tayar 
2442c965db44STomer Tayar 	/* Dump packed */
2443c965db44STomer Tayar 	if (packed)
2444c965db44STomer Tayar 		offset += qed_dump_num_param(dump_buf + offset,
2445c965db44STomer Tayar 					     dump, "packed", 1);
2446c965db44STomer Tayar 
2447c965db44STomer Tayar 	/* Dump reg type */
24482d22bc83SMichal Kalderon 	if (storm_letter) {
2449c965db44STomer Tayar 		strcpy(buf, "?STORM_");
2450c965db44STomer Tayar 		buf[0] = storm_letter;
2451c965db44STomer Tayar 		strcpy(buf + strlen(buf), mem_group);
2452c965db44STomer Tayar 	} else {
2453c965db44STomer Tayar 		strcpy(buf, mem_group);
2454c965db44STomer Tayar 	}
2455c965db44STomer Tayar 
2456c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset, dump, "type", buf);
24577b6859fbSMintz, Yuval 
2458c965db44STomer Tayar 	return offset;
2459c965db44STomer Tayar }
2460c965db44STomer Tayar 
2461c965db44STomer Tayar /* Dumps a single GRC memory. If name is NULL, the memory is stored by address.
2462c965db44STomer Tayar  * Returns the dumped size in dwords.
24637b6859fbSMintz, Yuval  * The addr and len arguments are specified in dwords.
2464c965db44STomer Tayar  */
2465c965db44STomer Tayar static u32 qed_grc_dump_mem(struct qed_hwfn *p_hwfn,
2466c965db44STomer Tayar 			    struct qed_ptt *p_ptt,
2467c965db44STomer Tayar 			    u32 *dump_buf,
2468c965db44STomer Tayar 			    bool dump,
2469c965db44STomer Tayar 			    const char *name,
2470be086e7cSMintz, Yuval 			    u32 addr,
2471be086e7cSMintz, Yuval 			    u32 len,
24727b6859fbSMintz, Yuval 			    bool wide_bus,
2473c965db44STomer Tayar 			    u32 bit_width,
2474c965db44STomer Tayar 			    bool packed,
24752d22bc83SMichal Kalderon 			    const char *mem_group, char storm_letter)
2476c965db44STomer Tayar {
2477c965db44STomer Tayar 	u32 offset = 0;
2478c965db44STomer Tayar 
2479c965db44STomer Tayar 	offset += qed_grc_dump_mem_hdr(p_hwfn,
2480c965db44STomer Tayar 				       dump_buf + offset,
2481c965db44STomer Tayar 				       dump,
2482c965db44STomer Tayar 				       name,
2483be086e7cSMintz, Yuval 				       addr,
2484be086e7cSMintz, Yuval 				       len,
2485c965db44STomer Tayar 				       bit_width,
24862d22bc83SMichal Kalderon 				       packed, mem_group, storm_letter);
2487be086e7cSMintz, Yuval 	offset += qed_grc_dump_addr_range(p_hwfn,
2488be086e7cSMintz, Yuval 					  p_ptt,
24897b6859fbSMintz, Yuval 					  dump_buf + offset,
2490d52c89f1SMichal Kalderon 					  dump, addr, len, wide_bus,
2491d52c89f1SMichal Kalderon 					  SPLIT_TYPE_NONE, 0);
24927b6859fbSMintz, Yuval 
2493c965db44STomer Tayar 	return offset;
2494c965db44STomer Tayar }
2495c965db44STomer Tayar 
2496c965db44STomer Tayar /* Dumps GRC memories entries. Returns the dumped size in dwords. */
2497c965db44STomer Tayar static u32 qed_grc_dump_mem_entries(struct qed_hwfn *p_hwfn,
2498c965db44STomer Tayar 				    struct qed_ptt *p_ptt,
24992d22bc83SMichal Kalderon 				    struct virt_mem_desc input_mems_arr,
2500c965db44STomer Tayar 				    u32 *dump_buf, bool dump)
2501c965db44STomer Tayar {
2502c965db44STomer Tayar 	u32 i, offset = 0, input_offset = 0;
2503c965db44STomer Tayar 	bool mode_match = true;
2504c965db44STomer Tayar 
25052d22bc83SMichal Kalderon 	while (input_offset < BYTES_TO_DWORDS(input_mems_arr.size)) {
2506c965db44STomer Tayar 		const struct dbg_dump_cond_hdr *cond_hdr;
25077b6859fbSMintz, Yuval 		u16 modes_buf_offset;
2508c965db44STomer Tayar 		u32 num_entries;
2509c965db44STomer Tayar 		bool eval_mode;
2510c965db44STomer Tayar 
25112d22bc83SMichal Kalderon 		cond_hdr =
25122d22bc83SMichal Kalderon 		    (const struct dbg_dump_cond_hdr *)input_mems_arr.ptr +
25132d22bc83SMichal Kalderon 		    input_offset++;
25147b6859fbSMintz, Yuval 		num_entries = cond_hdr->data_size / MEM_DUMP_ENTRY_SIZE_DWORDS;
2515c965db44STomer Tayar 
2516c965db44STomer Tayar 		/* Check required mode */
25177b6859fbSMintz, Yuval 		eval_mode = GET_FIELD(cond_hdr->mode.data,
25187b6859fbSMintz, Yuval 				      DBG_MODE_HDR_EVAL_MODE) > 0;
2519c965db44STomer Tayar 		if (eval_mode) {
25207b6859fbSMintz, Yuval 			modes_buf_offset =
2521c965db44STomer Tayar 				GET_FIELD(cond_hdr->mode.data,
2522c965db44STomer Tayar 					  DBG_MODE_HDR_MODES_BUF_OFFSET);
2523c965db44STomer Tayar 			mode_match = qed_is_mode_match(p_hwfn,
2524c965db44STomer Tayar 						       &modes_buf_offset);
2525c965db44STomer Tayar 		}
2526c965db44STomer Tayar 
2527c965db44STomer Tayar 		if (!mode_match) {
2528c965db44STomer Tayar 			input_offset += cond_hdr->data_size;
2529c965db44STomer Tayar 			continue;
2530c965db44STomer Tayar 		}
2531c965db44STomer Tayar 
2532c965db44STomer Tayar 		for (i = 0; i < num_entries;
2533c965db44STomer Tayar 		     i++, input_offset += MEM_DUMP_ENTRY_SIZE_DWORDS) {
2534c965db44STomer Tayar 			const struct dbg_dump_mem *mem =
25352d22bc83SMichal Kalderon 			    (const struct dbg_dump_mem *)((u32 *)
25362d22bc83SMichal Kalderon 							  input_mems_arr.ptr
25372d22bc83SMichal Kalderon 							  + input_offset);
25382d22bc83SMichal Kalderon 			const struct dbg_block *block;
25392d22bc83SMichal Kalderon 			char storm_letter = 0;
25407b6859fbSMintz, Yuval 			u32 mem_addr, mem_len;
25412d22bc83SMichal Kalderon 			bool mem_wide_bus;
25422d22bc83SMichal Kalderon 			u8 mem_group_id;
25437b6859fbSMintz, Yuval 
25442d22bc83SMichal Kalderon 			mem_group_id = GET_FIELD(mem->dword0,
25452d22bc83SMichal Kalderon 						 DBG_DUMP_MEM_MEM_GROUP_ID);
2546c965db44STomer Tayar 			if (mem_group_id >= MEM_GROUPS_NUM) {
2547c965db44STomer Tayar 				DP_NOTICE(p_hwfn, "Invalid mem_group_id\n");
2548c965db44STomer Tayar 				return 0;
2549c965db44STomer Tayar 			}
2550c965db44STomer Tayar 
25517b6859fbSMintz, Yuval 			if (!qed_grc_is_mem_included(p_hwfn,
25522d22bc83SMichal Kalderon 						     (enum block_id)
25532d22bc83SMichal Kalderon 						     cond_hdr->block_id,
25547b6859fbSMintz, Yuval 						     mem_group_id))
25557b6859fbSMintz, Yuval 				continue;
25567b6859fbSMintz, Yuval 
25577b6859fbSMintz, Yuval 			mem_addr = GET_FIELD(mem->dword0, DBG_DUMP_MEM_ADDRESS);
25587b6859fbSMintz, Yuval 			mem_len = GET_FIELD(mem->dword1, DBG_DUMP_MEM_LENGTH);
25597b6859fbSMintz, Yuval 			mem_wide_bus = GET_FIELD(mem->dword1,
25607b6859fbSMintz, Yuval 						 DBG_DUMP_MEM_WIDE_BUS);
2561c965db44STomer Tayar 
25622d22bc83SMichal Kalderon 			block = get_dbg_block(p_hwfn,
25632d22bc83SMichal Kalderon 					      cond_hdr->block_id);
25642d22bc83SMichal Kalderon 
25652d22bc83SMichal Kalderon 			/* If memory is associated with Storm,
25662d22bc83SMichal Kalderon 			 * update storm details
2567c965db44STomer Tayar 			 */
25682d22bc83SMichal Kalderon 			if (block->associated_storm_letter)
25692d22bc83SMichal Kalderon 				storm_letter = block->associated_storm_letter;
2570c965db44STomer Tayar 
2571c965db44STomer Tayar 			/* Dump memory */
25727b6859fbSMintz, Yuval 			offset += qed_grc_dump_mem(p_hwfn,
25737b6859fbSMintz, Yuval 						p_ptt,
25747b6859fbSMintz, Yuval 						dump_buf + offset,
25757b6859fbSMintz, Yuval 						dump,
25767b6859fbSMintz, Yuval 						NULL,
25777b6859fbSMintz, Yuval 						mem_addr,
25787b6859fbSMintz, Yuval 						mem_len,
25797b6859fbSMintz, Yuval 						mem_wide_bus,
25807b6859fbSMintz, Yuval 						0,
2581c965db44STomer Tayar 						false,
2582c965db44STomer Tayar 						s_mem_group_names[mem_group_id],
25837b6859fbSMintz, Yuval 						storm_letter);
2584c965db44STomer Tayar 		}
2585c965db44STomer Tayar 	}
2586c965db44STomer Tayar 
2587c965db44STomer Tayar 	return offset;
2588c965db44STomer Tayar }
2589c965db44STomer Tayar 
2590c965db44STomer Tayar /* Dumps GRC memories according to the input array dump_mem.
2591c965db44STomer Tayar  * Returns the dumped size in dwords.
2592c965db44STomer Tayar  */
2593c965db44STomer Tayar static u32 qed_grc_dump_memories(struct qed_hwfn *p_hwfn,
2594c965db44STomer Tayar 				 struct qed_ptt *p_ptt,
2595c965db44STomer Tayar 				 u32 *dump_buf, bool dump)
2596c965db44STomer Tayar {
25972d22bc83SMichal Kalderon 	struct virt_mem_desc *dbg_buf =
25982d22bc83SMichal Kalderon 	    &p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_MEM];
2599c965db44STomer Tayar 	u32 offset = 0, input_offset = 0;
2600c965db44STomer Tayar 
26012d22bc83SMichal Kalderon 	while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) {
26027b6859fbSMintz, Yuval 		const struct dbg_dump_split_hdr *split_hdr;
26032d22bc83SMichal Kalderon 		struct virt_mem_desc curr_input_mems_arr;
2604d52c89f1SMichal Kalderon 		enum init_split_types split_type;
26057b6859fbSMintz, Yuval 		u32 split_data_size;
26067b6859fbSMintz, Yuval 
26072d22bc83SMichal Kalderon 		split_hdr =
26082d22bc83SMichal Kalderon 		    (const struct dbg_dump_split_hdr *)dbg_buf->ptr +
26092d22bc83SMichal Kalderon 		    input_offset++;
26102d22bc83SMichal Kalderon 		split_type = GET_FIELD(split_hdr->hdr,
2611c965db44STomer Tayar 				       DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
26122d22bc83SMichal Kalderon 		split_data_size = GET_FIELD(split_hdr->hdr,
2613c965db44STomer Tayar 					    DBG_DUMP_SPLIT_HDR_DATA_SIZE);
26142d22bc83SMichal Kalderon 		curr_input_mems_arr.ptr = (u32 *)dbg_buf->ptr + input_offset;
26152d22bc83SMichal Kalderon 		curr_input_mems_arr.size = DWORDS_TO_BYTES(split_data_size);
2616c965db44STomer Tayar 
2617d52c89f1SMichal Kalderon 		if (split_type == SPLIT_TYPE_NONE)
2618c965db44STomer Tayar 			offset += qed_grc_dump_mem_entries(p_hwfn,
2619c965db44STomer Tayar 							   p_ptt,
2620c965db44STomer Tayar 							   curr_input_mems_arr,
2621c965db44STomer Tayar 							   dump_buf + offset,
2622c965db44STomer Tayar 							   dump);
2623d52c89f1SMichal Kalderon 		else
2624c965db44STomer Tayar 			DP_NOTICE(p_hwfn,
2625c965db44STomer Tayar 				  "Dumping split memories is currently not supported\n");
2626c965db44STomer Tayar 
2627c965db44STomer Tayar 		input_offset += split_data_size;
2628c965db44STomer Tayar 	}
2629c965db44STomer Tayar 
2630c965db44STomer Tayar 	return offset;
2631c965db44STomer Tayar }
2632c965db44STomer Tayar 
2633c965db44STomer Tayar /* Dumps GRC context data for the specified Storm.
2634c965db44STomer Tayar  * Returns the dumped size in dwords.
26357b6859fbSMintz, Yuval  * The lid_size argument is specified in quad-regs.
2636c965db44STomer Tayar  */
2637c965db44STomer Tayar static u32 qed_grc_dump_ctx_data(struct qed_hwfn *p_hwfn,
2638c965db44STomer Tayar 				 struct qed_ptt *p_ptt,
2639c965db44STomer Tayar 				 u32 *dump_buf,
2640c965db44STomer Tayar 				 bool dump,
2641c965db44STomer Tayar 				 const char *name,
2642c965db44STomer Tayar 				 u32 num_lids,
26432d22bc83SMichal Kalderon 				 enum cm_ctx_types ctx_type, u8 storm_id)
2644c965db44STomer Tayar {
26452d22bc83SMichal Kalderon 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
26467b6859fbSMintz, Yuval 	struct storm_defs *storm = &s_storm_defs[storm_id];
26472d22bc83SMichal Kalderon 	u32 i, lid, lid_size, total_size;
26482d22bc83SMichal Kalderon 	u32 rd_reg_addr, offset = 0;
26492d22bc83SMichal Kalderon 
26502d22bc83SMichal Kalderon 	/* Convert quad-regs to dwords */
26512d22bc83SMichal Kalderon 	lid_size = storm->cm_ctx_lid_sizes[dev_data->chip_id][ctx_type] * 4;
2652c965db44STomer Tayar 
2653c965db44STomer Tayar 	if (!lid_size)
2654c965db44STomer Tayar 		return 0;
26557b6859fbSMintz, Yuval 
2656c965db44STomer Tayar 	total_size = num_lids * lid_size;
26577b6859fbSMintz, Yuval 
2658c965db44STomer Tayar 	offset += qed_grc_dump_mem_hdr(p_hwfn,
2659c965db44STomer Tayar 				       dump_buf + offset,
2660c965db44STomer Tayar 				       dump,
2661c965db44STomer Tayar 				       name,
2662c965db44STomer Tayar 				       0,
2663c965db44STomer Tayar 				       total_size,
2664c965db44STomer Tayar 				       lid_size * 32,
26652d22bc83SMichal Kalderon 				       false, name, storm->letter);
26667b6859fbSMintz, Yuval 
26677b6859fbSMintz, Yuval 	if (!dump)
26687b6859fbSMintz, Yuval 		return offset + total_size;
2669c965db44STomer Tayar 
26702d22bc83SMichal Kalderon 	rd_reg_addr = BYTES_TO_DWORDS(storm->cm_ctx_rd_addr[ctx_type]);
26712d22bc83SMichal Kalderon 
2672c965db44STomer Tayar 	/* Dump context data */
2673c965db44STomer Tayar 	for (lid = 0; lid < num_lids; lid++) {
26742d22bc83SMichal Kalderon 		for (i = 0; i < lid_size; i++) {
2675c965db44STomer Tayar 			qed_wr(p_hwfn,
26767b6859fbSMintz, Yuval 			       p_ptt, storm->cm_ctx_wr_addr, (i << 9) | lid);
26772d22bc83SMichal Kalderon 			offset += qed_grc_dump_addr_range(p_hwfn,
26782d22bc83SMichal Kalderon 							  p_ptt,
26792d22bc83SMichal Kalderon 							  dump_buf + offset,
26802d22bc83SMichal Kalderon 							  dump,
26812d22bc83SMichal Kalderon 							  rd_reg_addr,
26822d22bc83SMichal Kalderon 							  1,
26832d22bc83SMichal Kalderon 							  false,
26842d22bc83SMichal Kalderon 							  SPLIT_TYPE_NONE, 0);
2685c965db44STomer Tayar 		}
2686c965db44STomer Tayar 	}
2687c965db44STomer Tayar 
2688c965db44STomer Tayar 	return offset;
2689c965db44STomer Tayar }
2690c965db44STomer Tayar 
2691c965db44STomer Tayar /* Dumps GRC contexts. Returns the dumped size in dwords. */
2692c965db44STomer Tayar static u32 qed_grc_dump_ctx(struct qed_hwfn *p_hwfn,
2693c965db44STomer Tayar 			    struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
2694c965db44STomer Tayar {
2695c965db44STomer Tayar 	u32 offset = 0;
2696c965db44STomer Tayar 	u8 storm_id;
2697c965db44STomer Tayar 
2698c965db44STomer Tayar 	for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
2699c965db44STomer Tayar 		if (!qed_grc_is_storm_included(p_hwfn,
2700c965db44STomer Tayar 					       (enum dbg_storms)storm_id))
2701c965db44STomer Tayar 			continue;
2702c965db44STomer Tayar 
2703c965db44STomer Tayar 		/* Dump Conn AG context size */
27042d22bc83SMichal Kalderon 		offset += qed_grc_dump_ctx_data(p_hwfn,
2705c965db44STomer Tayar 						p_ptt,
2706c965db44STomer Tayar 						dump_buf + offset,
2707c965db44STomer Tayar 						dump,
2708c965db44STomer Tayar 						"CONN_AG_CTX",
27092d22bc83SMichal Kalderon 						NUM_OF_LCIDS,
27102d22bc83SMichal Kalderon 						CM_CTX_CONN_AG, storm_id);
2711c965db44STomer Tayar 
2712c965db44STomer Tayar 		/* Dump Conn ST context size */
27132d22bc83SMichal Kalderon 		offset += qed_grc_dump_ctx_data(p_hwfn,
2714c965db44STomer Tayar 						p_ptt,
2715c965db44STomer Tayar 						dump_buf + offset,
2716c965db44STomer Tayar 						dump,
2717c965db44STomer Tayar 						"CONN_ST_CTX",
27182d22bc83SMichal Kalderon 						NUM_OF_LCIDS,
27192d22bc83SMichal Kalderon 						CM_CTX_CONN_ST, storm_id);
2720c965db44STomer Tayar 
2721c965db44STomer Tayar 		/* Dump Task AG context size */
27222d22bc83SMichal Kalderon 		offset += qed_grc_dump_ctx_data(p_hwfn,
2723c965db44STomer Tayar 						p_ptt,
2724c965db44STomer Tayar 						dump_buf + offset,
2725c965db44STomer Tayar 						dump,
2726c965db44STomer Tayar 						"TASK_AG_CTX",
27272d22bc83SMichal Kalderon 						NUM_OF_LTIDS,
27282d22bc83SMichal Kalderon 						CM_CTX_TASK_AG, storm_id);
2729c965db44STomer Tayar 
2730c965db44STomer Tayar 		/* Dump Task ST context size */
27312d22bc83SMichal Kalderon 		offset += qed_grc_dump_ctx_data(p_hwfn,
2732c965db44STomer Tayar 						p_ptt,
2733c965db44STomer Tayar 						dump_buf + offset,
2734c965db44STomer Tayar 						dump,
2735c965db44STomer Tayar 						"TASK_ST_CTX",
27362d22bc83SMichal Kalderon 						NUM_OF_LTIDS,
27372d22bc83SMichal Kalderon 						CM_CTX_TASK_ST, storm_id);
2738c965db44STomer Tayar 	}
2739c965db44STomer Tayar 
2740c965db44STomer Tayar 	return offset;
2741c965db44STomer Tayar }
2742c965db44STomer Tayar 
27432d22bc83SMichal Kalderon #define VFC_STATUS_RESP_READY_BIT	0
27442d22bc83SMichal Kalderon #define VFC_STATUS_BUSY_BIT		1
27452d22bc83SMichal Kalderon #define VFC_STATUS_SENDING_CMD_BIT	2
27462d22bc83SMichal Kalderon 
27472d22bc83SMichal Kalderon #define VFC_POLLING_DELAY_MS	1
27482d22bc83SMichal Kalderon #define VFC_POLLING_COUNT		20
27492d22bc83SMichal Kalderon 
27502d22bc83SMichal Kalderon /* Reads data from VFC. Returns the number of dwords read (0 on error).
27512d22bc83SMichal Kalderon  * Sizes are specified in dwords.
27522d22bc83SMichal Kalderon  */
27532d22bc83SMichal Kalderon static u32 qed_grc_dump_read_from_vfc(struct qed_hwfn *p_hwfn,
27542d22bc83SMichal Kalderon 				      struct qed_ptt *p_ptt,
27552d22bc83SMichal Kalderon 				      struct storm_defs *storm,
27562d22bc83SMichal Kalderon 				      u32 *cmd_data,
27572d22bc83SMichal Kalderon 				      u32 cmd_size,
27582d22bc83SMichal Kalderon 				      u32 *addr_data,
27592d22bc83SMichal Kalderon 				      u32 addr_size,
27602d22bc83SMichal Kalderon 				      u32 resp_size, u32 *dump_buf)
2761c965db44STomer Tayar {
27622d22bc83SMichal Kalderon 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
27632d22bc83SMichal Kalderon 	u32 vfc_status, polling_ms, polling_count = 0, i;
27642d22bc83SMichal Kalderon 	u32 reg_addr, sem_base;
27652d22bc83SMichal Kalderon 	bool is_ready = false;
2766c965db44STomer Tayar 
27672d22bc83SMichal Kalderon 	sem_base = storm->sem_fast_mem_addr;
27682d22bc83SMichal Kalderon 	polling_ms = VFC_POLLING_DELAY_MS *
27692d22bc83SMichal Kalderon 	    s_hw_type_defs[dev_data->hw_type].delay_factor;
2770c965db44STomer Tayar 
27712d22bc83SMichal Kalderon 	/* Write VFC command */
27722d22bc83SMichal Kalderon 	ARR_REG_WR(p_hwfn,
2773c965db44STomer Tayar 		   p_ptt,
27742d22bc83SMichal Kalderon 		   sem_base + SEM_FAST_REG_VFC_DATA_WR,
27752d22bc83SMichal Kalderon 		   cmd_data, cmd_size);
27762d22bc83SMichal Kalderon 
27772d22bc83SMichal Kalderon 	/* Write VFC address */
27782d22bc83SMichal Kalderon 	ARR_REG_WR(p_hwfn,
27792d22bc83SMichal Kalderon 		   p_ptt,
27802d22bc83SMichal Kalderon 		   sem_base + SEM_FAST_REG_VFC_ADDR,
27812d22bc83SMichal Kalderon 		   addr_data, addr_size);
27822d22bc83SMichal Kalderon 
27832d22bc83SMichal Kalderon 	/* Read response */
27842d22bc83SMichal Kalderon 	for (i = 0; i < resp_size; i++) {
27852d22bc83SMichal Kalderon 		/* Poll until ready */
27862d22bc83SMichal Kalderon 		do {
27872d22bc83SMichal Kalderon 			reg_addr = sem_base + SEM_FAST_REG_VFC_STATUS;
27882d22bc83SMichal Kalderon 			qed_grc_dump_addr_range(p_hwfn,
27892d22bc83SMichal Kalderon 						p_ptt,
27902d22bc83SMichal Kalderon 						&vfc_status,
2791c965db44STomer Tayar 						true,
27922d22bc83SMichal Kalderon 						BYTES_TO_DWORDS(reg_addr),
27932d22bc83SMichal Kalderon 						1,
27942d22bc83SMichal Kalderon 						false, SPLIT_TYPE_NONE, 0);
27952d22bc83SMichal Kalderon 			is_ready = vfc_status & BIT(VFC_STATUS_RESP_READY_BIT);
27962d22bc83SMichal Kalderon 
27972d22bc83SMichal Kalderon 			if (!is_ready) {
27982d22bc83SMichal Kalderon 				if (polling_count++ == VFC_POLLING_COUNT)
27992d22bc83SMichal Kalderon 					return 0;
28002d22bc83SMichal Kalderon 
28012d22bc83SMichal Kalderon 				msleep(polling_ms);
2802c965db44STomer Tayar 			}
28032d22bc83SMichal Kalderon 		} while (!is_ready);
28042d22bc83SMichal Kalderon 
28052d22bc83SMichal Kalderon 		reg_addr = sem_base + SEM_FAST_REG_VFC_DATA_RD;
28062d22bc83SMichal Kalderon 		qed_grc_dump_addr_range(p_hwfn,
28072d22bc83SMichal Kalderon 					p_ptt,
28082d22bc83SMichal Kalderon 					dump_buf + i,
28092d22bc83SMichal Kalderon 					true,
28102d22bc83SMichal Kalderon 					BYTES_TO_DWORDS(reg_addr),
28112d22bc83SMichal Kalderon 					1, false, SPLIT_TYPE_NONE, 0);
2812c965db44STomer Tayar 	}
2813c965db44STomer Tayar 
28142d22bc83SMichal Kalderon 	return resp_size;
2815c965db44STomer Tayar }
2816c965db44STomer Tayar 
2817c965db44STomer Tayar /* Dump VFC CAM. Returns the dumped size in dwords. */
2818c965db44STomer Tayar static u32 qed_grc_dump_vfc_cam(struct qed_hwfn *p_hwfn,
2819c965db44STomer Tayar 				struct qed_ptt *p_ptt,
2820c965db44STomer Tayar 				u32 *dump_buf, bool dump, u8 storm_id)
2821c965db44STomer Tayar {
2822c965db44STomer Tayar 	u32 total_size = VFC_CAM_NUM_ROWS * VFC_CAM_RESP_DWORDS;
28237b6859fbSMintz, Yuval 	struct storm_defs *storm = &s_storm_defs[storm_id];
2824c965db44STomer Tayar 	u32 cam_addr[VFC_CAM_ADDR_DWORDS] = { 0 };
2825c965db44STomer Tayar 	u32 cam_cmd[VFC_CAM_CMD_DWORDS] = { 0 };
28262d22bc83SMichal Kalderon 	u32 row, offset = 0;
2827c965db44STomer Tayar 
2828c965db44STomer Tayar 	offset += qed_grc_dump_mem_hdr(p_hwfn,
2829c965db44STomer Tayar 				       dump_buf + offset,
2830c965db44STomer Tayar 				       dump,
2831c965db44STomer Tayar 				       "vfc_cam",
2832c965db44STomer Tayar 				       0,
2833c965db44STomer Tayar 				       total_size,
2834c965db44STomer Tayar 				       256,
28352d22bc83SMichal Kalderon 				       false, "vfc_cam", storm->letter);
28367b6859fbSMintz, Yuval 
28377b6859fbSMintz, Yuval 	if (!dump)
28387b6859fbSMintz, Yuval 		return offset + total_size;
28397b6859fbSMintz, Yuval 
2840c965db44STomer Tayar 	/* Prepare CAM address */
2841c965db44STomer Tayar 	SET_VAR_FIELD(cam_addr, VFC_CAM_ADDR, OP, VFC_OPCODE_CAM_RD);
28427b6859fbSMintz, Yuval 
28432d22bc83SMichal Kalderon 	/* Read VFC CAM data */
28442d22bc83SMichal Kalderon 	for (row = 0; row < VFC_CAM_NUM_ROWS; row++) {
2845c965db44STomer Tayar 		SET_VAR_FIELD(cam_cmd, VFC_CAM_CMD, ROW, row);
28462d22bc83SMichal Kalderon 		offset += qed_grc_dump_read_from_vfc(p_hwfn,
2847c965db44STomer Tayar 						     p_ptt,
28482d22bc83SMichal Kalderon 						     storm,
28492d22bc83SMichal Kalderon 						     cam_cmd,
28502d22bc83SMichal Kalderon 						     VFC_CAM_CMD_DWORDS,
28512d22bc83SMichal Kalderon 						     cam_addr,
28522d22bc83SMichal Kalderon 						     VFC_CAM_ADDR_DWORDS,
28532d22bc83SMichal Kalderon 						     VFC_CAM_RESP_DWORDS,
28542d22bc83SMichal Kalderon 						     dump_buf + offset);
2855c965db44STomer Tayar 	}
2856c965db44STomer Tayar 
2857c965db44STomer Tayar 	return offset;
2858c965db44STomer Tayar }
2859c965db44STomer Tayar 
2860c965db44STomer Tayar /* Dump VFC RAM. Returns the dumped size in dwords. */
2861c965db44STomer Tayar static u32 qed_grc_dump_vfc_ram(struct qed_hwfn *p_hwfn,
2862c965db44STomer Tayar 				struct qed_ptt *p_ptt,
2863c965db44STomer Tayar 				u32 *dump_buf,
2864c965db44STomer Tayar 				bool dump,
2865c965db44STomer Tayar 				u8 storm_id, struct vfc_ram_defs *ram_defs)
2866c965db44STomer Tayar {
2867c965db44STomer Tayar 	u32 total_size = ram_defs->num_rows * VFC_RAM_RESP_DWORDS;
28687b6859fbSMintz, Yuval 	struct storm_defs *storm = &s_storm_defs[storm_id];
2869c965db44STomer Tayar 	u32 ram_addr[VFC_RAM_ADDR_DWORDS] = { 0 };
2870c965db44STomer Tayar 	u32 ram_cmd[VFC_RAM_CMD_DWORDS] = { 0 };
28712d22bc83SMichal Kalderon 	u32 row, offset = 0;
2872c965db44STomer Tayar 
2873c965db44STomer Tayar 	offset += qed_grc_dump_mem_hdr(p_hwfn,
2874c965db44STomer Tayar 				       dump_buf + offset,
2875c965db44STomer Tayar 				       dump,
2876c965db44STomer Tayar 				       ram_defs->mem_name,
2877c965db44STomer Tayar 				       0,
2878c965db44STomer Tayar 				       total_size,
2879c965db44STomer Tayar 				       256,
2880c965db44STomer Tayar 				       false,
2881c965db44STomer Tayar 				       ram_defs->type_name,
28822d22bc83SMichal Kalderon 				       storm->letter);
2883c965db44STomer Tayar 
2884c965db44STomer Tayar 	if (!dump)
2885c965db44STomer Tayar 		return offset + total_size;
2886c965db44STomer Tayar 
28872d22bc83SMichal Kalderon 	/* Prepare RAM address */
28882d22bc83SMichal Kalderon 	SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, OP, VFC_OPCODE_RAM_RD);
28892d22bc83SMichal Kalderon 
28902d22bc83SMichal Kalderon 	/* Read VFC RAM data */
2891c965db44STomer Tayar 	for (row = ram_defs->base_row;
28922d22bc83SMichal Kalderon 	     row < ram_defs->base_row + ram_defs->num_rows; row++) {
2893c965db44STomer Tayar 		SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, ROW, row);
28942d22bc83SMichal Kalderon 		offset += qed_grc_dump_read_from_vfc(p_hwfn,
2895c965db44STomer Tayar 						     p_ptt,
28962d22bc83SMichal Kalderon 						     storm,
28972d22bc83SMichal Kalderon 						     ram_cmd,
28982d22bc83SMichal Kalderon 						     VFC_RAM_CMD_DWORDS,
28992d22bc83SMichal Kalderon 						     ram_addr,
29002d22bc83SMichal Kalderon 						     VFC_RAM_ADDR_DWORDS,
29012d22bc83SMichal Kalderon 						     VFC_RAM_RESP_DWORDS,
29022d22bc83SMichal Kalderon 						     dump_buf + offset);
2903c965db44STomer Tayar 	}
2904c965db44STomer Tayar 
2905c965db44STomer Tayar 	return offset;
2906c965db44STomer Tayar }
2907c965db44STomer Tayar 
2908c965db44STomer Tayar /* Dumps GRC VFC data. Returns the dumped size in dwords. */
2909c965db44STomer Tayar static u32 qed_grc_dump_vfc(struct qed_hwfn *p_hwfn,
2910c965db44STomer Tayar 			    struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
2911c965db44STomer Tayar {
2912c965db44STomer Tayar 	u8 storm_id, i;
2913c965db44STomer Tayar 	u32 offset = 0;
2914c965db44STomer Tayar 
2915c965db44STomer Tayar 	for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
29167b6859fbSMintz, Yuval 		if (!qed_grc_is_storm_included(p_hwfn,
29177b6859fbSMintz, Yuval 					       (enum dbg_storms)storm_id) ||
29182d22bc83SMichal Kalderon 		    !s_storm_defs[storm_id].has_vfc)
29197b6859fbSMintz, Yuval 			continue;
29207b6859fbSMintz, Yuval 
2921c965db44STomer Tayar 		/* Read CAM */
2922c965db44STomer Tayar 		offset += qed_grc_dump_vfc_cam(p_hwfn,
2923c965db44STomer Tayar 					       p_ptt,
2924c965db44STomer Tayar 					       dump_buf + offset,
2925c965db44STomer Tayar 					       dump, storm_id);
2926c965db44STomer Tayar 
2927c965db44STomer Tayar 		/* Read RAM */
2928c965db44STomer Tayar 		for (i = 0; i < NUM_VFC_RAM_TYPES; i++)
2929c965db44STomer Tayar 			offset += qed_grc_dump_vfc_ram(p_hwfn,
2930c965db44STomer Tayar 						       p_ptt,
29317b6859fbSMintz, Yuval 						       dump_buf + offset,
2932c965db44STomer Tayar 						       dump,
2933c965db44STomer Tayar 						       storm_id,
29347b6859fbSMintz, Yuval 						       &s_vfc_ram_defs[i]);
2935c965db44STomer Tayar 	}
2936c965db44STomer Tayar 
2937c965db44STomer Tayar 	return offset;
2938c965db44STomer Tayar }
2939c965db44STomer Tayar 
2940c965db44STomer Tayar /* Dumps GRC RSS data. Returns the dumped size in dwords. */
2941c965db44STomer Tayar static u32 qed_grc_dump_rss(struct qed_hwfn *p_hwfn,
2942c965db44STomer Tayar 			    struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
2943c965db44STomer Tayar {
2944c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2945c965db44STomer Tayar 	u32 offset = 0;
2946c965db44STomer Tayar 	u8 rss_mem_id;
2947c965db44STomer Tayar 
2948c965db44STomer Tayar 	for (rss_mem_id = 0; rss_mem_id < NUM_RSS_MEM_TYPES; rss_mem_id++) {
2949da090917STomer Tayar 		u32 rss_addr, num_entries, total_dwords;
29507b6859fbSMintz, Yuval 		struct rss_mem_defs *rss_defs;
2951da090917STomer Tayar 		u32 addr, num_dwords_to_read;
29527b6859fbSMintz, Yuval 		bool packed;
29537b6859fbSMintz, Yuval 
29547b6859fbSMintz, Yuval 		rss_defs = &s_rss_mem_defs[rss_mem_id];
29557b6859fbSMintz, Yuval 		rss_addr = rss_defs->addr;
29567b6859fbSMintz, Yuval 		num_entries = rss_defs->num_entries[dev_data->chip_id];
2957da090917STomer Tayar 		total_dwords = (num_entries * rss_defs->entry_width) / 32;
2958da090917STomer Tayar 		packed = (rss_defs->entry_width == 16);
2959c965db44STomer Tayar 
2960c965db44STomer Tayar 		offset += qed_grc_dump_mem_hdr(p_hwfn,
2961c965db44STomer Tayar 					       dump_buf + offset,
2962c965db44STomer Tayar 					       dump,
2963c965db44STomer Tayar 					       rss_defs->mem_name,
2964be086e7cSMintz, Yuval 					       0,
2965be086e7cSMintz, Yuval 					       total_dwords,
2966da090917STomer Tayar 					       rss_defs->entry_width,
2967c965db44STomer Tayar 					       packed,
29682d22bc83SMichal Kalderon 					       rss_defs->type_name, 0);
2969c965db44STomer Tayar 
29707b6859fbSMintz, Yuval 		/* Dump RSS data */
2971c965db44STomer Tayar 		if (!dump) {
2972be086e7cSMintz, Yuval 			offset += total_dwords;
2973c965db44STomer Tayar 			continue;
2974c965db44STomer Tayar 		}
2975c965db44STomer Tayar 
2976be086e7cSMintz, Yuval 		addr = BYTES_TO_DWORDS(RSS_REG_RSS_RAM_DATA);
2977da090917STomer Tayar 		while (total_dwords) {
2978da090917STomer Tayar 			num_dwords_to_read = min_t(u32,
2979da090917STomer Tayar 						   RSS_REG_RSS_RAM_DATA_SIZE,
2980da090917STomer Tayar 						   total_dwords);
2981be086e7cSMintz, Yuval 			qed_wr(p_hwfn, p_ptt, RSS_REG_RSS_RAM_ADDR, rss_addr);
2982be086e7cSMintz, Yuval 			offset += qed_grc_dump_addr_range(p_hwfn,
2983be086e7cSMintz, Yuval 							  p_ptt,
29847b6859fbSMintz, Yuval 							  dump_buf + offset,
2985be086e7cSMintz, Yuval 							  dump,
2986be086e7cSMintz, Yuval 							  addr,
2987da090917STomer Tayar 							  num_dwords_to_read,
2988d52c89f1SMichal Kalderon 							  false,
2989d52c89f1SMichal Kalderon 							  SPLIT_TYPE_NONE, 0);
2990da090917STomer Tayar 			total_dwords -= num_dwords_to_read;
2991da090917STomer Tayar 			rss_addr++;
2992c965db44STomer Tayar 		}
2993c965db44STomer Tayar 	}
2994c965db44STomer Tayar 
2995c965db44STomer Tayar 	return offset;
2996c965db44STomer Tayar }
2997c965db44STomer Tayar 
2998c965db44STomer Tayar /* Dumps GRC Big RAM. Returns the dumped size in dwords. */
2999c965db44STomer Tayar static u32 qed_grc_dump_big_ram(struct qed_hwfn *p_hwfn,
3000c965db44STomer Tayar 				struct qed_ptt *p_ptt,
3001c965db44STomer Tayar 				u32 *dump_buf, bool dump, u8 big_ram_id)
3002c965db44STomer Tayar {
3003c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3004da090917STomer Tayar 	u32 block_size, ram_size, offset = 0, reg_val, i;
3005c965db44STomer Tayar 	char mem_name[12] = "???_BIG_RAM";
3006c965db44STomer Tayar 	char type_name[8] = "???_RAM";
3007be086e7cSMintz, Yuval 	struct big_ram_defs *big_ram;
3008c965db44STomer Tayar 
3009be086e7cSMintz, Yuval 	big_ram = &s_big_ram_defs[big_ram_id];
3010da090917STomer Tayar 	ram_size = big_ram->ram_size[dev_data->chip_id];
3011da090917STomer Tayar 
3012da090917STomer Tayar 	reg_val = qed_rd(p_hwfn, p_ptt, big_ram->is_256b_reg_addr);
3013da090917STomer Tayar 	block_size = reg_val &
3014da090917STomer Tayar 		     BIT(big_ram->is_256b_bit_offset[dev_data->chip_id]) ? 256
3015da090917STomer Tayar 									 : 128;
3016c965db44STomer Tayar 
3017c7d852e3SDenis Bolotin 	strncpy(type_name, big_ram->instance_name, BIG_RAM_NAME_LEN);
3018c7d852e3SDenis Bolotin 	strncpy(mem_name, big_ram->instance_name, BIG_RAM_NAME_LEN);
3019c965db44STomer Tayar 
3020c965db44STomer Tayar 	/* Dump memory header */
3021c965db44STomer Tayar 	offset += qed_grc_dump_mem_hdr(p_hwfn,
3022c965db44STomer Tayar 				       dump_buf + offset,
3023c965db44STomer Tayar 				       dump,
3024c965db44STomer Tayar 				       mem_name,
3025c965db44STomer Tayar 				       0,
3026c965db44STomer Tayar 				       ram_size,
3027da090917STomer Tayar 				       block_size * 8,
30282d22bc83SMichal Kalderon 				       false, type_name, 0);
3029c965db44STomer Tayar 
30307b6859fbSMintz, Yuval 	/* Read and dump Big RAM data */
3031c965db44STomer Tayar 	if (!dump)
3032c965db44STomer Tayar 		return offset + ram_size;
3033c965db44STomer Tayar 
30347b6859fbSMintz, Yuval 	/* Dump Big RAM */
3035da090917STomer Tayar 	for (i = 0; i < DIV_ROUND_UP(ram_size, BRB_REG_BIG_RAM_DATA_SIZE);
3036da090917STomer Tayar 	     i++) {
3037be086e7cSMintz, Yuval 		u32 addr, len;
3038be086e7cSMintz, Yuval 
3039be086e7cSMintz, Yuval 		qed_wr(p_hwfn, p_ptt, big_ram->addr_reg_addr, i);
3040be086e7cSMintz, Yuval 		addr = BYTES_TO_DWORDS(big_ram->data_reg_addr);
3041da090917STomer Tayar 		len = BRB_REG_BIG_RAM_DATA_SIZE;
3042be086e7cSMintz, Yuval 		offset += qed_grc_dump_addr_range(p_hwfn,
3043be086e7cSMintz, Yuval 						  p_ptt,
3044be086e7cSMintz, Yuval 						  dump_buf + offset,
3045be086e7cSMintz, Yuval 						  dump,
3046be086e7cSMintz, Yuval 						  addr,
30477b6859fbSMintz, Yuval 						  len,
3048d52c89f1SMichal Kalderon 						  false, SPLIT_TYPE_NONE, 0);
3049c965db44STomer Tayar 	}
3050c965db44STomer Tayar 
3051c965db44STomer Tayar 	return offset;
3052c965db44STomer Tayar }
3053c965db44STomer Tayar 
30542d22bc83SMichal Kalderon /* Dumps MCP scratchpad. Returns the dumped size in dwords. */
3055c965db44STomer Tayar static u32 qed_grc_dump_mcp(struct qed_hwfn *p_hwfn,
3056c965db44STomer Tayar 			    struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3057c965db44STomer Tayar {
3058c965db44STomer Tayar 	bool block_enable[MAX_BLOCK_ID] = { 0 };
3059be086e7cSMintz, Yuval 	u32 offset = 0, addr;
3060c965db44STomer Tayar 	bool halted = false;
3061c965db44STomer Tayar 
3062c965db44STomer Tayar 	/* Halt MCP */
3063be086e7cSMintz, Yuval 	if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {
3064c965db44STomer Tayar 		halted = !qed_mcp_halt(p_hwfn, p_ptt);
3065c965db44STomer Tayar 		if (!halted)
3066c965db44STomer Tayar 			DP_NOTICE(p_hwfn, "MCP halt failed!\n");
3067c965db44STomer Tayar 	}
3068c965db44STomer Tayar 
3069c965db44STomer Tayar 	/* Dump MCP scratchpad */
3070c965db44STomer Tayar 	offset += qed_grc_dump_mem(p_hwfn,
3071c965db44STomer Tayar 				   p_ptt,
3072c965db44STomer Tayar 				   dump_buf + offset,
3073c965db44STomer Tayar 				   dump,
3074c965db44STomer Tayar 				   NULL,
3075be086e7cSMintz, Yuval 				   BYTES_TO_DWORDS(MCP_REG_SCRATCH),
30762d22bc83SMichal Kalderon 				   MCP_REG_SCRATCH_SIZE,
30772d22bc83SMichal Kalderon 				   false, 0, false, "MCP", 0);
3078c965db44STomer Tayar 
3079c965db44STomer Tayar 	/* Dump MCP cpu_reg_file */
3080c965db44STomer Tayar 	offset += qed_grc_dump_mem(p_hwfn,
3081c965db44STomer Tayar 				   p_ptt,
3082c965db44STomer Tayar 				   dump_buf + offset,
3083c965db44STomer Tayar 				   dump,
3084c965db44STomer Tayar 				   NULL,
3085be086e7cSMintz, Yuval 				   BYTES_TO_DWORDS(MCP_REG_CPU_REG_FILE),
3086c965db44STomer Tayar 				   MCP_REG_CPU_REG_FILE_SIZE,
30872d22bc83SMichal Kalderon 				   false, 0, false, "MCP", 0);
3088c965db44STomer Tayar 
3089c965db44STomer Tayar 	/* Dump MCP registers */
3090c965db44STomer Tayar 	block_enable[BLOCK_MCP] = true;
3091c965db44STomer Tayar 	offset += qed_grc_dump_registers(p_hwfn,
3092c965db44STomer Tayar 					 p_ptt,
3093c965db44STomer Tayar 					 dump_buf + offset,
30942d22bc83SMichal Kalderon 					 dump, block_enable, "MCP");
3095c965db44STomer Tayar 
3096c965db44STomer Tayar 	/* Dump required non-MCP registers */
3097c965db44STomer Tayar 	offset += qed_grc_dump_regs_hdr(dump_buf + offset,
3098d52c89f1SMichal Kalderon 					dump, 1, SPLIT_TYPE_NONE, 0,
30992d22bc83SMichal Kalderon 					"MCP");
3100be086e7cSMintz, Yuval 	addr = BYTES_TO_DWORDS(MISC_REG_SHARED_MEM_ADDR);
3101c965db44STomer Tayar 	offset += qed_grc_dump_reg_entry(p_hwfn,
3102c965db44STomer Tayar 					 p_ptt,
3103c965db44STomer Tayar 					 dump_buf + offset,
3104c965db44STomer Tayar 					 dump,
3105be086e7cSMintz, Yuval 					 addr,
31067b6859fbSMintz, Yuval 					 1,
3107d52c89f1SMichal Kalderon 					 false, SPLIT_TYPE_NONE, 0);
3108c965db44STomer Tayar 
3109c965db44STomer Tayar 	/* Release MCP */
3110c965db44STomer Tayar 	if (halted && qed_mcp_resume(p_hwfn, p_ptt))
3111c965db44STomer Tayar 		DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n");
31127b6859fbSMintz, Yuval 
3113c965db44STomer Tayar 	return offset;
3114c965db44STomer Tayar }
3115c965db44STomer Tayar 
31162d22bc83SMichal Kalderon /* Dumps the tbus indirect memory for all PHYs.
31172d22bc83SMichal Kalderon  * Returns the dumped size in dwords.
31182d22bc83SMichal Kalderon  */
3119c965db44STomer Tayar static u32 qed_grc_dump_phy(struct qed_hwfn *p_hwfn,
3120c965db44STomer Tayar 			    struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3121c965db44STomer Tayar {
3122c965db44STomer Tayar 	u32 offset = 0, tbus_lo_offset, tbus_hi_offset;
3123c965db44STomer Tayar 	char mem_name[32];
3124c965db44STomer Tayar 	u8 phy_id;
3125c965db44STomer Tayar 
3126c965db44STomer Tayar 	for (phy_id = 0; phy_id < ARRAY_SIZE(s_phy_defs); phy_id++) {
31277b6859fbSMintz, Yuval 		u32 addr_lo_addr, addr_hi_addr, data_lo_addr, data_hi_addr;
31287b6859fbSMintz, Yuval 		struct phy_defs *phy_defs;
31297b6859fbSMintz, Yuval 		u8 *bytes_buf;
3130c965db44STomer Tayar 
31317b6859fbSMintz, Yuval 		phy_defs = &s_phy_defs[phy_id];
31327b6859fbSMintz, Yuval 		addr_lo_addr = phy_defs->base_addr +
31337b6859fbSMintz, Yuval 			       phy_defs->tbus_addr_lo_addr;
31347b6859fbSMintz, Yuval 		addr_hi_addr = phy_defs->base_addr +
31357b6859fbSMintz, Yuval 			       phy_defs->tbus_addr_hi_addr;
31367b6859fbSMintz, Yuval 		data_lo_addr = phy_defs->base_addr +
31377b6859fbSMintz, Yuval 			       phy_defs->tbus_data_lo_addr;
31387b6859fbSMintz, Yuval 		data_hi_addr = phy_defs->base_addr +
31397b6859fbSMintz, Yuval 			       phy_defs->tbus_data_hi_addr;
31407b6859fbSMintz, Yuval 
31417b6859fbSMintz, Yuval 		if (snprintf(mem_name, sizeof(mem_name), "tbus_%s",
31427b6859fbSMintz, Yuval 			     phy_defs->phy_name) < 0)
3143c965db44STomer Tayar 			DP_NOTICE(p_hwfn,
3144c965db44STomer Tayar 				  "Unexpected debug error: invalid PHY memory name\n");
31457b6859fbSMintz, Yuval 
3146c965db44STomer Tayar 		offset += qed_grc_dump_mem_hdr(p_hwfn,
3147c965db44STomer Tayar 					       dump_buf + offset,
3148c965db44STomer Tayar 					       dump,
3149c965db44STomer Tayar 					       mem_name,
3150c965db44STomer Tayar 					       0,
3151c965db44STomer Tayar 					       PHY_DUMP_SIZE_DWORDS,
31522d22bc83SMichal Kalderon 					       16, true, mem_name, 0);
31537b6859fbSMintz, Yuval 
31547b6859fbSMintz, Yuval 		if (!dump) {
31557b6859fbSMintz, Yuval 			offset += PHY_DUMP_SIZE_DWORDS;
31567b6859fbSMintz, Yuval 			continue;
31577b6859fbSMintz, Yuval 		}
3158c965db44STomer Tayar 
3159da090917STomer Tayar 		bytes_buf = (u8 *)(dump_buf + offset);
3160c965db44STomer Tayar 		for (tbus_hi_offset = 0;
3161c965db44STomer Tayar 		     tbus_hi_offset < (NUM_PHY_TBUS_ADDRESSES >> 8);
3162c965db44STomer Tayar 		     tbus_hi_offset++) {
31637b6859fbSMintz, Yuval 			qed_wr(p_hwfn, p_ptt, addr_hi_addr, tbus_hi_offset);
3164c965db44STomer Tayar 			for (tbus_lo_offset = 0; tbus_lo_offset < 256;
3165c965db44STomer Tayar 			     tbus_lo_offset++) {
3166c965db44STomer Tayar 				qed_wr(p_hwfn,
31677b6859fbSMintz, Yuval 				       p_ptt, addr_lo_addr, tbus_lo_offset);
31687b6859fbSMintz, Yuval 				*(bytes_buf++) = (u8)qed_rd(p_hwfn,
3169c965db44STomer Tayar 							    p_ptt,
3170c965db44STomer Tayar 							    data_lo_addr);
31717b6859fbSMintz, Yuval 				*(bytes_buf++) = (u8)qed_rd(p_hwfn,
31727b6859fbSMintz, Yuval 							    p_ptt,
3173c965db44STomer Tayar 							    data_hi_addr);
3174c965db44STomer Tayar 			}
3175c965db44STomer Tayar 		}
3176c965db44STomer Tayar 
3177c965db44STomer Tayar 		offset += PHY_DUMP_SIZE_DWORDS;
3178c965db44STomer Tayar 	}
3179c965db44STomer Tayar 
3180c965db44STomer Tayar 	return offset;
3181c965db44STomer Tayar }
3182c965db44STomer Tayar 
31832d22bc83SMichal Kalderon static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
3184c965db44STomer Tayar 					    struct qed_ptt *p_ptt,
31852d22bc83SMichal Kalderon 					    u32 image_type,
31862d22bc83SMichal Kalderon 					    u32 *nvram_offset_bytes,
31872d22bc83SMichal Kalderon 					    u32 *nvram_size_bytes);
3188c965db44STomer Tayar 
31892d22bc83SMichal Kalderon static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
31902d22bc83SMichal Kalderon 				      struct qed_ptt *p_ptt,
31912d22bc83SMichal Kalderon 				      u32 nvram_offset_bytes,
31922d22bc83SMichal Kalderon 				      u32 nvram_size_bytes, u32 *ret_buf);
31932d22bc83SMichal Kalderon 
31942d22bc83SMichal Kalderon /* Dumps the MCP HW dump from NVRAM. Returns the dumped size in dwords. */
31952d22bc83SMichal Kalderon static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn,
31962d22bc83SMichal Kalderon 				    struct qed_ptt *p_ptt,
31972d22bc83SMichal Kalderon 				    u32 *dump_buf, bool dump)
31982d22bc83SMichal Kalderon {
31992d22bc83SMichal Kalderon 	u32 hw_dump_offset_bytes = 0, hw_dump_size_bytes = 0;
32002d22bc83SMichal Kalderon 	u32 hw_dump_size_dwords = 0, offset = 0;
32012d22bc83SMichal Kalderon 	enum dbg_status status;
32022d22bc83SMichal Kalderon 
32032d22bc83SMichal Kalderon 	/* Read HW dump image from NVRAM */
32042d22bc83SMichal Kalderon 	status = qed_find_nvram_image(p_hwfn,
32052d22bc83SMichal Kalderon 				      p_ptt,
32062d22bc83SMichal Kalderon 				      NVM_TYPE_HW_DUMP_OUT,
32072d22bc83SMichal Kalderon 				      &hw_dump_offset_bytes,
32082d22bc83SMichal Kalderon 				      &hw_dump_size_bytes);
32092d22bc83SMichal Kalderon 	if (status != DBG_STATUS_OK)
32102d22bc83SMichal Kalderon 		return 0;
32112d22bc83SMichal Kalderon 
32122d22bc83SMichal Kalderon 	hw_dump_size_dwords = BYTES_TO_DWORDS(hw_dump_size_bytes);
32132d22bc83SMichal Kalderon 
32142d22bc83SMichal Kalderon 	/* Dump HW dump image section */
32152d22bc83SMichal Kalderon 	offset += qed_dump_section_hdr(dump_buf + offset,
32162d22bc83SMichal Kalderon 				       dump, "mcp_hw_dump", 1);
32172d22bc83SMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
32182d22bc83SMichal Kalderon 				     dump, "size", hw_dump_size_dwords);
32192d22bc83SMichal Kalderon 
32202d22bc83SMichal Kalderon 	/* Read MCP HW dump image into dump buffer */
32212d22bc83SMichal Kalderon 	if (dump && hw_dump_size_dwords) {
32222d22bc83SMichal Kalderon 		status = qed_nvram_read(p_hwfn,
32232d22bc83SMichal Kalderon 					p_ptt,
32242d22bc83SMichal Kalderon 					hw_dump_offset_bytes,
32252d22bc83SMichal Kalderon 					hw_dump_size_bytes, dump_buf + offset);
32262d22bc83SMichal Kalderon 		if (status != DBG_STATUS_OK) {
32272d22bc83SMichal Kalderon 			DP_NOTICE(p_hwfn,
32282d22bc83SMichal Kalderon 				  "Failed to read MCP HW Dump image from NVRAM\n");
32292d22bc83SMichal Kalderon 			return 0;
32302d22bc83SMichal Kalderon 		}
32312d22bc83SMichal Kalderon 	}
32322d22bc83SMichal Kalderon 	offset += hw_dump_size_dwords;
32332d22bc83SMichal Kalderon 
32342d22bc83SMichal Kalderon 	return offset;
3235c965db44STomer Tayar }
3236c965db44STomer Tayar 
3237c965db44STomer Tayar /* Dumps Static Debug data. Returns the dumped size in dwords. */
3238c965db44STomer Tayar static u32 qed_grc_dump_static_debug(struct qed_hwfn *p_hwfn,
3239c965db44STomer Tayar 				     struct qed_ptt *p_ptt,
3240c965db44STomer Tayar 				     u32 *dump_buf, bool dump)
3241c965db44STomer Tayar {
3242c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
32432d22bc83SMichal Kalderon 	u32 block_id, line_id, offset = 0, addr, len;
32447b6859fbSMintz, Yuval 
3245da090917STomer Tayar 	/* Don't dump static debug if a debug bus recording is in progress */
3246da090917STomer Tayar 	if (dump && qed_rd(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON))
32477b6859fbSMintz, Yuval 		return 0;
3248c965db44STomer Tayar 
3249c965db44STomer Tayar 	if (dump) {
32502d22bc83SMichal Kalderon 		/* Disable debug bus in all blocks */
32512d22bc83SMichal Kalderon 		qed_bus_disable_blocks(p_hwfn, p_ptt);
3252c965db44STomer Tayar 
3253c965db44STomer Tayar 		qed_bus_reset_dbg_block(p_hwfn, p_ptt);
32542d22bc83SMichal Kalderon 		qed_wr(p_hwfn,
32552d22bc83SMichal Kalderon 		       p_ptt, DBG_REG_FRAMING_MODE, DBG_BUS_FRAME_MODE_8HW);
3256c965db44STomer Tayar 		qed_wr(p_hwfn,
3257c965db44STomer Tayar 		       p_ptt, DBG_REG_DEBUG_TARGET, DBG_BUS_TARGET_ID_INT_BUF);
3258c965db44STomer Tayar 		qed_wr(p_hwfn, p_ptt, DBG_REG_FULL_MODE, 1);
3259c965db44STomer Tayar 		qed_bus_enable_dbg_block(p_hwfn, p_ptt, true);
3260c965db44STomer Tayar 	}
3261c965db44STomer Tayar 
3262c965db44STomer Tayar 	/* Dump all static debug lines for each relevant block */
3263c965db44STomer Tayar 	for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
32642d22bc83SMichal Kalderon 		const struct dbg_block_chip *block_per_chip;
32652d22bc83SMichal Kalderon 		const struct dbg_block *block;
32662d22bc83SMichal Kalderon 		bool is_removed, has_dbg_bus;
32672d22bc83SMichal Kalderon 		u16 modes_buf_offset;
32682d22bc83SMichal Kalderon 		u32 block_dwords;
3269c965db44STomer Tayar 
32702d22bc83SMichal Kalderon 		block_per_chip =
32712d22bc83SMichal Kalderon 		    qed_get_dbg_block_per_chip(p_hwfn, (enum block_id)block_id);
32722d22bc83SMichal Kalderon 		is_removed = GET_FIELD(block_per_chip->flags,
32732d22bc83SMichal Kalderon 				       DBG_BLOCK_CHIP_IS_REMOVED);
32742d22bc83SMichal Kalderon 		has_dbg_bus = GET_FIELD(block_per_chip->flags,
32752d22bc83SMichal Kalderon 					DBG_BLOCK_CHIP_HAS_DBG_BUS);
32762d22bc83SMichal Kalderon 
32772d22bc83SMichal Kalderon 		/* read+clear for NWS parity is not working, skip NWS block */
32782d22bc83SMichal Kalderon 		if (block_id == BLOCK_NWS)
3279c965db44STomer Tayar 			continue;
3280c965db44STomer Tayar 
32812d22bc83SMichal Kalderon 		if (!is_removed && has_dbg_bus &&
32822d22bc83SMichal Kalderon 		    GET_FIELD(block_per_chip->dbg_bus_mode.data,
32832d22bc83SMichal Kalderon 			      DBG_MODE_HDR_EVAL_MODE) > 0) {
32842d22bc83SMichal Kalderon 			modes_buf_offset =
32852d22bc83SMichal Kalderon 			    GET_FIELD(block_per_chip->dbg_bus_mode.data,
32862d22bc83SMichal Kalderon 				      DBG_MODE_HDR_MODES_BUF_OFFSET);
32872d22bc83SMichal Kalderon 			if (!qed_is_mode_match(p_hwfn, &modes_buf_offset))
32882d22bc83SMichal Kalderon 				has_dbg_bus = false;
32892d22bc83SMichal Kalderon 		}
32902d22bc83SMichal Kalderon 
32912d22bc83SMichal Kalderon 		if (is_removed || !has_dbg_bus)
32922d22bc83SMichal Kalderon 			continue;
32932d22bc83SMichal Kalderon 
32942d22bc83SMichal Kalderon 		block_dwords = NUM_DBG_LINES(block_per_chip) *
32957b6859fbSMintz, Yuval 			       STATIC_DEBUG_LINE_DWORDS;
32967b6859fbSMintz, Yuval 
3297c965db44STomer Tayar 		/* Dump static section params */
32982d22bc83SMichal Kalderon 		block = get_dbg_block(p_hwfn, (enum block_id)block_id);
3299c965db44STomer Tayar 		offset += qed_grc_dump_mem_hdr(p_hwfn,
3300c965db44STomer Tayar 					       dump_buf + offset,
3301c965db44STomer Tayar 					       dump,
33027b6859fbSMintz, Yuval 					       block->name,
33037b6859fbSMintz, Yuval 					       0,
33047b6859fbSMintz, Yuval 					       block_dwords,
33052d22bc83SMichal Kalderon 					       32, false, "STATIC", 0);
3306c965db44STomer Tayar 
33077b6859fbSMintz, Yuval 		if (!dump) {
33087b6859fbSMintz, Yuval 			offset += block_dwords;
33097b6859fbSMintz, Yuval 			continue;
33107b6859fbSMintz, Yuval 		}
33117b6859fbSMintz, Yuval 
33127b6859fbSMintz, Yuval 		/* If all lines are invalid - dump zeros */
33137b6859fbSMintz, Yuval 		if (dev_data->block_in_reset[block_id]) {
33147b6859fbSMintz, Yuval 			memset(dump_buf + offset, 0,
33157b6859fbSMintz, Yuval 			       DWORDS_TO_BYTES(block_dwords));
33167b6859fbSMintz, Yuval 			offset += block_dwords;
33177b6859fbSMintz, Yuval 			continue;
33187b6859fbSMintz, Yuval 		}
3319c965db44STomer Tayar 
3320c965db44STomer Tayar 		/* Enable block's client */
33217b6859fbSMintz, Yuval 		qed_bus_enable_clients(p_hwfn,
33227b6859fbSMintz, Yuval 				       p_ptt,
33232d22bc83SMichal Kalderon 				       BIT(block_per_chip->dbg_client_id));
3324c965db44STomer Tayar 
33257b6859fbSMintz, Yuval 		addr = BYTES_TO_DWORDS(DBG_REG_CALENDAR_OUT_DATA);
33267b6859fbSMintz, Yuval 		len = STATIC_DEBUG_LINE_DWORDS;
33272d22bc83SMichal Kalderon 		for (line_id = 0; line_id < (u32)NUM_DBG_LINES(block_per_chip);
3328c965db44STomer Tayar 		     line_id++) {
3329c965db44STomer Tayar 			/* Configure debug line ID */
33302d22bc83SMichal Kalderon 			qed_bus_config_dbg_line(p_hwfn,
3331c965db44STomer Tayar 						p_ptt,
3332c965db44STomer Tayar 						(enum block_id)block_id,
33337b6859fbSMintz, Yuval 						(u8)line_id, 0xf, 0, 0, 0);
3334c965db44STomer Tayar 
3335c965db44STomer Tayar 			/* Read debug line info */
33367b6859fbSMintz, Yuval 			offset += qed_grc_dump_addr_range(p_hwfn,
3337be086e7cSMintz, Yuval 							  p_ptt,
3338be086e7cSMintz, Yuval 							  dump_buf + offset,
3339be086e7cSMintz, Yuval 							  dump,
3340be086e7cSMintz, Yuval 							  addr,
33417b6859fbSMintz, Yuval 							  len,
3342d52c89f1SMichal Kalderon 							  true, SPLIT_TYPE_NONE,
3343d52c89f1SMichal Kalderon 							  0);
3344c965db44STomer Tayar 		}
3345c965db44STomer Tayar 
3346c965db44STomer Tayar 		/* Disable block's client and debug output */
3347c965db44STomer Tayar 		qed_bus_enable_clients(p_hwfn, p_ptt, 0);
33482d22bc83SMichal Kalderon 		qed_bus_config_dbg_line(p_hwfn, p_ptt,
33492d22bc83SMichal Kalderon 					(enum block_id)block_id, 0, 0, 0, 0, 0);
3350c965db44STomer Tayar 	}
3351c965db44STomer Tayar 
3352c965db44STomer Tayar 	if (dump) {
3353c965db44STomer Tayar 		qed_bus_enable_dbg_block(p_hwfn, p_ptt, false);
3354c965db44STomer Tayar 		qed_bus_enable_clients(p_hwfn, p_ptt, 0);
3355c965db44STomer Tayar 	}
3356c965db44STomer Tayar 
3357c965db44STomer Tayar 	return offset;
3358c965db44STomer Tayar }
3359c965db44STomer Tayar 
3360c965db44STomer Tayar /* Performs GRC Dump to the specified buffer.
3361c965db44STomer Tayar  * Returns the dumped size in dwords.
3362c965db44STomer Tayar  */
3363c965db44STomer Tayar static enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn,
3364c965db44STomer Tayar 				    struct qed_ptt *p_ptt,
3365c965db44STomer Tayar 				    u32 *dump_buf,
3366c965db44STomer Tayar 				    bool dump, u32 *num_dumped_dwords)
3367c965db44STomer Tayar {
3368c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
33692d22bc83SMichal Kalderon 	u32 dwords_read, offset = 0;
3370c965db44STomer Tayar 	bool parities_masked = false;
3371d52c89f1SMichal Kalderon 	u8 i;
3372c965db44STomer Tayar 
3373c965db44STomer Tayar 	*num_dumped_dwords = 0;
3374d52c89f1SMichal Kalderon 	dev_data->num_regs_read = 0;
3375c965db44STomer Tayar 
3376c965db44STomer Tayar 	/* Update reset state */
3377d52c89f1SMichal Kalderon 	if (dump)
3378c965db44STomer Tayar 		qed_update_blocks_reset_state(p_hwfn, p_ptt);
3379c965db44STomer Tayar 
3380c965db44STomer Tayar 	/* Dump global params */
3381c965db44STomer Tayar 	offset += qed_dump_common_global_params(p_hwfn,
3382c965db44STomer Tayar 						p_ptt,
3383c965db44STomer Tayar 						dump_buf + offset, dump, 4);
3384c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset,
3385c965db44STomer Tayar 				     dump, "dump-type", "grc-dump");
3386c965db44STomer Tayar 	offset += qed_dump_num_param(dump_buf + offset,
3387c965db44STomer Tayar 				     dump,
3388c965db44STomer Tayar 				     "num-lcids",
33892d22bc83SMichal Kalderon 				     NUM_OF_LCIDS);
3390c965db44STomer Tayar 	offset += qed_dump_num_param(dump_buf + offset,
3391c965db44STomer Tayar 				     dump,
3392c965db44STomer Tayar 				     "num-ltids",
33932d22bc83SMichal Kalderon 				     NUM_OF_LTIDS);
3394c965db44STomer Tayar 	offset += qed_dump_num_param(dump_buf + offset,
3395d52c89f1SMichal Kalderon 				     dump, "num-ports", dev_data->num_ports);
3396c965db44STomer Tayar 
3397c965db44STomer Tayar 	/* Dump reset registers (dumped before taking blocks out of reset ) */
3398c965db44STomer Tayar 	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
3399c965db44STomer Tayar 		offset += qed_grc_dump_reset_regs(p_hwfn,
3400c965db44STomer Tayar 						  p_ptt,
3401c965db44STomer Tayar 						  dump_buf + offset, dump);
3402c965db44STomer Tayar 
3403c965db44STomer Tayar 	/* Take all blocks out of reset (using reset registers) */
3404c965db44STomer Tayar 	if (dump) {
34052d22bc83SMichal Kalderon 		qed_grc_unreset_blocks(p_hwfn, p_ptt, false);
3406c965db44STomer Tayar 		qed_update_blocks_reset_state(p_hwfn, p_ptt);
3407c965db44STomer Tayar 	}
3408c965db44STomer Tayar 
3409c965db44STomer Tayar 	/* Disable all parities using MFW command */
34107b6859fbSMintz, Yuval 	if (dump &&
34117b6859fbSMintz, Yuval 	    !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {
3412c965db44STomer Tayar 		parities_masked = !qed_mcp_mask_parities(p_hwfn, p_ptt, 1);
3413c965db44STomer Tayar 		if (!parities_masked) {
3414be086e7cSMintz, Yuval 			DP_NOTICE(p_hwfn,
3415be086e7cSMintz, Yuval 				  "Failed to mask parities using MFW\n");
3416c965db44STomer Tayar 			if (qed_grc_get_param
3417c965db44STomer Tayar 			    (p_hwfn, DBG_GRC_PARAM_PARITY_SAFE))
3418c965db44STomer Tayar 				return DBG_STATUS_MCP_COULD_NOT_MASK_PRTY;
3419c965db44STomer Tayar 		}
3420c965db44STomer Tayar 	}
3421c965db44STomer Tayar 
3422c965db44STomer Tayar 	/* Dump modified registers (dumped before modifying them) */
3423c965db44STomer Tayar 	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
3424c965db44STomer Tayar 		offset += qed_grc_dump_modified_regs(p_hwfn,
3425c965db44STomer Tayar 						     p_ptt,
3426c965db44STomer Tayar 						     dump_buf + offset, dump);
3427c965db44STomer Tayar 
3428c965db44STomer Tayar 	/* Stall storms */
3429c965db44STomer Tayar 	if (dump &&
3430c965db44STomer Tayar 	    (qed_grc_is_included(p_hwfn,
3431c965db44STomer Tayar 				 DBG_GRC_PARAM_DUMP_IOR) ||
3432c965db44STomer Tayar 	     qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)))
3433c965db44STomer Tayar 		qed_grc_stall_storms(p_hwfn, p_ptt, true);
3434c965db44STomer Tayar 
3435c965db44STomer Tayar 	/* Dump all regs  */
3436c965db44STomer Tayar 	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS)) {
3437c965db44STomer Tayar 		bool block_enable[MAX_BLOCK_ID];
3438c965db44STomer Tayar 
34397b6859fbSMintz, Yuval 		/* Dump all blocks except MCP */
3440c965db44STomer Tayar 		for (i = 0; i < MAX_BLOCK_ID; i++)
3441c965db44STomer Tayar 			block_enable[i] = true;
3442c965db44STomer Tayar 		block_enable[BLOCK_MCP] = false;
3443c965db44STomer Tayar 		offset += qed_grc_dump_registers(p_hwfn,
3444c965db44STomer Tayar 						 p_ptt,
3445c965db44STomer Tayar 						 dump_buf +
3446c965db44STomer Tayar 						 offset,
3447c965db44STomer Tayar 						 dump,
34482d22bc83SMichal Kalderon 						 block_enable, NULL);
3449be086e7cSMintz, Yuval 
3450be086e7cSMintz, Yuval 		/* Dump special registers */
3451be086e7cSMintz, Yuval 		offset += qed_grc_dump_special_regs(p_hwfn,
3452be086e7cSMintz, Yuval 						    p_ptt,
3453be086e7cSMintz, Yuval 						    dump_buf + offset, dump);
3454c965db44STomer Tayar 	}
3455c965db44STomer Tayar 
3456c965db44STomer Tayar 	/* Dump memories */
3457c965db44STomer Tayar 	offset += qed_grc_dump_memories(p_hwfn, p_ptt, dump_buf + offset, dump);
3458c965db44STomer Tayar 
3459c965db44STomer Tayar 	/* Dump MCP */
3460c965db44STomer Tayar 	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP))
3461c965db44STomer Tayar 		offset += qed_grc_dump_mcp(p_hwfn,
3462c965db44STomer Tayar 					   p_ptt, dump_buf + offset, dump);
3463c965db44STomer Tayar 
3464c965db44STomer Tayar 	/* Dump context */
3465c965db44STomer Tayar 	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX))
3466c965db44STomer Tayar 		offset += qed_grc_dump_ctx(p_hwfn,
3467c965db44STomer Tayar 					   p_ptt, dump_buf + offset, dump);
3468c965db44STomer Tayar 
3469c965db44STomer Tayar 	/* Dump RSS memories */
3470c965db44STomer Tayar 	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RSS))
3471c965db44STomer Tayar 		offset += qed_grc_dump_rss(p_hwfn,
3472c965db44STomer Tayar 					   p_ptt, dump_buf + offset, dump);
3473c965db44STomer Tayar 
3474c965db44STomer Tayar 	/* Dump Big RAM */
3475c965db44STomer Tayar 	for (i = 0; i < NUM_BIG_RAM_TYPES; i++)
3476c965db44STomer Tayar 		if (qed_grc_is_included(p_hwfn, s_big_ram_defs[i].grc_param))
3477c965db44STomer Tayar 			offset += qed_grc_dump_big_ram(p_hwfn,
3478c965db44STomer Tayar 						       p_ptt,
3479c965db44STomer Tayar 						       dump_buf + offset,
3480c965db44STomer Tayar 						       dump, i);
3481c965db44STomer Tayar 
3482c965db44STomer Tayar 	/* Dump VFC */
34832d22bc83SMichal Kalderon 	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)) {
34842d22bc83SMichal Kalderon 		dwords_read = qed_grc_dump_vfc(p_hwfn,
3485c965db44STomer Tayar 					       p_ptt, dump_buf + offset, dump);
34862d22bc83SMichal Kalderon 		offset += dwords_read;
34872d22bc83SMichal Kalderon 		if (!dwords_read)
34882d22bc83SMichal Kalderon 			return DBG_STATUS_VFC_READ_ERROR;
34892d22bc83SMichal Kalderon 	}
3490c965db44STomer Tayar 
3491c965db44STomer Tayar 	/* Dump PHY tbus */
3492c965db44STomer Tayar 	if (qed_grc_is_included(p_hwfn,
3493c965db44STomer Tayar 				DBG_GRC_PARAM_DUMP_PHY) && dev_data->chip_id ==
34942d22bc83SMichal Kalderon 	    CHIP_K2 && dev_data->hw_type == HW_TYPE_ASIC)
3495c965db44STomer Tayar 		offset += qed_grc_dump_phy(p_hwfn,
3496c965db44STomer Tayar 					   p_ptt, dump_buf + offset, dump);
3497c965db44STomer Tayar 
34982d22bc83SMichal Kalderon 	/* Dump MCP HW Dump */
34992d22bc83SMichal Kalderon 	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP_HW_DUMP) &&
35002d22bc83SMichal Kalderon 	    !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP) && 1)
35012d22bc83SMichal Kalderon 		offset += qed_grc_dump_mcp_hw_dump(p_hwfn,
35022d22bc83SMichal Kalderon 						   p_ptt,
35032d22bc83SMichal Kalderon 						   dump_buf + offset, dump);
35042d22bc83SMichal Kalderon 
3505d52c89f1SMichal Kalderon 	/* Dump static debug data (only if not during debug bus recording) */
3506c965db44STomer Tayar 	if (qed_grc_is_included(p_hwfn,
3507c965db44STomer Tayar 				DBG_GRC_PARAM_DUMP_STATIC) &&
3508d52c89f1SMichal Kalderon 	    (!dump || dev_data->bus.state == DBG_BUS_STATE_IDLE))
3509c965db44STomer Tayar 		offset += qed_grc_dump_static_debug(p_hwfn,
3510c965db44STomer Tayar 						    p_ptt,
3511c965db44STomer Tayar 						    dump_buf + offset, dump);
3512c965db44STomer Tayar 
3513c965db44STomer Tayar 	/* Dump last section */
3514da090917STomer Tayar 	offset += qed_dump_last_section(dump_buf, offset, dump);
35157b6859fbSMintz, Yuval 
3516c965db44STomer Tayar 	if (dump) {
3517c965db44STomer Tayar 		/* Unstall storms */
3518c965db44STomer Tayar 		if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_UNSTALL))
3519c965db44STomer Tayar 			qed_grc_stall_storms(p_hwfn, p_ptt, false);
3520c965db44STomer Tayar 
3521c965db44STomer Tayar 		/* Clear parity status */
3522c965db44STomer Tayar 		qed_grc_clear_all_prty(p_hwfn, p_ptt);
3523c965db44STomer Tayar 
3524c965db44STomer Tayar 		/* Enable all parities using MFW command */
3525c965db44STomer Tayar 		if (parities_masked)
3526c965db44STomer Tayar 			qed_mcp_mask_parities(p_hwfn, p_ptt, 0);
3527c965db44STomer Tayar 	}
3528c965db44STomer Tayar 
3529c965db44STomer Tayar 	*num_dumped_dwords = offset;
3530c965db44STomer Tayar 
3531c965db44STomer Tayar 	return DBG_STATUS_OK;
3532c965db44STomer Tayar }
3533c965db44STomer Tayar 
3534c965db44STomer Tayar /* Writes the specified failing Idle Check rule to the specified buffer.
3535c965db44STomer Tayar  * Returns the dumped size in dwords.
3536c965db44STomer Tayar  */
3537c965db44STomer Tayar static u32 qed_idle_chk_dump_failure(struct qed_hwfn *p_hwfn,
3538c965db44STomer Tayar 				     struct qed_ptt *p_ptt,
3539c965db44STomer Tayar 				     u32 *
3540c965db44STomer Tayar 				     dump_buf,
3541c965db44STomer Tayar 				     bool dump,
3542c965db44STomer Tayar 				     u16 rule_id,
3543c965db44STomer Tayar 				     const struct dbg_idle_chk_rule *rule,
3544c965db44STomer Tayar 				     u16 fail_entry_id, u32 *cond_reg_values)
3545c965db44STomer Tayar {
3546c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
35477b6859fbSMintz, Yuval 	const struct dbg_idle_chk_cond_reg *cond_regs;
35487b6859fbSMintz, Yuval 	const struct dbg_idle_chk_info_reg *info_regs;
35497b6859fbSMintz, Yuval 	u32 i, next_reg_offset = 0, offset = 0;
35507b6859fbSMintz, Yuval 	struct dbg_idle_chk_result_hdr *hdr;
35517b6859fbSMintz, Yuval 	const union dbg_idle_chk_reg *regs;
3552c965db44STomer Tayar 	u8 reg_id;
3553c965db44STomer Tayar 
35547b6859fbSMintz, Yuval 	hdr = (struct dbg_idle_chk_result_hdr *)dump_buf;
35552d22bc83SMichal Kalderon 	regs = (const union dbg_idle_chk_reg *)
35562d22bc83SMichal Kalderon 		p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr +
35572d22bc83SMichal Kalderon 		rule->reg_offset;
35587b6859fbSMintz, Yuval 	cond_regs = &regs[0].cond_reg;
35597b6859fbSMintz, Yuval 	info_regs = &regs[rule->num_cond_regs].info_reg;
35607b6859fbSMintz, Yuval 
3561c965db44STomer Tayar 	/* Dump rule data */
3562c965db44STomer Tayar 	if (dump) {
3563c965db44STomer Tayar 		memset(hdr, 0, sizeof(*hdr));
3564c965db44STomer Tayar 		hdr->rule_id = rule_id;
3565c965db44STomer Tayar 		hdr->mem_entry_id = fail_entry_id;
3566c965db44STomer Tayar 		hdr->severity = rule->severity;
3567c965db44STomer Tayar 		hdr->num_dumped_cond_regs = rule->num_cond_regs;
3568c965db44STomer Tayar 	}
3569c965db44STomer Tayar 
3570c965db44STomer Tayar 	offset += IDLE_CHK_RESULT_HDR_DWORDS;
3571c965db44STomer Tayar 
3572c965db44STomer Tayar 	/* Dump condition register values */
3573c965db44STomer Tayar 	for (reg_id = 0; reg_id < rule->num_cond_regs; reg_id++) {
3574c965db44STomer Tayar 		const struct dbg_idle_chk_cond_reg *reg = &cond_regs[reg_id];
35757b6859fbSMintz, Yuval 		struct dbg_idle_chk_result_reg_hdr *reg_hdr;
35767b6859fbSMintz, Yuval 
35772d22bc83SMichal Kalderon 		reg_hdr =
35782d22bc83SMichal Kalderon 		    (struct dbg_idle_chk_result_reg_hdr *)(dump_buf + offset);
3579c965db44STomer Tayar 
3580c965db44STomer Tayar 		/* Write register header */
35817b6859fbSMintz, Yuval 		if (!dump) {
35827b6859fbSMintz, Yuval 			offset += IDLE_CHK_RESULT_REG_HDR_DWORDS +
35837b6859fbSMintz, Yuval 			    reg->entry_size;
35847b6859fbSMintz, Yuval 			continue;
35857b6859fbSMintz, Yuval 		}
35867b6859fbSMintz, Yuval 
3587c965db44STomer Tayar 		offset += IDLE_CHK_RESULT_REG_HDR_DWORDS;
35887b6859fbSMintz, Yuval 		memset(reg_hdr, 0, sizeof(*reg_hdr));
3589c965db44STomer Tayar 		reg_hdr->start_entry = reg->start_entry;
3590c965db44STomer Tayar 		reg_hdr->size = reg->entry_size;
3591c965db44STomer Tayar 		SET_FIELD(reg_hdr->data,
3592c965db44STomer Tayar 			  DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM,
35937b6859fbSMintz, Yuval 			  reg->num_entries > 1 || reg->start_entry > 0 ? 1 : 0);
3594c965db44STomer Tayar 		SET_FIELD(reg_hdr->data,
3595c965db44STomer Tayar 			  DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID, reg_id);
3596c965db44STomer Tayar 
3597c965db44STomer Tayar 		/* Write register values */
35987b6859fbSMintz, Yuval 		for (i = 0; i < reg_hdr->size; i++, next_reg_offset++, offset++)
35997b6859fbSMintz, Yuval 			dump_buf[offset] = cond_reg_values[next_reg_offset];
3600c965db44STomer Tayar 	}
3601c965db44STomer Tayar 
3602c965db44STomer Tayar 	/* Dump info register values */
3603c965db44STomer Tayar 	for (reg_id = 0; reg_id < rule->num_info_regs; reg_id++) {
3604c965db44STomer Tayar 		const struct dbg_idle_chk_info_reg *reg = &info_regs[reg_id];
3605c965db44STomer Tayar 		u32 block_id;
3606c965db44STomer Tayar 
36077b6859fbSMintz, Yuval 		/* Check if register's block is in reset */
3608c965db44STomer Tayar 		if (!dump) {
3609c965db44STomer Tayar 			offset += IDLE_CHK_RESULT_REG_HDR_DWORDS + reg->size;
3610c965db44STomer Tayar 			continue;
3611c965db44STomer Tayar 		}
3612c965db44STomer Tayar 
3613c965db44STomer Tayar 		block_id = GET_FIELD(reg->data, DBG_IDLE_CHK_INFO_REG_BLOCK_ID);
3614c965db44STomer Tayar 		if (block_id >= MAX_BLOCK_ID) {
3615c965db44STomer Tayar 			DP_NOTICE(p_hwfn, "Invalid block_id\n");
3616c965db44STomer Tayar 			return 0;
3617c965db44STomer Tayar 		}
3618c965db44STomer Tayar 
3619c965db44STomer Tayar 		if (!dev_data->block_in_reset[block_id]) {
36207b6859fbSMintz, Yuval 			struct dbg_idle_chk_result_reg_hdr *reg_hdr;
36217b6859fbSMintz, Yuval 			bool wide_bus, eval_mode, mode_match = true;
36227b6859fbSMintz, Yuval 			u16 modes_buf_offset;
36237b6859fbSMintz, Yuval 			u32 addr;
36247b6859fbSMintz, Yuval 
36257b6859fbSMintz, Yuval 			reg_hdr = (struct dbg_idle_chk_result_reg_hdr *)
36267b6859fbSMintz, Yuval 				  (dump_buf + offset);
3627c965db44STomer Tayar 
3628c965db44STomer Tayar 			/* Check mode */
36297b6859fbSMintz, Yuval 			eval_mode = GET_FIELD(reg->mode.data,
36307b6859fbSMintz, Yuval 					      DBG_MODE_HDR_EVAL_MODE) > 0;
3631c965db44STomer Tayar 			if (eval_mode) {
36327b6859fbSMintz, Yuval 				modes_buf_offset =
3633c965db44STomer Tayar 				    GET_FIELD(reg->mode.data,
3634c965db44STomer Tayar 					      DBG_MODE_HDR_MODES_BUF_OFFSET);
3635c965db44STomer Tayar 				mode_match =
3636c965db44STomer Tayar 					qed_is_mode_match(p_hwfn,
3637c965db44STomer Tayar 							  &modes_buf_offset);
3638c965db44STomer Tayar 			}
3639c965db44STomer Tayar 
36407b6859fbSMintz, Yuval 			if (!mode_match)
36417b6859fbSMintz, Yuval 				continue;
36427b6859fbSMintz, Yuval 
36437b6859fbSMintz, Yuval 			addr = GET_FIELD(reg->data,
3644be086e7cSMintz, Yuval 					 DBG_IDLE_CHK_INFO_REG_ADDRESS);
36457b6859fbSMintz, Yuval 			wide_bus = GET_FIELD(reg->data,
36467b6859fbSMintz, Yuval 					     DBG_IDLE_CHK_INFO_REG_WIDE_BUS);
3647c965db44STomer Tayar 
3648c965db44STomer Tayar 			/* Write register header */
3649c965db44STomer Tayar 			offset += IDLE_CHK_RESULT_REG_HDR_DWORDS;
3650c965db44STomer Tayar 			hdr->num_dumped_info_regs++;
3651c965db44STomer Tayar 			memset(reg_hdr, 0, sizeof(*reg_hdr));
3652c965db44STomer Tayar 			reg_hdr->size = reg->size;
3653c965db44STomer Tayar 			SET_FIELD(reg_hdr->data,
3654c965db44STomer Tayar 				  DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID,
3655c965db44STomer Tayar 				  rule->num_cond_regs + reg_id);
3656c965db44STomer Tayar 
3657c965db44STomer Tayar 			/* Write register values */
36587b6859fbSMintz, Yuval 			offset += qed_grc_dump_addr_range(p_hwfn,
3659be086e7cSMintz, Yuval 							  p_ptt,
3660be086e7cSMintz, Yuval 							  dump_buf + offset,
3661be086e7cSMintz, Yuval 							  dump,
3662be086e7cSMintz, Yuval 							  addr,
3663d52c89f1SMichal Kalderon 							  reg->size, wide_bus,
3664d52c89f1SMichal Kalderon 							  SPLIT_TYPE_NONE, 0);
3665c965db44STomer Tayar 		}
3666c965db44STomer Tayar 	}
3667c965db44STomer Tayar 
3668c965db44STomer Tayar 	return offset;
3669c965db44STomer Tayar }
3670c965db44STomer Tayar 
3671c965db44STomer Tayar /* Dumps idle check rule entries. Returns the dumped size in dwords. */
3672c965db44STomer Tayar static u32
3673c965db44STomer Tayar qed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
3674c965db44STomer Tayar 			       u32 *dump_buf, bool dump,
3675c965db44STomer Tayar 			       const struct dbg_idle_chk_rule *input_rules,
3676c965db44STomer Tayar 			       u32 num_input_rules, u32 *num_failing_rules)
3677c965db44STomer Tayar {
3678c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3679c965db44STomer Tayar 	u32 cond_reg_values[IDLE_CHK_MAX_ENTRIES_SIZE];
3680be086e7cSMintz, Yuval 	u32 i, offset = 0;
3681c965db44STomer Tayar 	u16 entry_id;
3682c965db44STomer Tayar 	u8 reg_id;
3683c965db44STomer Tayar 
3684c965db44STomer Tayar 	*num_failing_rules = 0;
36857b6859fbSMintz, Yuval 
3686c965db44STomer Tayar 	for (i = 0; i < num_input_rules; i++) {
3687c965db44STomer Tayar 		const struct dbg_idle_chk_cond_reg *cond_regs;
3688c965db44STomer Tayar 		const struct dbg_idle_chk_rule *rule;
3689c965db44STomer Tayar 		const union dbg_idle_chk_reg *regs;
3690c965db44STomer Tayar 		u16 num_reg_entries = 1;
3691c965db44STomer Tayar 		bool check_rule = true;
3692c965db44STomer Tayar 		const u32 *imm_values;
3693c965db44STomer Tayar 
3694c965db44STomer Tayar 		rule = &input_rules[i];
36952d22bc83SMichal Kalderon 		regs = (const union dbg_idle_chk_reg *)
36962d22bc83SMichal Kalderon 			p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr +
36972d22bc83SMichal Kalderon 			rule->reg_offset;
3698c965db44STomer Tayar 		cond_regs = &regs[0].cond_reg;
36992d22bc83SMichal Kalderon 		imm_values =
37002d22bc83SMichal Kalderon 		    (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr +
37012d22bc83SMichal Kalderon 		    rule->imm_offset;
3702c965db44STomer Tayar 
3703c965db44STomer Tayar 		/* Check if all condition register blocks are out of reset, and
3704c965db44STomer Tayar 		 * find maximal number of entries (all condition registers that
3705c965db44STomer Tayar 		 * are memories must have the same size, which is > 1).
3706c965db44STomer Tayar 		 */
3707c965db44STomer Tayar 		for (reg_id = 0; reg_id < rule->num_cond_regs && check_rule;
3708c965db44STomer Tayar 		     reg_id++) {
37097b6859fbSMintz, Yuval 			u32 block_id =
37107b6859fbSMintz, Yuval 				GET_FIELD(cond_regs[reg_id].data,
3711c965db44STomer Tayar 					  DBG_IDLE_CHK_COND_REG_BLOCK_ID);
3712c965db44STomer Tayar 
3713c965db44STomer Tayar 			if (block_id >= MAX_BLOCK_ID) {
3714c965db44STomer Tayar 				DP_NOTICE(p_hwfn, "Invalid block_id\n");
3715c965db44STomer Tayar 				return 0;
3716c965db44STomer Tayar 			}
3717c965db44STomer Tayar 
3718c965db44STomer Tayar 			check_rule = !dev_data->block_in_reset[block_id];
3719c965db44STomer Tayar 			if (cond_regs[reg_id].num_entries > num_reg_entries)
3720c965db44STomer Tayar 				num_reg_entries = cond_regs[reg_id].num_entries;
3721c965db44STomer Tayar 		}
3722c965db44STomer Tayar 
3723c965db44STomer Tayar 		if (!check_rule && dump)
3724c965db44STomer Tayar 			continue;
3725c965db44STomer Tayar 
3726be086e7cSMintz, Yuval 		if (!dump) {
3727da090917STomer Tayar 			u32 entry_dump_size =
3728da090917STomer Tayar 				qed_idle_chk_dump_failure(p_hwfn,
3729be086e7cSMintz, Yuval 							  p_ptt,
3730be086e7cSMintz, Yuval 							  dump_buf + offset,
3731be086e7cSMintz, Yuval 							  false,
3732be086e7cSMintz, Yuval 							  rule->rule_id,
3733be086e7cSMintz, Yuval 							  rule,
3734da090917STomer Tayar 							  0,
3735be086e7cSMintz, Yuval 							  NULL);
3736da090917STomer Tayar 
3737da090917STomer Tayar 			offset += num_reg_entries * entry_dump_size;
3738da090917STomer Tayar 			(*num_failing_rules) += num_reg_entries;
3739da090917STomer Tayar 			continue;
3740be086e7cSMintz, Yuval 		}
3741be086e7cSMintz, Yuval 
3742da090917STomer Tayar 		/* Go over all register entries (number of entries is the same
3743da090917STomer Tayar 		 * for all condition registers).
3744da090917STomer Tayar 		 */
3745da090917STomer Tayar 		for (entry_id = 0; entry_id < num_reg_entries; entry_id++) {
3746da090917STomer Tayar 			u32 next_reg_offset = 0;
3747da090917STomer Tayar 
3748c965db44STomer Tayar 			/* Read current entry of all condition registers */
3749be086e7cSMintz, Yuval 			for (reg_id = 0; reg_id < rule->num_cond_regs;
3750c965db44STomer Tayar 			     reg_id++) {
3751be086e7cSMintz, Yuval 				const struct dbg_idle_chk_cond_reg *reg =
3752be086e7cSMintz, Yuval 					&cond_regs[reg_id];
37537b6859fbSMintz, Yuval 				u32 padded_entry_size, addr;
37547b6859fbSMintz, Yuval 				bool wide_bus;
3755c965db44STomer Tayar 
3756be086e7cSMintz, Yuval 				/* Find GRC address (if it's a memory, the
3757be086e7cSMintz, Yuval 				 * address of the specific entry is calculated).
3758c965db44STomer Tayar 				 */
37597b6859fbSMintz, Yuval 				addr = GET_FIELD(reg->data,
3760be086e7cSMintz, Yuval 						 DBG_IDLE_CHK_COND_REG_ADDRESS);
37617b6859fbSMintz, Yuval 				wide_bus =
37627b6859fbSMintz, Yuval 				    GET_FIELD(reg->data,
37637b6859fbSMintz, Yuval 					      DBG_IDLE_CHK_COND_REG_WIDE_BUS);
3764c965db44STomer Tayar 				if (reg->num_entries > 1 ||
3765c965db44STomer Tayar 				    reg->start_entry > 0) {
37667b6859fbSMintz, Yuval 					padded_entry_size =
3767c965db44STomer Tayar 					   reg->entry_size > 1 ?
3768da090917STomer Tayar 					   roundup_pow_of_two(reg->entry_size) :
3769da090917STomer Tayar 					   1;
3770be086e7cSMintz, Yuval 					addr += (reg->start_entry + entry_id) *
3771be086e7cSMintz, Yuval 						padded_entry_size;
3772c965db44STomer Tayar 				}
3773c965db44STomer Tayar 
3774c965db44STomer Tayar 				/* Read registers */
3775c965db44STomer Tayar 				if (next_reg_offset + reg->entry_size >=
3776c965db44STomer Tayar 				    IDLE_CHK_MAX_ENTRIES_SIZE) {
3777c965db44STomer Tayar 					DP_NOTICE(p_hwfn,
3778c965db44STomer Tayar 						  "idle check registers entry is too large\n");
3779c965db44STomer Tayar 					return 0;
3780c965db44STomer Tayar 				}
3781c965db44STomer Tayar 
3782be086e7cSMintz, Yuval 				next_reg_offset +=
37837b6859fbSMintz, Yuval 				    qed_grc_dump_addr_range(p_hwfn, p_ptt,
3784be086e7cSMintz, Yuval 							    cond_reg_values +
3785be086e7cSMintz, Yuval 							    next_reg_offset,
3786be086e7cSMintz, Yuval 							    dump, addr,
37877b6859fbSMintz, Yuval 							    reg->entry_size,
3788d52c89f1SMichal Kalderon 							    wide_bus,
3789d52c89f1SMichal Kalderon 							    SPLIT_TYPE_NONE, 0);
3790c965db44STomer Tayar 			}
3791c965db44STomer Tayar 
37927b6859fbSMintz, Yuval 			/* Call rule condition function.
37937b6859fbSMintz, Yuval 			 * If returns true, it's a failure.
3794c965db44STomer Tayar 			 */
3795c965db44STomer Tayar 			if ((*cond_arr[rule->cond_id]) (cond_reg_values,
3796be086e7cSMintz, Yuval 							imm_values)) {
37977b6859fbSMintz, Yuval 				offset += qed_idle_chk_dump_failure(p_hwfn,
3798c965db44STomer Tayar 							p_ptt,
3799c965db44STomer Tayar 							dump_buf + offset,
3800c965db44STomer Tayar 							dump,
3801c965db44STomer Tayar 							rule->rule_id,
3802c965db44STomer Tayar 							rule,
3803c965db44STomer Tayar 							entry_id,
3804c965db44STomer Tayar 							cond_reg_values);
3805c965db44STomer Tayar 				(*num_failing_rules)++;
3806c965db44STomer Tayar 			}
3807c965db44STomer Tayar 		}
3808c965db44STomer Tayar 	}
3809c965db44STomer Tayar 
3810c965db44STomer Tayar 	return offset;
3811c965db44STomer Tayar }
3812c965db44STomer Tayar 
3813c965db44STomer Tayar /* Performs Idle Check Dump to the specified buffer.
3814c965db44STomer Tayar  * Returns the dumped size in dwords.
3815c965db44STomer Tayar  */
3816c965db44STomer Tayar static u32 qed_idle_chk_dump(struct qed_hwfn *p_hwfn,
3817c965db44STomer Tayar 			     struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3818c965db44STomer Tayar {
38192d22bc83SMichal Kalderon 	struct virt_mem_desc *dbg_buf =
38202d22bc83SMichal Kalderon 	    &p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES];
38212d22bc83SMichal Kalderon 	u32 num_failing_rules_offset, offset = 0,
38222d22bc83SMichal Kalderon 	    input_offset = 0, num_failing_rules = 0;
3823c965db44STomer Tayar 
38242d22bc83SMichal Kalderon 	/* Dump global params  - 1 must match below amount of params */
3825c965db44STomer Tayar 	offset += qed_dump_common_global_params(p_hwfn,
3826c965db44STomer Tayar 						p_ptt,
3827c965db44STomer Tayar 						dump_buf + offset, dump, 1);
3828c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset,
3829c965db44STomer Tayar 				     dump, "dump-type", "idle-chk");
3830c965db44STomer Tayar 
3831c965db44STomer Tayar 	/* Dump idle check section header with a single parameter */
3832c965db44STomer Tayar 	offset += qed_dump_section_hdr(dump_buf + offset, dump, "idle_chk", 1);
3833c965db44STomer Tayar 	num_failing_rules_offset = offset;
3834c965db44STomer Tayar 	offset += qed_dump_num_param(dump_buf + offset, dump, "num_rules", 0);
38357b6859fbSMintz, Yuval 
38362d22bc83SMichal Kalderon 	while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) {
3837c965db44STomer Tayar 		const struct dbg_idle_chk_cond_hdr *cond_hdr =
38382d22bc83SMichal Kalderon 		    (const struct dbg_idle_chk_cond_hdr *)dbg_buf->ptr +
38392d22bc83SMichal Kalderon 		    input_offset++;
38407b6859fbSMintz, Yuval 		bool eval_mode, mode_match = true;
38417b6859fbSMintz, Yuval 		u32 curr_failing_rules;
38427b6859fbSMintz, Yuval 		u16 modes_buf_offset;
3843c965db44STomer Tayar 
3844c965db44STomer Tayar 		/* Check mode */
38457b6859fbSMintz, Yuval 		eval_mode = GET_FIELD(cond_hdr->mode.data,
38467b6859fbSMintz, Yuval 				      DBG_MODE_HDR_EVAL_MODE) > 0;
3847c965db44STomer Tayar 		if (eval_mode) {
38487b6859fbSMintz, Yuval 			modes_buf_offset =
3849c965db44STomer Tayar 				GET_FIELD(cond_hdr->mode.data,
3850c965db44STomer Tayar 					  DBG_MODE_HDR_MODES_BUF_OFFSET);
3851c965db44STomer Tayar 			mode_match = qed_is_mode_match(p_hwfn,
3852c965db44STomer Tayar 						       &modes_buf_offset);
3853c965db44STomer Tayar 		}
3854c965db44STomer Tayar 
3855c965db44STomer Tayar 		if (mode_match) {
38562d22bc83SMichal Kalderon 			const struct dbg_idle_chk_rule *rule =
38572d22bc83SMichal Kalderon 			    (const struct dbg_idle_chk_rule *)((u32 *)
38582d22bc83SMichal Kalderon 							       dbg_buf->ptr
38592d22bc83SMichal Kalderon 							       + input_offset);
38602d22bc83SMichal Kalderon 			u32 num_input_rules =
38612d22bc83SMichal Kalderon 				cond_hdr->data_size / IDLE_CHK_RULE_SIZE_DWORDS;
3862c965db44STomer Tayar 			offset +=
3863c965db44STomer Tayar 			    qed_idle_chk_dump_rule_entries(p_hwfn,
3864c965db44STomer Tayar 							   p_ptt,
38652d22bc83SMichal Kalderon 							   dump_buf +
38662d22bc83SMichal Kalderon 							   offset,
3867c965db44STomer Tayar 							   dump,
38682d22bc83SMichal Kalderon 							   rule,
38692d22bc83SMichal Kalderon 							   num_input_rules,
3870c965db44STomer Tayar 							   &curr_failing_rules);
3871c965db44STomer Tayar 			num_failing_rules += curr_failing_rules;
3872c965db44STomer Tayar 		}
3873c965db44STomer Tayar 
3874c965db44STomer Tayar 		input_offset += cond_hdr->data_size;
3875c965db44STomer Tayar 	}
3876c965db44STomer Tayar 
3877c965db44STomer Tayar 	/* Overwrite num_rules parameter */
3878c965db44STomer Tayar 	if (dump)
3879c965db44STomer Tayar 		qed_dump_num_param(dump_buf + num_failing_rules_offset,
3880c965db44STomer Tayar 				   dump, "num_rules", num_failing_rules);
3881c965db44STomer Tayar 
38827b6859fbSMintz, Yuval 	/* Dump last section */
3883da090917STomer Tayar 	offset += qed_dump_last_section(dump_buf, offset, dump);
38847b6859fbSMintz, Yuval 
3885c965db44STomer Tayar 	return offset;
3886c965db44STomer Tayar }
3887c965db44STomer Tayar 
38887b6859fbSMintz, Yuval /* Finds the meta data image in NVRAM */
3889c965db44STomer Tayar static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
3890c965db44STomer Tayar 					    struct qed_ptt *p_ptt,
3891c965db44STomer Tayar 					    u32 image_type,
3892c965db44STomer Tayar 					    u32 *nvram_offset_bytes,
3893c965db44STomer Tayar 					    u32 *nvram_size_bytes)
3894c965db44STomer Tayar {
3895c965db44STomer Tayar 	u32 ret_mcp_resp, ret_mcp_param, ret_txn_size;
3896c965db44STomer Tayar 	struct mcp_file_att file_att;
38977b6859fbSMintz, Yuval 	int nvm_result;
3898c965db44STomer Tayar 
3899c965db44STomer Tayar 	/* Call NVRAM get file command */
39007b6859fbSMintz, Yuval 	nvm_result = qed_mcp_nvm_rd_cmd(p_hwfn,
3901be086e7cSMintz, Yuval 					p_ptt,
3902be086e7cSMintz, Yuval 					DRV_MSG_CODE_NVM_GET_FILE_ATT,
3903be086e7cSMintz, Yuval 					image_type,
3904be086e7cSMintz, Yuval 					&ret_mcp_resp,
3905be086e7cSMintz, Yuval 					&ret_mcp_param,
39067b6859fbSMintz, Yuval 					&ret_txn_size, (u32 *)&file_att);
3907c965db44STomer Tayar 
3908c965db44STomer Tayar 	/* Check response */
3909be086e7cSMintz, Yuval 	if (nvm_result ||
3910be086e7cSMintz, Yuval 	    (ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
3911c965db44STomer Tayar 		return DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
3912c965db44STomer Tayar 
3913c965db44STomer Tayar 	/* Update return values */
3914c965db44STomer Tayar 	*nvram_offset_bytes = file_att.nvm_start_addr;
3915c965db44STomer Tayar 	*nvram_size_bytes = file_att.len;
39167b6859fbSMintz, Yuval 
3917c965db44STomer Tayar 	DP_VERBOSE(p_hwfn,
3918c965db44STomer Tayar 		   QED_MSG_DEBUG,
3919c965db44STomer Tayar 		   "find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\n",
3920c965db44STomer Tayar 		   image_type, *nvram_offset_bytes, *nvram_size_bytes);
3921c965db44STomer Tayar 
3922c965db44STomer Tayar 	/* Check alignment */
3923c965db44STomer Tayar 	if (*nvram_size_bytes & 0x3)
3924c965db44STomer Tayar 		return DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE;
39257b6859fbSMintz, Yuval 
3926c965db44STomer Tayar 	return DBG_STATUS_OK;
3927c965db44STomer Tayar }
3928c965db44STomer Tayar 
39297b6859fbSMintz, Yuval /* Reads data from NVRAM */
3930c965db44STomer Tayar static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
3931c965db44STomer Tayar 				      struct qed_ptt *p_ptt,
3932c965db44STomer Tayar 				      u32 nvram_offset_bytes,
3933c965db44STomer Tayar 				      u32 nvram_size_bytes, u32 *ret_buf)
3934c965db44STomer Tayar {
39357b6859fbSMintz, Yuval 	u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy;
3936c965db44STomer Tayar 	s32 bytes_left = nvram_size_bytes;
39372d22bc83SMichal Kalderon 	u32 read_offset = 0, param = 0;
3938c965db44STomer Tayar 
3939c965db44STomer Tayar 	DP_VERBOSE(p_hwfn,
3940c965db44STomer Tayar 		   QED_MSG_DEBUG,
3941c965db44STomer Tayar 		   "nvram_read: reading image of size %d bytes from NVRAM\n",
3942c965db44STomer Tayar 		   nvram_size_bytes);
39437b6859fbSMintz, Yuval 
3944c965db44STomer Tayar 	do {
3945c965db44STomer Tayar 		bytes_to_copy =
3946c965db44STomer Tayar 		    (bytes_left >
3947c965db44STomer Tayar 		     MCP_DRV_NVM_BUF_LEN) ? MCP_DRV_NVM_BUF_LEN : bytes_left;
3948c965db44STomer Tayar 
3949c965db44STomer Tayar 		/* Call NVRAM read command */
39502d22bc83SMichal Kalderon 		SET_MFW_FIELD(param,
39512d22bc83SMichal Kalderon 			      DRV_MB_PARAM_NVM_OFFSET,
39522d22bc83SMichal Kalderon 			      nvram_offset_bytes + read_offset);
39532d22bc83SMichal Kalderon 		SET_MFW_FIELD(param, DRV_MB_PARAM_NVM_LEN, bytes_to_copy);
3954c965db44STomer Tayar 		if (qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt,
39552d22bc83SMichal Kalderon 				       DRV_MSG_CODE_NVM_READ_NVRAM, param,
39562d22bc83SMichal Kalderon 				       &ret_mcp_resp,
39572d22bc83SMichal Kalderon 				       &ret_mcp_param, &ret_read_size,
39587b6859fbSMintz, Yuval 				       (u32 *)((u8 *)ret_buf + read_offset)))
3959c965db44STomer Tayar 			return DBG_STATUS_NVRAM_READ_FAILED;
3960c965db44STomer Tayar 
3961c965db44STomer Tayar 		/* Check response */
3962c965db44STomer Tayar 		if ((ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
3963c965db44STomer Tayar 			return DBG_STATUS_NVRAM_READ_FAILED;
3964c965db44STomer Tayar 
3965c965db44STomer Tayar 		/* Update read offset */
3966c965db44STomer Tayar 		read_offset += ret_read_size;
3967c965db44STomer Tayar 		bytes_left -= ret_read_size;
3968c965db44STomer Tayar 	} while (bytes_left > 0);
3969c965db44STomer Tayar 
3970c965db44STomer Tayar 	return DBG_STATUS_OK;
3971c965db44STomer Tayar }
3972c965db44STomer Tayar 
3973c965db44STomer Tayar /* Get info on the MCP Trace data in the scratchpad:
39747b6859fbSMintz, Yuval  * - trace_data_grc_addr (OUT): trace data GRC address in bytes
39757b6859fbSMintz, Yuval  * - trace_data_size (OUT): trace data size in bytes (without the header)
3976c965db44STomer Tayar  */
3977c965db44STomer Tayar static enum dbg_status qed_mcp_trace_get_data_info(struct qed_hwfn *p_hwfn,
3978c965db44STomer Tayar 						   struct qed_ptt *p_ptt,
3979c965db44STomer Tayar 						   u32 *trace_data_grc_addr,
39807b6859fbSMintz, Yuval 						   u32 *trace_data_size)
3981c965db44STomer Tayar {
39827b6859fbSMintz, Yuval 	u32 spad_trace_offsize, signature;
3983c965db44STomer Tayar 
39847b6859fbSMintz, Yuval 	/* Read trace section offsize structure from MCP scratchpad */
39857b6859fbSMintz, Yuval 	spad_trace_offsize = qed_rd(p_hwfn, p_ptt, MCP_SPAD_TRACE_OFFSIZE_ADDR);
39867b6859fbSMintz, Yuval 
39877b6859fbSMintz, Yuval 	/* Extract trace section address from offsize (in scratchpad) */
3988c965db44STomer Tayar 	*trace_data_grc_addr =
3989c965db44STomer Tayar 		MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize);
3990c965db44STomer Tayar 
3991c965db44STomer Tayar 	/* Read signature from MCP trace section */
3992c965db44STomer Tayar 	signature = qed_rd(p_hwfn, p_ptt,
3993c965db44STomer Tayar 			   *trace_data_grc_addr +
3994c965db44STomer Tayar 			   offsetof(struct mcp_trace, signature));
39957b6859fbSMintz, Yuval 
3996c965db44STomer Tayar 	if (signature != MFW_TRACE_SIGNATURE)
3997c965db44STomer Tayar 		return DBG_STATUS_INVALID_TRACE_SIGNATURE;
3998c965db44STomer Tayar 
3999c965db44STomer Tayar 	/* Read trace size from MCP trace section */
40007b6859fbSMintz, Yuval 	*trace_data_size = qed_rd(p_hwfn,
4001c965db44STomer Tayar 				  p_ptt,
4002c965db44STomer Tayar 				  *trace_data_grc_addr +
4003c965db44STomer Tayar 				  offsetof(struct mcp_trace, size));
40047b6859fbSMintz, Yuval 
4005c965db44STomer Tayar 	return DBG_STATUS_OK;
4006c965db44STomer Tayar }
4007c965db44STomer Tayar 
40087b6859fbSMintz, Yuval /* Reads MCP trace meta data image from NVRAM
40097b6859fbSMintz, Yuval  * - running_bundle_id (OUT): running bundle ID (invalid when loaded from file)
40107b6859fbSMintz, Yuval  * - trace_meta_offset (OUT): trace meta offset in NVRAM in bytes (invalid when
40117b6859fbSMintz, Yuval  *			      loaded from file).
40127b6859fbSMintz, Yuval  * - trace_meta_size (OUT):   size in bytes of the trace meta data.
4013c965db44STomer Tayar  */
4014c965db44STomer Tayar static enum dbg_status qed_mcp_trace_get_meta_info(struct qed_hwfn *p_hwfn,
4015c965db44STomer Tayar 						   struct qed_ptt *p_ptt,
4016c965db44STomer Tayar 						   u32 trace_data_size_bytes,
4017c965db44STomer Tayar 						   u32 *running_bundle_id,
40187b6859fbSMintz, Yuval 						   u32 *trace_meta_offset,
40197b6859fbSMintz, Yuval 						   u32 *trace_meta_size)
4020c965db44STomer Tayar {
40217b6859fbSMintz, Yuval 	u32 spad_trace_offsize, nvram_image_type, running_mfw_addr;
40227b6859fbSMintz, Yuval 
4023c965db44STomer Tayar 	/* Read MCP trace section offsize structure from MCP scratchpad */
40247b6859fbSMintz, Yuval 	spad_trace_offsize = qed_rd(p_hwfn, p_ptt, MCP_SPAD_TRACE_OFFSIZE_ADDR);
4025c965db44STomer Tayar 
4026c965db44STomer Tayar 	/* Find running bundle ID */
40277b6859fbSMintz, Yuval 	running_mfw_addr =
4028c965db44STomer Tayar 		MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize) +
4029c965db44STomer Tayar 		QED_SECTION_SIZE(spad_trace_offsize) + trace_data_size_bytes;
4030c965db44STomer Tayar 	*running_bundle_id = qed_rd(p_hwfn, p_ptt, running_mfw_addr);
4031c965db44STomer Tayar 	if (*running_bundle_id > 1)
4032c965db44STomer Tayar 		return DBG_STATUS_INVALID_NVRAM_BUNDLE;
4033c965db44STomer Tayar 
4034c965db44STomer Tayar 	/* Find image in NVRAM */
4035c965db44STomer Tayar 	nvram_image_type =
4036c965db44STomer Tayar 	    (*running_bundle_id ==
4037c965db44STomer Tayar 	     DIR_ID_1) ? NVM_TYPE_MFW_TRACE1 : NVM_TYPE_MFW_TRACE2;
4038be086e7cSMintz, Yuval 	return qed_find_nvram_image(p_hwfn,
4039c965db44STomer Tayar 				    p_ptt,
4040c965db44STomer Tayar 				    nvram_image_type,
40417b6859fbSMintz, Yuval 				    trace_meta_offset, trace_meta_size);
4042c965db44STomer Tayar }
4043c965db44STomer Tayar 
40447b6859fbSMintz, Yuval /* Reads the MCP Trace meta data from NVRAM into the specified buffer */
4045c965db44STomer Tayar static enum dbg_status qed_mcp_trace_read_meta(struct qed_hwfn *p_hwfn,
4046c965db44STomer Tayar 					       struct qed_ptt *p_ptt,
4047c965db44STomer Tayar 					       u32 nvram_offset_in_bytes,
4048c965db44STomer Tayar 					       u32 size_in_bytes, u32 *buf)
4049c965db44STomer Tayar {
40507b6859fbSMintz, Yuval 	u8 modules_num, module_len, i, *byte_buf = (u8 *)buf;
40517b6859fbSMintz, Yuval 	enum dbg_status status;
4052c965db44STomer Tayar 	u32 signature;
4053c965db44STomer Tayar 
4054c965db44STomer Tayar 	/* Read meta data from NVRAM */
40557b6859fbSMintz, Yuval 	status = qed_nvram_read(p_hwfn,
4056c965db44STomer Tayar 				p_ptt,
40577b6859fbSMintz, Yuval 				nvram_offset_in_bytes, size_in_bytes, buf);
4058c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
4059c965db44STomer Tayar 		return status;
4060c965db44STomer Tayar 
4061c965db44STomer Tayar 	/* Extract and check first signature */
4062c965db44STomer Tayar 	signature = qed_read_unaligned_dword(byte_buf);
40637b6859fbSMintz, Yuval 	byte_buf += sizeof(signature);
40647b6859fbSMintz, Yuval 	if (signature != NVM_MAGIC_VALUE)
4065c965db44STomer Tayar 		return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4066c965db44STomer Tayar 
4067c965db44STomer Tayar 	/* Extract number of modules */
4068c965db44STomer Tayar 	modules_num = *(byte_buf++);
4069c965db44STomer Tayar 
4070c965db44STomer Tayar 	/* Skip all modules */
4071c965db44STomer Tayar 	for (i = 0; i < modules_num; i++) {
40727b6859fbSMintz, Yuval 		module_len = *(byte_buf++);
4073c965db44STomer Tayar 		byte_buf += module_len;
4074c965db44STomer Tayar 	}
4075c965db44STomer Tayar 
4076c965db44STomer Tayar 	/* Extract and check second signature */
4077c965db44STomer Tayar 	signature = qed_read_unaligned_dword(byte_buf);
40787b6859fbSMintz, Yuval 	byte_buf += sizeof(signature);
40797b6859fbSMintz, Yuval 	if (signature != NVM_MAGIC_VALUE)
4080c965db44STomer Tayar 		return DBG_STATUS_INVALID_TRACE_SIGNATURE;
40817b6859fbSMintz, Yuval 
4082c965db44STomer Tayar 	return DBG_STATUS_OK;
4083c965db44STomer Tayar }
4084c965db44STomer Tayar 
4085c965db44STomer Tayar /* Dump MCP Trace */
40868c93beafSYuval Mintz static enum dbg_status qed_mcp_trace_dump(struct qed_hwfn *p_hwfn,
4087c965db44STomer Tayar 					  struct qed_ptt *p_ptt,
4088c965db44STomer Tayar 					  u32 *dump_buf,
4089c965db44STomer Tayar 					  bool dump, u32 *num_dumped_dwords)
4090c965db44STomer Tayar {
4091c965db44STomer Tayar 	u32 trace_data_grc_addr, trace_data_size_bytes, trace_data_size_dwords;
4092be086e7cSMintz, Yuval 	u32 trace_meta_size_dwords = 0, running_bundle_id, offset = 0;
4093be086e7cSMintz, Yuval 	u32 trace_meta_offset_bytes = 0, trace_meta_size_bytes = 0;
4094c965db44STomer Tayar 	enum dbg_status status;
4095c965db44STomer Tayar 	int halted = 0;
40962d22bc83SMichal Kalderon 	bool use_mfw;
4097c965db44STomer Tayar 
4098c965db44STomer Tayar 	*num_dumped_dwords = 0;
4099c965db44STomer Tayar 
41002d22bc83SMichal Kalderon 	use_mfw = !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP);
41017b6859fbSMintz, Yuval 
4102c965db44STomer Tayar 	/* Get trace data info */
4103c965db44STomer Tayar 	status = qed_mcp_trace_get_data_info(p_hwfn,
4104c965db44STomer Tayar 					     p_ptt,
4105c965db44STomer Tayar 					     &trace_data_grc_addr,
4106c965db44STomer Tayar 					     &trace_data_size_bytes);
4107c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
4108c965db44STomer Tayar 		return status;
4109c965db44STomer Tayar 
4110c965db44STomer Tayar 	/* Dump global params */
4111c965db44STomer Tayar 	offset += qed_dump_common_global_params(p_hwfn,
4112c965db44STomer Tayar 						p_ptt,
4113c965db44STomer Tayar 						dump_buf + offset, dump, 1);
4114c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset,
4115c965db44STomer Tayar 				     dump, "dump-type", "mcp-trace");
4116c965db44STomer Tayar 
4117c965db44STomer Tayar 	/* Halt MCP while reading from scratchpad so the read data will be
41187b6859fbSMintz, Yuval 	 * consistent. if halt fails, MCP trace is taken anyway, with a small
4119c965db44STomer Tayar 	 * risk that it may be corrupt.
4120c965db44STomer Tayar 	 */
41212d22bc83SMichal Kalderon 	if (dump && use_mfw) {
4122c965db44STomer Tayar 		halted = !qed_mcp_halt(p_hwfn, p_ptt);
4123c965db44STomer Tayar 		if (!halted)
4124c965db44STomer Tayar 			DP_NOTICE(p_hwfn, "MCP halt failed!\n");
4125c965db44STomer Tayar 	}
4126c965db44STomer Tayar 
4127c965db44STomer Tayar 	/* Find trace data size */
4128c965db44STomer Tayar 	trace_data_size_dwords =
4129c965db44STomer Tayar 	    DIV_ROUND_UP(trace_data_size_bytes + sizeof(struct mcp_trace),
4130c965db44STomer Tayar 			 BYTES_IN_DWORD);
4131c965db44STomer Tayar 
4132c965db44STomer Tayar 	/* Dump trace data section header and param */
4133c965db44STomer Tayar 	offset += qed_dump_section_hdr(dump_buf + offset,
4134c965db44STomer Tayar 				       dump, "mcp_trace_data", 1);
4135c965db44STomer Tayar 	offset += qed_dump_num_param(dump_buf + offset,
4136c965db44STomer Tayar 				     dump, "size", trace_data_size_dwords);
4137c965db44STomer Tayar 
4138c965db44STomer Tayar 	/* Read trace data from scratchpad into dump buffer */
4139be086e7cSMintz, Yuval 	offset += qed_grc_dump_addr_range(p_hwfn,
4140c965db44STomer Tayar 					  p_ptt,
4141be086e7cSMintz, Yuval 					  dump_buf + offset,
4142be086e7cSMintz, Yuval 					  dump,
4143be086e7cSMintz, Yuval 					  BYTES_TO_DWORDS(trace_data_grc_addr),
4144d52c89f1SMichal Kalderon 					  trace_data_size_dwords, false,
4145d52c89f1SMichal Kalderon 					  SPLIT_TYPE_NONE, 0);
4146c965db44STomer Tayar 
4147c965db44STomer Tayar 	/* Resume MCP (only if halt succeeded) */
41487b6859fbSMintz, Yuval 	if (halted && qed_mcp_resume(p_hwfn, p_ptt))
4149c965db44STomer Tayar 		DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n");
4150c965db44STomer Tayar 
4151c965db44STomer Tayar 	/* Dump trace meta section header */
4152c965db44STomer Tayar 	offset += qed_dump_section_hdr(dump_buf + offset,
4153c965db44STomer Tayar 				       dump, "mcp_trace_meta", 1);
4154c965db44STomer Tayar 
415550bc60cbSMichal Kalderon 	/* If MCP Trace meta size parameter was set, use it.
415650bc60cbSMichal Kalderon 	 * Otherwise, read trace meta.
415750bc60cbSMichal Kalderon 	 * trace_meta_size_bytes is dword-aligned.
415850bc60cbSMichal Kalderon 	 */
415950bc60cbSMichal Kalderon 	trace_meta_size_bytes =
416050bc60cbSMichal Kalderon 		qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_MCP_TRACE_META_SIZE);
41612d22bc83SMichal Kalderon 	if ((!trace_meta_size_bytes || dump) && use_mfw)
4162c965db44STomer Tayar 		status = qed_mcp_trace_get_meta_info(p_hwfn,
4163c965db44STomer Tayar 						     p_ptt,
4164c965db44STomer Tayar 						     trace_data_size_bytes,
4165c965db44STomer Tayar 						     &running_bundle_id,
4166c965db44STomer Tayar 						     &trace_meta_offset_bytes,
4167c965db44STomer Tayar 						     &trace_meta_size_bytes);
4168be086e7cSMintz, Yuval 	if (status == DBG_STATUS_OK)
41692d22bc83SMichal Kalderon 		trace_meta_size_dwords = BYTES_TO_DWORDS(trace_meta_size_bytes);
4170c965db44STomer Tayar 
4171be086e7cSMintz, Yuval 	/* Dump trace meta size param */
4172be086e7cSMintz, Yuval 	offset += qed_dump_num_param(dump_buf + offset,
4173be086e7cSMintz, Yuval 				     dump, "size", trace_meta_size_dwords);
4174c965db44STomer Tayar 
4175c965db44STomer Tayar 	/* Read trace meta image into dump buffer */
4176be086e7cSMintz, Yuval 	if (dump && trace_meta_size_dwords)
4177c965db44STomer Tayar 		status = qed_mcp_trace_read_meta(p_hwfn,
4178c965db44STomer Tayar 						 p_ptt,
4179c965db44STomer Tayar 						 trace_meta_offset_bytes,
4180c965db44STomer Tayar 						 trace_meta_size_bytes,
4181c965db44STomer Tayar 						 dump_buf + offset);
4182be086e7cSMintz, Yuval 	if (status == DBG_STATUS_OK)
4183c965db44STomer Tayar 		offset += trace_meta_size_dwords;
4184c965db44STomer Tayar 
41857b6859fbSMintz, Yuval 	/* Dump last section */
4186da090917STomer Tayar 	offset += qed_dump_last_section(dump_buf, offset, dump);
41877b6859fbSMintz, Yuval 
4188c965db44STomer Tayar 	*num_dumped_dwords = offset;
4189c965db44STomer Tayar 
4190be086e7cSMintz, Yuval 	/* If no mcp access, indicate that the dump doesn't contain the meta
4191be086e7cSMintz, Yuval 	 * data from NVRAM.
4192be086e7cSMintz, Yuval 	 */
41932d22bc83SMichal Kalderon 	return use_mfw ? status : DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
4194c965db44STomer Tayar }
4195c965db44STomer Tayar 
4196c965db44STomer Tayar /* Dump GRC FIFO */
41978c93beafSYuval Mintz static enum dbg_status qed_reg_fifo_dump(struct qed_hwfn *p_hwfn,
4198c965db44STomer Tayar 					 struct qed_ptt *p_ptt,
4199c965db44STomer Tayar 					 u32 *dump_buf,
4200c965db44STomer Tayar 					 bool dump, u32 *num_dumped_dwords)
4201c965db44STomer Tayar {
4202da090917STomer Tayar 	u32 dwords_read, size_param_offset, offset = 0, addr, len;
4203c965db44STomer Tayar 	bool fifo_has_data;
4204c965db44STomer Tayar 
4205c965db44STomer Tayar 	*num_dumped_dwords = 0;
4206c965db44STomer Tayar 
4207c965db44STomer Tayar 	/* Dump global params */
4208c965db44STomer Tayar 	offset += qed_dump_common_global_params(p_hwfn,
4209c965db44STomer Tayar 						p_ptt,
4210c965db44STomer Tayar 						dump_buf + offset, dump, 1);
4211c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset,
4212c965db44STomer Tayar 				     dump, "dump-type", "reg-fifo");
4213c965db44STomer Tayar 
42147b6859fbSMintz, Yuval 	/* Dump fifo data section header and param. The size param is 0 for
42157b6859fbSMintz, Yuval 	 * now, and is overwritten after reading the FIFO.
4216c965db44STomer Tayar 	 */
4217c965db44STomer Tayar 	offset += qed_dump_section_hdr(dump_buf + offset,
4218c965db44STomer Tayar 				       dump, "reg_fifo_data", 1);
4219c965db44STomer Tayar 	size_param_offset = offset;
4220c965db44STomer Tayar 	offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4221c965db44STomer Tayar 
4222c965db44STomer Tayar 	if (!dump) {
4223c965db44STomer Tayar 		/* FIFO max size is REG_FIFO_DEPTH_DWORDS. There is no way to
4224c965db44STomer Tayar 		 * test how much data is available, except for reading it.
4225c965db44STomer Tayar 		 */
4226c965db44STomer Tayar 		offset += REG_FIFO_DEPTH_DWORDS;
42277b6859fbSMintz, Yuval 		goto out;
4228c965db44STomer Tayar 	}
4229c965db44STomer Tayar 
4230c965db44STomer Tayar 	fifo_has_data = qed_rd(p_hwfn, p_ptt,
4231c965db44STomer Tayar 			       GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
4232c965db44STomer Tayar 
4233c965db44STomer Tayar 	/* Pull available data from fifo. Use DMAE since this is widebus memory
4234c965db44STomer Tayar 	 * and must be accessed atomically. Test for dwords_read not passing
4235c965db44STomer Tayar 	 * buffer size since more entries could be added to the buffer as we are
4236c965db44STomer Tayar 	 * emptying it.
4237c965db44STomer Tayar 	 */
4238da090917STomer Tayar 	addr = BYTES_TO_DWORDS(GRC_REG_TRACE_FIFO);
4239da090917STomer Tayar 	len = REG_FIFO_ELEMENT_DWORDS;
4240c965db44STomer Tayar 	for (dwords_read = 0;
4241c965db44STomer Tayar 	     fifo_has_data && dwords_read < REG_FIFO_DEPTH_DWORDS;
4242da090917STomer Tayar 	     dwords_read += REG_FIFO_ELEMENT_DWORDS) {
4243da090917STomer Tayar 		offset += qed_grc_dump_addr_range(p_hwfn,
4244da090917STomer Tayar 						  p_ptt,
4245da090917STomer Tayar 						  dump_buf + offset,
4246da090917STomer Tayar 						  true,
4247da090917STomer Tayar 						  addr,
4248da090917STomer Tayar 						  len,
4249d52c89f1SMichal Kalderon 						  true, SPLIT_TYPE_NONE,
4250d52c89f1SMichal Kalderon 						  0);
4251c965db44STomer Tayar 		fifo_has_data = qed_rd(p_hwfn, p_ptt,
4252c965db44STomer Tayar 				       GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
4253c965db44STomer Tayar 	}
4254c965db44STomer Tayar 
4255c965db44STomer Tayar 	qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4256c965db44STomer Tayar 			   dwords_read);
42577b6859fbSMintz, Yuval out:
42587b6859fbSMintz, Yuval 	/* Dump last section */
4259da090917STomer Tayar 	offset += qed_dump_last_section(dump_buf, offset, dump);
4260c965db44STomer Tayar 
4261c965db44STomer Tayar 	*num_dumped_dwords = offset;
42627b6859fbSMintz, Yuval 
4263c965db44STomer Tayar 	return DBG_STATUS_OK;
4264c965db44STomer Tayar }
4265c965db44STomer Tayar 
4266c965db44STomer Tayar /* Dump IGU FIFO */
42678c93beafSYuval Mintz static enum dbg_status qed_igu_fifo_dump(struct qed_hwfn *p_hwfn,
4268c965db44STomer Tayar 					 struct qed_ptt *p_ptt,
4269c965db44STomer Tayar 					 u32 *dump_buf,
4270c965db44STomer Tayar 					 bool dump, u32 *num_dumped_dwords)
4271c965db44STomer Tayar {
4272da090917STomer Tayar 	u32 dwords_read, size_param_offset, offset = 0, addr, len;
4273c965db44STomer Tayar 	bool fifo_has_data;
4274c965db44STomer Tayar 
4275c965db44STomer Tayar 	*num_dumped_dwords = 0;
4276c965db44STomer Tayar 
4277c965db44STomer Tayar 	/* Dump global params */
4278c965db44STomer Tayar 	offset += qed_dump_common_global_params(p_hwfn,
4279c965db44STomer Tayar 						p_ptt,
4280c965db44STomer Tayar 						dump_buf + offset, dump, 1);
4281c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset,
4282c965db44STomer Tayar 				     dump, "dump-type", "igu-fifo");
4283c965db44STomer Tayar 
42847b6859fbSMintz, Yuval 	/* Dump fifo data section header and param. The size param is 0 for
42857b6859fbSMintz, Yuval 	 * now, and is overwritten after reading the FIFO.
4286c965db44STomer Tayar 	 */
4287c965db44STomer Tayar 	offset += qed_dump_section_hdr(dump_buf + offset,
4288c965db44STomer Tayar 				       dump, "igu_fifo_data", 1);
4289c965db44STomer Tayar 	size_param_offset = offset;
4290c965db44STomer Tayar 	offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4291c965db44STomer Tayar 
4292c965db44STomer Tayar 	if (!dump) {
4293c965db44STomer Tayar 		/* FIFO max size is IGU_FIFO_DEPTH_DWORDS. There is no way to
4294c965db44STomer Tayar 		 * test how much data is available, except for reading it.
4295c965db44STomer Tayar 		 */
4296c965db44STomer Tayar 		offset += IGU_FIFO_DEPTH_DWORDS;
42977b6859fbSMintz, Yuval 		goto out;
4298c965db44STomer Tayar 	}
4299c965db44STomer Tayar 
4300c965db44STomer Tayar 	fifo_has_data = qed_rd(p_hwfn, p_ptt,
4301c965db44STomer Tayar 			       IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
4302c965db44STomer Tayar 
4303c965db44STomer Tayar 	/* Pull available data from fifo. Use DMAE since this is widebus memory
4304c965db44STomer Tayar 	 * and must be accessed atomically. Test for dwords_read not passing
4305c965db44STomer Tayar 	 * buffer size since more entries could be added to the buffer as we are
4306c965db44STomer Tayar 	 * emptying it.
4307c965db44STomer Tayar 	 */
4308da090917STomer Tayar 	addr = BYTES_TO_DWORDS(IGU_REG_ERROR_HANDLING_MEMORY);
4309da090917STomer Tayar 	len = IGU_FIFO_ELEMENT_DWORDS;
4310c965db44STomer Tayar 	for (dwords_read = 0;
4311c965db44STomer Tayar 	     fifo_has_data && dwords_read < IGU_FIFO_DEPTH_DWORDS;
4312da090917STomer Tayar 	     dwords_read += IGU_FIFO_ELEMENT_DWORDS) {
4313da090917STomer Tayar 		offset += qed_grc_dump_addr_range(p_hwfn,
4314da090917STomer Tayar 						  p_ptt,
4315da090917STomer Tayar 						  dump_buf + offset,
4316da090917STomer Tayar 						  true,
4317da090917STomer Tayar 						  addr,
4318da090917STomer Tayar 						  len,
4319d52c89f1SMichal Kalderon 						  true, SPLIT_TYPE_NONE,
4320d52c89f1SMichal Kalderon 						  0);
4321c965db44STomer Tayar 		fifo_has_data = qed_rd(p_hwfn, p_ptt,
4322c965db44STomer Tayar 				       IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
4323c965db44STomer Tayar 	}
4324c965db44STomer Tayar 
4325c965db44STomer Tayar 	qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4326c965db44STomer Tayar 			   dwords_read);
43277b6859fbSMintz, Yuval out:
43287b6859fbSMintz, Yuval 	/* Dump last section */
4329da090917STomer Tayar 	offset += qed_dump_last_section(dump_buf, offset, dump);
4330c965db44STomer Tayar 
4331c965db44STomer Tayar 	*num_dumped_dwords = offset;
43327b6859fbSMintz, Yuval 
4333c965db44STomer Tayar 	return DBG_STATUS_OK;
4334c965db44STomer Tayar }
4335c965db44STomer Tayar 
4336c965db44STomer Tayar /* Protection Override dump */
43378c93beafSYuval Mintz static enum dbg_status qed_protection_override_dump(struct qed_hwfn *p_hwfn,
4338c965db44STomer Tayar 						    struct qed_ptt *p_ptt,
4339c965db44STomer Tayar 						    u32 *dump_buf,
43408c93beafSYuval Mintz 						    bool dump,
43418c93beafSYuval Mintz 						    u32 *num_dumped_dwords)
4342c965db44STomer Tayar {
4343da090917STomer Tayar 	u32 size_param_offset, override_window_dwords, offset = 0, addr;
4344c965db44STomer Tayar 
4345c965db44STomer Tayar 	*num_dumped_dwords = 0;
4346c965db44STomer Tayar 
4347c965db44STomer Tayar 	/* Dump global params */
4348c965db44STomer Tayar 	offset += qed_dump_common_global_params(p_hwfn,
4349c965db44STomer Tayar 						p_ptt,
4350c965db44STomer Tayar 						dump_buf + offset, dump, 1);
4351c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset,
4352c965db44STomer Tayar 				     dump, "dump-type", "protection-override");
4353c965db44STomer Tayar 
43547b6859fbSMintz, Yuval 	/* Dump data section header and param. The size param is 0 for now,
43557b6859fbSMintz, Yuval 	 * and is overwritten after reading the data.
4356c965db44STomer Tayar 	 */
4357c965db44STomer Tayar 	offset += qed_dump_section_hdr(dump_buf + offset,
4358c965db44STomer Tayar 				       dump, "protection_override_data", 1);
4359c965db44STomer Tayar 	size_param_offset = offset;
4360c965db44STomer Tayar 	offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4361c965db44STomer Tayar 
4362c965db44STomer Tayar 	if (!dump) {
4363c965db44STomer Tayar 		offset += PROTECTION_OVERRIDE_DEPTH_DWORDS;
43647b6859fbSMintz, Yuval 		goto out;
4365c965db44STomer Tayar 	}
4366c965db44STomer Tayar 
4367c965db44STomer Tayar 	/* Add override window info to buffer */
4368c965db44STomer Tayar 	override_window_dwords =
4369da090917STomer Tayar 		qed_rd(p_hwfn, p_ptt, GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW) *
4370c965db44STomer Tayar 		PROTECTION_OVERRIDE_ELEMENT_DWORDS;
43718a52bbabSMichal Kalderon 	if (override_window_dwords) {
4372da090917STomer Tayar 		addr = BYTES_TO_DWORDS(GRC_REG_PROTECTION_OVERRIDE_WINDOW);
4373da090917STomer Tayar 		offset += qed_grc_dump_addr_range(p_hwfn,
4374da090917STomer Tayar 						  p_ptt,
4375da090917STomer Tayar 						  dump_buf + offset,
4376da090917STomer Tayar 						  true,
4377da090917STomer Tayar 						  addr,
4378da090917STomer Tayar 						  override_window_dwords,
4379d52c89f1SMichal Kalderon 						  true, SPLIT_TYPE_NONE, 0);
4380c965db44STomer Tayar 		qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4381c965db44STomer Tayar 				   override_window_dwords);
43828a52bbabSMichal Kalderon 	}
43837b6859fbSMintz, Yuval out:
43847b6859fbSMintz, Yuval 	/* Dump last section */
4385da090917STomer Tayar 	offset += qed_dump_last_section(dump_buf, offset, dump);
4386c965db44STomer Tayar 
4387c965db44STomer Tayar 	*num_dumped_dwords = offset;
43887b6859fbSMintz, Yuval 
4389c965db44STomer Tayar 	return DBG_STATUS_OK;
4390c965db44STomer Tayar }
4391c965db44STomer Tayar 
4392c965db44STomer Tayar /* Performs FW Asserts Dump to the specified buffer.
4393c965db44STomer Tayar  * Returns the dumped size in dwords.
4394c965db44STomer Tayar  */
4395c965db44STomer Tayar static u32 qed_fw_asserts_dump(struct qed_hwfn *p_hwfn,
4396c965db44STomer Tayar 			       struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
4397c965db44STomer Tayar {
4398c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4399be086e7cSMintz, Yuval 	struct fw_asserts_ram_section *asserts;
4400c965db44STomer Tayar 	char storm_letter_str[2] = "?";
4401c965db44STomer Tayar 	struct fw_info fw_info;
4402be086e7cSMintz, Yuval 	u32 offset = 0;
4403c965db44STomer Tayar 	u8 storm_id;
4404c965db44STomer Tayar 
4405c965db44STomer Tayar 	/* Dump global params */
4406c965db44STomer Tayar 	offset += qed_dump_common_global_params(p_hwfn,
4407c965db44STomer Tayar 						p_ptt,
4408c965db44STomer Tayar 						dump_buf + offset, dump, 1);
4409c965db44STomer Tayar 	offset += qed_dump_str_param(dump_buf + offset,
4410c965db44STomer Tayar 				     dump, "dump-type", "fw-asserts");
44117b6859fbSMintz, Yuval 
44127b6859fbSMintz, Yuval 	/* Find Storm dump size */
4413c965db44STomer Tayar 	for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
4414be086e7cSMintz, Yuval 		u32 fw_asserts_section_addr, next_list_idx_addr, next_list_idx;
44157b6859fbSMintz, Yuval 		struct storm_defs *storm = &s_storm_defs[storm_id];
4416be086e7cSMintz, Yuval 		u32 last_list_idx, addr;
4417c965db44STomer Tayar 
44182d22bc83SMichal Kalderon 		if (dev_data->block_in_reset[storm->sem_block_id])
4419c965db44STomer Tayar 			continue;
4420c965db44STomer Tayar 
4421c965db44STomer Tayar 		/* Read FW info for the current Storm */
4422d52c89f1SMichal Kalderon 		qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, &fw_info);
4423c965db44STomer Tayar 
4424be086e7cSMintz, Yuval 		asserts = &fw_info.fw_asserts_section;
4425be086e7cSMintz, Yuval 
4426c965db44STomer Tayar 		/* Dump FW Asserts section header and params */
44277b6859fbSMintz, Yuval 		storm_letter_str[0] = storm->letter;
44287b6859fbSMintz, Yuval 		offset += qed_dump_section_hdr(dump_buf + offset,
44297b6859fbSMintz, Yuval 					       dump, "fw_asserts", 2);
44307b6859fbSMintz, Yuval 		offset += qed_dump_str_param(dump_buf + offset,
44317b6859fbSMintz, Yuval 					     dump, "storm", storm_letter_str);
44327b6859fbSMintz, Yuval 		offset += qed_dump_num_param(dump_buf + offset,
44337b6859fbSMintz, Yuval 					     dump,
44347b6859fbSMintz, Yuval 					     "size",
4435be086e7cSMintz, Yuval 					     asserts->list_element_dword_size);
4436c965db44STomer Tayar 
44377b6859fbSMintz, Yuval 		/* Read and dump FW Asserts data */
4438c965db44STomer Tayar 		if (!dump) {
4439be086e7cSMintz, Yuval 			offset += asserts->list_element_dword_size;
4440c965db44STomer Tayar 			continue;
4441c965db44STomer Tayar 		}
4442c965db44STomer Tayar 
44437b6859fbSMintz, Yuval 		fw_asserts_section_addr = storm->sem_fast_mem_addr +
4444c965db44STomer Tayar 			SEM_FAST_REG_INT_RAM +
4445be086e7cSMintz, Yuval 			RAM_LINES_TO_BYTES(asserts->section_ram_line_offset);
44467b6859fbSMintz, Yuval 		next_list_idx_addr = fw_asserts_section_addr +
4447be086e7cSMintz, Yuval 			DWORDS_TO_BYTES(asserts->list_next_index_dword_offset);
4448c965db44STomer Tayar 		next_list_idx = qed_rd(p_hwfn, p_ptt, next_list_idx_addr);
4449da090917STomer Tayar 		last_list_idx = (next_list_idx > 0 ?
4450da090917STomer Tayar 				 next_list_idx :
4451da090917STomer Tayar 				 asserts->list_num_elements) - 1;
4452be086e7cSMintz, Yuval 		addr = BYTES_TO_DWORDS(fw_asserts_section_addr) +
4453be086e7cSMintz, Yuval 		       asserts->list_dword_offset +
4454be086e7cSMintz, Yuval 		       last_list_idx * asserts->list_element_dword_size;
4455be086e7cSMintz, Yuval 		offset +=
4456be086e7cSMintz, Yuval 		    qed_grc_dump_addr_range(p_hwfn, p_ptt,
4457be086e7cSMintz, Yuval 					    dump_buf + offset,
4458be086e7cSMintz, Yuval 					    dump, addr,
44597b6859fbSMintz, Yuval 					    asserts->list_element_dword_size,
4460d52c89f1SMichal Kalderon 						  false, SPLIT_TYPE_NONE, 0);
4461c965db44STomer Tayar 	}
4462c965db44STomer Tayar 
4463c965db44STomer Tayar 	/* Dump last section */
4464da090917STomer Tayar 	offset += qed_dump_last_section(dump_buf, offset, dump);
44657b6859fbSMintz, Yuval 
4466c965db44STomer Tayar 	return offset;
4467c965db44STomer Tayar }
4468c965db44STomer Tayar 
44698a52bbabSMichal Kalderon /* Dumps the specified ILT pages to the specified buffer.
44708a52bbabSMichal Kalderon  * Returns the dumped size in dwords.
44718a52bbabSMichal Kalderon  */
44728a52bbabSMichal Kalderon static u32 qed_ilt_dump_pages_range(u32 *dump_buf,
44738a52bbabSMichal Kalderon 				    bool dump,
44748a52bbabSMichal Kalderon 				    u32 start_page_id,
44758a52bbabSMichal Kalderon 				    u32 num_pages,
44768a52bbabSMichal Kalderon 				    struct phys_mem_desc *ilt_pages,
44778a52bbabSMichal Kalderon 				    bool dump_page_ids)
44788a52bbabSMichal Kalderon {
44798a52bbabSMichal Kalderon 	u32 page_id, end_page_id, offset = 0;
44808a52bbabSMichal Kalderon 
44818a52bbabSMichal Kalderon 	if (num_pages == 0)
44828a52bbabSMichal Kalderon 		return offset;
44838a52bbabSMichal Kalderon 
44848a52bbabSMichal Kalderon 	end_page_id = start_page_id + num_pages - 1;
44858a52bbabSMichal Kalderon 
44868a52bbabSMichal Kalderon 	for (page_id = start_page_id; page_id <= end_page_id; page_id++) {
44878a52bbabSMichal Kalderon 		struct phys_mem_desc *mem_desc = &ilt_pages[page_id];
44888a52bbabSMichal Kalderon 
44898a52bbabSMichal Kalderon 		/**
44908a52bbabSMichal Kalderon 		 *
44918a52bbabSMichal Kalderon 		 * if (page_id >= ->p_cxt_mngr->ilt_shadow_size)
44928a52bbabSMichal Kalderon 		 *     break;
44938a52bbabSMichal Kalderon 		 */
44948a52bbabSMichal Kalderon 
44958a52bbabSMichal Kalderon 		if (!ilt_pages[page_id].virt_addr)
44968a52bbabSMichal Kalderon 			continue;
44978a52bbabSMichal Kalderon 
44988a52bbabSMichal Kalderon 		if (dump_page_ids) {
44998a52bbabSMichal Kalderon 			/* Copy page ID to dump buffer */
45008a52bbabSMichal Kalderon 			if (dump)
45018a52bbabSMichal Kalderon 				*(dump_buf + offset) = page_id;
45028a52bbabSMichal Kalderon 			offset++;
45038a52bbabSMichal Kalderon 		} else {
45048a52bbabSMichal Kalderon 			/* Copy page memory to dump buffer */
45058a52bbabSMichal Kalderon 			if (dump)
45068a52bbabSMichal Kalderon 				memcpy(dump_buf + offset,
45078a52bbabSMichal Kalderon 				       mem_desc->virt_addr, mem_desc->size);
45088a52bbabSMichal Kalderon 			offset += BYTES_TO_DWORDS(mem_desc->size);
45098a52bbabSMichal Kalderon 		}
45108a52bbabSMichal Kalderon 	}
45118a52bbabSMichal Kalderon 
45128a52bbabSMichal Kalderon 	return offset;
45138a52bbabSMichal Kalderon }
45148a52bbabSMichal Kalderon 
45158a52bbabSMichal Kalderon /* Dumps a section containing the dumped ILT pages.
45168a52bbabSMichal Kalderon  * Returns the dumped size in dwords.
45178a52bbabSMichal Kalderon  */
45188a52bbabSMichal Kalderon static u32 qed_ilt_dump_pages_section(struct qed_hwfn *p_hwfn,
45198a52bbabSMichal Kalderon 				      u32 *dump_buf,
45208a52bbabSMichal Kalderon 				      bool dump,
45218a52bbabSMichal Kalderon 				      u32 valid_conn_pf_pages,
45228a52bbabSMichal Kalderon 				      u32 valid_conn_vf_pages,
45238a52bbabSMichal Kalderon 				      struct phys_mem_desc *ilt_pages,
45248a52bbabSMichal Kalderon 				      bool dump_page_ids)
45258a52bbabSMichal Kalderon {
45268a52bbabSMichal Kalderon 	struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
45278a52bbabSMichal Kalderon 	u32 pf_start_line, start_page_id, offset = 0;
45288a52bbabSMichal Kalderon 	u32 cdut_pf_init_pages, cdut_vf_init_pages;
45298a52bbabSMichal Kalderon 	u32 cdut_pf_work_pages, cdut_vf_work_pages;
45308a52bbabSMichal Kalderon 	u32 base_data_offset, size_param_offset;
45318a52bbabSMichal Kalderon 	u32 cdut_pf_pages, cdut_vf_pages;
45328a52bbabSMichal Kalderon 	const char *section_name;
45338a52bbabSMichal Kalderon 	u8 i;
45348a52bbabSMichal Kalderon 
45358a52bbabSMichal Kalderon 	section_name = dump_page_ids ? "ilt_page_ids" : "ilt_page_mem";
45368a52bbabSMichal Kalderon 	cdut_pf_init_pages = qed_get_cdut_num_pf_init_pages(p_hwfn);
45378a52bbabSMichal Kalderon 	cdut_vf_init_pages = qed_get_cdut_num_vf_init_pages(p_hwfn);
45388a52bbabSMichal Kalderon 	cdut_pf_work_pages = qed_get_cdut_num_pf_work_pages(p_hwfn);
45398a52bbabSMichal Kalderon 	cdut_vf_work_pages = qed_get_cdut_num_vf_work_pages(p_hwfn);
45408a52bbabSMichal Kalderon 	cdut_pf_pages = cdut_pf_init_pages + cdut_pf_work_pages;
45418a52bbabSMichal Kalderon 	cdut_vf_pages = cdut_vf_init_pages + cdut_vf_work_pages;
45428a52bbabSMichal Kalderon 	pf_start_line = p_hwfn->p_cxt_mngr->pf_start_line;
45438a52bbabSMichal Kalderon 
45448a52bbabSMichal Kalderon 	offset +=
45458a52bbabSMichal Kalderon 	    qed_dump_section_hdr(dump_buf + offset, dump, section_name, 1);
45468a52bbabSMichal Kalderon 
45478a52bbabSMichal Kalderon 	/* Dump size parameter (0 for now, overwritten with real size later) */
45488a52bbabSMichal Kalderon 	size_param_offset = offset;
45498a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
45508a52bbabSMichal Kalderon 	base_data_offset = offset;
45518a52bbabSMichal Kalderon 
45528a52bbabSMichal Kalderon 	/* CDUC pages are ordered as follows:
45538a52bbabSMichal Kalderon 	 * - PF pages - valid section (included in PF connection type mapping)
45548a52bbabSMichal Kalderon 	 * - PF pages - invalid section (not dumped)
45558a52bbabSMichal Kalderon 	 * - For each VF in the PF:
45568a52bbabSMichal Kalderon 	 *   - VF pages - valid section (included in VF connection type mapping)
45578a52bbabSMichal Kalderon 	 *   - VF pages - invalid section (not dumped)
45588a52bbabSMichal Kalderon 	 */
45598a52bbabSMichal Kalderon 	if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUC)) {
45608a52bbabSMichal Kalderon 		/* Dump connection PF pages */
45618a52bbabSMichal Kalderon 		start_page_id = clients[ILT_CLI_CDUC].first.val - pf_start_line;
45628a52bbabSMichal Kalderon 		offset += qed_ilt_dump_pages_range(dump_buf + offset,
45638a52bbabSMichal Kalderon 						   dump,
45648a52bbabSMichal Kalderon 						   start_page_id,
45658a52bbabSMichal Kalderon 						   valid_conn_pf_pages,
45668a52bbabSMichal Kalderon 						   ilt_pages, dump_page_ids);
45678a52bbabSMichal Kalderon 
45688a52bbabSMichal Kalderon 		/* Dump connection VF pages */
45698a52bbabSMichal Kalderon 		start_page_id += clients[ILT_CLI_CDUC].pf_total_lines;
45708a52bbabSMichal Kalderon 		for (i = 0; i < p_hwfn->p_cxt_mngr->vf_count;
45718a52bbabSMichal Kalderon 		     i++, start_page_id += clients[ILT_CLI_CDUC].vf_total_lines)
45728a52bbabSMichal Kalderon 			offset += qed_ilt_dump_pages_range(dump_buf + offset,
45738a52bbabSMichal Kalderon 							   dump,
45748a52bbabSMichal Kalderon 							   start_page_id,
45758a52bbabSMichal Kalderon 							   valid_conn_vf_pages,
45768a52bbabSMichal Kalderon 							   ilt_pages,
45778a52bbabSMichal Kalderon 							   dump_page_ids);
45788a52bbabSMichal Kalderon 	}
45798a52bbabSMichal Kalderon 
45808a52bbabSMichal Kalderon 	/* CDUT pages are ordered as follows:
45818a52bbabSMichal Kalderon 	 * - PF init pages (not dumped)
45828a52bbabSMichal Kalderon 	 * - PF work pages
45838a52bbabSMichal Kalderon 	 * - For each VF in the PF:
45848a52bbabSMichal Kalderon 	 *   - VF init pages (not dumped)
45858a52bbabSMichal Kalderon 	 *   - VF work pages
45868a52bbabSMichal Kalderon 	 */
45878a52bbabSMichal Kalderon 	if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUT)) {
45888a52bbabSMichal Kalderon 		/* Dump task PF pages */
45898a52bbabSMichal Kalderon 		start_page_id = clients[ILT_CLI_CDUT].first.val +
45908a52bbabSMichal Kalderon 		    cdut_pf_init_pages - pf_start_line;
45918a52bbabSMichal Kalderon 		offset += qed_ilt_dump_pages_range(dump_buf + offset,
45928a52bbabSMichal Kalderon 						   dump,
45938a52bbabSMichal Kalderon 						   start_page_id,
45948a52bbabSMichal Kalderon 						   cdut_pf_work_pages,
45958a52bbabSMichal Kalderon 						   ilt_pages, dump_page_ids);
45968a52bbabSMichal Kalderon 
45978a52bbabSMichal Kalderon 		/* Dump task VF pages */
45988a52bbabSMichal Kalderon 		start_page_id = clients[ILT_CLI_CDUT].first.val +
45998a52bbabSMichal Kalderon 		    cdut_pf_pages + cdut_vf_init_pages - pf_start_line;
46008a52bbabSMichal Kalderon 		for (i = 0; i < p_hwfn->p_cxt_mngr->vf_count;
46018a52bbabSMichal Kalderon 		     i++, start_page_id += cdut_vf_pages)
46028a52bbabSMichal Kalderon 			offset += qed_ilt_dump_pages_range(dump_buf + offset,
46038a52bbabSMichal Kalderon 							   dump,
46048a52bbabSMichal Kalderon 							   start_page_id,
46058a52bbabSMichal Kalderon 							   cdut_vf_work_pages,
46068a52bbabSMichal Kalderon 							   ilt_pages,
46078a52bbabSMichal Kalderon 							   dump_page_ids);
46088a52bbabSMichal Kalderon 	}
46098a52bbabSMichal Kalderon 
46108a52bbabSMichal Kalderon 	/* Overwrite size param */
46118a52bbabSMichal Kalderon 	if (dump)
46128a52bbabSMichal Kalderon 		qed_dump_num_param(dump_buf + size_param_offset,
46138a52bbabSMichal Kalderon 				   dump, "size", offset - base_data_offset);
46148a52bbabSMichal Kalderon 
46158a52bbabSMichal Kalderon 	return offset;
46168a52bbabSMichal Kalderon }
46178a52bbabSMichal Kalderon 
46188a52bbabSMichal Kalderon /* Performs ILT Dump to the specified buffer.
46198a52bbabSMichal Kalderon  * Returns the dumped size in dwords.
46208a52bbabSMichal Kalderon  */
46218a52bbabSMichal Kalderon static u32 qed_ilt_dump(struct qed_hwfn *p_hwfn,
46228a52bbabSMichal Kalderon 			struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
46238a52bbabSMichal Kalderon {
46248a52bbabSMichal Kalderon 	struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
46258a52bbabSMichal Kalderon 	u32 valid_conn_vf_cids, valid_conn_vf_pages, offset = 0;
46268a52bbabSMichal Kalderon 	u32 valid_conn_pf_cids, valid_conn_pf_pages, num_pages;
46278a52bbabSMichal Kalderon 	u32 num_cids_per_page, conn_ctx_size;
46288a52bbabSMichal Kalderon 	u32 cduc_page_size, cdut_page_size;
46298a52bbabSMichal Kalderon 	struct phys_mem_desc *ilt_pages;
46308a52bbabSMichal Kalderon 	u8 conn_type;
46318a52bbabSMichal Kalderon 
46328a52bbabSMichal Kalderon 	cduc_page_size = 1 <<
46338a52bbabSMichal Kalderon 	    (clients[ILT_CLI_CDUC].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN);
46348a52bbabSMichal Kalderon 	cdut_page_size = 1 <<
46358a52bbabSMichal Kalderon 	    (clients[ILT_CLI_CDUT].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN);
46368a52bbabSMichal Kalderon 	conn_ctx_size = p_hwfn->p_cxt_mngr->conn_ctx_size;
46378a52bbabSMichal Kalderon 	num_cids_per_page = (int)(cduc_page_size / conn_ctx_size);
46388a52bbabSMichal Kalderon 	ilt_pages = p_hwfn->p_cxt_mngr->ilt_shadow;
46398a52bbabSMichal Kalderon 
46408a52bbabSMichal Kalderon 	/* Dump global params - 22 must match number of params below */
46418a52bbabSMichal Kalderon 	offset += qed_dump_common_global_params(p_hwfn, p_ptt,
46428a52bbabSMichal Kalderon 						dump_buf + offset, dump, 22);
46438a52bbabSMichal Kalderon 	offset += qed_dump_str_param(dump_buf + offset,
46448a52bbabSMichal Kalderon 				     dump, "dump-type", "ilt-dump");
46458a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46468a52bbabSMichal Kalderon 				     dump,
46478a52bbabSMichal Kalderon 				     "cduc-page-size", cduc_page_size);
46488a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46498a52bbabSMichal Kalderon 				     dump,
46508a52bbabSMichal Kalderon 				     "cduc-first-page-id",
46518a52bbabSMichal Kalderon 				     clients[ILT_CLI_CDUC].first.val);
46528a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46538a52bbabSMichal Kalderon 				     dump,
46548a52bbabSMichal Kalderon 				     "cduc-last-page-id",
46558a52bbabSMichal Kalderon 				     clients[ILT_CLI_CDUC].last.val);
46568a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46578a52bbabSMichal Kalderon 				     dump,
46588a52bbabSMichal Kalderon 				     "cduc-num-pf-pages",
46598a52bbabSMichal Kalderon 				     clients
46608a52bbabSMichal Kalderon 				     [ILT_CLI_CDUC].pf_total_lines);
46618a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46628a52bbabSMichal Kalderon 				     dump,
46638a52bbabSMichal Kalderon 				     "cduc-num-vf-pages",
46648a52bbabSMichal Kalderon 				     clients
46658a52bbabSMichal Kalderon 				     [ILT_CLI_CDUC].vf_total_lines);
46668a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46678a52bbabSMichal Kalderon 				     dump,
46688a52bbabSMichal Kalderon 				     "max-conn-ctx-size",
46698a52bbabSMichal Kalderon 				     conn_ctx_size);
46708a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46718a52bbabSMichal Kalderon 				     dump,
46728a52bbabSMichal Kalderon 				     "cdut-page-size", cdut_page_size);
46738a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46748a52bbabSMichal Kalderon 				     dump,
46758a52bbabSMichal Kalderon 				     "cdut-first-page-id",
46768a52bbabSMichal Kalderon 				     clients[ILT_CLI_CDUT].first.val);
46778a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46788a52bbabSMichal Kalderon 				     dump,
46798a52bbabSMichal Kalderon 				     "cdut-last-page-id",
46808a52bbabSMichal Kalderon 				     clients[ILT_CLI_CDUT].last.val);
46818a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46828a52bbabSMichal Kalderon 				     dump,
46838a52bbabSMichal Kalderon 				     "cdut-num-pf-init-pages",
46848a52bbabSMichal Kalderon 				     qed_get_cdut_num_pf_init_pages(p_hwfn));
46858a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46868a52bbabSMichal Kalderon 				     dump,
46878a52bbabSMichal Kalderon 				     "cdut-num-vf-init-pages",
46888a52bbabSMichal Kalderon 				     qed_get_cdut_num_vf_init_pages(p_hwfn));
46898a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46908a52bbabSMichal Kalderon 				     dump,
46918a52bbabSMichal Kalderon 				     "cdut-num-pf-work-pages",
46928a52bbabSMichal Kalderon 				     qed_get_cdut_num_pf_work_pages(p_hwfn));
46938a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46948a52bbabSMichal Kalderon 				     dump,
46958a52bbabSMichal Kalderon 				     "cdut-num-vf-work-pages",
46968a52bbabSMichal Kalderon 				     qed_get_cdut_num_vf_work_pages(p_hwfn));
46978a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
46988a52bbabSMichal Kalderon 				     dump,
46998a52bbabSMichal Kalderon 				     "max-task-ctx-size",
47008a52bbabSMichal Kalderon 				     p_hwfn->p_cxt_mngr->task_ctx_size);
47018a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
47028a52bbabSMichal Kalderon 				     dump,
47038a52bbabSMichal Kalderon 				     "task-type-id",
47048a52bbabSMichal Kalderon 				     p_hwfn->p_cxt_mngr->task_type_id);
47058a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
47068a52bbabSMichal Kalderon 				     dump,
47078a52bbabSMichal Kalderon 				     "first-vf-id-in-pf",
47088a52bbabSMichal Kalderon 				     p_hwfn->p_cxt_mngr->first_vf_in_pf);
47098a52bbabSMichal Kalderon 	offset += /* 18 */ qed_dump_num_param(dump_buf + offset,
47108a52bbabSMichal Kalderon 					      dump,
47118a52bbabSMichal Kalderon 					      "num-vfs-in-pf",
47128a52bbabSMichal Kalderon 					      p_hwfn->p_cxt_mngr->vf_count);
47138a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
47148a52bbabSMichal Kalderon 				     dump,
47158a52bbabSMichal Kalderon 				     "ptr-size-bytes", sizeof(void *));
47168a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
47178a52bbabSMichal Kalderon 				     dump,
47188a52bbabSMichal Kalderon 				     "pf-start-line",
47198a52bbabSMichal Kalderon 				     p_hwfn->p_cxt_mngr->pf_start_line);
47208a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
47218a52bbabSMichal Kalderon 				     dump,
47228a52bbabSMichal Kalderon 				     "page-mem-desc-size-dwords",
47238a52bbabSMichal Kalderon 				     PAGE_MEM_DESC_SIZE_DWORDS);
47248a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
47258a52bbabSMichal Kalderon 				     dump,
47268a52bbabSMichal Kalderon 				     "ilt-shadow-size",
47278a52bbabSMichal Kalderon 				     p_hwfn->p_cxt_mngr->ilt_shadow_size);
47288a52bbabSMichal Kalderon 	/* Additional/Less parameters require matching of number in call to
47298a52bbabSMichal Kalderon 	 * dump_common_global_params()
47308a52bbabSMichal Kalderon 	 */
47318a52bbabSMichal Kalderon 
47328a52bbabSMichal Kalderon 	/* Dump section containing number of PF CIDs per connection type */
47338a52bbabSMichal Kalderon 	offset += qed_dump_section_hdr(dump_buf + offset,
47348a52bbabSMichal Kalderon 				       dump, "num_pf_cids_per_conn_type", 1);
47358a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
47368a52bbabSMichal Kalderon 				     dump, "size", NUM_OF_CONNECTION_TYPES_E4);
47378a52bbabSMichal Kalderon 	for (conn_type = 0, valid_conn_pf_cids = 0;
47388a52bbabSMichal Kalderon 	     conn_type < NUM_OF_CONNECTION_TYPES_E4; conn_type++, offset++) {
47398a52bbabSMichal Kalderon 		u32 num_pf_cids =
47408a52bbabSMichal Kalderon 		    p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cid_count;
47418a52bbabSMichal Kalderon 
47428a52bbabSMichal Kalderon 		if (dump)
47438a52bbabSMichal Kalderon 			*(dump_buf + offset) = num_pf_cids;
47448a52bbabSMichal Kalderon 		valid_conn_pf_cids += num_pf_cids;
47458a52bbabSMichal Kalderon 	}
47468a52bbabSMichal Kalderon 
47478a52bbabSMichal Kalderon 	/* Dump section containing number of VF CIDs per connection type */
47488a52bbabSMichal Kalderon 	offset += qed_dump_section_hdr(dump_buf + offset,
47498a52bbabSMichal Kalderon 				       dump, "num_vf_cids_per_conn_type", 1);
47508a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
47518a52bbabSMichal Kalderon 				     dump, "size", NUM_OF_CONNECTION_TYPES_E4);
47528a52bbabSMichal Kalderon 	for (conn_type = 0, valid_conn_vf_cids = 0;
47538a52bbabSMichal Kalderon 	     conn_type < NUM_OF_CONNECTION_TYPES_E4; conn_type++, offset++) {
47548a52bbabSMichal Kalderon 		u32 num_vf_cids =
47558a52bbabSMichal Kalderon 		    p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cids_per_vf;
47568a52bbabSMichal Kalderon 
47578a52bbabSMichal Kalderon 		if (dump)
47588a52bbabSMichal Kalderon 			*(dump_buf + offset) = num_vf_cids;
47598a52bbabSMichal Kalderon 		valid_conn_vf_cids += num_vf_cids;
47608a52bbabSMichal Kalderon 	}
47618a52bbabSMichal Kalderon 
47628a52bbabSMichal Kalderon 	/* Dump section containing physical memory descs for each ILT page */
47638a52bbabSMichal Kalderon 	num_pages = p_hwfn->p_cxt_mngr->ilt_shadow_size;
47648a52bbabSMichal Kalderon 	offset += qed_dump_section_hdr(dump_buf + offset,
47658a52bbabSMichal Kalderon 				       dump, "ilt_page_desc", 1);
47668a52bbabSMichal Kalderon 	offset += qed_dump_num_param(dump_buf + offset,
47678a52bbabSMichal Kalderon 				     dump,
47688a52bbabSMichal Kalderon 				     "size",
47698a52bbabSMichal Kalderon 				     num_pages * PAGE_MEM_DESC_SIZE_DWORDS);
47708a52bbabSMichal Kalderon 
47718a52bbabSMichal Kalderon 	/* Copy memory descriptors to dump buffer */
47728a52bbabSMichal Kalderon 	if (dump) {
47738a52bbabSMichal Kalderon 		u32 page_id;
47748a52bbabSMichal Kalderon 
47758a52bbabSMichal Kalderon 		for (page_id = 0; page_id < num_pages;
47768a52bbabSMichal Kalderon 		     page_id++, offset += PAGE_MEM_DESC_SIZE_DWORDS)
47778a52bbabSMichal Kalderon 			memcpy(dump_buf + offset,
47788a52bbabSMichal Kalderon 			       &ilt_pages[page_id],
47798a52bbabSMichal Kalderon 			       DWORDS_TO_BYTES(PAGE_MEM_DESC_SIZE_DWORDS));
47808a52bbabSMichal Kalderon 	} else {
47818a52bbabSMichal Kalderon 		offset += num_pages * PAGE_MEM_DESC_SIZE_DWORDS;
47828a52bbabSMichal Kalderon 	}
47838a52bbabSMichal Kalderon 
47848a52bbabSMichal Kalderon 	valid_conn_pf_pages = DIV_ROUND_UP(valid_conn_pf_cids,
47858a52bbabSMichal Kalderon 					   num_cids_per_page);
47868a52bbabSMichal Kalderon 	valid_conn_vf_pages = DIV_ROUND_UP(valid_conn_vf_cids,
47878a52bbabSMichal Kalderon 					   num_cids_per_page);
47888a52bbabSMichal Kalderon 
47898a52bbabSMichal Kalderon 	/* Dump ILT pages IDs */
47908a52bbabSMichal Kalderon 	offset += qed_ilt_dump_pages_section(p_hwfn,
47918a52bbabSMichal Kalderon 					     dump_buf + offset,
47928a52bbabSMichal Kalderon 					     dump,
47938a52bbabSMichal Kalderon 					     valid_conn_pf_pages,
47948a52bbabSMichal Kalderon 					     valid_conn_vf_pages,
47958a52bbabSMichal Kalderon 					     ilt_pages, true);
47968a52bbabSMichal Kalderon 
47978a52bbabSMichal Kalderon 	/* Dump ILT pages memory */
47988a52bbabSMichal Kalderon 	offset += qed_ilt_dump_pages_section(p_hwfn,
47998a52bbabSMichal Kalderon 					     dump_buf + offset,
48008a52bbabSMichal Kalderon 					     dump,
48018a52bbabSMichal Kalderon 					     valid_conn_pf_pages,
48028a52bbabSMichal Kalderon 					     valid_conn_vf_pages,
48038a52bbabSMichal Kalderon 					     ilt_pages, false);
48048a52bbabSMichal Kalderon 
48058a52bbabSMichal Kalderon 	/* Dump last section */
48068a52bbabSMichal Kalderon 	offset += qed_dump_last_section(dump_buf, offset, dump);
48078a52bbabSMichal Kalderon 
48088a52bbabSMichal Kalderon 	return offset;
48098a52bbabSMichal Kalderon }
48108a52bbabSMichal Kalderon 
4811c965db44STomer Tayar /***************************** Public Functions *******************************/
4812c965db44STomer Tayar 
48132d22bc83SMichal Kalderon enum dbg_status qed_dbg_set_bin_ptr(struct qed_hwfn *p_hwfn,
48142d22bc83SMichal Kalderon 				    const u8 * const bin_ptr)
4815c965db44STomer Tayar {
48162d22bc83SMichal Kalderon 	struct bin_buffer_hdr *buf_hdrs = (struct bin_buffer_hdr *)bin_ptr;
4817c965db44STomer Tayar 	u8 buf_id;
4818c965db44STomer Tayar 
48192d22bc83SMichal Kalderon 	/* Convert binary data to debug arrays */
48202d22bc83SMichal Kalderon 	for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++)
48212d22bc83SMichal Kalderon 		qed_set_dbg_bin_buf(p_hwfn,
48222d22bc83SMichal Kalderon 				    buf_id,
48232d22bc83SMichal Kalderon 				    (u32 *)(bin_ptr + buf_hdrs[buf_id].offset),
48242d22bc83SMichal Kalderon 				    buf_hdrs[buf_id].length);
4825c965db44STomer Tayar 
4826c965db44STomer Tayar 	return DBG_STATUS_OK;
4827c965db44STomer Tayar }
4828c965db44STomer Tayar 
4829d52c89f1SMichal Kalderon bool qed_read_fw_info(struct qed_hwfn *p_hwfn,
4830d52c89f1SMichal Kalderon 		      struct qed_ptt *p_ptt, struct fw_info *fw_info)
4831d52c89f1SMichal Kalderon {
4832d52c89f1SMichal Kalderon 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4833d52c89f1SMichal Kalderon 	u8 storm_id;
4834d52c89f1SMichal Kalderon 
4835d52c89f1SMichal Kalderon 	for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
4836d52c89f1SMichal Kalderon 		struct storm_defs *storm = &s_storm_defs[storm_id];
4837d52c89f1SMichal Kalderon 
4838d52c89f1SMichal Kalderon 		/* Skip Storm if it's in reset */
48392d22bc83SMichal Kalderon 		if (dev_data->block_in_reset[storm->sem_block_id])
4840d52c89f1SMichal Kalderon 			continue;
4841d52c89f1SMichal Kalderon 
4842d52c89f1SMichal Kalderon 		/* Read FW info for the current Storm */
4843d52c89f1SMichal Kalderon 		qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, fw_info);
4844d52c89f1SMichal Kalderon 
4845d52c89f1SMichal Kalderon 		return true;
4846d52c89f1SMichal Kalderon 	}
4847d52c89f1SMichal Kalderon 
4848d52c89f1SMichal Kalderon 	return false;
4849d52c89f1SMichal Kalderon }
4850d52c89f1SMichal Kalderon 
48513b86bd07SSudarsana Reddy Kalluru enum dbg_status qed_dbg_grc_config(struct qed_hwfn *p_hwfn,
48523b86bd07SSudarsana Reddy Kalluru 				   enum dbg_grc_params grc_param, u32 val)
48533b86bd07SSudarsana Reddy Kalluru {
48542d22bc83SMichal Kalderon 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
48553b86bd07SSudarsana Reddy Kalluru 	enum dbg_status status;
48563b86bd07SSudarsana Reddy Kalluru 	int i;
48573b86bd07SSudarsana Reddy Kalluru 
48582d22bc83SMichal Kalderon 	DP_VERBOSE(p_hwfn,
48592d22bc83SMichal Kalderon 		   QED_MSG_DEBUG,
48603b86bd07SSudarsana Reddy Kalluru 		   "dbg_grc_config: paramId = %d, val = %d\n", grc_param, val);
48613b86bd07SSudarsana Reddy Kalluru 
48622d22bc83SMichal Kalderon 	status = qed_dbg_dev_init(p_hwfn);
48633b86bd07SSudarsana Reddy Kalluru 	if (status != DBG_STATUS_OK)
48643b86bd07SSudarsana Reddy Kalluru 		return status;
48653b86bd07SSudarsana Reddy Kalluru 
48663b86bd07SSudarsana Reddy Kalluru 	/* Initializes the GRC parameters (if not initialized). Needed in order
48673b86bd07SSudarsana Reddy Kalluru 	 * to set the default parameter values for the first time.
48683b86bd07SSudarsana Reddy Kalluru 	 */
48693b86bd07SSudarsana Reddy Kalluru 	qed_dbg_grc_init_params(p_hwfn);
48703b86bd07SSudarsana Reddy Kalluru 
48713b86bd07SSudarsana Reddy Kalluru 	if (grc_param >= MAX_DBG_GRC_PARAMS)
48723b86bd07SSudarsana Reddy Kalluru 		return DBG_STATUS_INVALID_ARGS;
48733b86bd07SSudarsana Reddy Kalluru 	if (val < s_grc_param_defs[grc_param].min ||
48743b86bd07SSudarsana Reddy Kalluru 	    val > s_grc_param_defs[grc_param].max)
48753b86bd07SSudarsana Reddy Kalluru 		return DBG_STATUS_INVALID_ARGS;
48763b86bd07SSudarsana Reddy Kalluru 
48773b86bd07SSudarsana Reddy Kalluru 	if (s_grc_param_defs[grc_param].is_preset) {
48783b86bd07SSudarsana Reddy Kalluru 		/* Preset param */
48793b86bd07SSudarsana Reddy Kalluru 
48803b86bd07SSudarsana Reddy Kalluru 		/* Disabling a preset is not allowed. Call
48813b86bd07SSudarsana Reddy Kalluru 		 * dbg_grc_set_params_default instead.
48823b86bd07SSudarsana Reddy Kalluru 		 */
48833b86bd07SSudarsana Reddy Kalluru 		if (!val)
48843b86bd07SSudarsana Reddy Kalluru 			return DBG_STATUS_INVALID_ARGS;
48853b86bd07SSudarsana Reddy Kalluru 
48863b86bd07SSudarsana Reddy Kalluru 		/* Update all params with the preset values */
48873b86bd07SSudarsana Reddy Kalluru 		for (i = 0; i < MAX_DBG_GRC_PARAMS; i++) {
48882d22bc83SMichal Kalderon 			struct grc_param_defs *defs = &s_grc_param_defs[i];
48893b86bd07SSudarsana Reddy Kalluru 			u32 preset_val;
48903b86bd07SSudarsana Reddy Kalluru 			/* Skip persistent params */
48912d22bc83SMichal Kalderon 			if (defs->is_persistent)
48923b86bd07SSudarsana Reddy Kalluru 				continue;
48933b86bd07SSudarsana Reddy Kalluru 
48943b86bd07SSudarsana Reddy Kalluru 			/* Find preset value */
48953b86bd07SSudarsana Reddy Kalluru 			if (grc_param == DBG_GRC_PARAM_EXCLUDE_ALL)
48963b86bd07SSudarsana Reddy Kalluru 				preset_val =
48972d22bc83SMichal Kalderon 				    defs->exclude_all_preset_val;
48983b86bd07SSudarsana Reddy Kalluru 			else if (grc_param == DBG_GRC_PARAM_CRASH)
48993b86bd07SSudarsana Reddy Kalluru 				preset_val =
49002d22bc83SMichal Kalderon 				    defs->crash_preset_val[dev_data->chip_id];
49013b86bd07SSudarsana Reddy Kalluru 			else
49023b86bd07SSudarsana Reddy Kalluru 				return DBG_STATUS_INVALID_ARGS;
49033b86bd07SSudarsana Reddy Kalluru 
49042d22bc83SMichal Kalderon 			qed_grc_set_param(p_hwfn, i, preset_val);
49053b86bd07SSudarsana Reddy Kalluru 		}
49063b86bd07SSudarsana Reddy Kalluru 	} else {
49073b86bd07SSudarsana Reddy Kalluru 		/* Regular param - set its value */
49083b86bd07SSudarsana Reddy Kalluru 		qed_grc_set_param(p_hwfn, grc_param, val);
49093b86bd07SSudarsana Reddy Kalluru 	}
49103b86bd07SSudarsana Reddy Kalluru 
49113b86bd07SSudarsana Reddy Kalluru 	return DBG_STATUS_OK;
49123b86bd07SSudarsana Reddy Kalluru }
49133b86bd07SSudarsana Reddy Kalluru 
4914be086e7cSMintz, Yuval /* Assign default GRC param values */
4915be086e7cSMintz, Yuval void qed_dbg_grc_set_params_default(struct qed_hwfn *p_hwfn)
4916be086e7cSMintz, Yuval {
4917be086e7cSMintz, Yuval 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4918be086e7cSMintz, Yuval 	u32 i;
4919be086e7cSMintz, Yuval 
4920be086e7cSMintz, Yuval 	for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
492150bc60cbSMichal Kalderon 		if (!s_grc_param_defs[i].is_persistent)
4922be086e7cSMintz, Yuval 			dev_data->grc.param_val[i] =
4923be086e7cSMintz, Yuval 			    s_grc_param_defs[i].default_val[dev_data->chip_id];
4924be086e7cSMintz, Yuval }
4925be086e7cSMintz, Yuval 
4926c965db44STomer Tayar enum dbg_status qed_dbg_grc_get_dump_buf_size(struct qed_hwfn *p_hwfn,
4927c965db44STomer Tayar 					      struct qed_ptt *p_ptt,
4928c965db44STomer Tayar 					      u32 *buf_size)
4929c965db44STomer Tayar {
49302d22bc83SMichal Kalderon 	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
4931c965db44STomer Tayar 
4932c965db44STomer Tayar 	*buf_size = 0;
49337b6859fbSMintz, Yuval 
4934c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
4935c965db44STomer Tayar 		return status;
49367b6859fbSMintz, Yuval 
49372d22bc83SMichal Kalderon 	if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
49382d22bc83SMichal Kalderon 	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr ||
49392d22bc83SMichal Kalderon 	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr ||
49402d22bc83SMichal Kalderon 	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||
49412d22bc83SMichal Kalderon 	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)
4942c965db44STomer Tayar 		return DBG_STATUS_DBG_ARRAY_NOT_SET;
49437b6859fbSMintz, Yuval 
4944c965db44STomer Tayar 	return qed_grc_dump(p_hwfn, p_ptt, NULL, false, buf_size);
4945c965db44STomer Tayar }
4946c965db44STomer Tayar 
4947c965db44STomer Tayar enum dbg_status qed_dbg_grc_dump(struct qed_hwfn *p_hwfn,
4948c965db44STomer Tayar 				 struct qed_ptt *p_ptt,
4949c965db44STomer Tayar 				 u32 *dump_buf,
4950c965db44STomer Tayar 				 u32 buf_size_in_dwords,
4951c965db44STomer Tayar 				 u32 *num_dumped_dwords)
4952c965db44STomer Tayar {
4953c965db44STomer Tayar 	u32 needed_buf_size_in_dwords;
4954c965db44STomer Tayar 	enum dbg_status status;
4955c965db44STomer Tayar 
4956c965db44STomer Tayar 	*num_dumped_dwords = 0;
49577b6859fbSMintz, Yuval 
49587b6859fbSMintz, Yuval 	status = qed_dbg_grc_get_dump_buf_size(p_hwfn,
49597b6859fbSMintz, Yuval 					       p_ptt,
49607b6859fbSMintz, Yuval 					       &needed_buf_size_in_dwords);
4961c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
4962c965db44STomer Tayar 		return status;
49637b6859fbSMintz, Yuval 
4964c965db44STomer Tayar 	if (buf_size_in_dwords < needed_buf_size_in_dwords)
4965c965db44STomer Tayar 		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
4966c965db44STomer Tayar 
4967c965db44STomer Tayar 	/* GRC Dump */
4968c965db44STomer Tayar 	status = qed_grc_dump(p_hwfn, p_ptt, dump_buf, true, num_dumped_dwords);
4969c965db44STomer Tayar 
4970be086e7cSMintz, Yuval 	/* Revert GRC params to their default */
4971be086e7cSMintz, Yuval 	qed_dbg_grc_set_params_default(p_hwfn);
4972be086e7cSMintz, Yuval 
4973c965db44STomer Tayar 	return status;
4974c965db44STomer Tayar }
4975c965db44STomer Tayar 
4976c965db44STomer Tayar enum dbg_status qed_dbg_idle_chk_get_dump_buf_size(struct qed_hwfn *p_hwfn,
4977c965db44STomer Tayar 						   struct qed_ptt *p_ptt,
4978c965db44STomer Tayar 						   u32 *buf_size)
4979c965db44STomer Tayar {
4980c965db44STomer Tayar 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
49812d22bc83SMichal Kalderon 	struct idle_chk_data *idle_chk = &dev_data->idle_chk;
49827b6859fbSMintz, Yuval 	enum dbg_status status;
4983c965db44STomer Tayar 
4984c965db44STomer Tayar 	*buf_size = 0;
49857b6859fbSMintz, Yuval 
49862d22bc83SMichal Kalderon 	status = qed_dbg_dev_init(p_hwfn);
4987c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
4988c965db44STomer Tayar 		return status;
49897b6859fbSMintz, Yuval 
49902d22bc83SMichal Kalderon 	if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
49912d22bc83SMichal Kalderon 	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr ||
49922d22bc83SMichal Kalderon 	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr ||
49932d22bc83SMichal Kalderon 	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr)
4994c965db44STomer Tayar 		return DBG_STATUS_DBG_ARRAY_NOT_SET;
49957b6859fbSMintz, Yuval 
49967b6859fbSMintz, Yuval 	if (!idle_chk->buf_size_set) {
49977b6859fbSMintz, Yuval 		idle_chk->buf_size = qed_idle_chk_dump(p_hwfn,
49987b6859fbSMintz, Yuval 						       p_ptt, NULL, false);
49997b6859fbSMintz, Yuval 		idle_chk->buf_size_set = true;
5000c965db44STomer Tayar 	}
5001c965db44STomer Tayar 
50027b6859fbSMintz, Yuval 	*buf_size = idle_chk->buf_size;
50037b6859fbSMintz, Yuval 
5004c965db44STomer Tayar 	return DBG_STATUS_OK;
5005c965db44STomer Tayar }
5006c965db44STomer Tayar 
5007c965db44STomer Tayar enum dbg_status qed_dbg_idle_chk_dump(struct qed_hwfn *p_hwfn,
5008c965db44STomer Tayar 				      struct qed_ptt *p_ptt,
5009c965db44STomer Tayar 				      u32 *dump_buf,
5010c965db44STomer Tayar 				      u32 buf_size_in_dwords,
5011c965db44STomer Tayar 				      u32 *num_dumped_dwords)
5012c965db44STomer Tayar {
5013c965db44STomer Tayar 	u32 needed_buf_size_in_dwords;
5014c965db44STomer Tayar 	enum dbg_status status;
5015c965db44STomer Tayar 
5016c965db44STomer Tayar 	*num_dumped_dwords = 0;
50177b6859fbSMintz, Yuval 
50187b6859fbSMintz, Yuval 	status = qed_dbg_idle_chk_get_dump_buf_size(p_hwfn,
50197b6859fbSMintz, Yuval 						    p_ptt,
50207b6859fbSMintz, Yuval 						    &needed_buf_size_in_dwords);
5021c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
5022c965db44STomer Tayar 		return status;
50237b6859fbSMintz, Yuval 
5024c965db44STomer Tayar 	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5025c965db44STomer Tayar 		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5026c965db44STomer Tayar 
5027c965db44STomer Tayar 	/* Update reset state */
50282d22bc83SMichal Kalderon 	qed_grc_unreset_blocks(p_hwfn, p_ptt, true);
5029c965db44STomer Tayar 	qed_update_blocks_reset_state(p_hwfn, p_ptt);
5030c965db44STomer Tayar 
5031c965db44STomer Tayar 	/* Idle Check Dump */
5032c965db44STomer Tayar 	*num_dumped_dwords = qed_idle_chk_dump(p_hwfn, p_ptt, dump_buf, true);
5033be086e7cSMintz, Yuval 
5034be086e7cSMintz, Yuval 	/* Revert GRC params to their default */
5035be086e7cSMintz, Yuval 	qed_dbg_grc_set_params_default(p_hwfn);
5036be086e7cSMintz, Yuval 
5037c965db44STomer Tayar 	return DBG_STATUS_OK;
5038c965db44STomer Tayar }
5039c965db44STomer Tayar 
5040c965db44STomer Tayar enum dbg_status qed_dbg_mcp_trace_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5041c965db44STomer Tayar 						    struct qed_ptt *p_ptt,
5042c965db44STomer Tayar 						    u32 *buf_size)
5043c965db44STomer Tayar {
50442d22bc83SMichal Kalderon 	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5045c965db44STomer Tayar 
5046c965db44STomer Tayar 	*buf_size = 0;
50477b6859fbSMintz, Yuval 
5048c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
5049c965db44STomer Tayar 		return status;
50507b6859fbSMintz, Yuval 
5051c965db44STomer Tayar 	return qed_mcp_trace_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5052c965db44STomer Tayar }
5053c965db44STomer Tayar 
5054c965db44STomer Tayar enum dbg_status qed_dbg_mcp_trace_dump(struct qed_hwfn *p_hwfn,
5055c965db44STomer Tayar 				       struct qed_ptt *p_ptt,
5056c965db44STomer Tayar 				       u32 *dump_buf,
5057c965db44STomer Tayar 				       u32 buf_size_in_dwords,
5058c965db44STomer Tayar 				       u32 *num_dumped_dwords)
5059c965db44STomer Tayar {
5060c965db44STomer Tayar 	u32 needed_buf_size_in_dwords;
5061c965db44STomer Tayar 	enum dbg_status status;
5062c965db44STomer Tayar 
5063be086e7cSMintz, Yuval 	status =
50647b6859fbSMintz, Yuval 		qed_dbg_mcp_trace_get_dump_buf_size(p_hwfn,
50657b6859fbSMintz, Yuval 						    p_ptt,
5066c965db44STomer Tayar 						    &needed_buf_size_in_dwords);
50677b6859fbSMintz, Yuval 	if (status != DBG_STATUS_OK && status !=
50687b6859fbSMintz, Yuval 	    DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
5069c965db44STomer Tayar 		return status;
5070be086e7cSMintz, Yuval 
5071c965db44STomer Tayar 	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5072c965db44STomer Tayar 		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5073c965db44STomer Tayar 
5074c965db44STomer Tayar 	/* Update reset state */
5075c965db44STomer Tayar 	qed_update_blocks_reset_state(p_hwfn, p_ptt);
5076c965db44STomer Tayar 
5077c965db44STomer Tayar 	/* Perform dump */
5078be086e7cSMintz, Yuval 	status = qed_mcp_trace_dump(p_hwfn,
5079c965db44STomer Tayar 				    p_ptt, dump_buf, true, num_dumped_dwords);
5080be086e7cSMintz, Yuval 
5081be086e7cSMintz, Yuval 	/* Revert GRC params to their default */
5082be086e7cSMintz, Yuval 	qed_dbg_grc_set_params_default(p_hwfn);
5083be086e7cSMintz, Yuval 
5084be086e7cSMintz, Yuval 	return status;
5085c965db44STomer Tayar }
5086c965db44STomer Tayar 
5087c965db44STomer Tayar enum dbg_status qed_dbg_reg_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5088c965db44STomer Tayar 						   struct qed_ptt *p_ptt,
5089c965db44STomer Tayar 						   u32 *buf_size)
5090c965db44STomer Tayar {
50912d22bc83SMichal Kalderon 	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5092c965db44STomer Tayar 
5093c965db44STomer Tayar 	*buf_size = 0;
50947b6859fbSMintz, Yuval 
5095c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
5096c965db44STomer Tayar 		return status;
50977b6859fbSMintz, Yuval 
5098c965db44STomer Tayar 	return qed_reg_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5099c965db44STomer Tayar }
5100c965db44STomer Tayar 
5101c965db44STomer Tayar enum dbg_status qed_dbg_reg_fifo_dump(struct qed_hwfn *p_hwfn,
5102c965db44STomer Tayar 				      struct qed_ptt *p_ptt,
5103c965db44STomer Tayar 				      u32 *dump_buf,
5104c965db44STomer Tayar 				      u32 buf_size_in_dwords,
5105c965db44STomer Tayar 				      u32 *num_dumped_dwords)
5106c965db44STomer Tayar {
5107c965db44STomer Tayar 	u32 needed_buf_size_in_dwords;
5108c965db44STomer Tayar 	enum dbg_status status;
5109c965db44STomer Tayar 
5110c965db44STomer Tayar 	*num_dumped_dwords = 0;
51117b6859fbSMintz, Yuval 
51127b6859fbSMintz, Yuval 	status = qed_dbg_reg_fifo_get_dump_buf_size(p_hwfn,
51137b6859fbSMintz, Yuval 						    p_ptt,
51147b6859fbSMintz, Yuval 						    &needed_buf_size_in_dwords);
5115c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
5116c965db44STomer Tayar 		return status;
51177b6859fbSMintz, Yuval 
5118c965db44STomer Tayar 	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5119c965db44STomer Tayar 		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5120c965db44STomer Tayar 
5121c965db44STomer Tayar 	/* Update reset state */
5122c965db44STomer Tayar 	qed_update_blocks_reset_state(p_hwfn, p_ptt);
5123be086e7cSMintz, Yuval 
5124be086e7cSMintz, Yuval 	status = qed_reg_fifo_dump(p_hwfn,
5125c965db44STomer Tayar 				   p_ptt, dump_buf, true, num_dumped_dwords);
5126be086e7cSMintz, Yuval 
5127be086e7cSMintz, Yuval 	/* Revert GRC params to their default */
5128be086e7cSMintz, Yuval 	qed_dbg_grc_set_params_default(p_hwfn);
5129be086e7cSMintz, Yuval 
5130be086e7cSMintz, Yuval 	return status;
5131c965db44STomer Tayar }
5132c965db44STomer Tayar 
5133c965db44STomer Tayar enum dbg_status qed_dbg_igu_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5134c965db44STomer Tayar 						   struct qed_ptt *p_ptt,
5135c965db44STomer Tayar 						   u32 *buf_size)
5136c965db44STomer Tayar {
51372d22bc83SMichal Kalderon 	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5138c965db44STomer Tayar 
5139c965db44STomer Tayar 	*buf_size = 0;
51407b6859fbSMintz, Yuval 
5141c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
5142c965db44STomer Tayar 		return status;
51437b6859fbSMintz, Yuval 
5144c965db44STomer Tayar 	return qed_igu_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5145c965db44STomer Tayar }
5146c965db44STomer Tayar 
5147c965db44STomer Tayar enum dbg_status qed_dbg_igu_fifo_dump(struct qed_hwfn *p_hwfn,
5148c965db44STomer Tayar 				      struct qed_ptt *p_ptt,
5149c965db44STomer Tayar 				      u32 *dump_buf,
5150c965db44STomer Tayar 				      u32 buf_size_in_dwords,
5151c965db44STomer Tayar 				      u32 *num_dumped_dwords)
5152c965db44STomer Tayar {
5153c965db44STomer Tayar 	u32 needed_buf_size_in_dwords;
5154c965db44STomer Tayar 	enum dbg_status status;
5155c965db44STomer Tayar 
5156c965db44STomer Tayar 	*num_dumped_dwords = 0;
51577b6859fbSMintz, Yuval 
51587b6859fbSMintz, Yuval 	status = qed_dbg_igu_fifo_get_dump_buf_size(p_hwfn,
51597b6859fbSMintz, Yuval 						    p_ptt,
51607b6859fbSMintz, Yuval 						    &needed_buf_size_in_dwords);
5161c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
5162c965db44STomer Tayar 		return status;
51637b6859fbSMintz, Yuval 
5164c965db44STomer Tayar 	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5165c965db44STomer Tayar 		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5166c965db44STomer Tayar 
5167c965db44STomer Tayar 	/* Update reset state */
5168c965db44STomer Tayar 	qed_update_blocks_reset_state(p_hwfn, p_ptt);
5169be086e7cSMintz, Yuval 
5170be086e7cSMintz, Yuval 	status = qed_igu_fifo_dump(p_hwfn,
5171c965db44STomer Tayar 				   p_ptt, dump_buf, true, num_dumped_dwords);
5172be086e7cSMintz, Yuval 	/* Revert GRC params to their default */
5173be086e7cSMintz, Yuval 	qed_dbg_grc_set_params_default(p_hwfn);
5174be086e7cSMintz, Yuval 
5175be086e7cSMintz, Yuval 	return status;
5176c965db44STomer Tayar }
5177c965db44STomer Tayar 
5178c965db44STomer Tayar enum dbg_status
5179c965db44STomer Tayar qed_dbg_protection_override_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5180c965db44STomer Tayar 					      struct qed_ptt *p_ptt,
5181c965db44STomer Tayar 					      u32 *buf_size)
5182c965db44STomer Tayar {
51832d22bc83SMichal Kalderon 	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5184c965db44STomer Tayar 
5185c965db44STomer Tayar 	*buf_size = 0;
51867b6859fbSMintz, Yuval 
5187c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
5188c965db44STomer Tayar 		return status;
51897b6859fbSMintz, Yuval 
5190c965db44STomer Tayar 	return qed_protection_override_dump(p_hwfn,
5191c965db44STomer Tayar 					    p_ptt, NULL, false, buf_size);
5192c965db44STomer Tayar }
5193c965db44STomer Tayar 
5194c965db44STomer Tayar enum dbg_status qed_dbg_protection_override_dump(struct qed_hwfn *p_hwfn,
5195c965db44STomer Tayar 						 struct qed_ptt *p_ptt,
5196c965db44STomer Tayar 						 u32 *dump_buf,
5197c965db44STomer Tayar 						 u32 buf_size_in_dwords,
5198c965db44STomer Tayar 						 u32 *num_dumped_dwords)
5199c965db44STomer Tayar {
52007b6859fbSMintz, Yuval 	u32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords;
5201c965db44STomer Tayar 	enum dbg_status status;
5202c965db44STomer Tayar 
5203c965db44STomer Tayar 	*num_dumped_dwords = 0;
52047b6859fbSMintz, Yuval 
52057b6859fbSMintz, Yuval 	status =
52067b6859fbSMintz, Yuval 		qed_dbg_protection_override_get_dump_buf_size(p_hwfn,
52077b6859fbSMintz, Yuval 							      p_ptt,
52087b6859fbSMintz, Yuval 							      p_size);
5209c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
5210c965db44STomer Tayar 		return status;
52117b6859fbSMintz, Yuval 
5212c965db44STomer Tayar 	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5213c965db44STomer Tayar 		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5214c965db44STomer Tayar 
5215c965db44STomer Tayar 	/* Update reset state */
5216c965db44STomer Tayar 	qed_update_blocks_reset_state(p_hwfn, p_ptt);
5217be086e7cSMintz, Yuval 
5218be086e7cSMintz, Yuval 	status = qed_protection_override_dump(p_hwfn,
5219c965db44STomer Tayar 					      p_ptt,
5220be086e7cSMintz, Yuval 					      dump_buf,
5221be086e7cSMintz, Yuval 					      true, num_dumped_dwords);
5222be086e7cSMintz, Yuval 
5223be086e7cSMintz, Yuval 	/* Revert GRC params to their default */
5224be086e7cSMintz, Yuval 	qed_dbg_grc_set_params_default(p_hwfn);
5225be086e7cSMintz, Yuval 
5226be086e7cSMintz, Yuval 	return status;
5227c965db44STomer Tayar }
5228c965db44STomer Tayar 
5229c965db44STomer Tayar enum dbg_status qed_dbg_fw_asserts_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5230c965db44STomer Tayar 						     struct qed_ptt *p_ptt,
5231c965db44STomer Tayar 						     u32 *buf_size)
5232c965db44STomer Tayar {
52332d22bc83SMichal Kalderon 	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5234c965db44STomer Tayar 
5235c965db44STomer Tayar 	*buf_size = 0;
52367b6859fbSMintz, Yuval 
5237c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
5238c965db44STomer Tayar 		return status;
5239c965db44STomer Tayar 
5240c965db44STomer Tayar 	/* Update reset state */
5241c965db44STomer Tayar 	qed_update_blocks_reset_state(p_hwfn, p_ptt);
52427b6859fbSMintz, Yuval 
5243c965db44STomer Tayar 	*buf_size = qed_fw_asserts_dump(p_hwfn, p_ptt, NULL, false);
52447b6859fbSMintz, Yuval 
5245c965db44STomer Tayar 	return DBG_STATUS_OK;
5246c965db44STomer Tayar }
5247c965db44STomer Tayar 
5248c965db44STomer Tayar enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn *p_hwfn,
5249c965db44STomer Tayar 					struct qed_ptt *p_ptt,
5250c965db44STomer Tayar 					u32 *dump_buf,
5251c965db44STomer Tayar 					u32 buf_size_in_dwords,
5252c965db44STomer Tayar 					u32 *num_dumped_dwords)
5253c965db44STomer Tayar {
52547b6859fbSMintz, Yuval 	u32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords;
5255c965db44STomer Tayar 	enum dbg_status status;
5256c965db44STomer Tayar 
5257c965db44STomer Tayar 	*num_dumped_dwords = 0;
52587b6859fbSMintz, Yuval 
52597b6859fbSMintz, Yuval 	status =
52607b6859fbSMintz, Yuval 		qed_dbg_fw_asserts_get_dump_buf_size(p_hwfn,
52617b6859fbSMintz, Yuval 						     p_ptt,
52627b6859fbSMintz, Yuval 						     p_size);
5263c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
5264c965db44STomer Tayar 		return status;
52657b6859fbSMintz, Yuval 
5266c965db44STomer Tayar 	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5267c965db44STomer Tayar 		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5268c965db44STomer Tayar 
5269c965db44STomer Tayar 	*num_dumped_dwords = qed_fw_asserts_dump(p_hwfn, p_ptt, dump_buf, true);
52707b6859fbSMintz, Yuval 
52717b6859fbSMintz, Yuval 	/* Revert GRC params to their default */
52727b6859fbSMintz, Yuval 	qed_dbg_grc_set_params_default(p_hwfn);
52737b6859fbSMintz, Yuval 
5274c965db44STomer Tayar 	return DBG_STATUS_OK;
5275c965db44STomer Tayar }
5276c965db44STomer Tayar 
52778a52bbabSMichal Kalderon static enum dbg_status qed_dbg_ilt_get_dump_buf_size(struct qed_hwfn *p_hwfn,
52788a52bbabSMichal Kalderon 						     struct qed_ptt *p_ptt,
52798a52bbabSMichal Kalderon 						     u32 *buf_size)
52808a52bbabSMichal Kalderon {
52812d22bc83SMichal Kalderon 	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
52828a52bbabSMichal Kalderon 
52838a52bbabSMichal Kalderon 	*buf_size = 0;
52848a52bbabSMichal Kalderon 
52858a52bbabSMichal Kalderon 	if (status != DBG_STATUS_OK)
52868a52bbabSMichal Kalderon 		return status;
52878a52bbabSMichal Kalderon 
52888a52bbabSMichal Kalderon 	*buf_size = qed_ilt_dump(p_hwfn, p_ptt, NULL, false);
52898a52bbabSMichal Kalderon 
52908a52bbabSMichal Kalderon 	return DBG_STATUS_OK;
52918a52bbabSMichal Kalderon }
52928a52bbabSMichal Kalderon 
52938a52bbabSMichal Kalderon static enum dbg_status qed_dbg_ilt_dump(struct qed_hwfn *p_hwfn,
52948a52bbabSMichal Kalderon 					struct qed_ptt *p_ptt,
52958a52bbabSMichal Kalderon 					u32 *dump_buf,
52968a52bbabSMichal Kalderon 					u32 buf_size_in_dwords,
52978a52bbabSMichal Kalderon 					u32 *num_dumped_dwords)
52988a52bbabSMichal Kalderon {
52998a52bbabSMichal Kalderon 	u32 needed_buf_size_in_dwords;
53008a52bbabSMichal Kalderon 	enum dbg_status status;
53018a52bbabSMichal Kalderon 
53028a52bbabSMichal Kalderon 	*num_dumped_dwords = 0;
53038a52bbabSMichal Kalderon 
53048a52bbabSMichal Kalderon 	status = qed_dbg_ilt_get_dump_buf_size(p_hwfn,
53058a52bbabSMichal Kalderon 					       p_ptt,
53068a52bbabSMichal Kalderon 					       &needed_buf_size_in_dwords);
53078a52bbabSMichal Kalderon 	if (status != DBG_STATUS_OK)
53088a52bbabSMichal Kalderon 		return status;
53098a52bbabSMichal Kalderon 
53108a52bbabSMichal Kalderon 	if (buf_size_in_dwords < needed_buf_size_in_dwords)
53118a52bbabSMichal Kalderon 		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
53128a52bbabSMichal Kalderon 
53138a52bbabSMichal Kalderon 	*num_dumped_dwords = qed_ilt_dump(p_hwfn, p_ptt, dump_buf, true);
53148a52bbabSMichal Kalderon 
53158a52bbabSMichal Kalderon 	/* Reveret GRC params to their default */
53168a52bbabSMichal Kalderon 	qed_dbg_grc_set_params_default(p_hwfn);
53178a52bbabSMichal Kalderon 
53188a52bbabSMichal Kalderon 	return DBG_STATUS_OK;
53198a52bbabSMichal Kalderon }
53208a52bbabSMichal Kalderon 
53210ebbd1c8SMintz, Yuval enum dbg_status qed_dbg_read_attn(struct qed_hwfn *p_hwfn,
53220ebbd1c8SMintz, Yuval 				  struct qed_ptt *p_ptt,
53230ebbd1c8SMintz, Yuval 				  enum block_id block_id,
53240ebbd1c8SMintz, Yuval 				  enum dbg_attn_type attn_type,
53250ebbd1c8SMintz, Yuval 				  bool clear_status,
53260ebbd1c8SMintz, Yuval 				  struct dbg_attn_block_result *results)
53270ebbd1c8SMintz, Yuval {
53282d22bc83SMichal Kalderon 	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
53290ebbd1c8SMintz, Yuval 	u8 reg_idx, num_attn_regs, num_result_regs = 0;
53300ebbd1c8SMintz, Yuval 	const struct dbg_attn_reg *attn_reg_arr;
53310ebbd1c8SMintz, Yuval 
53320ebbd1c8SMintz, Yuval 	if (status != DBG_STATUS_OK)
53330ebbd1c8SMintz, Yuval 		return status;
53340ebbd1c8SMintz, Yuval 
53352d22bc83SMichal Kalderon 	if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
53362d22bc83SMichal Kalderon 	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||
53372d22bc83SMichal Kalderon 	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)
53380ebbd1c8SMintz, Yuval 		return DBG_STATUS_DBG_ARRAY_NOT_SET;
53390ebbd1c8SMintz, Yuval 
53402d22bc83SMichal Kalderon 	attn_reg_arr = qed_get_block_attn_regs(p_hwfn,
53412d22bc83SMichal Kalderon 					       block_id,
53420ebbd1c8SMintz, Yuval 					       attn_type, &num_attn_regs);
53430ebbd1c8SMintz, Yuval 
53440ebbd1c8SMintz, Yuval 	for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
53450ebbd1c8SMintz, Yuval 		const struct dbg_attn_reg *reg_data = &attn_reg_arr[reg_idx];
53460ebbd1c8SMintz, Yuval 		struct dbg_attn_reg_result *reg_result;
53470ebbd1c8SMintz, Yuval 		u32 sts_addr, sts_val;
53480ebbd1c8SMintz, Yuval 		u16 modes_buf_offset;
53490ebbd1c8SMintz, Yuval 		bool eval_mode;
53500ebbd1c8SMintz, Yuval 
53510ebbd1c8SMintz, Yuval 		/* Check mode */
53520ebbd1c8SMintz, Yuval 		eval_mode = GET_FIELD(reg_data->mode.data,
53530ebbd1c8SMintz, Yuval 				      DBG_MODE_HDR_EVAL_MODE) > 0;
53540ebbd1c8SMintz, Yuval 		modes_buf_offset = GET_FIELD(reg_data->mode.data,
53550ebbd1c8SMintz, Yuval 					     DBG_MODE_HDR_MODES_BUF_OFFSET);
53560ebbd1c8SMintz, Yuval 		if (eval_mode && !qed_is_mode_match(p_hwfn, &modes_buf_offset))
53570ebbd1c8SMintz, Yuval 			continue;
53580ebbd1c8SMintz, Yuval 
53590ebbd1c8SMintz, Yuval 		/* Mode match - read attention status register */
53600ebbd1c8SMintz, Yuval 		sts_addr = DWORDS_TO_BYTES(clear_status ?
53610ebbd1c8SMintz, Yuval 					   reg_data->sts_clr_address :
53620ebbd1c8SMintz, Yuval 					   GET_FIELD(reg_data->data,
53630ebbd1c8SMintz, Yuval 						     DBG_ATTN_REG_STS_ADDRESS));
53640ebbd1c8SMintz, Yuval 		sts_val = qed_rd(p_hwfn, p_ptt, sts_addr);
53650ebbd1c8SMintz, Yuval 		if (!sts_val)
53660ebbd1c8SMintz, Yuval 			continue;
53670ebbd1c8SMintz, Yuval 
53680ebbd1c8SMintz, Yuval 		/* Non-zero attention status - add to results */
53690ebbd1c8SMintz, Yuval 		reg_result = &results->reg_results[num_result_regs];
53700ebbd1c8SMintz, Yuval 		SET_FIELD(reg_result->data,
53710ebbd1c8SMintz, Yuval 			  DBG_ATTN_REG_RESULT_STS_ADDRESS, sts_addr);
53720ebbd1c8SMintz, Yuval 		SET_FIELD(reg_result->data,
53730ebbd1c8SMintz, Yuval 			  DBG_ATTN_REG_RESULT_NUM_REG_ATTN,
53740ebbd1c8SMintz, Yuval 			  GET_FIELD(reg_data->data, DBG_ATTN_REG_NUM_REG_ATTN));
53750ebbd1c8SMintz, Yuval 		reg_result->block_attn_offset = reg_data->block_attn_offset;
53760ebbd1c8SMintz, Yuval 		reg_result->sts_val = sts_val;
53770ebbd1c8SMintz, Yuval 		reg_result->mask_val = qed_rd(p_hwfn,
53780ebbd1c8SMintz, Yuval 					      p_ptt,
53790ebbd1c8SMintz, Yuval 					      DWORDS_TO_BYTES
53800ebbd1c8SMintz, Yuval 					      (reg_data->mask_address));
53810ebbd1c8SMintz, Yuval 		num_result_regs++;
53820ebbd1c8SMintz, Yuval 	}
53830ebbd1c8SMintz, Yuval 
53840ebbd1c8SMintz, Yuval 	results->block_id = (u8)block_id;
53850ebbd1c8SMintz, Yuval 	results->names_offset =
53862d22bc83SMichal Kalderon 	    qed_get_block_attn_data(p_hwfn, block_id, attn_type)->names_offset;
53870ebbd1c8SMintz, Yuval 	SET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE, attn_type);
53880ebbd1c8SMintz, Yuval 	SET_FIELD(results->data,
53890ebbd1c8SMintz, Yuval 		  DBG_ATTN_BLOCK_RESULT_NUM_REGS, num_result_regs);
53900ebbd1c8SMintz, Yuval 
53910ebbd1c8SMintz, Yuval 	return DBG_STATUS_OK;
53920ebbd1c8SMintz, Yuval }
53930ebbd1c8SMintz, Yuval 
5394c965db44STomer Tayar /******************************* Data Types **********************************/
5395c965db44STomer Tayar 
53967b6859fbSMintz, Yuval /* REG fifo element */
5397c965db44STomer Tayar struct reg_fifo_element {
5398c965db44STomer Tayar 	u64 data;
5399c965db44STomer Tayar #define REG_FIFO_ELEMENT_ADDRESS_SHIFT		0
5400c965db44STomer Tayar #define REG_FIFO_ELEMENT_ADDRESS_MASK		0x7fffff
5401c965db44STomer Tayar #define REG_FIFO_ELEMENT_ACCESS_SHIFT		23
5402c965db44STomer Tayar #define REG_FIFO_ELEMENT_ACCESS_MASK		0x1
5403c965db44STomer Tayar #define REG_FIFO_ELEMENT_PF_SHIFT		24
5404c965db44STomer Tayar #define REG_FIFO_ELEMENT_PF_MASK		0xf
5405c965db44STomer Tayar #define REG_FIFO_ELEMENT_VF_SHIFT		28
5406c965db44STomer Tayar #define REG_FIFO_ELEMENT_VF_MASK		0xff
5407c965db44STomer Tayar #define REG_FIFO_ELEMENT_PORT_SHIFT		36
5408c965db44STomer Tayar #define REG_FIFO_ELEMENT_PORT_MASK		0x3
5409c965db44STomer Tayar #define REG_FIFO_ELEMENT_PRIVILEGE_SHIFT	38
5410c965db44STomer Tayar #define REG_FIFO_ELEMENT_PRIVILEGE_MASK		0x3
5411c965db44STomer Tayar #define REG_FIFO_ELEMENT_PROTECTION_SHIFT	40
5412c965db44STomer Tayar #define REG_FIFO_ELEMENT_PROTECTION_MASK	0x7
5413c965db44STomer Tayar #define REG_FIFO_ELEMENT_MASTER_SHIFT		43
5414c965db44STomer Tayar #define REG_FIFO_ELEMENT_MASTER_MASK		0xf
5415c965db44STomer Tayar #define REG_FIFO_ELEMENT_ERROR_SHIFT		47
5416c965db44STomer Tayar #define REG_FIFO_ELEMENT_ERROR_MASK		0x1f
5417c965db44STomer Tayar };
5418c965db44STomer Tayar 
54192d22bc83SMichal Kalderon /* REG fifo error element */
54202d22bc83SMichal Kalderon struct reg_fifo_err {
54212d22bc83SMichal Kalderon 	u32 err_code;
54222d22bc83SMichal Kalderon 	const char *err_msg;
54232d22bc83SMichal Kalderon };
54242d22bc83SMichal Kalderon 
5425c965db44STomer Tayar /* IGU fifo element */
5426c965db44STomer Tayar struct igu_fifo_element {
5427c965db44STomer Tayar 	u32 dword0;
5428c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD0_FID_SHIFT		0
5429c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD0_FID_MASK		0xff
5430c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD0_IS_PF_SHIFT		8
5431c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD0_IS_PF_MASK		0x1
5432c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD0_SOURCE_SHIFT		9
5433c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD0_SOURCE_MASK		0xf
5434c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_SHIFT		13
5435c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_MASK		0xf
5436c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_SHIFT		17
5437c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_MASK		0x7fff
5438c965db44STomer Tayar 	u32 dword1;
5439c965db44STomer Tayar 	u32 dword2;
5440c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_SHIFT	0
5441c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_MASK		0x1
5442c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_SHIFT		1
5443c965db44STomer Tayar #define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_MASK		0xffffffff
5444c965db44STomer Tayar 	u32 reserved;
5445c965db44STomer Tayar };
5446c965db44STomer Tayar 
5447c965db44STomer Tayar struct igu_fifo_wr_data {
5448c965db44STomer Tayar 	u32 data;
5449c965db44STomer Tayar #define IGU_FIFO_WR_DATA_PROD_CONS_SHIFT		0
5450c965db44STomer Tayar #define IGU_FIFO_WR_DATA_PROD_CONS_MASK			0xffffff
5451c965db44STomer Tayar #define IGU_FIFO_WR_DATA_UPDATE_FLAG_SHIFT		24
5452c965db44STomer Tayar #define IGU_FIFO_WR_DATA_UPDATE_FLAG_MASK		0x1
5453c965db44STomer Tayar #define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_SHIFT	25
5454c965db44STomer Tayar #define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_MASK		0x3
5455c965db44STomer Tayar #define IGU_FIFO_WR_DATA_SEGMENT_SHIFT			27
5456c965db44STomer Tayar #define IGU_FIFO_WR_DATA_SEGMENT_MASK			0x1
5457c965db44STomer Tayar #define IGU_FIFO_WR_DATA_TIMER_MASK_SHIFT		28
5458c965db44STomer Tayar #define IGU_FIFO_WR_DATA_TIMER_MASK_MASK		0x1
5459c965db44STomer Tayar #define IGU_FIFO_WR_DATA_CMD_TYPE_SHIFT			31
5460c965db44STomer Tayar #define IGU_FIFO_WR_DATA_CMD_TYPE_MASK			0x1
5461c965db44STomer Tayar };
5462c965db44STomer Tayar 
5463c965db44STomer Tayar struct igu_fifo_cleanup_wr_data {
5464c965db44STomer Tayar 	u32 data;
5465c965db44STomer Tayar #define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_SHIFT		0
5466c965db44STomer Tayar #define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_MASK		0x7ffffff
5467c965db44STomer Tayar #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_SHIFT	27
5468c965db44STomer Tayar #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_MASK	0x1
5469c965db44STomer Tayar #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_SHIFT	28
5470c965db44STomer Tayar #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_MASK	0x7
5471c965db44STomer Tayar #define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_SHIFT		31
5472c965db44STomer Tayar #define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_MASK		0x1
5473c965db44STomer Tayar };
5474c965db44STomer Tayar 
5475c965db44STomer Tayar /* Protection override element */
5476c965db44STomer Tayar struct protection_override_element {
5477c965db44STomer Tayar 	u64 data;
5478c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_SHIFT		0
5479c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_MASK		0x7fffff
5480c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_SHIFT		23
5481c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_MASK		0xffffff
5482c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_READ_SHIFT			47
5483c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_READ_MASK			0x1
5484c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_WRITE_SHIFT			48
5485c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_WRITE_MASK			0x1
5486c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_SHIFT	49
5487c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_MASK	0x7
5488c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_SHIFT	52
5489c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_MASK	0x7
5490c965db44STomer Tayar };
5491c965db44STomer Tayar 
5492c965db44STomer Tayar enum igu_fifo_sources {
5493c965db44STomer Tayar 	IGU_SRC_PXP0,
5494c965db44STomer Tayar 	IGU_SRC_PXP1,
5495c965db44STomer Tayar 	IGU_SRC_PXP2,
5496c965db44STomer Tayar 	IGU_SRC_PXP3,
5497c965db44STomer Tayar 	IGU_SRC_PXP4,
5498c965db44STomer Tayar 	IGU_SRC_PXP5,
5499c965db44STomer Tayar 	IGU_SRC_PXP6,
5500c965db44STomer Tayar 	IGU_SRC_PXP7,
5501c965db44STomer Tayar 	IGU_SRC_CAU,
5502c965db44STomer Tayar 	IGU_SRC_ATTN,
5503c965db44STomer Tayar 	IGU_SRC_GRC
5504c965db44STomer Tayar };
5505c965db44STomer Tayar 
5506c965db44STomer Tayar enum igu_fifo_addr_types {
5507c965db44STomer Tayar 	IGU_ADDR_TYPE_MSIX_MEM,
5508c965db44STomer Tayar 	IGU_ADDR_TYPE_WRITE_PBA,
5509c965db44STomer Tayar 	IGU_ADDR_TYPE_WRITE_INT_ACK,
5510c965db44STomer Tayar 	IGU_ADDR_TYPE_WRITE_ATTN_BITS,
5511c965db44STomer Tayar 	IGU_ADDR_TYPE_READ_INT,
5512c965db44STomer Tayar 	IGU_ADDR_TYPE_WRITE_PROD_UPDATE,
5513c965db44STomer Tayar 	IGU_ADDR_TYPE_RESERVED
5514c965db44STomer Tayar };
5515c965db44STomer Tayar 
5516c965db44STomer Tayar struct igu_fifo_addr_data {
5517c965db44STomer Tayar 	u16 start_addr;
5518c965db44STomer Tayar 	u16 end_addr;
5519c965db44STomer Tayar 	char *desc;
5520c965db44STomer Tayar 	char *vf_desc;
5521c965db44STomer Tayar 	enum igu_fifo_addr_types type;
5522c965db44STomer Tayar };
5523c965db44STomer Tayar 
5524c965db44STomer Tayar /******************************** Constants **********************************/
5525c965db44STomer Tayar 
5526c965db44STomer Tayar #define MAX_MSG_LEN				1024
55277b6859fbSMintz, Yuval 
5528c965db44STomer Tayar #define MCP_TRACE_MAX_MODULE_LEN		8
5529c965db44STomer Tayar #define MCP_TRACE_FORMAT_MAX_PARAMS		3
5530c965db44STomer Tayar #define MCP_TRACE_FORMAT_PARAM_WIDTH \
55312d22bc83SMichal Kalderon 	(MCP_TRACE_FORMAT_P2_SIZE_OFFSET - MCP_TRACE_FORMAT_P1_SIZE_OFFSET)
55327b6859fbSMintz, Yuval 
5533c965db44STomer Tayar #define REG_FIFO_ELEMENT_ADDR_FACTOR		4
5534c965db44STomer Tayar #define REG_FIFO_ELEMENT_IS_PF_VF_VAL		127
55357b6859fbSMintz, Yuval 
5536c965db44STomer Tayar #define PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR	4
5537c965db44STomer Tayar 
5538c965db44STomer Tayar /***************************** Constant Arrays *******************************/
5539c965db44STomer Tayar 
5540c965db44STomer Tayar /* Status string array */
5541c965db44STomer Tayar static const char * const s_status_str[] = {
55427b6859fbSMintz, Yuval 	/* DBG_STATUS_OK */
5543c965db44STomer Tayar 	"Operation completed successfully",
55447b6859fbSMintz, Yuval 
55457b6859fbSMintz, Yuval 	/* DBG_STATUS_APP_VERSION_NOT_SET */
5546c965db44STomer Tayar 	"Debug application version wasn't set",
55477b6859fbSMintz, Yuval 
55487b6859fbSMintz, Yuval 	/* DBG_STATUS_UNSUPPORTED_APP_VERSION */
5549c965db44STomer Tayar 	"Unsupported debug application version",
55507b6859fbSMintz, Yuval 
55517b6859fbSMintz, Yuval 	/* DBG_STATUS_DBG_BLOCK_NOT_RESET */
5552c965db44STomer Tayar 	"The debug block wasn't reset since the last recording",
55537b6859fbSMintz, Yuval 
55547b6859fbSMintz, Yuval 	/* DBG_STATUS_INVALID_ARGS */
5555c965db44STomer Tayar 	"Invalid arguments",
55567b6859fbSMintz, Yuval 
55577b6859fbSMintz, Yuval 	/* DBG_STATUS_OUTPUT_ALREADY_SET */
5558c965db44STomer Tayar 	"The debug output was already set",
55597b6859fbSMintz, Yuval 
55607b6859fbSMintz, Yuval 	/* DBG_STATUS_INVALID_PCI_BUF_SIZE */
5561c965db44STomer Tayar 	"Invalid PCI buffer size",
55627b6859fbSMintz, Yuval 
55637b6859fbSMintz, Yuval 	/* DBG_STATUS_PCI_BUF_ALLOC_FAILED */
5564c965db44STomer Tayar 	"PCI buffer allocation failed",
55657b6859fbSMintz, Yuval 
55667b6859fbSMintz, Yuval 	/* DBG_STATUS_PCI_BUF_NOT_ALLOCATED */
5567c965db44STomer Tayar 	"A PCI buffer wasn't allocated",
55687b6859fbSMintz, Yuval 
55692d22bc83SMichal Kalderon 	/* DBG_STATUS_INVALID_FILTER_TRIGGER_DWORDS */
55702d22bc83SMichal Kalderon 	"The filter/trigger constraint dword offsets are not enabled for recording",
5571a5124386SColin Ian King 	/* DBG_STATUS_NO_MATCHING_FRAMING_MODE */
5572a5124386SColin Ian King 	"No matching framing mode",
55737b6859fbSMintz, Yuval 
55742d22bc83SMichal Kalderon 	/* DBG_STATUS_VFC_READ_ERROR */
55752d22bc83SMichal Kalderon 	"Error reading from VFC",
55767b6859fbSMintz, Yuval 
55777b6859fbSMintz, Yuval 	/* DBG_STATUS_STORM_ALREADY_ENABLED */
5578c965db44STomer Tayar 	"The Storm was already enabled",
55797b6859fbSMintz, Yuval 
55807b6859fbSMintz, Yuval 	/* DBG_STATUS_STORM_NOT_ENABLED */
5581c965db44STomer Tayar 	"The specified Storm wasn't enabled",
55827b6859fbSMintz, Yuval 
55837b6859fbSMintz, Yuval 	/* DBG_STATUS_BLOCK_ALREADY_ENABLED */
5584c965db44STomer Tayar 	"The block was already enabled",
55857b6859fbSMintz, Yuval 
55867b6859fbSMintz, Yuval 	/* DBG_STATUS_BLOCK_NOT_ENABLED */
5587c965db44STomer Tayar 	"The specified block wasn't enabled",
55887b6859fbSMintz, Yuval 
55897b6859fbSMintz, Yuval 	/* DBG_STATUS_NO_INPUT_ENABLED */
5590c965db44STomer Tayar 	"No input was enabled for recording",
55917b6859fbSMintz, Yuval 
55922d22bc83SMichal Kalderon 	/* DBG_STATUS_NO_FILTER_TRIGGER_256B */
55932d22bc83SMichal Kalderon 	"Filters and triggers are not allowed in E4 256-bit mode",
55947b6859fbSMintz, Yuval 
55957b6859fbSMintz, Yuval 	/* DBG_STATUS_FILTER_ALREADY_ENABLED */
5596c965db44STomer Tayar 	"The filter was already enabled",
55977b6859fbSMintz, Yuval 
55987b6859fbSMintz, Yuval 	/* DBG_STATUS_TRIGGER_ALREADY_ENABLED */
5599c965db44STomer Tayar 	"The trigger was already enabled",
56007b6859fbSMintz, Yuval 
56017b6859fbSMintz, Yuval 	/* DBG_STATUS_TRIGGER_NOT_ENABLED */
5602c965db44STomer Tayar 	"The trigger wasn't enabled",
56037b6859fbSMintz, Yuval 
56047b6859fbSMintz, Yuval 	/* DBG_STATUS_CANT_ADD_CONSTRAINT */
5605c965db44STomer Tayar 	"A constraint can be added only after a filter was enabled or a trigger state was added",
56067b6859fbSMintz, Yuval 
56077b6859fbSMintz, Yuval 	/* DBG_STATUS_TOO_MANY_TRIGGER_STATES */
5608c965db44STomer Tayar 	"Cannot add more than 3 trigger states",
56097b6859fbSMintz, Yuval 
56107b6859fbSMintz, Yuval 	/* DBG_STATUS_TOO_MANY_CONSTRAINTS */
5611c965db44STomer Tayar 	"Cannot add more than 4 constraints per filter or trigger state",
56127b6859fbSMintz, Yuval 
56137b6859fbSMintz, Yuval 	/* DBG_STATUS_RECORDING_NOT_STARTED */
5614c965db44STomer Tayar 	"The recording wasn't started",
56157b6859fbSMintz, Yuval 
56167b6859fbSMintz, Yuval 	/* DBG_STATUS_DATA_DIDNT_TRIGGER */
5617c965db44STomer Tayar 	"A trigger was configured, but it didn't trigger",
56187b6859fbSMintz, Yuval 
56197b6859fbSMintz, Yuval 	/* DBG_STATUS_NO_DATA_RECORDED */
5620c965db44STomer Tayar 	"No data was recorded",
56217b6859fbSMintz, Yuval 
56227b6859fbSMintz, Yuval 	/* DBG_STATUS_DUMP_BUF_TOO_SMALL */
5623c965db44STomer Tayar 	"Dump buffer is too small",
56247b6859fbSMintz, Yuval 
56257b6859fbSMintz, Yuval 	/* DBG_STATUS_DUMP_NOT_CHUNK_ALIGNED */
5626c965db44STomer Tayar 	"Dumped data is not aligned to chunks",
56277b6859fbSMintz, Yuval 
56287b6859fbSMintz, Yuval 	/* DBG_STATUS_UNKNOWN_CHIP */
5629c965db44STomer Tayar 	"Unknown chip",
56307b6859fbSMintz, Yuval 
56317b6859fbSMintz, Yuval 	/* DBG_STATUS_VIRT_MEM_ALLOC_FAILED */
5632c965db44STomer Tayar 	"Failed allocating virtual memory",
56337b6859fbSMintz, Yuval 
56347b6859fbSMintz, Yuval 	/* DBG_STATUS_BLOCK_IN_RESET */
5635c965db44STomer Tayar 	"The input block is in reset",
56367b6859fbSMintz, Yuval 
56377b6859fbSMintz, Yuval 	/* DBG_STATUS_INVALID_TRACE_SIGNATURE */
5638c965db44STomer Tayar 	"Invalid MCP trace signature found in NVRAM",
56397b6859fbSMintz, Yuval 
56407b6859fbSMintz, Yuval 	/* DBG_STATUS_INVALID_NVRAM_BUNDLE */
5641c965db44STomer Tayar 	"Invalid bundle ID found in NVRAM",
56427b6859fbSMintz, Yuval 
56437b6859fbSMintz, Yuval 	/* DBG_STATUS_NVRAM_GET_IMAGE_FAILED */
5644c965db44STomer Tayar 	"Failed getting NVRAM image",
56457b6859fbSMintz, Yuval 
56467b6859fbSMintz, Yuval 	/* DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE */
5647c965db44STomer Tayar 	"NVRAM image is not dword-aligned",
56487b6859fbSMintz, Yuval 
56497b6859fbSMintz, Yuval 	/* DBG_STATUS_NVRAM_READ_FAILED */
5650c965db44STomer Tayar 	"Failed reading from NVRAM",
56517b6859fbSMintz, Yuval 
56527b6859fbSMintz, Yuval 	/* DBG_STATUS_IDLE_CHK_PARSE_FAILED */
5653c965db44STomer Tayar 	"Idle check parsing failed",
56547b6859fbSMintz, Yuval 
56557b6859fbSMintz, Yuval 	/* DBG_STATUS_MCP_TRACE_BAD_DATA */
5656c965db44STomer Tayar 	"MCP Trace data is corrupt",
56577b6859fbSMintz, Yuval 
56587b6859fbSMintz, Yuval 	/* DBG_STATUS_MCP_TRACE_NO_META */
56597b6859fbSMintz, Yuval 	"Dump doesn't contain meta data - it must be provided in image file",
56607b6859fbSMintz, Yuval 
56617b6859fbSMintz, Yuval 	/* DBG_STATUS_MCP_COULD_NOT_HALT */
5662c965db44STomer Tayar 	"Failed to halt MCP",
56637b6859fbSMintz, Yuval 
56647b6859fbSMintz, Yuval 	/* DBG_STATUS_MCP_COULD_NOT_RESUME */
5665c965db44STomer Tayar 	"Failed to resume MCP after halt",
56667b6859fbSMintz, Yuval 
56672d22bc83SMichal Kalderon 	/* DBG_STATUS_RESERVED0 */
56682d22bc83SMichal Kalderon 	"",
56697b6859fbSMintz, Yuval 
56707b6859fbSMintz, Yuval 	/* DBG_STATUS_SEMI_FIFO_NOT_EMPTY */
5671c965db44STomer Tayar 	"Failed to empty SEMI sync FIFO",
56727b6859fbSMintz, Yuval 
56737b6859fbSMintz, Yuval 	/* DBG_STATUS_IGU_FIFO_BAD_DATA */
5674c965db44STomer Tayar 	"IGU FIFO data is corrupt",
56757b6859fbSMintz, Yuval 
56767b6859fbSMintz, Yuval 	/* DBG_STATUS_MCP_COULD_NOT_MASK_PRTY */
5677c965db44STomer Tayar 	"MCP failed to mask parities",
56787b6859fbSMintz, Yuval 
56797b6859fbSMintz, Yuval 	/* DBG_STATUS_FW_ASSERTS_PARSE_FAILED */
5680c965db44STomer Tayar 	"FW Asserts parsing failed",
56817b6859fbSMintz, Yuval 
56827b6859fbSMintz, Yuval 	/* DBG_STATUS_REG_FIFO_BAD_DATA */
5683c965db44STomer Tayar 	"GRC FIFO data is corrupt",
56847b6859fbSMintz, Yuval 
56857b6859fbSMintz, Yuval 	/* DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA */
5686c965db44STomer Tayar 	"Protection Override data is corrupt",
56877b6859fbSMintz, Yuval 
56887b6859fbSMintz, Yuval 	/* DBG_STATUS_DBG_ARRAY_NOT_SET */
5689c965db44STomer Tayar 	"Debug arrays were not set (when using binary files, dbg_set_bin_ptr must be called)",
56907b6859fbSMintz, Yuval 
56912d22bc83SMichal Kalderon 	/* DBG_STATUS_RESERVED1 */
56922d22bc83SMichal Kalderon 	"",
56937b6859fbSMintz, Yuval 
56947b6859fbSMintz, Yuval 	/* DBG_STATUS_NON_MATCHING_LINES */
56952d22bc83SMichal Kalderon 	"Non-matching debug lines - in E4, all lines must be of the same type (either 128b or 256b)",
56967b6859fbSMintz, Yuval 
56972d22bc83SMichal Kalderon 	/* DBG_STATUS_INSUFFICIENT_HW_IDS */
56982d22bc83SMichal Kalderon 	"Insufficient HW IDs. Try to record less Storms/blocks",
56997b6859fbSMintz, Yuval 
57007b6859fbSMintz, Yuval 	/* DBG_STATUS_DBG_BUS_IN_USE */
57012d22bc83SMichal Kalderon 	"The debug bus is in use",
57022d22bc83SMichal Kalderon 
57032d22bc83SMichal Kalderon 	/* DBG_STATUS_INVALID_STORM_DBG_MODE */
57042d22bc83SMichal Kalderon 	"The storm debug mode is not supported in the current chip",
57052d22bc83SMichal Kalderon 
57062d22bc83SMichal Kalderon 	/* DBG_STATUS_OTHER_ENGINE_BB_ONLY */
57072d22bc83SMichal Kalderon 	"Other engine is supported only in BB",
57082d22bc83SMichal Kalderon 
57092d22bc83SMichal Kalderon 	/* DBG_STATUS_FILTER_SINGLE_HW_ID */
57102d22bc83SMichal Kalderon 	"The configured filter mode requires a single Storm/block input",
57112d22bc83SMichal Kalderon 
57122d22bc83SMichal Kalderon 	/* DBG_STATUS_TRIGGER_SINGLE_HW_ID */
57132d22bc83SMichal Kalderon 	"The configured filter mode requires that all the constraints of a single trigger state will be defined on a single Storm/block input",
57142d22bc83SMichal Kalderon 
57152d22bc83SMichal Kalderon 	/* DBG_STATUS_MISSING_TRIGGER_STATE_STORM */
57162d22bc83SMichal Kalderon 	"When triggering on Storm data, the Storm to trigger on must be specified"
5717c965db44STomer Tayar };
5718c965db44STomer Tayar 
5719c965db44STomer Tayar /* Idle check severity names array */
5720c965db44STomer Tayar static const char * const s_idle_chk_severity_str[] = {
5721c965db44STomer Tayar 	"Error",
5722c965db44STomer Tayar 	"Error if no traffic",
5723c965db44STomer Tayar 	"Warning"
5724c965db44STomer Tayar };
5725c965db44STomer Tayar 
5726c965db44STomer Tayar /* MCP Trace level names array */
5727c965db44STomer Tayar static const char * const s_mcp_trace_level_str[] = {
5728c965db44STomer Tayar 	"ERROR",
5729c965db44STomer Tayar 	"TRACE",
5730c965db44STomer Tayar 	"DEBUG"
5731c965db44STomer Tayar };
5732c965db44STomer Tayar 
57337b6859fbSMintz, Yuval /* Access type names array */
5734c965db44STomer Tayar static const char * const s_access_strs[] = {
5735c965db44STomer Tayar 	"read",
5736c965db44STomer Tayar 	"write"
5737c965db44STomer Tayar };
5738c965db44STomer Tayar 
57397b6859fbSMintz, Yuval /* Privilege type names array */
5740c965db44STomer Tayar static const char * const s_privilege_strs[] = {
5741c965db44STomer Tayar 	"VF",
5742c965db44STomer Tayar 	"PDA",
5743c965db44STomer Tayar 	"HV",
5744c965db44STomer Tayar 	"UA"
5745c965db44STomer Tayar };
5746c965db44STomer Tayar 
57477b6859fbSMintz, Yuval /* Protection type names array */
5748c965db44STomer Tayar static const char * const s_protection_strs[] = {
5749c965db44STomer Tayar 	"(default)",
5750c965db44STomer Tayar 	"(default)",
5751c965db44STomer Tayar 	"(default)",
5752c965db44STomer Tayar 	"(default)",
5753c965db44STomer Tayar 	"override VF",
5754c965db44STomer Tayar 	"override PDA",
5755c965db44STomer Tayar 	"override HV",
5756c965db44STomer Tayar 	"override UA"
5757c965db44STomer Tayar };
5758c965db44STomer Tayar 
57597b6859fbSMintz, Yuval /* Master type names array */
5760c965db44STomer Tayar static const char * const s_master_strs[] = {
5761c965db44STomer Tayar 	"???",
5762c965db44STomer Tayar 	"pxp",
5763c965db44STomer Tayar 	"mcp",
5764c965db44STomer Tayar 	"msdm",
5765c965db44STomer Tayar 	"psdm",
5766c965db44STomer Tayar 	"ysdm",
5767c965db44STomer Tayar 	"usdm",
5768c965db44STomer Tayar 	"tsdm",
5769c965db44STomer Tayar 	"xsdm",
5770c965db44STomer Tayar 	"dbu",
5771c965db44STomer Tayar 	"dmae",
57722d22bc83SMichal Kalderon 	"jdap",
5773c965db44STomer Tayar 	"???",
5774c965db44STomer Tayar 	"???",
5775c965db44STomer Tayar 	"???",
5776c965db44STomer Tayar 	"???"
5777c965db44STomer Tayar };
5778c965db44STomer Tayar 
57797b6859fbSMintz, Yuval /* REG FIFO error messages array */
57802d22bc83SMichal Kalderon static struct reg_fifo_err s_reg_fifo_errors[] = {
57812d22bc83SMichal Kalderon 	{1, "grc timeout"},
57822d22bc83SMichal Kalderon 	{2, "address doesn't belong to any block"},
57832d22bc83SMichal Kalderon 	{4, "reserved address in block or write to read-only address"},
57842d22bc83SMichal Kalderon 	{8, "privilege/protection mismatch"},
57852d22bc83SMichal Kalderon 	{16, "path isolation error"},
57862d22bc83SMichal Kalderon 	{17, "RSL error"}
5787c965db44STomer Tayar };
5788c965db44STomer Tayar 
57897b6859fbSMintz, Yuval /* IGU FIFO sources array */
5790c965db44STomer Tayar static const char * const s_igu_fifo_source_strs[] = {
5791c965db44STomer Tayar 	"TSTORM",
5792c965db44STomer Tayar 	"MSTORM",
5793c965db44STomer Tayar 	"USTORM",
5794c965db44STomer Tayar 	"XSTORM",
5795c965db44STomer Tayar 	"YSTORM",
5796c965db44STomer Tayar 	"PSTORM",
5797c965db44STomer Tayar 	"PCIE",
5798c965db44STomer Tayar 	"NIG_QM_PBF",
5799c965db44STomer Tayar 	"CAU",
5800c965db44STomer Tayar 	"ATTN",
5801c965db44STomer Tayar 	"GRC",
5802c965db44STomer Tayar };
5803c965db44STomer Tayar 
58047b6859fbSMintz, Yuval /* IGU FIFO error messages */
5805c965db44STomer Tayar static const char * const s_igu_fifo_error_strs[] = {
5806c965db44STomer Tayar 	"no error",
5807c965db44STomer Tayar 	"length error",
5808c965db44STomer Tayar 	"function disabled",
58091d510657SColin Ian King 	"VF sent command to attention address",
5810c965db44STomer Tayar 	"host sent prod update command",
5811c965db44STomer Tayar 	"read of during interrupt register while in MIMD mode",
5812c965db44STomer Tayar 	"access to PXP BAR reserved address",
5813c965db44STomer Tayar 	"producer update command to attention index",
5814c965db44STomer Tayar 	"unknown error",
5815c965db44STomer Tayar 	"SB index not valid",
5816c965db44STomer Tayar 	"SB relative index and FID not found",
5817c965db44STomer Tayar 	"FID not match",
5818c965db44STomer Tayar 	"command with error flag asserted (PCI error or CAU discard)",
5819c965db44STomer Tayar 	"VF sent cleanup and RF cleanup is disabled",
5820c965db44STomer Tayar 	"cleanup command on type bigger than 4"
5821c965db44STomer Tayar };
5822c965db44STomer Tayar 
5823c965db44STomer Tayar /* IGU FIFO address data */
5824c965db44STomer Tayar static const struct igu_fifo_addr_data s_igu_fifo_addr_data[] = {
58257b6859fbSMintz, Yuval 	{0x0, 0x101, "MSI-X Memory", NULL,
58267b6859fbSMintz, Yuval 	 IGU_ADDR_TYPE_MSIX_MEM},
58277b6859fbSMintz, Yuval 	{0x102, 0x1ff, "reserved", NULL,
58287b6859fbSMintz, Yuval 	 IGU_ADDR_TYPE_RESERVED},
58297b6859fbSMintz, Yuval 	{0x200, 0x200, "Write PBA[0:63]", NULL,
58307b6859fbSMintz, Yuval 	 IGU_ADDR_TYPE_WRITE_PBA},
5831c965db44STomer Tayar 	{0x201, 0x201, "Write PBA[64:127]", "reserved",
5832c965db44STomer Tayar 	 IGU_ADDR_TYPE_WRITE_PBA},
58337b6859fbSMintz, Yuval 	{0x202, 0x202, "Write PBA[128]", "reserved",
58347b6859fbSMintz, Yuval 	 IGU_ADDR_TYPE_WRITE_PBA},
58357b6859fbSMintz, Yuval 	{0x203, 0x3ff, "reserved", NULL,
58367b6859fbSMintz, Yuval 	 IGU_ADDR_TYPE_RESERVED},
5837c965db44STomer Tayar 	{0x400, 0x5ef, "Write interrupt acknowledgment", NULL,
5838c965db44STomer Tayar 	 IGU_ADDR_TYPE_WRITE_INT_ACK},
5839c965db44STomer Tayar 	{0x5f0, 0x5f0, "Attention bits update", NULL,
5840c965db44STomer Tayar 	 IGU_ADDR_TYPE_WRITE_ATTN_BITS},
5841c965db44STomer Tayar 	{0x5f1, 0x5f1, "Attention bits set", NULL,
5842c965db44STomer Tayar 	 IGU_ADDR_TYPE_WRITE_ATTN_BITS},
5843c965db44STomer Tayar 	{0x5f2, 0x5f2, "Attention bits clear", NULL,
5844c965db44STomer Tayar 	 IGU_ADDR_TYPE_WRITE_ATTN_BITS},
5845c965db44STomer Tayar 	{0x5f3, 0x5f3, "Read interrupt 0:63 with mask", NULL,
5846c965db44STomer Tayar 	 IGU_ADDR_TYPE_READ_INT},
5847c965db44STomer Tayar 	{0x5f4, 0x5f4, "Read interrupt 0:31 with mask", NULL,
5848c965db44STomer Tayar 	 IGU_ADDR_TYPE_READ_INT},
5849c965db44STomer Tayar 	{0x5f5, 0x5f5, "Read interrupt 32:63 with mask", NULL,
5850c965db44STomer Tayar 	 IGU_ADDR_TYPE_READ_INT},
5851c965db44STomer Tayar 	{0x5f6, 0x5f6, "Read interrupt 0:63 without mask", NULL,
5852c965db44STomer Tayar 	 IGU_ADDR_TYPE_READ_INT},
58537b6859fbSMintz, Yuval 	{0x5f7, 0x5ff, "reserved", NULL,
58547b6859fbSMintz, Yuval 	 IGU_ADDR_TYPE_RESERVED},
58557b6859fbSMintz, Yuval 	{0x600, 0x7ff, "Producer update", NULL,
58567b6859fbSMintz, Yuval 	 IGU_ADDR_TYPE_WRITE_PROD_UPDATE}
5857c965db44STomer Tayar };
5858c965db44STomer Tayar 
5859c965db44STomer Tayar /******************************** Variables **********************************/
5860c965db44STomer Tayar 
5861c965db44STomer Tayar /* Temporary buffer, used for print size calculations */
5862c965db44STomer Tayar static char s_temp_buf[MAX_MSG_LEN];
5863c965db44STomer Tayar 
58647b6859fbSMintz, Yuval /**************************** Private Functions ******************************/
5865c965db44STomer Tayar 
5866c965db44STomer Tayar static u32 qed_cyclic_add(u32 a, u32 b, u32 size)
5867c965db44STomer Tayar {
5868c965db44STomer Tayar 	return (a + b) % size;
5869c965db44STomer Tayar }
5870c965db44STomer Tayar 
5871c965db44STomer Tayar static u32 qed_cyclic_sub(u32 a, u32 b, u32 size)
5872c965db44STomer Tayar {
5873c965db44STomer Tayar 	return (size + a - b) % size;
5874c965db44STomer Tayar }
5875c965db44STomer Tayar 
5876c965db44STomer Tayar /* Reads the specified number of bytes from the specified cyclic buffer (up to 4
5877c965db44STomer Tayar  * bytes) and returns them as a dword value. the specified buffer offset is
5878c965db44STomer Tayar  * updated.
5879c965db44STomer Tayar  */
5880c965db44STomer Tayar static u32 qed_read_from_cyclic_buf(void *buf,
5881c965db44STomer Tayar 				    u32 *offset,
5882c965db44STomer Tayar 				    u32 buf_size, u8 num_bytes_to_read)
5883c965db44STomer Tayar {
58847b6859fbSMintz, Yuval 	u8 i, *val_ptr, *bytes_buf = (u8 *)buf;
5885c965db44STomer Tayar 	u32 val = 0;
5886c965db44STomer Tayar 
5887c965db44STomer Tayar 	val_ptr = (u8 *)&val;
5888c965db44STomer Tayar 
588950bc60cbSMichal Kalderon 	/* Assume running on a LITTLE ENDIAN and the buffer is network order
589050bc60cbSMichal Kalderon 	 * (BIG ENDIAN), as high order bytes are placed in lower memory address.
589150bc60cbSMichal Kalderon 	 */
5892c965db44STomer Tayar 	for (i = 0; i < num_bytes_to_read; i++) {
5893c965db44STomer Tayar 		val_ptr[i] = bytes_buf[*offset];
5894c965db44STomer Tayar 		*offset = qed_cyclic_add(*offset, 1, buf_size);
5895c965db44STomer Tayar 	}
5896c965db44STomer Tayar 
5897c965db44STomer Tayar 	return val;
5898c965db44STomer Tayar }
5899c965db44STomer Tayar 
5900c965db44STomer Tayar /* Reads and returns the next byte from the specified buffer.
5901c965db44STomer Tayar  * The specified buffer offset is updated.
5902c965db44STomer Tayar  */
5903c965db44STomer Tayar static u8 qed_read_byte_from_buf(void *buf, u32 *offset)
5904c965db44STomer Tayar {
5905c965db44STomer Tayar 	return ((u8 *)buf)[(*offset)++];
5906c965db44STomer Tayar }
5907c965db44STomer Tayar 
5908c965db44STomer Tayar /* Reads and returns the next dword from the specified buffer.
5909c965db44STomer Tayar  * The specified buffer offset is updated.
5910c965db44STomer Tayar  */
5911c965db44STomer Tayar static u32 qed_read_dword_from_buf(void *buf, u32 *offset)
5912c965db44STomer Tayar {
5913c965db44STomer Tayar 	u32 dword_val = *(u32 *)&((u8 *)buf)[*offset];
5914c965db44STomer Tayar 
5915c965db44STomer Tayar 	*offset += 4;
59167b6859fbSMintz, Yuval 
5917c965db44STomer Tayar 	return dword_val;
5918c965db44STomer Tayar }
5919c965db44STomer Tayar 
5920c965db44STomer Tayar /* Reads the next string from the specified buffer, and copies it to the
5921c965db44STomer Tayar  * specified pointer. The specified buffer offset is updated.
5922c965db44STomer Tayar  */
5923c965db44STomer Tayar static void qed_read_str_from_buf(void *buf, u32 *offset, u32 size, char *dest)
5924c965db44STomer Tayar {
5925c965db44STomer Tayar 	const char *source_str = &((const char *)buf)[*offset];
5926c965db44STomer Tayar 
5927c965db44STomer Tayar 	strncpy(dest, source_str, size);
5928c965db44STomer Tayar 	dest[size - 1] = '\0';
5929c965db44STomer Tayar 	*offset += size;
5930c965db44STomer Tayar }
5931c965db44STomer Tayar 
5932c965db44STomer Tayar /* Returns a pointer to the specified offset (in bytes) of the specified buffer.
5933c965db44STomer Tayar  * If the specified buffer in NULL, a temporary buffer pointer is returned.
5934c965db44STomer Tayar  */
5935c965db44STomer Tayar static char *qed_get_buf_ptr(void *buf, u32 offset)
5936c965db44STomer Tayar {
5937c965db44STomer Tayar 	return buf ? (char *)buf + offset : s_temp_buf;
5938c965db44STomer Tayar }
5939c965db44STomer Tayar 
5940c965db44STomer Tayar /* Reads a param from the specified buffer. Returns the number of dwords read.
5941c965db44STomer Tayar  * If the returned str_param is NULL, the param is numeric and its value is
5942c965db44STomer Tayar  * returned in num_param.
5943c965db44STomer Tayar  * Otheriwise, the param is a string and its pointer is returned in str_param.
5944c965db44STomer Tayar  */
5945c965db44STomer Tayar static u32 qed_read_param(u32 *dump_buf,
5946c965db44STomer Tayar 			  const char **param_name,
5947c965db44STomer Tayar 			  const char **param_str_val, u32 *param_num_val)
5948c965db44STomer Tayar {
5949c965db44STomer Tayar 	char *char_buf = (char *)dump_buf;
59507b6859fbSMintz, Yuval 	size_t offset = 0;
5951c965db44STomer Tayar 
5952c965db44STomer Tayar 	/* Extract param name */
5953c965db44STomer Tayar 	*param_name = char_buf;
5954c965db44STomer Tayar 	offset += strlen(*param_name) + 1;
5955c965db44STomer Tayar 
5956c965db44STomer Tayar 	/* Check param type */
5957c965db44STomer Tayar 	if (*(char_buf + offset++)) {
5958c965db44STomer Tayar 		/* String param */
5959c965db44STomer Tayar 		*param_str_val = char_buf + offset;
5960da090917STomer Tayar 		*param_num_val = 0;
5961c965db44STomer Tayar 		offset += strlen(*param_str_val) + 1;
5962c965db44STomer Tayar 		if (offset & 0x3)
5963c965db44STomer Tayar 			offset += (4 - (offset & 0x3));
5964c965db44STomer Tayar 	} else {
5965c965db44STomer Tayar 		/* Numeric param */
5966c965db44STomer Tayar 		*param_str_val = NULL;
5967c965db44STomer Tayar 		if (offset & 0x3)
5968c965db44STomer Tayar 			offset += (4 - (offset & 0x3));
5969c965db44STomer Tayar 		*param_num_val = *(u32 *)(char_buf + offset);
5970c965db44STomer Tayar 		offset += 4;
5971c965db44STomer Tayar 	}
5972c965db44STomer Tayar 
597350bc60cbSMichal Kalderon 	return (u32)offset / 4;
5974c965db44STomer Tayar }
5975c965db44STomer Tayar 
5976c965db44STomer Tayar /* Reads a section header from the specified buffer.
5977c965db44STomer Tayar  * Returns the number of dwords read.
5978c965db44STomer Tayar  */
5979c965db44STomer Tayar static u32 qed_read_section_hdr(u32 *dump_buf,
5980c965db44STomer Tayar 				const char **section_name,
5981c965db44STomer Tayar 				u32 *num_section_params)
5982c965db44STomer Tayar {
5983c965db44STomer Tayar 	const char *param_str_val;
5984c965db44STomer Tayar 
5985c965db44STomer Tayar 	return qed_read_param(dump_buf,
5986c965db44STomer Tayar 			      section_name, &param_str_val, num_section_params);
5987c965db44STomer Tayar }
5988c965db44STomer Tayar 
5989c965db44STomer Tayar /* Reads section params from the specified buffer and prints them to the results
5990c965db44STomer Tayar  * buffer. Returns the number of dwords read.
5991c965db44STomer Tayar  */
5992c965db44STomer Tayar static u32 qed_print_section_params(u32 *dump_buf,
5993c965db44STomer Tayar 				    u32 num_section_params,
5994c965db44STomer Tayar 				    char *results_buf, u32 *num_chars_printed)
5995c965db44STomer Tayar {
5996c965db44STomer Tayar 	u32 i, dump_offset = 0, results_offset = 0;
5997c965db44STomer Tayar 
5998c965db44STomer Tayar 	for (i = 0; i < num_section_params; i++) {
59997b6859fbSMintz, Yuval 		const char *param_name, *param_str_val;
6000c965db44STomer Tayar 		u32 param_num_val = 0;
6001c965db44STomer Tayar 
6002c965db44STomer Tayar 		dump_offset += qed_read_param(dump_buf + dump_offset,
6003c965db44STomer Tayar 					      &param_name,
6004c965db44STomer Tayar 					      &param_str_val, &param_num_val);
60057b6859fbSMintz, Yuval 
6006c965db44STomer Tayar 		if (param_str_val)
6007c965db44STomer Tayar 			results_offset +=
6008c965db44STomer Tayar 				sprintf(qed_get_buf_ptr(results_buf,
6009c965db44STomer Tayar 							results_offset),
6010c965db44STomer Tayar 					"%s: %s\n", param_name, param_str_val);
6011c965db44STomer Tayar 		else if (strcmp(param_name, "fw-timestamp"))
6012c965db44STomer Tayar 			results_offset +=
6013c965db44STomer Tayar 				sprintf(qed_get_buf_ptr(results_buf,
6014c965db44STomer Tayar 							results_offset),
6015c965db44STomer Tayar 					"%s: %d\n", param_name, param_num_val);
6016c965db44STomer Tayar 	}
6017c965db44STomer Tayar 
60187b6859fbSMintz, Yuval 	results_offset += sprintf(qed_get_buf_ptr(results_buf, results_offset),
60197b6859fbSMintz, Yuval 				  "\n");
6020c965db44STomer Tayar 
60217b6859fbSMintz, Yuval 	*num_chars_printed = results_offset;
60227b6859fbSMintz, Yuval 
60237b6859fbSMintz, Yuval 	return dump_offset;
6024c965db44STomer Tayar }
6025c965db44STomer Tayar 
60262d22bc83SMichal Kalderon /* Returns the block name that matches the specified block ID,
60272d22bc83SMichal Kalderon  * or NULL if not found.
60282d22bc83SMichal Kalderon  */
60292d22bc83SMichal Kalderon static const char *qed_dbg_get_block_name(struct qed_hwfn *p_hwfn,
60302d22bc83SMichal Kalderon 					  enum block_id block_id)
60312d22bc83SMichal Kalderon {
60322d22bc83SMichal Kalderon 	const struct dbg_block_user *block =
60332d22bc83SMichal Kalderon 	    (const struct dbg_block_user *)
60342d22bc83SMichal Kalderon 	    p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS_USER_DATA].ptr + block_id;
60352d22bc83SMichal Kalderon 
60362d22bc83SMichal Kalderon 	return (const char *)block->name;
60372d22bc83SMichal Kalderon }
60382d22bc83SMichal Kalderon 
60392d22bc83SMichal Kalderon static struct dbg_tools_user_data *qed_dbg_get_user_data(struct qed_hwfn
60402d22bc83SMichal Kalderon 							 *p_hwfn)
6041a3f72307SDenis Bolotin {
6042a3f72307SDenis Bolotin 	return (struct dbg_tools_user_data *)p_hwfn->dbg_user_info;
6043a3f72307SDenis Bolotin }
6044a3f72307SDenis Bolotin 
6045c965db44STomer Tayar /* Parses the idle check rules and returns the number of characters printed.
6046c965db44STomer Tayar  * In case of parsing error, returns 0.
6047c965db44STomer Tayar  */
60482d22bc83SMichal Kalderon static u32 qed_parse_idle_chk_dump_rules(struct qed_hwfn *p_hwfn,
60492d22bc83SMichal Kalderon 					 u32 *dump_buf,
6050c965db44STomer Tayar 					 u32 *dump_buf_end,
6051c965db44STomer Tayar 					 u32 num_rules,
6052c965db44STomer Tayar 					 bool print_fw_idle_chk,
6053c965db44STomer Tayar 					 char *results_buf,
6054c965db44STomer Tayar 					 u32 *num_errors, u32 *num_warnings)
6055c965db44STomer Tayar {
60567b6859fbSMintz, Yuval 	/* Offset in results_buf in bytes */
60577b6859fbSMintz, Yuval 	u32 results_offset = 0;
60587b6859fbSMintz, Yuval 
60597b6859fbSMintz, Yuval 	u32 rule_idx;
6060c965db44STomer Tayar 	u16 i, j;
6061c965db44STomer Tayar 
6062c965db44STomer Tayar 	*num_errors = 0;
6063c965db44STomer Tayar 	*num_warnings = 0;
6064c965db44STomer Tayar 
6065c965db44STomer Tayar 	/* Go over dumped results */
6066c965db44STomer Tayar 	for (rule_idx = 0; rule_idx < num_rules && dump_buf < dump_buf_end;
6067c965db44STomer Tayar 	     rule_idx++) {
6068c965db44STomer Tayar 		const struct dbg_idle_chk_rule_parsing_data *rule_parsing_data;
6069c965db44STomer Tayar 		struct dbg_idle_chk_result_hdr *hdr;
60707b6859fbSMintz, Yuval 		const char *parsing_str, *lsi_msg;
6071c965db44STomer Tayar 		u32 parsing_str_offset;
6072c965db44STomer Tayar 		bool has_fw_msg;
60737b6859fbSMintz, Yuval 		u8 curr_reg_id;
6074c965db44STomer Tayar 
6075c965db44STomer Tayar 		hdr = (struct dbg_idle_chk_result_hdr *)dump_buf;
6076c965db44STomer Tayar 		rule_parsing_data =
6077c965db44STomer Tayar 		    (const struct dbg_idle_chk_rule_parsing_data *)
60782d22bc83SMichal Kalderon 		    p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr +
60792d22bc83SMichal Kalderon 		    hdr->rule_id;
6080c965db44STomer Tayar 		parsing_str_offset =
6081c965db44STomer Tayar 		    GET_FIELD(rule_parsing_data->data,
6082c965db44STomer Tayar 			      DBG_IDLE_CHK_RULE_PARSING_DATA_STR_OFFSET);
6083c965db44STomer Tayar 		has_fw_msg =
6084c965db44STomer Tayar 		    GET_FIELD(rule_parsing_data->data,
6085c965db44STomer Tayar 			      DBG_IDLE_CHK_RULE_PARSING_DATA_HAS_FW_MSG) > 0;
60862d22bc83SMichal Kalderon 		parsing_str = (const char *)
60872d22bc83SMichal Kalderon 		    p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr +
60882d22bc83SMichal Kalderon 		    parsing_str_offset;
6089c965db44STomer Tayar 		lsi_msg = parsing_str;
60907b6859fbSMintz, Yuval 		curr_reg_id = 0;
6091c965db44STomer Tayar 
6092c965db44STomer Tayar 		if (hdr->severity >= MAX_DBG_IDLE_CHK_SEVERITY_TYPES)
6093c965db44STomer Tayar 			return 0;
6094c965db44STomer Tayar 
6095c965db44STomer Tayar 		/* Skip rule header */
60967b6859fbSMintz, Yuval 		dump_buf += BYTES_TO_DWORDS(sizeof(*hdr));
6097c965db44STomer Tayar 
6098c965db44STomer Tayar 		/* Update errors/warnings count */
6099c965db44STomer Tayar 		if (hdr->severity == IDLE_CHK_SEVERITY_ERROR ||
6100c965db44STomer Tayar 		    hdr->severity == IDLE_CHK_SEVERITY_ERROR_NO_TRAFFIC)
6101c965db44STomer Tayar 			(*num_errors)++;
6102c965db44STomer Tayar 		else
6103c965db44STomer Tayar 			(*num_warnings)++;
6104c965db44STomer Tayar 
6105c965db44STomer Tayar 		/* Print rule severity */
6106c965db44STomer Tayar 		results_offset +=
6107c965db44STomer Tayar 		    sprintf(qed_get_buf_ptr(results_buf,
6108c965db44STomer Tayar 					    results_offset), "%s: ",
6109c965db44STomer Tayar 			    s_idle_chk_severity_str[hdr->severity]);
6110c965db44STomer Tayar 
6111c965db44STomer Tayar 		/* Print rule message */
6112c965db44STomer Tayar 		if (has_fw_msg)
6113c965db44STomer Tayar 			parsing_str += strlen(parsing_str) + 1;
6114c965db44STomer Tayar 		results_offset +=
6115c965db44STomer Tayar 		    sprintf(qed_get_buf_ptr(results_buf,
6116c965db44STomer Tayar 					    results_offset), "%s.",
6117c965db44STomer Tayar 			    has_fw_msg &&
6118c965db44STomer Tayar 			    print_fw_idle_chk ? parsing_str : lsi_msg);
6119c965db44STomer Tayar 		parsing_str += strlen(parsing_str) + 1;
6120c965db44STomer Tayar 
6121c965db44STomer Tayar 		/* Print register values */
6122c965db44STomer Tayar 		results_offset +=
6123c965db44STomer Tayar 		    sprintf(qed_get_buf_ptr(results_buf,
6124c965db44STomer Tayar 					    results_offset), " Registers:");
6125c965db44STomer Tayar 		for (i = 0;
6126c965db44STomer Tayar 		     i < hdr->num_dumped_cond_regs + hdr->num_dumped_info_regs;
6127c965db44STomer Tayar 		     i++) {
61287b6859fbSMintz, Yuval 			struct dbg_idle_chk_result_reg_hdr *reg_hdr;
61297b6859fbSMintz, Yuval 			bool is_mem;
61307b6859fbSMintz, Yuval 			u8 reg_id;
61317b6859fbSMintz, Yuval 
61327b6859fbSMintz, Yuval 			reg_hdr =
61337b6859fbSMintz, Yuval 				(struct dbg_idle_chk_result_reg_hdr *)dump_buf;
61347b6859fbSMintz, Yuval 			is_mem = GET_FIELD(reg_hdr->data,
6135c965db44STomer Tayar 					   DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM);
61367b6859fbSMintz, Yuval 			reg_id = GET_FIELD(reg_hdr->data,
6137c965db44STomer Tayar 					   DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID);
6138c965db44STomer Tayar 
6139c965db44STomer Tayar 			/* Skip reg header */
61407b6859fbSMintz, Yuval 			dump_buf += BYTES_TO_DWORDS(sizeof(*reg_hdr));
6141c965db44STomer Tayar 
6142c965db44STomer Tayar 			/* Skip register names until the required reg_id is
6143c965db44STomer Tayar 			 * reached.
6144c965db44STomer Tayar 			 */
6145c965db44STomer Tayar 			for (; reg_id > curr_reg_id;
6146c965db44STomer Tayar 			     curr_reg_id++,
6147c965db44STomer Tayar 			     parsing_str += strlen(parsing_str) + 1);
6148c965db44STomer Tayar 
6149c965db44STomer Tayar 			results_offset +=
6150c965db44STomer Tayar 			    sprintf(qed_get_buf_ptr(results_buf,
6151c965db44STomer Tayar 						    results_offset), " %s",
6152c965db44STomer Tayar 				    parsing_str);
6153c965db44STomer Tayar 			if (i < hdr->num_dumped_cond_regs && is_mem)
6154c965db44STomer Tayar 				results_offset +=
6155c965db44STomer Tayar 				    sprintf(qed_get_buf_ptr(results_buf,
6156c965db44STomer Tayar 							    results_offset),
6157c965db44STomer Tayar 					    "[%d]", hdr->mem_entry_id +
6158c965db44STomer Tayar 					    reg_hdr->start_entry);
6159c965db44STomer Tayar 			results_offset +=
6160c965db44STomer Tayar 			    sprintf(qed_get_buf_ptr(results_buf,
6161c965db44STomer Tayar 						    results_offset), "=");
6162c965db44STomer Tayar 			for (j = 0; j < reg_hdr->size; j++, dump_buf++) {
6163c965db44STomer Tayar 				results_offset +=
6164c965db44STomer Tayar 				    sprintf(qed_get_buf_ptr(results_buf,
6165c965db44STomer Tayar 							    results_offset),
6166c965db44STomer Tayar 					    "0x%x", *dump_buf);
6167c965db44STomer Tayar 				if (j < reg_hdr->size - 1)
6168c965db44STomer Tayar 					results_offset +=
6169c965db44STomer Tayar 					    sprintf(qed_get_buf_ptr
6170c965db44STomer Tayar 						    (results_buf,
6171c965db44STomer Tayar 						     results_offset), ",");
6172c965db44STomer Tayar 			}
6173c965db44STomer Tayar 		}
6174c965db44STomer Tayar 
6175c965db44STomer Tayar 		results_offset +=
6176c965db44STomer Tayar 		    sprintf(qed_get_buf_ptr(results_buf, results_offset), "\n");
6177c965db44STomer Tayar 	}
6178c965db44STomer Tayar 
6179c965db44STomer Tayar 	/* Check if end of dump buffer was exceeded */
6180c965db44STomer Tayar 	if (dump_buf > dump_buf_end)
6181c965db44STomer Tayar 		return 0;
61827b6859fbSMintz, Yuval 
6183c965db44STomer Tayar 	return results_offset;
6184c965db44STomer Tayar }
6185c965db44STomer Tayar 
6186c965db44STomer Tayar /* Parses an idle check dump buffer.
6187c965db44STomer Tayar  * If result_buf is not NULL, the idle check results are printed to it.
6188c965db44STomer Tayar  * In any case, the required results buffer size is assigned to
6189c965db44STomer Tayar  * parsed_results_bytes.
6190c965db44STomer Tayar  * The parsing status is returned.
6191c965db44STomer Tayar  */
61922d22bc83SMichal Kalderon static enum dbg_status qed_parse_idle_chk_dump(struct qed_hwfn *p_hwfn,
61932d22bc83SMichal Kalderon 					       u32 *dump_buf,
6194c965db44STomer Tayar 					       u32 num_dumped_dwords,
6195c965db44STomer Tayar 					       char *results_buf,
6196c965db44STomer Tayar 					       u32 *parsed_results_bytes,
6197c965db44STomer Tayar 					       u32 *num_errors,
6198c965db44STomer Tayar 					       u32 *num_warnings)
6199c965db44STomer Tayar {
6200c965db44STomer Tayar 	const char *section_name, *param_name, *param_str_val;
6201c965db44STomer Tayar 	u32 *dump_buf_end = dump_buf + num_dumped_dwords;
6202c965db44STomer Tayar 	u32 num_section_params = 0, num_rules;
62037b6859fbSMintz, Yuval 
62047b6859fbSMintz, Yuval 	/* Offset in results_buf in bytes */
62057b6859fbSMintz, Yuval 	u32 results_offset = 0;
6206c965db44STomer Tayar 
6207c965db44STomer Tayar 	*parsed_results_bytes = 0;
6208c965db44STomer Tayar 	*num_errors = 0;
6209c965db44STomer Tayar 	*num_warnings = 0;
62107b6859fbSMintz, Yuval 
62112d22bc83SMichal Kalderon 	if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr ||
62122d22bc83SMichal Kalderon 	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr)
6213c965db44STomer Tayar 		return DBG_STATUS_DBG_ARRAY_NOT_SET;
6214c965db44STomer Tayar 
6215c965db44STomer Tayar 	/* Read global_params section */
6216c965db44STomer Tayar 	dump_buf += qed_read_section_hdr(dump_buf,
6217c965db44STomer Tayar 					 &section_name, &num_section_params);
6218c965db44STomer Tayar 	if (strcmp(section_name, "global_params"))
6219c965db44STomer Tayar 		return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6220c965db44STomer Tayar 
6221c965db44STomer Tayar 	/* Print global params */
6222c965db44STomer Tayar 	dump_buf += qed_print_section_params(dump_buf,
6223c965db44STomer Tayar 					     num_section_params,
6224c965db44STomer Tayar 					     results_buf, &results_offset);
6225c965db44STomer Tayar 
6226c965db44STomer Tayar 	/* Read idle_chk section */
6227c965db44STomer Tayar 	dump_buf += qed_read_section_hdr(dump_buf,
6228c965db44STomer Tayar 					 &section_name, &num_section_params);
6229c965db44STomer Tayar 	if (strcmp(section_name, "idle_chk") || num_section_params != 1)
6230c965db44STomer Tayar 		return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6231c965db44STomer Tayar 	dump_buf += qed_read_param(dump_buf,
6232c965db44STomer Tayar 				   &param_name, &param_str_val, &num_rules);
62337b6859fbSMintz, Yuval 	if (strcmp(param_name, "num_rules"))
6234c965db44STomer Tayar 		return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6235c965db44STomer Tayar 
6236c965db44STomer Tayar 	if (num_rules) {
6237c965db44STomer Tayar 		u32 rules_print_size;
6238c965db44STomer Tayar 
6239c965db44STomer Tayar 		/* Print FW output */
6240c965db44STomer Tayar 		results_offset +=
6241c965db44STomer Tayar 		    sprintf(qed_get_buf_ptr(results_buf,
6242c965db44STomer Tayar 					    results_offset),
6243c965db44STomer Tayar 			    "FW_IDLE_CHECK:\n");
6244c965db44STomer Tayar 		rules_print_size =
62452d22bc83SMichal Kalderon 			qed_parse_idle_chk_dump_rules(p_hwfn,
62462d22bc83SMichal Kalderon 						      dump_buf,
6247da090917STomer Tayar 						      dump_buf_end,
6248da090917STomer Tayar 						      num_rules,
6249c965db44STomer Tayar 						      true,
6250c965db44STomer Tayar 						      results_buf ?
6251c965db44STomer Tayar 						      results_buf +
6252da090917STomer Tayar 						      results_offset :
6253da090917STomer Tayar 						      NULL,
6254da090917STomer Tayar 						      num_errors,
6255da090917STomer Tayar 						      num_warnings);
6256c965db44STomer Tayar 		results_offset += rules_print_size;
62577b6859fbSMintz, Yuval 		if (!rules_print_size)
6258c965db44STomer Tayar 			return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6259c965db44STomer Tayar 
6260c965db44STomer Tayar 		/* Print LSI output */
6261c965db44STomer Tayar 		results_offset +=
6262c965db44STomer Tayar 		    sprintf(qed_get_buf_ptr(results_buf,
6263c965db44STomer Tayar 					    results_offset),
6264c965db44STomer Tayar 			    "\nLSI_IDLE_CHECK:\n");
6265c965db44STomer Tayar 		rules_print_size =
62662d22bc83SMichal Kalderon 			qed_parse_idle_chk_dump_rules(p_hwfn,
62672d22bc83SMichal Kalderon 						      dump_buf,
6268da090917STomer Tayar 						      dump_buf_end,
6269da090917STomer Tayar 						      num_rules,
6270c965db44STomer Tayar 						      false,
6271c965db44STomer Tayar 						      results_buf ?
6272c965db44STomer Tayar 						      results_buf +
6273da090917STomer Tayar 						      results_offset :
6274da090917STomer Tayar 						      NULL,
6275da090917STomer Tayar 						      num_errors,
6276da090917STomer Tayar 						      num_warnings);
6277c965db44STomer Tayar 		results_offset += rules_print_size;
62787b6859fbSMintz, Yuval 		if (!rules_print_size)
6279c965db44STomer Tayar 			return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6280c965db44STomer Tayar 	}
6281c965db44STomer Tayar 
6282c965db44STomer Tayar 	/* Print errors/warnings count */
62837b6859fbSMintz, Yuval 	if (*num_errors)
6284c965db44STomer Tayar 		results_offset +=
6285c965db44STomer Tayar 		    sprintf(qed_get_buf_ptr(results_buf,
6286c965db44STomer Tayar 					    results_offset),
6287c965db44STomer Tayar 			    "\nIdle Check failed!!! (with %d errors and %d warnings)\n",
6288c965db44STomer Tayar 			    *num_errors, *num_warnings);
62897b6859fbSMintz, Yuval 	else if (*num_warnings)
6290c965db44STomer Tayar 		results_offset +=
6291c965db44STomer Tayar 		    sprintf(qed_get_buf_ptr(results_buf,
6292c965db44STomer Tayar 					    results_offset),
62937b6859fbSMintz, Yuval 			    "\nIdle Check completed successfully (with %d warnings)\n",
6294c965db44STomer Tayar 			    *num_warnings);
62957b6859fbSMintz, Yuval 	else
6296c965db44STomer Tayar 		results_offset +=
6297c965db44STomer Tayar 		    sprintf(qed_get_buf_ptr(results_buf,
6298c965db44STomer Tayar 					    results_offset),
62997b6859fbSMintz, Yuval 			    "\nIdle Check completed successfully\n");
6300c965db44STomer Tayar 
6301c965db44STomer Tayar 	/* Add 1 for string NULL termination */
6302c965db44STomer Tayar 	*parsed_results_bytes = results_offset + 1;
63037b6859fbSMintz, Yuval 
6304c965db44STomer Tayar 	return DBG_STATUS_OK;
6305c965db44STomer Tayar }
6306c965db44STomer Tayar 
6307c965db44STomer Tayar /* Allocates and fills MCP Trace meta data based on the specified meta data
6308c965db44STomer Tayar  * dump buffer.
6309c965db44STomer Tayar  * Returns debug status code.
6310c965db44STomer Tayar  */
6311a3f72307SDenis Bolotin static enum dbg_status
6312a3f72307SDenis Bolotin qed_mcp_trace_alloc_meta_data(struct qed_hwfn *p_hwfn,
6313a3f72307SDenis Bolotin 			      const u32 *meta_buf)
6314c965db44STomer Tayar {
6315a3f72307SDenis Bolotin 	struct dbg_tools_user_data *dev_user_data;
6316c965db44STomer Tayar 	u32 offset = 0, signature, i;
6317a3f72307SDenis Bolotin 	struct mcp_trace_meta *meta;
6318a3f72307SDenis Bolotin 	u8 *meta_buf_bytes;
6319a3f72307SDenis Bolotin 
6320a3f72307SDenis Bolotin 	dev_user_data = qed_dbg_get_user_data(p_hwfn);
6321a3f72307SDenis Bolotin 	meta = &dev_user_data->mcp_trace_meta;
6322a3f72307SDenis Bolotin 	meta_buf_bytes = (u8 *)meta_buf;
6323c965db44STomer Tayar 
632450bc60cbSMichal Kalderon 	/* Free the previous meta before loading a new one. */
6325a3f72307SDenis Bolotin 	if (meta->is_allocated)
6326a3f72307SDenis Bolotin 		qed_mcp_trace_free_meta_data(p_hwfn);
632750bc60cbSMichal Kalderon 
6328c965db44STomer Tayar 	memset(meta, 0, sizeof(*meta));
6329c965db44STomer Tayar 
6330c965db44STomer Tayar 	/* Read first signature */
6331c965db44STomer Tayar 	signature = qed_read_dword_from_buf(meta_buf_bytes, &offset);
63327b6859fbSMintz, Yuval 	if (signature != NVM_MAGIC_VALUE)
6333c965db44STomer Tayar 		return DBG_STATUS_INVALID_TRACE_SIGNATURE;
6334c965db44STomer Tayar 
63357b6859fbSMintz, Yuval 	/* Read no. of modules and allocate memory for their pointers */
6336c965db44STomer Tayar 	meta->modules_num = qed_read_byte_from_buf(meta_buf_bytes, &offset);
63376396bb22SKees Cook 	meta->modules = kcalloc(meta->modules_num, sizeof(char *),
63386396bb22SKees Cook 				GFP_KERNEL);
6339c965db44STomer Tayar 	if (!meta->modules)
6340c965db44STomer Tayar 		return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6341c965db44STomer Tayar 
6342c965db44STomer Tayar 	/* Allocate and read all module strings */
6343c965db44STomer Tayar 	for (i = 0; i < meta->modules_num; i++) {
6344c965db44STomer Tayar 		u8 module_len = qed_read_byte_from_buf(meta_buf_bytes, &offset);
6345c965db44STomer Tayar 
6346c965db44STomer Tayar 		*(meta->modules + i) = kzalloc(module_len, GFP_KERNEL);
6347c965db44STomer Tayar 		if (!(*(meta->modules + i))) {
6348c965db44STomer Tayar 			/* Update number of modules to be released */
6349c965db44STomer Tayar 			meta->modules_num = i ? i - 1 : 0;
6350c965db44STomer Tayar 			return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6351c965db44STomer Tayar 		}
6352c965db44STomer Tayar 
6353c965db44STomer Tayar 		qed_read_str_from_buf(meta_buf_bytes, &offset, module_len,
6354c965db44STomer Tayar 				      *(meta->modules + i));
6355c965db44STomer Tayar 		if (module_len > MCP_TRACE_MAX_MODULE_LEN)
6356c965db44STomer Tayar 			(*(meta->modules + i))[MCP_TRACE_MAX_MODULE_LEN] = '\0';
6357c965db44STomer Tayar 	}
6358c965db44STomer Tayar 
6359c965db44STomer Tayar 	/* Read second signature */
6360c965db44STomer Tayar 	signature = qed_read_dword_from_buf(meta_buf_bytes, &offset);
63617b6859fbSMintz, Yuval 	if (signature != NVM_MAGIC_VALUE)
6362c965db44STomer Tayar 		return DBG_STATUS_INVALID_TRACE_SIGNATURE;
6363c965db44STomer Tayar 
6364c965db44STomer Tayar 	/* Read number of formats and allocate memory for all formats */
6365c965db44STomer Tayar 	meta->formats_num = qed_read_dword_from_buf(meta_buf_bytes, &offset);
63666396bb22SKees Cook 	meta->formats = kcalloc(meta->formats_num,
6367c965db44STomer Tayar 				sizeof(struct mcp_trace_format),
6368c965db44STomer Tayar 				GFP_KERNEL);
6369c965db44STomer Tayar 	if (!meta->formats)
6370c965db44STomer Tayar 		return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6371c965db44STomer Tayar 
6372c965db44STomer Tayar 	/* Allocate and read all strings */
6373c965db44STomer Tayar 	for (i = 0; i < meta->formats_num; i++) {
6374c965db44STomer Tayar 		struct mcp_trace_format *format_ptr = &meta->formats[i];
6375c965db44STomer Tayar 		u8 format_len;
6376c965db44STomer Tayar 
6377c965db44STomer Tayar 		format_ptr->data = qed_read_dword_from_buf(meta_buf_bytes,
6378c965db44STomer Tayar 							   &offset);
63792d22bc83SMichal Kalderon 		format_len = GET_MFW_FIELD(format_ptr->data,
63802d22bc83SMichal Kalderon 					   MCP_TRACE_FORMAT_LEN);
6381c965db44STomer Tayar 		format_ptr->format_str = kzalloc(format_len, GFP_KERNEL);
6382c965db44STomer Tayar 		if (!format_ptr->format_str) {
6383c965db44STomer Tayar 			/* Update number of modules to be released */
6384c965db44STomer Tayar 			meta->formats_num = i ? i - 1 : 0;
6385c965db44STomer Tayar 			return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6386c965db44STomer Tayar 		}
6387c965db44STomer Tayar 
6388c965db44STomer Tayar 		qed_read_str_from_buf(meta_buf_bytes,
6389c965db44STomer Tayar 				      &offset,
6390c965db44STomer Tayar 				      format_len, format_ptr->format_str);
6391c965db44STomer Tayar 	}
6392c965db44STomer Tayar 
6393a3f72307SDenis Bolotin 	meta->is_allocated = true;
6394c965db44STomer Tayar 	return DBG_STATUS_OK;
6395c965db44STomer Tayar }
6396c965db44STomer Tayar 
639750bc60cbSMichal Kalderon /* Parses an MCP trace buffer. If result_buf is not NULL, the MCP Trace results
639850bc60cbSMichal Kalderon  * are printed to it. The parsing status is returned.
639950bc60cbSMichal Kalderon  * Arguments:
640050bc60cbSMichal Kalderon  * trace_buf - MCP trace cyclic buffer
640150bc60cbSMichal Kalderon  * trace_buf_size - MCP trace cyclic buffer size in bytes
640250bc60cbSMichal Kalderon  * data_offset - offset in bytes of the data to parse in the MCP trace cyclic
640350bc60cbSMichal Kalderon  *		 buffer.
640450bc60cbSMichal Kalderon  * data_size - size in bytes of data to parse.
640550bc60cbSMichal Kalderon  * parsed_buf - destination buffer for parsed data.
6406a3f72307SDenis Bolotin  * parsed_results_bytes - size of parsed data in bytes.
640750bc60cbSMichal Kalderon  */
6408a3f72307SDenis Bolotin static enum dbg_status qed_parse_mcp_trace_buf(struct qed_hwfn *p_hwfn,
6409a3f72307SDenis Bolotin 					       u8 *trace_buf,
641050bc60cbSMichal Kalderon 					       u32 trace_buf_size,
641150bc60cbSMichal Kalderon 					       u32 data_offset,
641250bc60cbSMichal Kalderon 					       u32 data_size,
641350bc60cbSMichal Kalderon 					       char *parsed_buf,
6414a3f72307SDenis Bolotin 					       u32 *parsed_results_bytes)
641550bc60cbSMichal Kalderon {
6416a3f72307SDenis Bolotin 	struct dbg_tools_user_data *dev_user_data;
6417a3f72307SDenis Bolotin 	struct mcp_trace_meta *meta;
641850bc60cbSMichal Kalderon 	u32 param_mask, param_shift;
641950bc60cbSMichal Kalderon 	enum dbg_status status;
642050bc60cbSMichal Kalderon 
6421a3f72307SDenis Bolotin 	dev_user_data = qed_dbg_get_user_data(p_hwfn);
6422a3f72307SDenis Bolotin 	meta = &dev_user_data->mcp_trace_meta;
6423a3f72307SDenis Bolotin 	*parsed_results_bytes = 0;
642450bc60cbSMichal Kalderon 
6425a3f72307SDenis Bolotin 	if (!meta->is_allocated)
642650bc60cbSMichal Kalderon 		return DBG_STATUS_MCP_TRACE_BAD_DATA;
642750bc60cbSMichal Kalderon 
642850bc60cbSMichal Kalderon 	status = DBG_STATUS_OK;
642950bc60cbSMichal Kalderon 
643050bc60cbSMichal Kalderon 	while (data_size) {
643150bc60cbSMichal Kalderon 		struct mcp_trace_format *format_ptr;
643250bc60cbSMichal Kalderon 		u8 format_level, format_module;
643350bc60cbSMichal Kalderon 		u32 params[3] = { 0, 0, 0 };
643450bc60cbSMichal Kalderon 		u32 header, format_idx, i;
643550bc60cbSMichal Kalderon 
643650bc60cbSMichal Kalderon 		if (data_size < MFW_TRACE_ENTRY_SIZE)
643750bc60cbSMichal Kalderon 			return DBG_STATUS_MCP_TRACE_BAD_DATA;
643850bc60cbSMichal Kalderon 
643950bc60cbSMichal Kalderon 		header = qed_read_from_cyclic_buf(trace_buf,
644050bc60cbSMichal Kalderon 						  &data_offset,
644150bc60cbSMichal Kalderon 						  trace_buf_size,
644250bc60cbSMichal Kalderon 						  MFW_TRACE_ENTRY_SIZE);
644350bc60cbSMichal Kalderon 		data_size -= MFW_TRACE_ENTRY_SIZE;
644450bc60cbSMichal Kalderon 		format_idx = header & MFW_TRACE_EVENTID_MASK;
644550bc60cbSMichal Kalderon 
644650bc60cbSMichal Kalderon 		/* Skip message if its index doesn't exist in the meta data */
6447a3f72307SDenis Bolotin 		if (format_idx >= meta->formats_num) {
64482d22bc83SMichal Kalderon 			u8 format_size = (u8)GET_MFW_FIELD(header,
64492d22bc83SMichal Kalderon 							   MFW_TRACE_PRM_SIZE);
645050bc60cbSMichal Kalderon 
645150bc60cbSMichal Kalderon 			if (data_size < format_size)
645250bc60cbSMichal Kalderon 				return DBG_STATUS_MCP_TRACE_BAD_DATA;
645350bc60cbSMichal Kalderon 
645450bc60cbSMichal Kalderon 			data_offset = qed_cyclic_add(data_offset,
645550bc60cbSMichal Kalderon 						     format_size,
645650bc60cbSMichal Kalderon 						     trace_buf_size);
645750bc60cbSMichal Kalderon 			data_size -= format_size;
645850bc60cbSMichal Kalderon 			continue;
645950bc60cbSMichal Kalderon 		}
646050bc60cbSMichal Kalderon 
6461a3f72307SDenis Bolotin 		format_ptr = &meta->formats[format_idx];
646250bc60cbSMichal Kalderon 
646350bc60cbSMichal Kalderon 		for (i = 0,
64642d22bc83SMichal Kalderon 		     param_mask = MCP_TRACE_FORMAT_P1_SIZE_MASK, param_shift =
64652d22bc83SMichal Kalderon 		     MCP_TRACE_FORMAT_P1_SIZE_OFFSET;
646650bc60cbSMichal Kalderon 		     i < MCP_TRACE_FORMAT_MAX_PARAMS;
64672d22bc83SMichal Kalderon 		     i++, param_mask <<= MCP_TRACE_FORMAT_PARAM_WIDTH,
646850bc60cbSMichal Kalderon 		     param_shift += MCP_TRACE_FORMAT_PARAM_WIDTH) {
646950bc60cbSMichal Kalderon 			/* Extract param size (0..3) */
647050bc60cbSMichal Kalderon 			u8 param_size = (u8)((format_ptr->data & param_mask) >>
647150bc60cbSMichal Kalderon 					     param_shift);
647250bc60cbSMichal Kalderon 
647350bc60cbSMichal Kalderon 			/* If the param size is zero, there are no other
647450bc60cbSMichal Kalderon 			 * parameters.
647550bc60cbSMichal Kalderon 			 */
647650bc60cbSMichal Kalderon 			if (!param_size)
647750bc60cbSMichal Kalderon 				break;
647850bc60cbSMichal Kalderon 
647950bc60cbSMichal Kalderon 			/* Size is encoded using 2 bits, where 3 is used to
648050bc60cbSMichal Kalderon 			 * encode 4.
648150bc60cbSMichal Kalderon 			 */
648250bc60cbSMichal Kalderon 			if (param_size == 3)
648350bc60cbSMichal Kalderon 				param_size = 4;
648450bc60cbSMichal Kalderon 
648550bc60cbSMichal Kalderon 			if (data_size < param_size)
648650bc60cbSMichal Kalderon 				return DBG_STATUS_MCP_TRACE_BAD_DATA;
648750bc60cbSMichal Kalderon 
648850bc60cbSMichal Kalderon 			params[i] = qed_read_from_cyclic_buf(trace_buf,
648950bc60cbSMichal Kalderon 							     &data_offset,
649050bc60cbSMichal Kalderon 							     trace_buf_size,
649150bc60cbSMichal Kalderon 							     param_size);
649250bc60cbSMichal Kalderon 			data_size -= param_size;
649350bc60cbSMichal Kalderon 		}
649450bc60cbSMichal Kalderon 
64952d22bc83SMichal Kalderon 		format_level = (u8)GET_MFW_FIELD(format_ptr->data,
64962d22bc83SMichal Kalderon 						 MCP_TRACE_FORMAT_LEVEL);
64972d22bc83SMichal Kalderon 		format_module = (u8)GET_MFW_FIELD(format_ptr->data,
64982d22bc83SMichal Kalderon 						  MCP_TRACE_FORMAT_MODULE);
649950bc60cbSMichal Kalderon 		if (format_level >= ARRAY_SIZE(s_mcp_trace_level_str))
650050bc60cbSMichal Kalderon 			return DBG_STATUS_MCP_TRACE_BAD_DATA;
650150bc60cbSMichal Kalderon 
650250bc60cbSMichal Kalderon 		/* Print current message to results buffer */
6503a3f72307SDenis Bolotin 		*parsed_results_bytes +=
6504a3f72307SDenis Bolotin 			sprintf(qed_get_buf_ptr(parsed_buf,
6505a3f72307SDenis Bolotin 						*parsed_results_bytes),
650650bc60cbSMichal Kalderon 				"%s %-8s: ",
650750bc60cbSMichal Kalderon 				s_mcp_trace_level_str[format_level],
6508a3f72307SDenis Bolotin 				meta->modules[format_module]);
6509a3f72307SDenis Bolotin 		*parsed_results_bytes +=
6510a3f72307SDenis Bolotin 		    sprintf(qed_get_buf_ptr(parsed_buf, *parsed_results_bytes),
651150bc60cbSMichal Kalderon 			    format_ptr->format_str,
651250bc60cbSMichal Kalderon 			    params[0], params[1], params[2]);
651350bc60cbSMichal Kalderon 	}
651450bc60cbSMichal Kalderon 
651550bc60cbSMichal Kalderon 	/* Add string NULL terminator */
6516a3f72307SDenis Bolotin 	(*parsed_results_bytes)++;
651750bc60cbSMichal Kalderon 
651850bc60cbSMichal Kalderon 	return status;
651950bc60cbSMichal Kalderon }
652050bc60cbSMichal Kalderon 
6521c965db44STomer Tayar /* Parses an MCP Trace dump buffer.
6522c965db44STomer Tayar  * If result_buf is not NULL, the MCP Trace results are printed to it.
6523c965db44STomer Tayar  * In any case, the required results buffer size is assigned to
6524a3f72307SDenis Bolotin  * parsed_results_bytes.
6525c965db44STomer Tayar  * The parsing status is returned.
6526c965db44STomer Tayar  */
6527c965db44STomer Tayar static enum dbg_status qed_parse_mcp_trace_dump(struct qed_hwfn *p_hwfn,
6528c965db44STomer Tayar 						u32 *dump_buf,
6529a3f72307SDenis Bolotin 						char *results_buf,
6530a3f72307SDenis Bolotin 						u32 *parsed_results_bytes,
6531a3f72307SDenis Bolotin 						bool free_meta_data)
6532c965db44STomer Tayar {
6533c965db44STomer Tayar 	const char *section_name, *param_name, *param_str_val;
653450bc60cbSMichal Kalderon 	u32 data_size, trace_data_dwords, trace_meta_dwords;
6535a3f72307SDenis Bolotin 	u32 offset, results_offset, results_buf_bytes;
653650bc60cbSMichal Kalderon 	u32 param_num_val, num_section_params;
6537c965db44STomer Tayar 	struct mcp_trace *trace;
6538c965db44STomer Tayar 	enum dbg_status status;
6539c965db44STomer Tayar 	const u32 *meta_buf;
6540c965db44STomer Tayar 	u8 *trace_buf;
6541c965db44STomer Tayar 
6542a3f72307SDenis Bolotin 	*parsed_results_bytes = 0;
6543c965db44STomer Tayar 
6544c965db44STomer Tayar 	/* Read global_params section */
6545c965db44STomer Tayar 	dump_buf += qed_read_section_hdr(dump_buf,
6546c965db44STomer Tayar 					 &section_name, &num_section_params);
6547c965db44STomer Tayar 	if (strcmp(section_name, "global_params"))
6548c965db44STomer Tayar 		return DBG_STATUS_MCP_TRACE_BAD_DATA;
6549c965db44STomer Tayar 
6550c965db44STomer Tayar 	/* Print global params */
6551c965db44STomer Tayar 	dump_buf += qed_print_section_params(dump_buf,
6552c965db44STomer Tayar 					     num_section_params,
6553a3f72307SDenis Bolotin 					     results_buf, &results_offset);
6554c965db44STomer Tayar 
6555c965db44STomer Tayar 	/* Read trace_data section */
6556c965db44STomer Tayar 	dump_buf += qed_read_section_hdr(dump_buf,
6557c965db44STomer Tayar 					 &section_name, &num_section_params);
6558c965db44STomer Tayar 	if (strcmp(section_name, "mcp_trace_data") || num_section_params != 1)
6559c965db44STomer Tayar 		return DBG_STATUS_MCP_TRACE_BAD_DATA;
6560c965db44STomer Tayar 	dump_buf += qed_read_param(dump_buf,
6561c965db44STomer Tayar 				   &param_name, &param_str_val, &param_num_val);
6562c965db44STomer Tayar 	if (strcmp(param_name, "size"))
6563c965db44STomer Tayar 		return DBG_STATUS_MCP_TRACE_BAD_DATA;
6564c965db44STomer Tayar 	trace_data_dwords = param_num_val;
6565c965db44STomer Tayar 
6566c965db44STomer Tayar 	/* Prepare trace info */
6567c965db44STomer Tayar 	trace = (struct mcp_trace *)dump_buf;
6568a3f72307SDenis Bolotin 	if (trace->signature != MFW_TRACE_SIGNATURE || !trace->size)
6569a3f72307SDenis Bolotin 		return DBG_STATUS_MCP_TRACE_BAD_DATA;
6570a3f72307SDenis Bolotin 
65717b6859fbSMintz, Yuval 	trace_buf = (u8 *)dump_buf + sizeof(*trace);
6572c965db44STomer Tayar 	offset = trace->trace_oldest;
657350bc60cbSMichal Kalderon 	data_size = qed_cyclic_sub(trace->trace_prod, offset, trace->size);
6574c965db44STomer Tayar 	dump_buf += trace_data_dwords;
6575c965db44STomer Tayar 
6576c965db44STomer Tayar 	/* Read meta_data section */
6577c965db44STomer Tayar 	dump_buf += qed_read_section_hdr(dump_buf,
6578c965db44STomer Tayar 					 &section_name, &num_section_params);
6579c965db44STomer Tayar 	if (strcmp(section_name, "mcp_trace_meta"))
6580c965db44STomer Tayar 		return DBG_STATUS_MCP_TRACE_BAD_DATA;
6581c965db44STomer Tayar 	dump_buf += qed_read_param(dump_buf,
6582c965db44STomer Tayar 				   &param_name, &param_str_val, &param_num_val);
65837b6859fbSMintz, Yuval 	if (strcmp(param_name, "size"))
6584c965db44STomer Tayar 		return DBG_STATUS_MCP_TRACE_BAD_DATA;
6585c965db44STomer Tayar 	trace_meta_dwords = param_num_val;
6586c965db44STomer Tayar 
6587c965db44STomer Tayar 	/* Choose meta data buffer */
6588c965db44STomer Tayar 	if (!trace_meta_dwords) {
6589c965db44STomer Tayar 		/* Dump doesn't include meta data */
6590a3f72307SDenis Bolotin 		struct dbg_tools_user_data *dev_user_data =
6591a3f72307SDenis Bolotin 			qed_dbg_get_user_data(p_hwfn);
6592a3f72307SDenis Bolotin 
6593a3f72307SDenis Bolotin 		if (!dev_user_data->mcp_trace_user_meta_buf)
6594c965db44STomer Tayar 			return DBG_STATUS_MCP_TRACE_NO_META;
6595a3f72307SDenis Bolotin 
6596a3f72307SDenis Bolotin 		meta_buf = dev_user_data->mcp_trace_user_meta_buf;
6597c965db44STomer Tayar 	} else {
6598c965db44STomer Tayar 		/* Dump includes meta data */
6599c965db44STomer Tayar 		meta_buf = dump_buf;
6600c965db44STomer Tayar 	}
6601c965db44STomer Tayar 
6602c965db44STomer Tayar 	/* Allocate meta data memory */
6603a3f72307SDenis Bolotin 	status = qed_mcp_trace_alloc_meta_data(p_hwfn, meta_buf);
6604c965db44STomer Tayar 	if (status != DBG_STATUS_OK)
6605c965db44STomer Tayar 		return status;
660650bc60cbSMichal Kalderon 
6607a3f72307SDenis Bolotin 	status = qed_parse_mcp_trace_buf(p_hwfn,
6608a3f72307SDenis Bolotin 					 trace_buf,
660950bc60cbSMichal Kalderon 					 trace->size,
661050bc60cbSMichal Kalderon 					 offset,
661150bc60cbSMichal Kalderon 					 data_size,
6612a3f72307SDenis Bolotin 					 results_buf ?
6613a3f72307SDenis Bolotin 					 results_buf + results_offset :
661450bc60cbSMichal Kalderon 					 NULL,
6615a3f72307SDenis Bolotin 					 &results_buf_bytes);
661650bc60cbSMichal Kalderon 	if (status != DBG_STATUS_OK)
661750bc60cbSMichal Kalderon 		return status;
661850bc60cbSMichal Kalderon 
6619a3f72307SDenis Bolotin 	if (free_meta_data)
6620a3f72307SDenis Bolotin 		qed_mcp_trace_free_meta_data(p_hwfn);
6621a3f72307SDenis Bolotin 
6622a3f72307SDenis Bolotin 	*parsed_results_bytes = results_offset + results_buf_bytes;
662350bc60cbSMichal Kalderon 
662450bc60cbSMichal Kalderon 	return DBG_STATUS_OK;
6625c965db44STomer Tayar }
6626c965db44STomer Tayar 
6627c965db44STomer Tayar /* Parses a Reg FIFO dump buffer.
6628c965db44STomer Tayar  * If result_buf is not NULL, the Reg FIFO results are printed to it.
6629c965db44STomer Tayar  * In any case, the required results buffer size is assigned to
6630c965db44STomer Tayar  * parsed_results_bytes.
6631c965db44STomer Tayar  * The parsing status is returned.
6632c965db44STomer Tayar  */
6633da090917STomer Tayar static enum dbg_status qed_parse_reg_fifo_dump(u32 *dump_buf,
6634c965db44STomer Tayar 					       char *results_buf,
6635c965db44STomer Tayar 					       u32 *parsed_results_bytes)
6636c965db44STomer Tayar {
6637c965db44STomer Tayar 	const char *section_name, *param_name, *param_str_val;
66387b6859fbSMintz, Yuval 	u32 param_num_val, num_section_params, num_elements;
6639c965db44STomer Tayar 	struct reg_fifo_element *elements;
66402d22bc83SMichal Kalderon 	u8 i, j, err_code, vf_val;
66417b6859fbSMintz, Yuval 	u32 results_offset = 0;
6642c965db44STomer Tayar 	char vf_str[4];
6643c965db44STomer Tayar 
6644c965db44STomer Tayar 	/* Read global_params section */
6645c965db44STomer Tayar 	dump_buf += qed_read_section_hdr(dump_buf,
6646c965db44STomer Tayar 					 &section_name, &num_section_params);
6647c965db44STomer Tayar 	if (strcmp(section_name, "global_params"))
6648c965db44STomer Tayar 		return DBG_STATUS_REG_FIFO_BAD_DATA;
6649c965db44STomer Tayar 
6650c965db44STomer Tayar 	/* Print global params */
6651c965db44STomer Tayar 	dump_buf += qed_print_section_params(dump_buf,
6652c965db44STomer Tayar 					     num_section_params,
6653c965db44STomer Tayar 					     results_buf, &results_offset);
6654c965db44STomer Tayar 
6655c965db44STomer Tayar 	/* Read reg_fifo_data section */
6656c965db44STomer Tayar 	dump_buf += qed_read_section_hdr(dump_buf,
6657c965db44STomer Tayar 					 &section_name, &num_section_params);
6658c965db44STomer Tayar 	if (strcmp(section_name, "reg_fifo_data"))
6659c965db44STomer Tayar 		return DBG_STATUS_REG_FIFO_BAD_DATA;
6660c965db44STomer Tayar 	dump_buf += qed_read_param(dump_buf,
6661c965db44STomer Tayar 				   &param_name, &param_str_val, &param_num_val);
6662c965db44STomer Tayar 	if (strcmp(param_name, "size"))
6663c965db44STomer Tayar 		return DBG_STATUS_REG_FIFO_BAD_DATA;
6664c965db44STomer Tayar 	if (param_num_val % REG_FIFO_ELEMENT_DWORDS)
6665c965db44STomer Tayar 		return DBG_STATUS_REG_FIFO_BAD_DATA;
6666c965db44STomer Tayar 	num_elements = param_num_val / REG_FIFO_ELEMENT_DWORDS;
6667c965db44STomer Tayar 	elements = (struct reg_fifo_element *)dump_buf;
6668c965db44STomer Tayar 
6669c965db44STomer Tayar 	/* Decode elements */
6670c965db44STomer Tayar 	for (i = 0; i < num_elements; i++) {
66712d22bc83SMichal Kalderon 		const char *err_msg = NULL;
6672c965db44STomer Tayar 
6673c965db44STomer Tayar 		/* Discover if element belongs to a VF or a PF */
6674c965db44STomer Tayar 		vf_val = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_VF);
6675c965db44STomer Tayar 		if (vf_val == REG_FIFO_ELEMENT_IS_PF_VF_VAL)
6676c965db44STomer Tayar 			sprintf(vf_str, "%s", "N/A");
6677c965db44STomer Tayar 		else
6678c965db44STomer Tayar 			sprintf(vf_str, "%d", vf_val);
6679c965db44STomer Tayar 
66802d22bc83SMichal Kalderon 		/* Find error message */
66812d22bc83SMichal Kalderon 		err_code = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_ERROR);
66822d22bc83SMichal Kalderon 		for (j = 0; j < ARRAY_SIZE(s_reg_fifo_errors) && !err_msg; j++)
66832d22bc83SMichal Kalderon 			if (err_code == s_reg_fifo_errors[j].err_code)
66842d22bc83SMichal Kalderon 				err_msg = s_reg_fifo_errors[j].err_msg;
66852d22bc83SMichal Kalderon 
6686c965db44STomer Tayar 		/* Add parsed element to parsed buffer */
6687c965db44STomer Tayar 		results_offset +=
6688c965db44STomer Tayar 		    sprintf(qed_get_buf_ptr(results_buf,
6689c965db44STomer Tayar 					    results_offset),
66902d22bc83SMichal Kalderon 			    "raw: 0x%016llx, address: 0x%07x, access: %-5s, pf: %2d, vf: %s, port: %d, privilege: %-3s, protection: %-12s, master: %-4s, error: %s\n",
6691c965db44STomer Tayar 			    elements[i].data,
6692be086e7cSMintz, Yuval 			    (u32)GET_FIELD(elements[i].data,
6693c965db44STomer Tayar 					   REG_FIFO_ELEMENT_ADDRESS) *
6694c965db44STomer Tayar 			    REG_FIFO_ELEMENT_ADDR_FACTOR,
6695c965db44STomer Tayar 			    s_access_strs[GET_FIELD(elements[i].data,
6696c965db44STomer Tayar 						    REG_FIFO_ELEMENT_ACCESS)],
6697be086e7cSMintz, Yuval 			    (u32)GET_FIELD(elements[i].data,
66987b6859fbSMintz, Yuval 					   REG_FIFO_ELEMENT_PF),
66997b6859fbSMintz, Yuval 			    vf_str,
6700be086e7cSMintz, Yuval 			    (u32)GET_FIELD(elements[i].data,
6701c965db44STomer Tayar 					   REG_FIFO_ELEMENT_PORT),
67027b6859fbSMintz, Yuval 			    s_privilege_strs[GET_FIELD(elements[i].data,
6703c965db44STomer Tayar 						REG_FIFO_ELEMENT_PRIVILEGE)],
6704c965db44STomer Tayar 			    s_protection_strs[GET_FIELD(elements[i].data,
6705c965db44STomer Tayar 						REG_FIFO_ELEMENT_PROTECTION)],
6706c965db44STomer Tayar 			    s_master_strs[GET_FIELD(elements[i].data,
67072d22bc83SMichal Kalderon 						    REG_FIFO_ELEMENT_MASTER)],
67082d22bc83SMichal Kalderon 			    err_msg ? err_msg : "unknown error code");
6709c965db44STomer Tayar 	}
6710c965db44STomer Tayar 
6711c965db44STomer Tayar 	results_offset += sprintf(qed_get_buf_ptr(results_buf,
6712c965db44STomer Tayar 						  results_offset),
6713c965db44STomer Tayar 				  "fifo contained %d elements", num_elements);
6714c965db44STomer Tayar 
6715c965db44STomer Tayar 	/* Add 1 for string NULL termination */
6716c965db44STomer Tayar 	*parsed_results_bytes = results_offset + 1;
67177b6859fbSMintz, Yuval 
6718c965db44STomer Tayar 	return DBG_STATUS_OK;
6719c965db44STomer Tayar }
6720c965db44STomer Tayar 
67217b6859fbSMintz, Yuval static enum dbg_status qed_parse_igu_fifo_element(struct igu_fifo_element
67227b6859fbSMintz, Yuval 						  *element, char
67237b6859fbSMintz, Yuval 						  *results_buf,
6724da090917STomer Tayar 						  u32 *results_offset)
6725c965db44STomer Tayar {
67267b6859fbSMintz, Yuval 	const struct igu_fifo_addr_data *found_addr = NULL;
67277b6859fbSMintz, Yuval 	u8 source, err_type, i, is_cleanup;
67287b6859fbSMintz, Yuval 	char parsed_addr_data[32];
67297b6859fbSMintz, Yuval 	char parsed_wr_data[256];
67307b6859fbSMintz, Yuval 	u32 wr_data, prod_cons;
67317b6859fbSMintz, Yuval 	bool is_wr_cmd, is_pf;
67327b6859fbSMintz, Yuval 	u16 cmd_addr;
67337b6859fbSMintz, Yuval 	u64 dword12;
67347b6859fbSMintz, Yuval 
67357b6859fbSMintz, Yuval 	/* Dword12 (dword index 1 and 2) contains bits 32..95 of the
67367b6859fbSMintz, Yuval 	 * FIFO element.
67377b6859fbSMintz, Yuval 	 */
67387b6859fbSMintz, Yuval 	dword12 = ((u64)element->dword2 << 32) | element->dword1;
67397b6859fbSMintz, Yuval 	is_wr_cmd = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD);
67407b6859fbSMintz, Yuval 	is_pf = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_IS_PF);
67417b6859fbSMintz, Yuval 	cmd_addr = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR);
67427b6859fbSMintz, Yuval 	source = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_SOURCE);
67437b6859fbSMintz, Yuval 	err_type = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE);
67447b6859fbSMintz, Yuval 
67457b6859fbSMintz, Yuval 	if (source >= ARRAY_SIZE(s_igu_fifo_source_strs))
67467b6859fbSMintz, Yuval 		return DBG_STATUS_IGU_FIFO_BAD_DATA;
67477b6859fbSMintz, Yuval 	if (err_type >= ARRAY_SIZE(s_igu_fifo_error_strs))
67487b6859fbSMintz, Yuval 		return DBG_STATUS_IGU_FIFO_BAD_DATA;
67497b6859fbSMintz, Yuval 
67507b6859fbSMintz, Yuval 	/* Find address data */
67517b6859fbSMintz, Yuval 	for (i = 0; i < ARRAY_SIZE(s_igu_fifo_addr_data) && !found_addr; i++) {
67527b6859fbSMintz, Yuval 		const struct igu_fifo_addr_data *curr_addr =
67537b6859fbSMintz, Yuval 			&s_igu_fifo_addr_data[i];
67547b6859fbSMintz, Yuval 
67557b6859fbSMintz, Yuval 		if (cmd_addr >= curr_addr->start_addr && cmd_addr <=
67567b6859fbSMintz, Yuval 		    curr_addr->end_addr)
67577b6859fbSMintz, Yuval 			found_addr = curr_addr;
6758c965db44STomer Tayar 	}
6759c965db44STomer Tayar 
67607b6859fbSMintz, Yuval 	if (!found_addr)
67617b6859fbSMintz, Yuval 		return DBG_STATUS_IGU_FIFO_BAD_DATA;
6762c965db44STomer Tayar 
67637b6859fbSMintz, Yuval 	/* Prepare parsed address data */
67647b6859fbSMintz, Yuval 	switch (found_addr->type) {
67657b6859fbSMintz, Yuval 	case IGU_ADDR_TYPE_MSIX_MEM:
67667b6859fbSMintz, Yuval 		sprintf(parsed_addr_data, " vector_num = 0x%x", cmd_addr / 2);
67677b6859fbSMintz, Yuval 		break;
67687b6859fbSMintz, Yuval 	case IGU_ADDR_TYPE_WRITE_INT_ACK:
67697b6859fbSMintz, Yuval 	case IGU_ADDR_TYPE_WRITE_PROD_UPDATE:
67707b6859fbSMintz, Yuval 		sprintf(parsed_addr_data,
67717b6859fbSMintz, Yuval 			" SB = 0x%x", cmd_addr - found_addr->start_addr);
67727b6859fbSMintz, Yuval 		break;
67737b6859fbSMintz, Yuval 	default:
67747b6859fbSMintz, Yuval 		parsed_addr_data[0] = '\0';
67757b6859fbSMintz, Yuval 	}
67767b6859fbSMintz, Yuval 
67777b6859fbSMintz, Yuval 	if (!is_wr_cmd) {
67787b6859fbSMintz, Yuval 		parsed_wr_data[0] = '\0';
67797b6859fbSMintz, Yuval 		goto out;
67807b6859fbSMintz, Yuval 	}
67817b6859fbSMintz, Yuval 
67827b6859fbSMintz, Yuval 	/* Prepare parsed write data */
67837b6859fbSMintz, Yuval 	wr_data = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_WR_DATA);
67847b6859fbSMintz, Yuval 	prod_cons = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_PROD_CONS);
67857b6859fbSMintz, Yuval 	is_cleanup = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_CMD_TYPE);
67867b6859fbSMintz, Yuval 
67877b6859fbSMintz, Yuval 	if (source == IGU_SRC_ATTN) {
67887b6859fbSMintz, Yuval 		sprintf(parsed_wr_data, "prod: 0x%x, ", prod_cons);
67897b6859fbSMintz, Yuval 	} else {
67907b6859fbSMintz, Yuval 		if (is_cleanup) {
67917b6859fbSMintz, Yuval 			u8 cleanup_val, cleanup_type;
67927b6859fbSMintz, Yuval 
67937b6859fbSMintz, Yuval 			cleanup_val =
67947b6859fbSMintz, Yuval 				GET_FIELD(wr_data,
67957b6859fbSMintz, Yuval 					  IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL);
67967b6859fbSMintz, Yuval 			cleanup_type =
67977b6859fbSMintz, Yuval 			    GET_FIELD(wr_data,
67987b6859fbSMintz, Yuval 				      IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE);
67997b6859fbSMintz, Yuval 
68007b6859fbSMintz, Yuval 			sprintf(parsed_wr_data,
68017b6859fbSMintz, Yuval 				"cmd_type: cleanup, cleanup_val: %s, cleanup_type : %d, ",
68027b6859fbSMintz, Yuval 				cleanup_val ? "set" : "clear",
68037b6859fbSMintz, Yuval 				cleanup_type);
68047b6859fbSMintz, Yuval 		} else {
68057b6859fbSMintz, Yuval 			u8 update_flag, en_dis_int_for_sb, segment;
68067b6859fbSMintz, Yuval 			u8 timer_mask;
68077b6859fbSMintz, Yuval 
68087b6859fbSMintz, Yuval 			update_flag = GET_FIELD(wr_data,
68097b6859fbSMintz, Yuval 						IGU_FIFO_WR_DATA_UPDATE_FLAG);
68107b6859fbSMintz, Yuval 			en_dis_int_for_sb =
68117b6859fbSMintz, Yuval 				GET_FIELD(wr_data,
68127b6859fbSMintz, Yuval 					  IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB);
68137b6859fbSMintz, Yuval 			segment = GET_FIELD(wr_data,
68147b6859fbSMintz, Yuval 					    IGU_FIFO_WR_DATA_SEGMENT);
68157b6859fbSMintz, Yuval 			timer_mask = GET_FIELD(wr_data,
68167b6859fbSMintz, Yuval 					       IGU_FIFO_WR_DATA_TIMER_MASK);
68177b6859fbSMintz, Yuval 
68187b6859fbSMintz, Yuval 			sprintf(parsed_wr_data,
68197b6859fbSMintz, Yuval 				"cmd_type: prod/cons update, prod/cons: 0x%x, update_flag: %s, en_dis_int_for_sb : %s, segment : %s, timer_mask = %d, ",
68207b6859fbSMintz, Yuval 				prod_cons,
68217b6859fbSMintz, Yuval 				update_flag ? "update" : "nop",
6822da090917STomer Tayar 				en_dis_int_for_sb ?
6823da090917STomer Tayar 				(en_dis_int_for_sb == 1 ? "disable" : "nop") :
6824da090917STomer Tayar 				"enable",
68257b6859fbSMintz, Yuval 				segment ? "attn" : "regular",
68267b6859fbSMintz, Yuval 				timer_mask);
68277b6859fbSMintz, Yuval 		}
68287b6859fbSMintz, Yuval 	}
68297b6859fbSMintz, Yuval out:
68307b6859fbSMintz, Yuval 	/* Add parsed element to parsed buffer */
68317b6859fbSMintz, Yuval 	*results_offset += sprintf(qed_get_buf_ptr(results_buf,
68327b6859fbSMintz, Yuval 						   *results_offset),
68337b6859fbSMintz, Yuval 				   "raw: 0x%01x%08x%08x, %s: %d, source : %s, type : %s, cmd_addr : 0x%x(%s%s), %serror: %s\n",
68347b6859fbSMintz, Yuval 				   element->dword2, element->dword1,
68357b6859fbSMintz, Yuval 				   element->dword0,
68367b6859fbSMintz, Yuval 				   is_pf ? "pf" : "vf",
68377b6859fbSMintz, Yuval 				   GET_FIELD(element->dword0,
68387b6859fbSMintz, Yuval 					     IGU_FIFO_ELEMENT_DWORD0_FID),
68397b6859fbSMintz, Yuval 				   s_igu_fifo_source_strs[source],
68407b6859fbSMintz, Yuval 				   is_wr_cmd ? "wr" : "rd",
68417b6859fbSMintz, Yuval 				   cmd_addr,
68427b6859fbSMintz, Yuval 				   (!is_pf && found_addr->vf_desc)
68437b6859fbSMintz, Yuval 				   ? found_addr->vf_desc
68447b6859fbSMintz, Yuval 				   : found_addr->desc,
68457b6859fbSMintz, Yuval 				   parsed_addr_data,
68467b6859fbSMintz, Yuval 				   parsed_wr_data,
68477b6859fbSMintz, Yuval 				   s_igu_fifo_error_strs[err_type]);
68487b6859fbSMintz, Yuval 
68497b6859fbSMintz, Yuval 	return DBG_STATUS_OK;
6850c965db44STomer Tayar }
6851c965db44STomer Tayar 
6852c965db44STomer Tayar /* Parses an IGU FIFO dump buffer.
6853c965db44STomer Tayar  * If result_buf is not NULL, the IGU FIFO results are printed to it.
6854c965db44STomer Tayar  * In any case, the required results buffer size is assigned to
6855c965db44STomer Tayar  * parsed_results_bytes.
6856c965db44STomer Tayar  * The parsing status is returned.
6857c965db44STomer Tayar  */
6858da090917STomer Tayar static enum dbg_status qed_parse_igu_fifo_dump(u32 *dump_buf,
6859c965db44STomer Tayar 					       char *results_buf,
6860c965db44STomer Tayar 					       u32 *parsed_results_bytes)
6861c965db44STomer Tayar {
6862c965db44STomer Tayar 	const char *section_name, *param_name, *param_str_val;
68637b6859fbSMintz, Yuval 	u32 param_num_val, num_section_params, num_elements;
6864c965db44STomer Tayar 	struct igu_fifo_element *elements;
68657b6859fbSMintz, Yuval 	enum dbg_status status;
68667b6859fbSMintz, Yuval 	u32 results_offset = 0;
68677b6859fbSMintz, Yuval 	u8 i;
6868c965db44STomer Tayar 
6869c965db44STomer Tayar 	/* Read global_params section */
6870c965db44STomer Tayar 	dump_buf += qed_read_section_hdr(dump_buf,
6871c965db44STomer Tayar 					 &section_name, &num_section_params);
6872c965db44STomer Tayar 	if (strcmp(section_name, "global_params"))
6873c965db44STomer Tayar 		return DBG_STATUS_IGU_FIFO_BAD_DATA;
6874c965db44STomer Tayar 
6875c965db44STomer Tayar 	/* Print global params */
6876c965db44STomer Tayar 	dump_buf += qed_print_section_params(dump_buf,
6877c965db44STomer Tayar 					     num_section_params,
6878c965db44STomer Tayar 					     results_buf, &results_offset);
6879c965db44STomer Tayar 
6880c965db44STomer Tayar 	/* Read igu_fifo_data section */
6881c965db44STomer Tayar 	dump_buf += qed_read_section_hdr(dump_buf,
6882c965db44STomer Tayar 					 &section_name, &num_section_params);
6883c965db44STomer Tayar 	if (strcmp(section_name, "igu_fifo_data"))
6884c965db44STomer Tayar 		return DBG_STATUS_IGU_FIFO_BAD_DATA;
6885c965db44STomer Tayar 	dump_buf += qed_read_param(dump_buf,
6886c965db44STomer Tayar 				   &param_name, &param_str_val, &param_num_val);
6887c965db44STomer Tayar 	if (strcmp(param_name, "size"))
6888c965db44STomer Tayar 		return DBG_STATUS_IGU_FIFO_BAD_DATA;
6889c965db44STomer Tayar 	if (param_num_val % IGU_FIFO_ELEMENT_DWORDS)
6890c965db44STomer Tayar 		return DBG_STATUS_IGU_FIFO_BAD_DATA;
6891c965db44STomer Tayar 	num_elements = param_num_val / IGU_FIFO_ELEMENT_DWORDS;
6892c965db44STomer Tayar 	elements = (struct igu_fifo_element *)dump_buf;
6893c965db44STomer Tayar 
6894c965db44STomer Tayar 	/* Decode elements */
6895c965db44STomer Tayar 	for (i = 0; i < num_elements; i++) {
68967b6859fbSMintz, Yuval 		status = qed_parse_igu_fifo_element(&elements[i],
68977b6859fbSMintz, Yuval 						    results_buf,
6898da090917STomer Tayar 						    &results_offset);
68997b6859fbSMintz, Yuval 		if (status != DBG_STATUS_OK)
69007b6859fbSMintz, Yuval 			return status;
6901c965db44STomer Tayar 	}
6902c965db44STomer Tayar 
6903c965db44STomer Tayar 	results_offset += sprintf(qed_get_buf_ptr(results_buf,
6904c965db44STomer Tayar 						  results_offset),
6905c965db44STomer Tayar 				  "fifo contained %d elements", num_elements);
6906c965db44STomer Tayar 
6907c965db44STomer Tayar 	/* Add 1 for string NULL termination */
6908c965db44STomer Tayar 	*parsed_results_bytes = results_offset + 1;
69097b6859fbSMintz, Yuval 
6910c965db44STomer Tayar 	return DBG_STATUS_OK;
6911c965db44STomer Tayar }
6912c965db44STomer Tayar 
6913c965db44STomer Tayar static enum dbg_status
6914da090917STomer Tayar qed_parse_protection_override_dump(u32 *dump_buf,
6915c965db44STomer Tayar 				   char *results_buf,
6916c965db44STomer Tayar 				   u32 *parsed_results_bytes)
6917c965db44STomer Tayar {
6918c965db44STomer Tayar 	const char *section_name, *param_name, *param_str_val;
69197b6859fbSMintz, Yuval 	u32 param_num_val, num_section_params, num_elements;
6920c965db44STomer Tayar 	struct protection_override_element *elements;
69217b6859fbSMintz, Yuval 	u32 results_offset = 0;
6922c965db44STomer Tayar 	u8 i;
6923c965db44STomer Tayar 
6924c965db44STomer Tayar 	/* Read global_params section */
6925c965db44STomer Tayar 	dump_buf += qed_read_section_hdr(dump_buf,
6926c965db44STomer Tayar 					 &section_name, &num_section_params);
6927c965db44STomer Tayar 	if (strcmp(section_name, "global_params"))
6928c965db44STomer Tayar 		return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
6929c965db44STomer Tayar 
6930c965db44STomer Tayar 	/* Print global params */
6931c965db44STomer Tayar 	dump_buf += qed_print_section_params(dump_buf,
6932c965db44STomer Tayar 					     num_section_params,
6933c965db44STomer Tayar 					     results_buf, &results_offset);
6934c965db44STomer Tayar 
6935c965db44STomer Tayar 	/* Read protection_override_data section */
6936c965db44STomer Tayar 	dump_buf += qed_read_section_hdr(dump_buf,
6937c965db44STomer Tayar 					 &section_name, &num_section_params);
6938c965db44STomer Tayar 	if (strcmp(section_name, "protection_override_data"))
6939c965db44STomer Tayar 		return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
6940c965db44STomer Tayar 	dump_buf += qed_read_param(dump_buf,
6941c965db44STomer Tayar 				   &param_name, &param_str_val, &param_num_val);
6942c965db44STomer Tayar 	if (strcmp(param_name, "size"))
6943c965db44STomer Tayar 		return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
69447b6859fbSMintz, Yuval 	if (param_num_val % PROTECTION_OVERRIDE_ELEMENT_DWORDS)
6945c965db44STomer Tayar 		return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
6946c965db44STomer Tayar 	num_elements = param_num_val / PROTECTION_OVERRIDE_ELEMENT_DWORDS;
6947c965db44STomer Tayar 	elements = (struct protection_override_element *)dump_buf;
6948c965db44STomer Tayar 
6949c965db44STomer Tayar 	/* Decode elements */
6950c965db44STomer Tayar 	for (i = 0; i < num_elements; i++) {
6951c965db44STomer Tayar 		u32 address = GET_FIELD(elements[i].data,
6952c965db44STomer Tayar 					PROTECTION_OVERRIDE_ELEMENT_ADDRESS) *
6953c965db44STomer Tayar 			      PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR;
6954c965db44STomer Tayar 
6955c965db44STomer Tayar 		results_offset +=
6956c965db44STomer Tayar 		    sprintf(qed_get_buf_ptr(results_buf,
6957c965db44STomer Tayar 					    results_offset),
6958be086e7cSMintz, Yuval 			    "window %2d, address: 0x%07x, size: %7d regs, read: %d, write: %d, read protection: %-12s, write protection: %-12s\n",
6959c965db44STomer Tayar 			    i, address,
6960be086e7cSMintz, Yuval 			    (u32)GET_FIELD(elements[i].data,
6961c965db44STomer Tayar 				      PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE),
6962be086e7cSMintz, Yuval 			    (u32)GET_FIELD(elements[i].data,
6963c965db44STomer Tayar 				      PROTECTION_OVERRIDE_ELEMENT_READ),
6964be086e7cSMintz, Yuval 			    (u32)GET_FIELD(elements[i].data,
6965c965db44STomer Tayar 				      PROTECTION_OVERRIDE_ELEMENT_WRITE),
6966c965db44STomer Tayar 			    s_protection_strs[GET_FIELD(elements[i].data,
6967c965db44STomer Tayar 				PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION)],
6968c965db44STomer Tayar 			    s_protection_strs[GET_FIELD(elements[i].data,
6969c965db44STomer Tayar 				PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION)]);
6970c965db44STomer Tayar 	}
6971c965db44STomer Tayar 
6972c965db44STomer Tayar 	results_offset += sprintf(qed_get_buf_ptr(results_buf,
6973c965db44STomer Tayar 						  results_offset),
6974c965db44STomer Tayar 				  "protection override contained %d elements",
6975c965db44STomer Tayar 				  num_elements);
6976c965db44STomer Tayar 
6977c965db44STomer Tayar 	/* Add 1 for string NULL termination */
6978c965db44STomer Tayar 	*parsed_results_bytes = results_offset + 1;
69797b6859fbSMintz, Yuval 
6980c965db44STomer Tayar 	return DBG_STATUS_OK;
6981c965db44STomer Tayar }
6982c965db44STomer Tayar 
69837b6859fbSMintz, Yuval /* Parses a FW Asserts dump buffer.
69847b6859fbSMintz, Yuval  * If result_buf is not NULL, the FW Asserts results are printed to it.
69857b6859fbSMintz, Yuval  * In any case, the required results buffer size is assigned to
69867b6859fbSMintz, Yuval  * parsed_results_bytes.
69877b6859fbSMintz, Yuval  * The parsing status is returned.
69887b6859fbSMintz, Yuval  */
6989da090917STomer Tayar static enum dbg_status qed_parse_fw_asserts_dump(u32 *dump_buf,
69907b6859fbSMintz, Yuval 						 char *results_buf,
69917b6859fbSMintz, Yuval 						 u32 *parsed_results_bytes)
69927b6859fbSMintz, Yuval {
69937b6859fbSMintz, Yuval 	u32 num_section_params, param_num_val, i, results_offset = 0;
69947b6859fbSMintz, Yuval 	const char *param_name, *param_str_val, *section_name;
69957b6859fbSMintz, Yuval 	bool last_section_found = false;
69967b6859fbSMintz, Yuval 
69977b6859fbSMintz, Yuval 	*parsed_results_bytes = 0;
69987b6859fbSMintz, Yuval 
69997b6859fbSMintz, Yuval 	/* Read global_params section */
70007b6859fbSMintz, Yuval 	dump_buf += qed_read_section_hdr(dump_buf,
70017b6859fbSMintz, Yuval 					 &section_name, &num_section_params);
70027b6859fbSMintz, Yuval 	if (strcmp(section_name, "global_params"))
70037b6859fbSMintz, Yuval 		return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
70047b6859fbSMintz, Yuval 
70057b6859fbSMintz, Yuval 	/* Print global params */
70067b6859fbSMintz, Yuval 	dump_buf += qed_print_section_params(dump_buf,
70077b6859fbSMintz, Yuval 					     num_section_params,
70087b6859fbSMintz, Yuval 					     results_buf, &results_offset);
70097b6859fbSMintz, Yuval 
70107b6859fbSMintz, Yuval 	while (!last_section_found) {
70117b6859fbSMintz, Yuval 		dump_buf += qed_read_section_hdr(dump_buf,
70127b6859fbSMintz, Yuval 						 &section_name,
70137b6859fbSMintz, Yuval 						 &num_section_params);
70147b6859fbSMintz, Yuval 		if (!strcmp(section_name, "fw_asserts")) {
70157b6859fbSMintz, Yuval 			/* Extract params */
70167b6859fbSMintz, Yuval 			const char *storm_letter = NULL;
70177b6859fbSMintz, Yuval 			u32 storm_dump_size = 0;
70187b6859fbSMintz, Yuval 
70197b6859fbSMintz, Yuval 			for (i = 0; i < num_section_params; i++) {
70207b6859fbSMintz, Yuval 				dump_buf += qed_read_param(dump_buf,
70217b6859fbSMintz, Yuval 							   &param_name,
70227b6859fbSMintz, Yuval 							   &param_str_val,
70237b6859fbSMintz, Yuval 							   &param_num_val);
70247b6859fbSMintz, Yuval 				if (!strcmp(param_name, "storm"))
70257b6859fbSMintz, Yuval 					storm_letter = param_str_val;
70267b6859fbSMintz, Yuval 				else if (!strcmp(param_name, "size"))
70277b6859fbSMintz, Yuval 					storm_dump_size = param_num_val;
70287b6859fbSMintz, Yuval 				else
70297b6859fbSMintz, Yuval 					return
70307b6859fbSMintz, Yuval 					    DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
70317b6859fbSMintz, Yuval 			}
70327b6859fbSMintz, Yuval 
70337b6859fbSMintz, Yuval 			if (!storm_letter || !storm_dump_size)
70347b6859fbSMintz, Yuval 				return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
70357b6859fbSMintz, Yuval 
70367b6859fbSMintz, Yuval 			/* Print data */
70377b6859fbSMintz, Yuval 			results_offset +=
70387b6859fbSMintz, Yuval 			    sprintf(qed_get_buf_ptr(results_buf,
70397b6859fbSMintz, Yuval 						    results_offset),
70407b6859fbSMintz, Yuval 				    "\n%sSTORM_ASSERT: size=%d\n",
70417b6859fbSMintz, Yuval 				    storm_letter, storm_dump_size);
70427b6859fbSMintz, Yuval 			for (i = 0; i < storm_dump_size; i++, dump_buf++)
70437b6859fbSMintz, Yuval 				results_offset +=
70447b6859fbSMintz, Yuval 				    sprintf(qed_get_buf_ptr(results_buf,
70457b6859fbSMintz, Yuval 							    results_offset),
70467b6859fbSMintz, Yuval 					    "%08x\n", *dump_buf);
70477b6859fbSMintz, Yuval 		} else if (!strcmp(section_name, "last")) {
70487b6859fbSMintz, Yuval 			last_section_found = true;
70497b6859fbSMintz, Yuval 		} else {
70507b6859fbSMintz, Yuval 			return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
70517b6859fbSMintz, Yuval 		}
70527b6859fbSMintz, Yuval 	}
70537b6859fbSMintz, Yuval 
70547b6859fbSMintz, Yuval 	/* Add 1 for string NULL termination */
70557b6859fbSMintz, Yuval 	*parsed_results_bytes = results_offset + 1;
70567b6859fbSMintz, Yuval 
70577b6859fbSMintz, Yuval 	return DBG_STATUS_OK;
70587b6859fbSMintz, Yuval }
70597b6859fbSMintz, Yuval 
70607b6859fbSMintz, Yuval /***************************** Public Functions *******************************/
70617b6859fbSMintz, Yuval 
70622d22bc83SMichal Kalderon enum dbg_status qed_dbg_user_set_bin_ptr(struct qed_hwfn *p_hwfn,
70632d22bc83SMichal Kalderon 					 const u8 * const bin_ptr)
70647b6859fbSMintz, Yuval {
70652d22bc83SMichal Kalderon 	struct bin_buffer_hdr *buf_hdrs = (struct bin_buffer_hdr *)bin_ptr;
70667b6859fbSMintz, Yuval 	u8 buf_id;
70677b6859fbSMintz, Yuval 
70687b6859fbSMintz, Yuval 	/* Convert binary data to debug arrays */
70692d22bc83SMichal Kalderon 	for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++)
70702d22bc83SMichal Kalderon 		qed_set_dbg_bin_buf(p_hwfn,
70712d22bc83SMichal Kalderon 				    (enum bin_dbg_buffer_type)buf_id,
70722d22bc83SMichal Kalderon 				    (u32 *)(bin_ptr + buf_hdrs[buf_id].offset),
70732d22bc83SMichal Kalderon 				    buf_hdrs[buf_id].length);
70747b6859fbSMintz, Yuval 
70757b6859fbSMintz, Yuval 	return DBG_STATUS_OK;
70767b6859fbSMintz, Yuval }
70777b6859fbSMintz, Yuval 
70782d22bc83SMichal Kalderon enum dbg_status qed_dbg_alloc_user_data(struct qed_hwfn *p_hwfn,
70792d22bc83SMichal Kalderon 					void **user_data_ptr)
7080a3f72307SDenis Bolotin {
70812d22bc83SMichal Kalderon 	*user_data_ptr = kzalloc(sizeof(struct dbg_tools_user_data),
7082a3f72307SDenis Bolotin 				 GFP_KERNEL);
70832d22bc83SMichal Kalderon 	if (!(*user_data_ptr))
7084a3f72307SDenis Bolotin 		return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
7085a3f72307SDenis Bolotin 
7086a3f72307SDenis Bolotin 	return DBG_STATUS_OK;
7087a3f72307SDenis Bolotin }
7088a3f72307SDenis Bolotin 
70897b6859fbSMintz, Yuval const char *qed_dbg_get_status_str(enum dbg_status status)
70907b6859fbSMintz, Yuval {
70917b6859fbSMintz, Yuval 	return (status <
70927b6859fbSMintz, Yuval 		MAX_DBG_STATUS) ? s_status_str[status] : "Invalid debug status";
70937b6859fbSMintz, Yuval }
70947b6859fbSMintz, Yuval 
70957b6859fbSMintz, Yuval enum dbg_status qed_get_idle_chk_results_buf_size(struct qed_hwfn *p_hwfn,
70967b6859fbSMintz, Yuval 						  u32 *dump_buf,
70977b6859fbSMintz, Yuval 						  u32 num_dumped_dwords,
70987b6859fbSMintz, Yuval 						  u32 *results_buf_size)
70997b6859fbSMintz, Yuval {
71007b6859fbSMintz, Yuval 	u32 num_errors, num_warnings;
71017b6859fbSMintz, Yuval 
71022d22bc83SMichal Kalderon 	return qed_parse_idle_chk_dump(p_hwfn,
71032d22bc83SMichal Kalderon 				       dump_buf,
71047b6859fbSMintz, Yuval 				       num_dumped_dwords,
71057b6859fbSMintz, Yuval 				       NULL,
71067b6859fbSMintz, Yuval 				       results_buf_size,
71077b6859fbSMintz, Yuval 				       &num_errors, &num_warnings);
71087b6859fbSMintz, Yuval }
71097b6859fbSMintz, Yuval 
71107b6859fbSMintz, Yuval enum dbg_status qed_print_idle_chk_results(struct qed_hwfn *p_hwfn,
71117b6859fbSMintz, Yuval 					   u32 *dump_buf,
71127b6859fbSMintz, Yuval 					   u32 num_dumped_dwords,
71137b6859fbSMintz, Yuval 					   char *results_buf,
7114da090917STomer Tayar 					   u32 *num_errors,
7115da090917STomer Tayar 					   u32 *num_warnings)
71167b6859fbSMintz, Yuval {
71177b6859fbSMintz, Yuval 	u32 parsed_buf_size;
71187b6859fbSMintz, Yuval 
71192d22bc83SMichal Kalderon 	return qed_parse_idle_chk_dump(p_hwfn,
71202d22bc83SMichal Kalderon 				       dump_buf,
71217b6859fbSMintz, Yuval 				       num_dumped_dwords,
71227b6859fbSMintz, Yuval 				       results_buf,
71237b6859fbSMintz, Yuval 				       &parsed_buf_size,
71247b6859fbSMintz, Yuval 				       num_errors, num_warnings);
71257b6859fbSMintz, Yuval }
71267b6859fbSMintz, Yuval 
7127a3f72307SDenis Bolotin void qed_dbg_mcp_trace_set_meta_data(struct qed_hwfn *p_hwfn,
7128a3f72307SDenis Bolotin 				     const u32 *meta_buf)
71297b6859fbSMintz, Yuval {
7130a3f72307SDenis Bolotin 	struct dbg_tools_user_data *dev_user_data =
7131a3f72307SDenis Bolotin 		qed_dbg_get_user_data(p_hwfn);
7132a3f72307SDenis Bolotin 
7133a3f72307SDenis Bolotin 	dev_user_data->mcp_trace_user_meta_buf = meta_buf;
71347b6859fbSMintz, Yuval }
71357b6859fbSMintz, Yuval 
71367b6859fbSMintz, Yuval enum dbg_status qed_get_mcp_trace_results_buf_size(struct qed_hwfn *p_hwfn,
71377b6859fbSMintz, Yuval 						   u32 *dump_buf,
71387b6859fbSMintz, Yuval 						   u32 num_dumped_dwords,
71397b6859fbSMintz, Yuval 						   u32 *results_buf_size)
71407b6859fbSMintz, Yuval {
71417b6859fbSMintz, Yuval 	return qed_parse_mcp_trace_dump(p_hwfn,
7142a3f72307SDenis Bolotin 					dump_buf, NULL, results_buf_size, true);
71437b6859fbSMintz, Yuval }
71447b6859fbSMintz, Yuval 
71457b6859fbSMintz, Yuval enum dbg_status qed_print_mcp_trace_results(struct qed_hwfn *p_hwfn,
71467b6859fbSMintz, Yuval 					    u32 *dump_buf,
71477b6859fbSMintz, Yuval 					    u32 num_dumped_dwords,
71487b6859fbSMintz, Yuval 					    char *results_buf)
71497b6859fbSMintz, Yuval {
71507b6859fbSMintz, Yuval 	u32 parsed_buf_size;
71517b6859fbSMintz, Yuval 
71527b6859fbSMintz, Yuval 	return qed_parse_mcp_trace_dump(p_hwfn,
71537b6859fbSMintz, Yuval 					dump_buf,
7154a3f72307SDenis Bolotin 					results_buf, &parsed_buf_size, true);
71557b6859fbSMintz, Yuval }
71567b6859fbSMintz, Yuval 
7157a3f72307SDenis Bolotin enum dbg_status qed_print_mcp_trace_results_cont(struct qed_hwfn *p_hwfn,
7158a3f72307SDenis Bolotin 						 u32 *dump_buf,
7159a3f72307SDenis Bolotin 						 char *results_buf)
7160a3f72307SDenis Bolotin {
7161a3f72307SDenis Bolotin 	u32 parsed_buf_size;
7162a3f72307SDenis Bolotin 
7163a3f72307SDenis Bolotin 	return qed_parse_mcp_trace_dump(p_hwfn, dump_buf, results_buf,
7164a3f72307SDenis Bolotin 					&parsed_buf_size, false);
7165a3f72307SDenis Bolotin }
7166a3f72307SDenis Bolotin 
7167a3f72307SDenis Bolotin enum dbg_status qed_print_mcp_trace_line(struct qed_hwfn *p_hwfn,
7168a3f72307SDenis Bolotin 					 u8 *dump_buf,
716950bc60cbSMichal Kalderon 					 u32 num_dumped_bytes,
717050bc60cbSMichal Kalderon 					 char *results_buf)
717150bc60cbSMichal Kalderon {
7172a3f72307SDenis Bolotin 	u32 parsed_results_bytes;
717350bc60cbSMichal Kalderon 
7174a3f72307SDenis Bolotin 	return qed_parse_mcp_trace_buf(p_hwfn,
7175a3f72307SDenis Bolotin 				       dump_buf,
717650bc60cbSMichal Kalderon 				       num_dumped_bytes,
717750bc60cbSMichal Kalderon 				       0,
717850bc60cbSMichal Kalderon 				       num_dumped_bytes,
7179a3f72307SDenis Bolotin 				       results_buf, &parsed_results_bytes);
7180a3f72307SDenis Bolotin }
7181a3f72307SDenis Bolotin 
7182a3f72307SDenis Bolotin /* Frees the specified MCP Trace meta data */
7183a3f72307SDenis Bolotin void qed_mcp_trace_free_meta_data(struct qed_hwfn *p_hwfn)
7184a3f72307SDenis Bolotin {
7185a3f72307SDenis Bolotin 	struct dbg_tools_user_data *dev_user_data;
7186a3f72307SDenis Bolotin 	struct mcp_trace_meta *meta;
7187a3f72307SDenis Bolotin 	u32 i;
7188a3f72307SDenis Bolotin 
7189a3f72307SDenis Bolotin 	dev_user_data = qed_dbg_get_user_data(p_hwfn);
7190a3f72307SDenis Bolotin 	meta = &dev_user_data->mcp_trace_meta;
7191a3f72307SDenis Bolotin 	if (!meta->is_allocated)
7192a3f72307SDenis Bolotin 		return;
7193a3f72307SDenis Bolotin 
7194a3f72307SDenis Bolotin 	/* Release modules */
7195a3f72307SDenis Bolotin 	if (meta->modules) {
7196a3f72307SDenis Bolotin 		for (i = 0; i < meta->modules_num; i++)
7197a3f72307SDenis Bolotin 			kfree(meta->modules[i]);
7198a3f72307SDenis Bolotin 		kfree(meta->modules);
7199a3f72307SDenis Bolotin 	}
7200a3f72307SDenis Bolotin 
7201a3f72307SDenis Bolotin 	/* Release formats */
7202a3f72307SDenis Bolotin 	if (meta->formats) {
7203a3f72307SDenis Bolotin 		for (i = 0; i < meta->formats_num; i++)
7204a3f72307SDenis Bolotin 			kfree(meta->formats[i].format_str);
7205a3f72307SDenis Bolotin 		kfree(meta->formats);
7206a3f72307SDenis Bolotin 	}
7207a3f72307SDenis Bolotin 
7208a3f72307SDenis Bolotin 	meta->is_allocated = false;
720950bc60cbSMichal Kalderon }
721050bc60cbSMichal Kalderon 
72117b6859fbSMintz, Yuval enum dbg_status qed_get_reg_fifo_results_buf_size(struct qed_hwfn *p_hwfn,
72127b6859fbSMintz, Yuval 						  u32 *dump_buf,
72137b6859fbSMintz, Yuval 						  u32 num_dumped_dwords,
72147b6859fbSMintz, Yuval 						  u32 *results_buf_size)
72157b6859fbSMintz, Yuval {
7216da090917STomer Tayar 	return qed_parse_reg_fifo_dump(dump_buf, NULL, results_buf_size);
72177b6859fbSMintz, Yuval }
72187b6859fbSMintz, Yuval 
72197b6859fbSMintz, Yuval enum dbg_status qed_print_reg_fifo_results(struct qed_hwfn *p_hwfn,
72207b6859fbSMintz, Yuval 					   u32 *dump_buf,
72217b6859fbSMintz, Yuval 					   u32 num_dumped_dwords,
72227b6859fbSMintz, Yuval 					   char *results_buf)
72237b6859fbSMintz, Yuval {
72247b6859fbSMintz, Yuval 	u32 parsed_buf_size;
72257b6859fbSMintz, Yuval 
7226da090917STomer Tayar 	return qed_parse_reg_fifo_dump(dump_buf, results_buf, &parsed_buf_size);
72277b6859fbSMintz, Yuval }
72287b6859fbSMintz, Yuval 
72297b6859fbSMintz, Yuval enum dbg_status qed_get_igu_fifo_results_buf_size(struct qed_hwfn *p_hwfn,
72307b6859fbSMintz, Yuval 						  u32 *dump_buf,
72317b6859fbSMintz, Yuval 						  u32 num_dumped_dwords,
72327b6859fbSMintz, Yuval 						  u32 *results_buf_size)
72337b6859fbSMintz, Yuval {
7234da090917STomer Tayar 	return qed_parse_igu_fifo_dump(dump_buf, NULL, results_buf_size);
72357b6859fbSMintz, Yuval }
72367b6859fbSMintz, Yuval 
72377b6859fbSMintz, Yuval enum dbg_status qed_print_igu_fifo_results(struct qed_hwfn *p_hwfn,
72387b6859fbSMintz, Yuval 					   u32 *dump_buf,
72397b6859fbSMintz, Yuval 					   u32 num_dumped_dwords,
72407b6859fbSMintz, Yuval 					   char *results_buf)
72417b6859fbSMintz, Yuval {
72427b6859fbSMintz, Yuval 	u32 parsed_buf_size;
72437b6859fbSMintz, Yuval 
7244da090917STomer Tayar 	return qed_parse_igu_fifo_dump(dump_buf, results_buf, &parsed_buf_size);
72457b6859fbSMintz, Yuval }
72467b6859fbSMintz, Yuval 
7247c965db44STomer Tayar enum dbg_status
7248c965db44STomer Tayar qed_get_protection_override_results_buf_size(struct qed_hwfn *p_hwfn,
7249c965db44STomer Tayar 					     u32 *dump_buf,
7250c965db44STomer Tayar 					     u32 num_dumped_dwords,
7251c965db44STomer Tayar 					     u32 *results_buf_size)
7252c965db44STomer Tayar {
7253da090917STomer Tayar 	return qed_parse_protection_override_dump(dump_buf,
7254c965db44STomer Tayar 						  NULL, results_buf_size);
7255c965db44STomer Tayar }
7256c965db44STomer Tayar 
7257c965db44STomer Tayar enum dbg_status qed_print_protection_override_results(struct qed_hwfn *p_hwfn,
7258c965db44STomer Tayar 						      u32 *dump_buf,
7259c965db44STomer Tayar 						      u32 num_dumped_dwords,
7260c965db44STomer Tayar 						      char *results_buf)
7261c965db44STomer Tayar {
7262c965db44STomer Tayar 	u32 parsed_buf_size;
7263c965db44STomer Tayar 
7264da090917STomer Tayar 	return qed_parse_protection_override_dump(dump_buf,
7265c965db44STomer Tayar 						  results_buf,
7266c965db44STomer Tayar 						  &parsed_buf_size);
7267c965db44STomer Tayar }
7268c965db44STomer Tayar 
7269c965db44STomer Tayar enum dbg_status qed_get_fw_asserts_results_buf_size(struct qed_hwfn *p_hwfn,
7270c965db44STomer Tayar 						    u32 *dump_buf,
7271c965db44STomer Tayar 						    u32 num_dumped_dwords,
7272c965db44STomer Tayar 						    u32 *results_buf_size)
7273c965db44STomer Tayar {
7274da090917STomer Tayar 	return qed_parse_fw_asserts_dump(dump_buf, NULL, results_buf_size);
7275c965db44STomer Tayar }
7276c965db44STomer Tayar 
7277c965db44STomer Tayar enum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn,
7278c965db44STomer Tayar 					     u32 *dump_buf,
7279c965db44STomer Tayar 					     u32 num_dumped_dwords,
7280c965db44STomer Tayar 					     char *results_buf)
7281c965db44STomer Tayar {
7282c965db44STomer Tayar 	u32 parsed_buf_size;
7283c965db44STomer Tayar 
7284da090917STomer Tayar 	return qed_parse_fw_asserts_dump(dump_buf,
7285c965db44STomer Tayar 					 results_buf, &parsed_buf_size);
7286c965db44STomer Tayar }
7287c965db44STomer Tayar 
72880ebbd1c8SMintz, Yuval enum dbg_status qed_dbg_parse_attn(struct qed_hwfn *p_hwfn,
72890ebbd1c8SMintz, Yuval 				   struct dbg_attn_block_result *results)
72900ebbd1c8SMintz, Yuval {
72910ebbd1c8SMintz, Yuval 	const u32 *block_attn_name_offsets;
72922d22bc83SMichal Kalderon 	const char *attn_name_base;
72930ebbd1c8SMintz, Yuval 	const char *block_name;
72942d22bc83SMichal Kalderon 	enum dbg_attn_type attn_type;
72950ebbd1c8SMintz, Yuval 	u8 num_regs, i, j;
72960ebbd1c8SMintz, Yuval 
72970ebbd1c8SMintz, Yuval 	num_regs = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_NUM_REGS);
72982d22bc83SMichal Kalderon 	attn_type = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE);
72992d22bc83SMichal Kalderon 	block_name = qed_dbg_get_block_name(p_hwfn, results->block_id);
73002d22bc83SMichal Kalderon 	if (!block_name)
73012d22bc83SMichal Kalderon 		return DBG_STATUS_INVALID_ARGS;
73020ebbd1c8SMintz, Yuval 
73032d22bc83SMichal Kalderon 	if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr ||
73042d22bc83SMichal Kalderon 	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr ||
73052d22bc83SMichal Kalderon 	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr)
73060ebbd1c8SMintz, Yuval 		return DBG_STATUS_DBG_ARRAY_NOT_SET;
73070ebbd1c8SMintz, Yuval 
73082d22bc83SMichal Kalderon 	block_attn_name_offsets =
73092d22bc83SMichal Kalderon 	    (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr +
73102d22bc83SMichal Kalderon 	    results->names_offset;
73112d22bc83SMichal Kalderon 
73122d22bc83SMichal Kalderon 	attn_name_base = p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr;
73130ebbd1c8SMintz, Yuval 
73140ebbd1c8SMintz, Yuval 	/* Go over registers with a non-zero attention status */
73150ebbd1c8SMintz, Yuval 	for (i = 0; i < num_regs; i++) {
7316da090917STomer Tayar 		struct dbg_attn_bit_mapping *bit_mapping;
73170ebbd1c8SMintz, Yuval 		struct dbg_attn_reg_result *reg_result;
73180ebbd1c8SMintz, Yuval 		u8 num_reg_attn, bit_idx = 0;
73190ebbd1c8SMintz, Yuval 
73200ebbd1c8SMintz, Yuval 		reg_result = &results->reg_results[i];
73210ebbd1c8SMintz, Yuval 		num_reg_attn = GET_FIELD(reg_result->data,
73220ebbd1c8SMintz, Yuval 					 DBG_ATTN_REG_RESULT_NUM_REG_ATTN);
73232d22bc83SMichal Kalderon 		bit_mapping = (struct dbg_attn_bit_mapping *)
73242d22bc83SMichal Kalderon 		    p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr +
73252d22bc83SMichal Kalderon 		    reg_result->block_attn_offset;
73260ebbd1c8SMintz, Yuval 
73270ebbd1c8SMintz, Yuval 		/* Go over attention status bits */
73282d22bc83SMichal Kalderon 		for (j = 0; j < num_reg_attn; j++, bit_idx++) {
7329da090917STomer Tayar 			u16 attn_idx_val = GET_FIELD(bit_mapping[j].data,
73300ebbd1c8SMintz, Yuval 						     DBG_ATTN_BIT_MAPPING_VAL);
73310ebbd1c8SMintz, Yuval 			const char *attn_name, *attn_type_str, *masked_str;
73322d22bc83SMichal Kalderon 			u32 attn_name_offset;
73332d22bc83SMichal Kalderon 			u32 sts_addr;
73340ebbd1c8SMintz, Yuval 
73350ebbd1c8SMintz, Yuval 			/* Check if bit mask should be advanced (due to unused
73360ebbd1c8SMintz, Yuval 			 * bits).
73370ebbd1c8SMintz, Yuval 			 */
7338da090917STomer Tayar 			if (GET_FIELD(bit_mapping[j].data,
73390ebbd1c8SMintz, Yuval 				      DBG_ATTN_BIT_MAPPING_IS_UNUSED_BIT_CNT)) {
73400ebbd1c8SMintz, Yuval 				bit_idx += (u8)attn_idx_val;
73410ebbd1c8SMintz, Yuval 				continue;
73420ebbd1c8SMintz, Yuval 			}
73430ebbd1c8SMintz, Yuval 
73440ebbd1c8SMintz, Yuval 			/* Check current bit index */
73452d22bc83SMichal Kalderon 			if (!(reg_result->sts_val & BIT(bit_idx)))
73460ebbd1c8SMintz, Yuval 				continue;
73470ebbd1c8SMintz, Yuval 
73482d22bc83SMichal Kalderon 			/* An attention bit with value=1 was found
73492d22bc83SMichal Kalderon 			 * Find attention name
73502d22bc83SMichal Kalderon 			 */
7351da090917STomer Tayar 			attn_name_offset =
7352da090917STomer Tayar 				block_attn_name_offsets[attn_idx_val];
73532d22bc83SMichal Kalderon 			attn_name = attn_name_base + attn_name_offset;
73542d22bc83SMichal Kalderon 			attn_type_str =
73552d22bc83SMichal Kalderon 				(attn_type ==
73562d22bc83SMichal Kalderon 				 ATTN_TYPE_INTERRUPT ? "Interrupt" :
73572d22bc83SMichal Kalderon 				 "Parity");
73580ebbd1c8SMintz, Yuval 			masked_str = reg_result->mask_val & BIT(bit_idx) ?
73590ebbd1c8SMintz, Yuval 				     " [masked]" : "";
73600ebbd1c8SMintz, Yuval 			sts_addr = GET_FIELD(reg_result->data,
73610ebbd1c8SMintz, Yuval 					     DBG_ATTN_REG_RESULT_STS_ADDRESS);
73620ebbd1c8SMintz, Yuval 			DP_NOTICE(p_hwfn,
73630ebbd1c8SMintz, Yuval 				  "%s (%s) : %s [address 0x%08x, bit %d]%s\n",
73640ebbd1c8SMintz, Yuval 				  block_name, attn_type_str, attn_name,
73652d22bc83SMichal Kalderon 				  sts_addr * 4, bit_idx, masked_str);
73660ebbd1c8SMintz, Yuval 		}
73670ebbd1c8SMintz, Yuval 	}
73680ebbd1c8SMintz, Yuval 
73690ebbd1c8SMintz, Yuval 	return DBG_STATUS_OK;
73700ebbd1c8SMintz, Yuval }
73710ebbd1c8SMintz, Yuval 
73722d22bc83SMichal Kalderon static DEFINE_MUTEX(qed_dbg_lock);
73732d22bc83SMichal Kalderon 
7374c965db44STomer Tayar /* Wrapper for unifying the idle_chk and mcp_trace api */
73758c93beafSYuval Mintz static enum dbg_status
73768c93beafSYuval Mintz qed_print_idle_chk_results_wrapper(struct qed_hwfn *p_hwfn,
7377c965db44STomer Tayar 				   u32 *dump_buf,
7378c965db44STomer Tayar 				   u32 num_dumped_dwords,
7379c965db44STomer Tayar 				   char *results_buf)
7380c965db44STomer Tayar {
7381c965db44STomer Tayar 	u32 num_errors, num_warnnings;
7382c965db44STomer Tayar 
7383c965db44STomer Tayar 	return qed_print_idle_chk_results(p_hwfn, dump_buf, num_dumped_dwords,
7384c965db44STomer Tayar 					  results_buf, &num_errors,
7385c965db44STomer Tayar 					  &num_warnnings);
7386c965db44STomer Tayar }
7387c965db44STomer Tayar 
7388c965db44STomer Tayar /* Feature meta data lookup table */
7389c965db44STomer Tayar static struct {
7390c965db44STomer Tayar 	char *name;
7391c965db44STomer Tayar 	enum dbg_status (*get_size)(struct qed_hwfn *p_hwfn,
7392c965db44STomer Tayar 				    struct qed_ptt *p_ptt, u32 *size);
7393c965db44STomer Tayar 	enum dbg_status (*perform_dump)(struct qed_hwfn *p_hwfn,
7394c965db44STomer Tayar 					struct qed_ptt *p_ptt, u32 *dump_buf,
7395c965db44STomer Tayar 					u32 buf_size, u32 *dumped_dwords);
7396c965db44STomer Tayar 	enum dbg_status (*print_results)(struct qed_hwfn *p_hwfn,
7397c965db44STomer Tayar 					 u32 *dump_buf, u32 num_dumped_dwords,
7398c965db44STomer Tayar 					 char *results_buf);
7399c965db44STomer Tayar 	enum dbg_status (*results_buf_size)(struct qed_hwfn *p_hwfn,
7400c965db44STomer Tayar 					    u32 *dump_buf,
7401c965db44STomer Tayar 					    u32 num_dumped_dwords,
7402c965db44STomer Tayar 					    u32 *results_buf_size);
7403c965db44STomer Tayar } qed_features_lookup[] = {
7404c965db44STomer Tayar 	{
7405c965db44STomer Tayar 	"grc", qed_dbg_grc_get_dump_buf_size,
7406c965db44STomer Tayar 		    qed_dbg_grc_dump, NULL, NULL}, {
7407c965db44STomer Tayar 	"idle_chk",
7408c965db44STomer Tayar 		    qed_dbg_idle_chk_get_dump_buf_size,
7409c965db44STomer Tayar 		    qed_dbg_idle_chk_dump,
7410c965db44STomer Tayar 		    qed_print_idle_chk_results_wrapper,
7411c965db44STomer Tayar 		    qed_get_idle_chk_results_buf_size}, {
7412c965db44STomer Tayar 	"mcp_trace",
7413c965db44STomer Tayar 		    qed_dbg_mcp_trace_get_dump_buf_size,
7414c965db44STomer Tayar 		    qed_dbg_mcp_trace_dump, qed_print_mcp_trace_results,
7415c965db44STomer Tayar 		    qed_get_mcp_trace_results_buf_size}, {
7416c965db44STomer Tayar 	"reg_fifo",
7417c965db44STomer Tayar 		    qed_dbg_reg_fifo_get_dump_buf_size,
7418c965db44STomer Tayar 		    qed_dbg_reg_fifo_dump, qed_print_reg_fifo_results,
7419c965db44STomer Tayar 		    qed_get_reg_fifo_results_buf_size}, {
7420c965db44STomer Tayar 	"igu_fifo",
7421c965db44STomer Tayar 		    qed_dbg_igu_fifo_get_dump_buf_size,
7422c965db44STomer Tayar 		    qed_dbg_igu_fifo_dump, qed_print_igu_fifo_results,
7423c965db44STomer Tayar 		    qed_get_igu_fifo_results_buf_size}, {
7424c965db44STomer Tayar 	"protection_override",
7425c965db44STomer Tayar 		    qed_dbg_protection_override_get_dump_buf_size,
7426c965db44STomer Tayar 		    qed_dbg_protection_override_dump,
7427c965db44STomer Tayar 		    qed_print_protection_override_results,
7428c965db44STomer Tayar 		    qed_get_protection_override_results_buf_size}, {
7429c965db44STomer Tayar 	"fw_asserts",
7430c965db44STomer Tayar 		    qed_dbg_fw_asserts_get_dump_buf_size,
7431c965db44STomer Tayar 		    qed_dbg_fw_asserts_dump,
7432c965db44STomer Tayar 		    qed_print_fw_asserts_results,
74338a52bbabSMichal Kalderon 		    qed_get_fw_asserts_results_buf_size}, {
74348a52bbabSMichal Kalderon 	"ilt",
74358a52bbabSMichal Kalderon 		    qed_dbg_ilt_get_dump_buf_size,
74368a52bbabSMichal Kalderon 		    qed_dbg_ilt_dump, NULL, NULL},};
7437c965db44STomer Tayar 
7438c965db44STomer Tayar static void qed_dbg_print_feature(u8 *p_text_buf, u32 text_size)
7439c965db44STomer Tayar {
7440c965db44STomer Tayar 	u32 i, precision = 80;
7441c965db44STomer Tayar 
7442c965db44STomer Tayar 	if (!p_text_buf)
7443c965db44STomer Tayar 		return;
7444c965db44STomer Tayar 
7445c965db44STomer Tayar 	pr_notice("\n%.*s", precision, p_text_buf);
7446c965db44STomer Tayar 	for (i = precision; i < text_size; i += precision)
7447c965db44STomer Tayar 		pr_cont("%.*s", precision, p_text_buf + i);
7448c965db44STomer Tayar 	pr_cont("\n");
7449c965db44STomer Tayar }
7450c965db44STomer Tayar 
7451c965db44STomer Tayar #define QED_RESULTS_BUF_MIN_SIZE 16
7452c965db44STomer Tayar /* Generic function for decoding debug feature info */
74538c93beafSYuval Mintz static enum dbg_status format_feature(struct qed_hwfn *p_hwfn,
7454c965db44STomer Tayar 				      enum qed_dbg_features feature_idx)
7455c965db44STomer Tayar {
7456c965db44STomer Tayar 	struct qed_dbg_feature *feature =
7457ca352f00SIgor Russkikh 	    &p_hwfn->cdev->dbg_features[feature_idx];
7458c965db44STomer Tayar 	u32 text_size_bytes, null_char_pos, i;
7459c965db44STomer Tayar 	enum dbg_status rc;
7460c965db44STomer Tayar 	char *text_buf;
7461c965db44STomer Tayar 
7462c965db44STomer Tayar 	/* Check if feature supports formatting capability */
7463c965db44STomer Tayar 	if (!qed_features_lookup[feature_idx].results_buf_size)
7464c965db44STomer Tayar 		return DBG_STATUS_OK;
7465c965db44STomer Tayar 
7466c965db44STomer Tayar 	/* Obtain size of formatted output */
7467c965db44STomer Tayar 	rc = qed_features_lookup[feature_idx].
7468c965db44STomer Tayar 		results_buf_size(p_hwfn, (u32 *)feature->dump_buf,
7469c965db44STomer Tayar 				 feature->dumped_dwords, &text_size_bytes);
7470c965db44STomer Tayar 	if (rc != DBG_STATUS_OK)
7471c965db44STomer Tayar 		return rc;
7472c965db44STomer Tayar 
7473c965db44STomer Tayar 	/* Make sure that the allocated size is a multiple of dword (4 bytes) */
7474c965db44STomer Tayar 	null_char_pos = text_size_bytes - 1;
7475c965db44STomer Tayar 	text_size_bytes = (text_size_bytes + 3) & ~0x3;
7476c965db44STomer Tayar 
7477c965db44STomer Tayar 	if (text_size_bytes < QED_RESULTS_BUF_MIN_SIZE) {
7478c965db44STomer Tayar 		DP_NOTICE(p_hwfn->cdev,
7479c965db44STomer Tayar 			  "formatted size of feature was too small %d. Aborting\n",
7480c965db44STomer Tayar 			  text_size_bytes);
7481c965db44STomer Tayar 		return DBG_STATUS_INVALID_ARGS;
7482c965db44STomer Tayar 	}
7483c965db44STomer Tayar 
7484c965db44STomer Tayar 	/* Allocate temp text buf */
7485c965db44STomer Tayar 	text_buf = vzalloc(text_size_bytes);
7486c965db44STomer Tayar 	if (!text_buf)
7487c965db44STomer Tayar 		return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
7488c965db44STomer Tayar 
7489c965db44STomer Tayar 	/* Decode feature opcodes to string on temp buf */
7490c965db44STomer Tayar 	rc = qed_features_lookup[feature_idx].
7491c965db44STomer Tayar 		print_results(p_hwfn, (u32 *)feature->dump_buf,
7492c965db44STomer Tayar 			      feature->dumped_dwords, text_buf);
7493c965db44STomer Tayar 	if (rc != DBG_STATUS_OK) {
7494c965db44STomer Tayar 		vfree(text_buf);
7495c965db44STomer Tayar 		return rc;
7496c965db44STomer Tayar 	}
7497c965db44STomer Tayar 
7498c965db44STomer Tayar 	/* Replace the original null character with a '\n' character.
7499c965db44STomer Tayar 	 * The bytes that were added as a result of the dword alignment are also
7500c965db44STomer Tayar 	 * padded with '\n' characters.
7501c965db44STomer Tayar 	 */
7502c965db44STomer Tayar 	for (i = null_char_pos; i < text_size_bytes; i++)
7503c965db44STomer Tayar 		text_buf[i] = '\n';
7504c965db44STomer Tayar 
7505c965db44STomer Tayar 	/* Dump printable feature to log */
7506ca352f00SIgor Russkikh 	if (p_hwfn->cdev->print_dbg_data)
7507c965db44STomer Tayar 		qed_dbg_print_feature(text_buf, text_size_bytes);
7508c965db44STomer Tayar 
7509c965db44STomer Tayar 	/* Free the old dump_buf and point the dump_buf to the newly allocagted
7510c965db44STomer Tayar 	 * and formatted text buffer.
7511c965db44STomer Tayar 	 */
7512c965db44STomer Tayar 	vfree(feature->dump_buf);
7513c965db44STomer Tayar 	feature->dump_buf = text_buf;
7514c965db44STomer Tayar 	feature->buf_size = text_size_bytes;
7515c965db44STomer Tayar 	feature->dumped_dwords = text_size_bytes / 4;
7516c965db44STomer Tayar 	return rc;
7517c965db44STomer Tayar }
7518c965db44STomer Tayar 
75198a52bbabSMichal Kalderon #define MAX_DBG_FEATURE_SIZE_DWORDS	0x3FFFFFFF
75208a52bbabSMichal Kalderon 
7521c965db44STomer Tayar /* Generic function for performing the dump of a debug feature. */
75228c93beafSYuval Mintz static enum dbg_status qed_dbg_dump(struct qed_hwfn *p_hwfn,
75238c93beafSYuval Mintz 				    struct qed_ptt *p_ptt,
7524c965db44STomer Tayar 				    enum qed_dbg_features feature_idx)
7525c965db44STomer Tayar {
7526c965db44STomer Tayar 	struct qed_dbg_feature *feature =
7527ca352f00SIgor Russkikh 	    &p_hwfn->cdev->dbg_features[feature_idx];
7528c965db44STomer Tayar 	u32 buf_size_dwords;
7529c965db44STomer Tayar 	enum dbg_status rc;
7530c965db44STomer Tayar 
7531c965db44STomer Tayar 	DP_NOTICE(p_hwfn->cdev, "Collecting a debug feature [\"%s\"]\n",
7532c965db44STomer Tayar 		  qed_features_lookup[feature_idx].name);
7533c965db44STomer Tayar 
7534c965db44STomer Tayar 	/* Dump_buf was already allocated need to free (this can happen if dump
7535c965db44STomer Tayar 	 * was called but file was never read).
7536c965db44STomer Tayar 	 * We can't use the buffer as is since size may have changed.
7537c965db44STomer Tayar 	 */
7538c965db44STomer Tayar 	if (feature->dump_buf) {
7539c965db44STomer Tayar 		vfree(feature->dump_buf);
7540c965db44STomer Tayar 		feature->dump_buf = NULL;
7541c965db44STomer Tayar 	}
7542c965db44STomer Tayar 
7543c965db44STomer Tayar 	/* Get buffer size from hsi, allocate accordingly, and perform the
7544c965db44STomer Tayar 	 * dump.
7545c965db44STomer Tayar 	 */
7546c965db44STomer Tayar 	rc = qed_features_lookup[feature_idx].get_size(p_hwfn, p_ptt,
7547c965db44STomer Tayar 						       &buf_size_dwords);
7548be086e7cSMintz, Yuval 	if (rc != DBG_STATUS_OK && rc != DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
7549c965db44STomer Tayar 		return rc;
75502d22bc83SMichal Kalderon 
75512d22bc83SMichal Kalderon 	if (buf_size_dwords > MAX_DBG_FEATURE_SIZE_DWORDS) {
75522d22bc83SMichal Kalderon 		feature->buf_size = 0;
75532d22bc83SMichal Kalderon 		DP_NOTICE(p_hwfn->cdev,
75542d22bc83SMichal Kalderon 			  "Debug feature [\"%s\"] size (0x%x dwords) exceeds maximum size (0x%x dwords)\n",
75552d22bc83SMichal Kalderon 			  qed_features_lookup[feature_idx].name,
75562d22bc83SMichal Kalderon 			  buf_size_dwords, MAX_DBG_FEATURE_SIZE_DWORDS);
75572d22bc83SMichal Kalderon 
75582d22bc83SMichal Kalderon 		return DBG_STATUS_OK;
75592d22bc83SMichal Kalderon 	}
75602d22bc83SMichal Kalderon 
7561c965db44STomer Tayar 	feature->buf_size = buf_size_dwords * sizeof(u32);
7562c965db44STomer Tayar 	feature->dump_buf = vmalloc(feature->buf_size);
7563c965db44STomer Tayar 	if (!feature->dump_buf)
7564c965db44STomer Tayar 		return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
7565c965db44STomer Tayar 
7566c965db44STomer Tayar 	rc = qed_features_lookup[feature_idx].
7567c965db44STomer Tayar 		perform_dump(p_hwfn, p_ptt, (u32 *)feature->dump_buf,
7568c965db44STomer Tayar 			     feature->buf_size / sizeof(u32),
7569c965db44STomer Tayar 			     &feature->dumped_dwords);
7570c965db44STomer Tayar 
7571c965db44STomer Tayar 	/* If mcp is stuck we get DBG_STATUS_NVRAM_GET_IMAGE_FAILED error.
7572c965db44STomer Tayar 	 * In this case the buffer holds valid binary data, but we wont able
7573c965db44STomer Tayar 	 * to parse it (since parsing relies on data in NVRAM which is only
7574c965db44STomer Tayar 	 * accessible when MFW is responsive). skip the formatting but return
7575c965db44STomer Tayar 	 * success so that binary data is provided.
7576c965db44STomer Tayar 	 */
7577c965db44STomer Tayar 	if (rc == DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
7578c965db44STomer Tayar 		return DBG_STATUS_OK;
7579c965db44STomer Tayar 
7580c965db44STomer Tayar 	if (rc != DBG_STATUS_OK)
7581c965db44STomer Tayar 		return rc;
7582c965db44STomer Tayar 
7583c965db44STomer Tayar 	/* Format output */
7584c965db44STomer Tayar 	rc = format_feature(p_hwfn, feature_idx);
7585c965db44STomer Tayar 	return rc;
7586c965db44STomer Tayar }
7587c965db44STomer Tayar 
7588c965db44STomer Tayar int qed_dbg_grc(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
7589c965db44STomer Tayar {
7590c965db44STomer Tayar 	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_GRC, num_dumped_bytes);
7591c965db44STomer Tayar }
7592c965db44STomer Tayar 
7593c965db44STomer Tayar int qed_dbg_grc_size(struct qed_dev *cdev)
7594c965db44STomer Tayar {
7595c965db44STomer Tayar 	return qed_dbg_feature_size(cdev, DBG_FEATURE_GRC);
7596c965db44STomer Tayar }
7597c965db44STomer Tayar 
7598c965db44STomer Tayar int qed_dbg_idle_chk(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
7599c965db44STomer Tayar {
7600c965db44STomer Tayar 	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IDLE_CHK,
7601c965db44STomer Tayar 			       num_dumped_bytes);
7602c965db44STomer Tayar }
7603c965db44STomer Tayar 
7604c965db44STomer Tayar int qed_dbg_idle_chk_size(struct qed_dev *cdev)
7605c965db44STomer Tayar {
7606c965db44STomer Tayar 	return qed_dbg_feature_size(cdev, DBG_FEATURE_IDLE_CHK);
7607c965db44STomer Tayar }
7608c965db44STomer Tayar 
7609c965db44STomer Tayar int qed_dbg_reg_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
7610c965db44STomer Tayar {
7611c965db44STomer Tayar 	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_REG_FIFO,
7612c965db44STomer Tayar 			       num_dumped_bytes);
7613c965db44STomer Tayar }
7614c965db44STomer Tayar 
7615c965db44STomer Tayar int qed_dbg_reg_fifo_size(struct qed_dev *cdev)
7616c965db44STomer Tayar {
7617c965db44STomer Tayar 	return qed_dbg_feature_size(cdev, DBG_FEATURE_REG_FIFO);
7618c965db44STomer Tayar }
7619c965db44STomer Tayar 
7620c965db44STomer Tayar int qed_dbg_igu_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
7621c965db44STomer Tayar {
7622c965db44STomer Tayar 	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IGU_FIFO,
7623c965db44STomer Tayar 			       num_dumped_bytes);
7624c965db44STomer Tayar }
7625c965db44STomer Tayar 
7626c965db44STomer Tayar int qed_dbg_igu_fifo_size(struct qed_dev *cdev)
7627c965db44STomer Tayar {
7628c965db44STomer Tayar 	return qed_dbg_feature_size(cdev, DBG_FEATURE_IGU_FIFO);
7629c965db44STomer Tayar }
7630c965db44STomer Tayar 
7631bf774d14SYueHaibing static int qed_dbg_nvm_image_length(struct qed_hwfn *p_hwfn,
76321ac4329aSDenis Bolotin 				    enum qed_nvm_images image_id, u32 *length)
76331ac4329aSDenis Bolotin {
76341ac4329aSDenis Bolotin 	struct qed_nvm_image_att image_att;
76351ac4329aSDenis Bolotin 	int rc;
76361ac4329aSDenis Bolotin 
76371ac4329aSDenis Bolotin 	*length = 0;
76381ac4329aSDenis Bolotin 	rc = qed_mcp_get_nvm_image_att(p_hwfn, image_id, &image_att);
76391ac4329aSDenis Bolotin 	if (rc)
76401ac4329aSDenis Bolotin 		return rc;
76411ac4329aSDenis Bolotin 
76421ac4329aSDenis Bolotin 	*length = image_att.length;
76431ac4329aSDenis Bolotin 
76441ac4329aSDenis Bolotin 	return rc;
76451ac4329aSDenis Bolotin }
76461ac4329aSDenis Bolotin 
7647bf774d14SYueHaibing static int qed_dbg_nvm_image(struct qed_dev *cdev, void *buffer,
7648bf774d14SYueHaibing 			     u32 *num_dumped_bytes,
7649bf774d14SYueHaibing 			     enum qed_nvm_images image_id)
76501ac4329aSDenis Bolotin {
76511ac4329aSDenis Bolotin 	struct qed_hwfn *p_hwfn =
7652ca352f00SIgor Russkikh 		&cdev->hwfns[cdev->engine_for_debug];
76531ac4329aSDenis Bolotin 	u32 len_rounded, i;
76541ac4329aSDenis Bolotin 	__be32 val;
76551ac4329aSDenis Bolotin 	int rc;
76561ac4329aSDenis Bolotin 
76571ac4329aSDenis Bolotin 	*num_dumped_bytes = 0;
76581ac4329aSDenis Bolotin 	rc = qed_dbg_nvm_image_length(p_hwfn, image_id, &len_rounded);
76591ac4329aSDenis Bolotin 	if (rc)
76601ac4329aSDenis Bolotin 		return rc;
76611ac4329aSDenis Bolotin 
76621ac4329aSDenis Bolotin 	DP_NOTICE(p_hwfn->cdev,
76631ac4329aSDenis Bolotin 		  "Collecting a debug feature [\"nvram image %d\"]\n",
76641ac4329aSDenis Bolotin 		  image_id);
76651ac4329aSDenis Bolotin 
76661ac4329aSDenis Bolotin 	len_rounded = roundup(len_rounded, sizeof(u32));
76671ac4329aSDenis Bolotin 	rc = qed_mcp_get_nvm_image(p_hwfn, image_id, buffer, len_rounded);
76681ac4329aSDenis Bolotin 	if (rc)
76691ac4329aSDenis Bolotin 		return rc;
76701ac4329aSDenis Bolotin 
76711ac4329aSDenis Bolotin 	/* QED_NVM_IMAGE_NVM_META image is not swapped like other images */
76721ac4329aSDenis Bolotin 	if (image_id != QED_NVM_IMAGE_NVM_META)
76731ac4329aSDenis Bolotin 		for (i = 0; i < len_rounded; i += 4) {
76741ac4329aSDenis Bolotin 			val = cpu_to_be32(*(u32 *)(buffer + i));
76751ac4329aSDenis Bolotin 			*(u32 *)(buffer + i) = val;
76761ac4329aSDenis Bolotin 		}
76771ac4329aSDenis Bolotin 
76781ac4329aSDenis Bolotin 	*num_dumped_bytes = len_rounded;
76791ac4329aSDenis Bolotin 
76801ac4329aSDenis Bolotin 	return rc;
76811ac4329aSDenis Bolotin }
76821ac4329aSDenis Bolotin 
7683c965db44STomer Tayar int qed_dbg_protection_override(struct qed_dev *cdev, void *buffer,
7684c965db44STomer Tayar 				u32 *num_dumped_bytes)
7685c965db44STomer Tayar {
7686c965db44STomer Tayar 	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_PROTECTION_OVERRIDE,
7687c965db44STomer Tayar 			       num_dumped_bytes);
7688c965db44STomer Tayar }
7689c965db44STomer Tayar 
7690c965db44STomer Tayar int qed_dbg_protection_override_size(struct qed_dev *cdev)
7691c965db44STomer Tayar {
7692c965db44STomer Tayar 	return qed_dbg_feature_size(cdev, DBG_FEATURE_PROTECTION_OVERRIDE);
7693c965db44STomer Tayar }
7694c965db44STomer Tayar 
7695c965db44STomer Tayar int qed_dbg_fw_asserts(struct qed_dev *cdev, void *buffer,
7696c965db44STomer Tayar 		       u32 *num_dumped_bytes)
7697c965db44STomer Tayar {
7698c965db44STomer Tayar 	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_FW_ASSERTS,
7699c965db44STomer Tayar 			       num_dumped_bytes);
7700c965db44STomer Tayar }
7701c965db44STomer Tayar 
7702c965db44STomer Tayar int qed_dbg_fw_asserts_size(struct qed_dev *cdev)
7703c965db44STomer Tayar {
7704c965db44STomer Tayar 	return qed_dbg_feature_size(cdev, DBG_FEATURE_FW_ASSERTS);
7705c965db44STomer Tayar }
7706c965db44STomer Tayar 
77078a52bbabSMichal Kalderon int qed_dbg_ilt(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
77088a52bbabSMichal Kalderon {
77098a52bbabSMichal Kalderon 	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_ILT, num_dumped_bytes);
77108a52bbabSMichal Kalderon }
77118a52bbabSMichal Kalderon 
77128a52bbabSMichal Kalderon int qed_dbg_ilt_size(struct qed_dev *cdev)
77138a52bbabSMichal Kalderon {
77148a52bbabSMichal Kalderon 	return qed_dbg_feature_size(cdev, DBG_FEATURE_ILT);
77158a52bbabSMichal Kalderon }
77168a52bbabSMichal Kalderon 
7717c965db44STomer Tayar int qed_dbg_mcp_trace(struct qed_dev *cdev, void *buffer,
7718c965db44STomer Tayar 		      u32 *num_dumped_bytes)
7719c965db44STomer Tayar {
7720c965db44STomer Tayar 	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_MCP_TRACE,
7721c965db44STomer Tayar 			       num_dumped_bytes);
7722c965db44STomer Tayar }
7723c965db44STomer Tayar 
7724c965db44STomer Tayar int qed_dbg_mcp_trace_size(struct qed_dev *cdev)
7725c965db44STomer Tayar {
7726c965db44STomer Tayar 	return qed_dbg_feature_size(cdev, DBG_FEATURE_MCP_TRACE);
7727c965db44STomer Tayar }
7728c965db44STomer Tayar 
7729c965db44STomer Tayar /* Defines the amount of bytes allocated for recording the length of debugfs
7730c965db44STomer Tayar  * feature buffer.
7731c965db44STomer Tayar  */
7732c965db44STomer Tayar #define REGDUMP_HEADER_SIZE			sizeof(u32)
77338a52bbabSMichal Kalderon #define REGDUMP_HEADER_SIZE_SHIFT		0
77348a52bbabSMichal Kalderon #define REGDUMP_HEADER_SIZE_MASK		0xffffff
7735c965db44STomer Tayar #define REGDUMP_HEADER_FEATURE_SHIFT		24
77368a52bbabSMichal Kalderon #define REGDUMP_HEADER_FEATURE_MASK		0x3f
7737c965db44STomer Tayar #define REGDUMP_HEADER_OMIT_ENGINE_SHIFT	30
77388a52bbabSMichal Kalderon #define REGDUMP_HEADER_OMIT_ENGINE_MASK		0x1
77398a52bbabSMichal Kalderon #define REGDUMP_HEADER_ENGINE_SHIFT		31
77408a52bbabSMichal Kalderon #define REGDUMP_HEADER_ENGINE_MASK		0x1
77418a52bbabSMichal Kalderon #define REGDUMP_MAX_SIZE			0x1000000
77428a52bbabSMichal Kalderon #define ILT_DUMP_MAX_SIZE			(1024 * 1024 * 15)
77438a52bbabSMichal Kalderon 
7744c965db44STomer Tayar enum debug_print_features {
7745c965db44STomer Tayar 	OLD_MODE = 0,
7746c965db44STomer Tayar 	IDLE_CHK = 1,
7747c965db44STomer Tayar 	GRC_DUMP = 2,
7748c965db44STomer Tayar 	MCP_TRACE = 3,
7749c965db44STomer Tayar 	REG_FIFO = 4,
7750c965db44STomer Tayar 	PROTECTION_OVERRIDE = 5,
7751c965db44STomer Tayar 	IGU_FIFO = 6,
7752c965db44STomer Tayar 	PHY = 7,
7753c965db44STomer Tayar 	FW_ASSERTS = 8,
77541ac4329aSDenis Bolotin 	NVM_CFG1 = 9,
77551ac4329aSDenis Bolotin 	DEFAULT_CFG = 10,
77561ac4329aSDenis Bolotin 	NVM_META = 11,
77578a52bbabSMichal Kalderon 	MDUMP = 12,
77588a52bbabSMichal Kalderon 	ILT_DUMP = 13,
7759c965db44STomer Tayar };
7760c965db44STomer Tayar 
77612d22bc83SMichal Kalderon static u32 qed_calc_regdump_header(struct qed_dev *cdev,
77622d22bc83SMichal Kalderon 				   enum debug_print_features feature,
7763c965db44STomer Tayar 				   int engine, u32 feature_size, u8 omit_engine)
7764c965db44STomer Tayar {
77652d22bc83SMichal Kalderon 	u32 res = 0;
77662d22bc83SMichal Kalderon 
77672d22bc83SMichal Kalderon 	SET_FIELD(res, REGDUMP_HEADER_SIZE, feature_size);
77682d22bc83SMichal Kalderon 	if (res != feature_size)
77692d22bc83SMichal Kalderon 		DP_NOTICE(cdev,
77702d22bc83SMichal Kalderon 			  "Feature %d is too large (size 0x%x) and will corrupt the dump\n",
77712d22bc83SMichal Kalderon 			  feature, feature_size);
77722d22bc83SMichal Kalderon 
77732d22bc83SMichal Kalderon 	SET_FIELD(res, REGDUMP_HEADER_FEATURE, feature);
77742d22bc83SMichal Kalderon 	SET_FIELD(res, REGDUMP_HEADER_OMIT_ENGINE, omit_engine);
77752d22bc83SMichal Kalderon 	SET_FIELD(res, REGDUMP_HEADER_ENGINE, engine);
77762d22bc83SMichal Kalderon 
77772d22bc83SMichal Kalderon 	return res;
7778c965db44STomer Tayar }
7779c965db44STomer Tayar 
7780c965db44STomer Tayar int qed_dbg_all_data(struct qed_dev *cdev, void *buffer)
7781c965db44STomer Tayar {
7782c965db44STomer Tayar 	u8 cur_engine, omit_engine = 0, org_engine;
77833b86bd07SSudarsana Reddy Kalluru 	struct qed_hwfn *p_hwfn =
7784ca352f00SIgor Russkikh 		&cdev->hwfns[cdev->engine_for_debug];
77853b86bd07SSudarsana Reddy Kalluru 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
77863b86bd07SSudarsana Reddy Kalluru 	int grc_params[MAX_DBG_GRC_PARAMS], i;
7787c965db44STomer Tayar 	u32 offset = 0, feature_size;
7788c965db44STomer Tayar 	int rc;
7789c965db44STomer Tayar 
77903b86bd07SSudarsana Reddy Kalluru 	for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
77913b86bd07SSudarsana Reddy Kalluru 		grc_params[i] = dev_data->grc.param_val[i];
77923b86bd07SSudarsana Reddy Kalluru 
77932d22bc83SMichal Kalderon 	if (!QED_IS_CMT(cdev))
7794c965db44STomer Tayar 		omit_engine = 1;
7795c965db44STomer Tayar 
77962d22bc83SMichal Kalderon 	mutex_lock(&qed_dbg_lock);
77972d22bc83SMichal Kalderon 
7798c965db44STomer Tayar 	org_engine = qed_get_debug_engine(cdev);
7799c965db44STomer Tayar 	for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
7800c965db44STomer Tayar 		/* Collect idle_chks and grcDump for each hw function */
7801c965db44STomer Tayar 		DP_VERBOSE(cdev, QED_MSG_DEBUG,
7802c965db44STomer Tayar 			   "obtaining idle_chk and grcdump for current engine\n");
7803c965db44STomer Tayar 		qed_set_debug_engine(cdev, cur_engine);
7804c965db44STomer Tayar 
7805c965db44STomer Tayar 		/* First idle_chk */
7806c965db44STomer Tayar 		rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset +
7807c965db44STomer Tayar 				      REGDUMP_HEADER_SIZE, &feature_size);
7808c965db44STomer Tayar 		if (!rc) {
7809c965db44STomer Tayar 			*(u32 *)((u8 *)buffer + offset) =
78102d22bc83SMichal Kalderon 			    qed_calc_regdump_header(cdev, IDLE_CHK, cur_engine,
7811c965db44STomer Tayar 						    feature_size, omit_engine);
7812c965db44STomer Tayar 			offset += (feature_size + REGDUMP_HEADER_SIZE);
7813c965db44STomer Tayar 		} else {
7814c965db44STomer Tayar 			DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
7815c965db44STomer Tayar 		}
7816c965db44STomer Tayar 
7817c965db44STomer Tayar 		/* Second idle_chk */
7818c965db44STomer Tayar 		rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset +
7819c965db44STomer Tayar 				      REGDUMP_HEADER_SIZE, &feature_size);
7820c965db44STomer Tayar 		if (!rc) {
7821c965db44STomer Tayar 			*(u32 *)((u8 *)buffer + offset) =
78222d22bc83SMichal Kalderon 			    qed_calc_regdump_header(cdev, IDLE_CHK, cur_engine,
7823c965db44STomer Tayar 						    feature_size, omit_engine);
7824c965db44STomer Tayar 			offset += (feature_size + REGDUMP_HEADER_SIZE);
7825c965db44STomer Tayar 		} else {
7826c965db44STomer Tayar 			DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
7827c965db44STomer Tayar 		}
7828c965db44STomer Tayar 
7829c965db44STomer Tayar 		/* reg_fifo dump */
7830c965db44STomer Tayar 		rc = qed_dbg_reg_fifo(cdev, (u8 *)buffer + offset +
7831c965db44STomer Tayar 				      REGDUMP_HEADER_SIZE, &feature_size);
7832c965db44STomer Tayar 		if (!rc) {
7833c965db44STomer Tayar 			*(u32 *)((u8 *)buffer + offset) =
78342d22bc83SMichal Kalderon 			    qed_calc_regdump_header(cdev, REG_FIFO, cur_engine,
7835c965db44STomer Tayar 						    feature_size, omit_engine);
7836c965db44STomer Tayar 			offset += (feature_size + REGDUMP_HEADER_SIZE);
7837c965db44STomer Tayar 		} else {
7838c965db44STomer Tayar 			DP_ERR(cdev, "qed_dbg_reg_fifo failed. rc = %d\n", rc);
7839c965db44STomer Tayar 		}
7840c965db44STomer Tayar 
7841c965db44STomer Tayar 		/* igu_fifo dump */
7842c965db44STomer Tayar 		rc = qed_dbg_igu_fifo(cdev, (u8 *)buffer + offset +
7843c965db44STomer Tayar 				      REGDUMP_HEADER_SIZE, &feature_size);
7844c965db44STomer Tayar 		if (!rc) {
7845c965db44STomer Tayar 			*(u32 *)((u8 *)buffer + offset) =
78462d22bc83SMichal Kalderon 			    qed_calc_regdump_header(cdev, IGU_FIFO, cur_engine,
7847c965db44STomer Tayar 						    feature_size, omit_engine);
7848c965db44STomer Tayar 			offset += (feature_size + REGDUMP_HEADER_SIZE);
7849c965db44STomer Tayar 		} else {
7850c965db44STomer Tayar 			DP_ERR(cdev, "qed_dbg_igu_fifo failed. rc = %d", rc);
7851c965db44STomer Tayar 		}
7852c965db44STomer Tayar 
7853c965db44STomer Tayar 		/* protection_override dump */
7854c965db44STomer Tayar 		rc = qed_dbg_protection_override(cdev, (u8 *)buffer + offset +
7855c965db44STomer Tayar 						 REGDUMP_HEADER_SIZE,
7856c965db44STomer Tayar 						 &feature_size);
7857c965db44STomer Tayar 		if (!rc) {
7858c965db44STomer Tayar 			*(u32 *)((u8 *)buffer + offset) =
78592d22bc83SMichal Kalderon 			    qed_calc_regdump_header(cdev, PROTECTION_OVERRIDE,
7860c965db44STomer Tayar 						    cur_engine,
7861c965db44STomer Tayar 						    feature_size, omit_engine);
7862c965db44STomer Tayar 			offset += (feature_size + REGDUMP_HEADER_SIZE);
7863c965db44STomer Tayar 		} else {
7864c965db44STomer Tayar 			DP_ERR(cdev,
7865c965db44STomer Tayar 			       "qed_dbg_protection_override failed. rc = %d\n",
7866c965db44STomer Tayar 			       rc);
7867c965db44STomer Tayar 		}
7868c965db44STomer Tayar 
7869c965db44STomer Tayar 		/* fw_asserts dump */
7870c965db44STomer Tayar 		rc = qed_dbg_fw_asserts(cdev, (u8 *)buffer + offset +
7871c965db44STomer Tayar 					REGDUMP_HEADER_SIZE, &feature_size);
7872c965db44STomer Tayar 		if (!rc) {
7873c965db44STomer Tayar 			*(u32 *)((u8 *)buffer + offset) =
78742d22bc83SMichal Kalderon 			    qed_calc_regdump_header(cdev, FW_ASSERTS,
78752d22bc83SMichal Kalderon 						    cur_engine, feature_size,
78762d22bc83SMichal Kalderon 						    omit_engine);
7877c965db44STomer Tayar 			offset += (feature_size + REGDUMP_HEADER_SIZE);
7878c965db44STomer Tayar 		} else {
7879c965db44STomer Tayar 			DP_ERR(cdev, "qed_dbg_fw_asserts failed. rc = %d\n",
7880c965db44STomer Tayar 			       rc);
7881c965db44STomer Tayar 		}
7882c965db44STomer Tayar 
78838a52bbabSMichal Kalderon 		feature_size = qed_dbg_ilt_size(cdev);
78848a52bbabSMichal Kalderon 		if (!cdev->disable_ilt_dump &&
78858a52bbabSMichal Kalderon 		    feature_size < ILT_DUMP_MAX_SIZE) {
78868a52bbabSMichal Kalderon 			rc = qed_dbg_ilt(cdev, (u8 *)buffer + offset +
78878a52bbabSMichal Kalderon 					 REGDUMP_HEADER_SIZE, &feature_size);
78888a52bbabSMichal Kalderon 			if (!rc) {
78898a52bbabSMichal Kalderon 				*(u32 *)((u8 *)buffer + offset) =
78902d22bc83SMichal Kalderon 				    qed_calc_regdump_header(cdev, ILT_DUMP,
78918a52bbabSMichal Kalderon 							    cur_engine,
78928a52bbabSMichal Kalderon 							    feature_size,
78938a52bbabSMichal Kalderon 							    omit_engine);
78948a52bbabSMichal Kalderon 				offset += feature_size + REGDUMP_HEADER_SIZE;
78958a52bbabSMichal Kalderon 			} else {
78968a52bbabSMichal Kalderon 				DP_ERR(cdev, "qed_dbg_ilt failed. rc = %d\n",
78978a52bbabSMichal Kalderon 				       rc);
78988a52bbabSMichal Kalderon 			}
78998a52bbabSMichal Kalderon 		}
79003b86bd07SSudarsana Reddy Kalluru 
7901c965db44STomer Tayar 		/* GRC dump - must be last because when mcp stuck it will
7902c965db44STomer Tayar 		 * clutter idle_chk, reg_fifo, ...
7903c965db44STomer Tayar 		 */
79042d22bc83SMichal Kalderon 		for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
79052d22bc83SMichal Kalderon 			dev_data->grc.param_val[i] = grc_params[i];
79062d22bc83SMichal Kalderon 
7907c965db44STomer Tayar 		rc = qed_dbg_grc(cdev, (u8 *)buffer + offset +
7908c965db44STomer Tayar 				 REGDUMP_HEADER_SIZE, &feature_size);
7909c965db44STomer Tayar 		if (!rc) {
7910c965db44STomer Tayar 			*(u32 *)((u8 *)buffer + offset) =
79112d22bc83SMichal Kalderon 			    qed_calc_regdump_header(cdev, GRC_DUMP,
79122d22bc83SMichal Kalderon 						    cur_engine,
7913c965db44STomer Tayar 						    feature_size, omit_engine);
7914c965db44STomer Tayar 			offset += (feature_size + REGDUMP_HEADER_SIZE);
7915c965db44STomer Tayar 		} else {
7916c965db44STomer Tayar 			DP_ERR(cdev, "qed_dbg_grc failed. rc = %d", rc);
7917c965db44STomer Tayar 		}
7918c965db44STomer Tayar 	}
7919c965db44STomer Tayar 
792050bc60cbSMichal Kalderon 	qed_set_debug_engine(cdev, org_engine);
79212d22bc83SMichal Kalderon 
7922c965db44STomer Tayar 	/* mcp_trace */
7923c965db44STomer Tayar 	rc = qed_dbg_mcp_trace(cdev, (u8 *)buffer + offset +
7924c965db44STomer Tayar 			       REGDUMP_HEADER_SIZE, &feature_size);
7925c965db44STomer Tayar 	if (!rc) {
7926c965db44STomer Tayar 		*(u32 *)((u8 *)buffer + offset) =
79272d22bc83SMichal Kalderon 		    qed_calc_regdump_header(cdev, MCP_TRACE, cur_engine,
7928c965db44STomer Tayar 					    feature_size, omit_engine);
7929c965db44STomer Tayar 		offset += (feature_size + REGDUMP_HEADER_SIZE);
7930c965db44STomer Tayar 	} else {
7931c965db44STomer Tayar 		DP_ERR(cdev, "qed_dbg_mcp_trace failed. rc = %d\n", rc);
7932c965db44STomer Tayar 	}
7933c965db44STomer Tayar 
79341ac4329aSDenis Bolotin 	/* nvm cfg1 */
79351ac4329aSDenis Bolotin 	rc = qed_dbg_nvm_image(cdev,
79362d22bc83SMichal Kalderon 			       (u8 *)buffer + offset +
79372d22bc83SMichal Kalderon 			       REGDUMP_HEADER_SIZE, &feature_size,
79382d22bc83SMichal Kalderon 			       QED_NVM_IMAGE_NVM_CFG1);
79391ac4329aSDenis Bolotin 	if (!rc) {
79401ac4329aSDenis Bolotin 		*(u32 *)((u8 *)buffer + offset) =
79412d22bc83SMichal Kalderon 		    qed_calc_regdump_header(cdev, NVM_CFG1, cur_engine,
79421ac4329aSDenis Bolotin 					    feature_size, omit_engine);
79431ac4329aSDenis Bolotin 		offset += (feature_size + REGDUMP_HEADER_SIZE);
79441ac4329aSDenis Bolotin 	} else if (rc != -ENOENT) {
79451ac4329aSDenis Bolotin 		DP_ERR(cdev,
79461ac4329aSDenis Bolotin 		       "qed_dbg_nvm_image failed for image  %d (%s), rc = %d\n",
79471ac4329aSDenis Bolotin 		       QED_NVM_IMAGE_NVM_CFG1, "QED_NVM_IMAGE_NVM_CFG1", rc);
79481ac4329aSDenis Bolotin 	}
79491ac4329aSDenis Bolotin 
79501ac4329aSDenis Bolotin 	/* nvm default */
79511ac4329aSDenis Bolotin 	rc = qed_dbg_nvm_image(cdev,
79521ac4329aSDenis Bolotin 			       (u8 *)buffer + offset + REGDUMP_HEADER_SIZE,
79531ac4329aSDenis Bolotin 			       &feature_size, QED_NVM_IMAGE_DEFAULT_CFG);
79541ac4329aSDenis Bolotin 	if (!rc) {
79551ac4329aSDenis Bolotin 		*(u32 *)((u8 *)buffer + offset) =
79562d22bc83SMichal Kalderon 		    qed_calc_regdump_header(cdev, DEFAULT_CFG, cur_engine,
79571ac4329aSDenis Bolotin 					    feature_size, omit_engine);
79581ac4329aSDenis Bolotin 		offset += (feature_size + REGDUMP_HEADER_SIZE);
79591ac4329aSDenis Bolotin 	} else if (rc != -ENOENT) {
79601ac4329aSDenis Bolotin 		DP_ERR(cdev,
79611ac4329aSDenis Bolotin 		       "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
79621ac4329aSDenis Bolotin 		       QED_NVM_IMAGE_DEFAULT_CFG, "QED_NVM_IMAGE_DEFAULT_CFG",
79631ac4329aSDenis Bolotin 		       rc);
79641ac4329aSDenis Bolotin 	}
79651ac4329aSDenis Bolotin 
79661ac4329aSDenis Bolotin 	/* nvm meta */
79671ac4329aSDenis Bolotin 	rc = qed_dbg_nvm_image(cdev,
79681ac4329aSDenis Bolotin 			       (u8 *)buffer + offset + REGDUMP_HEADER_SIZE,
79691ac4329aSDenis Bolotin 			       &feature_size, QED_NVM_IMAGE_NVM_META);
79701ac4329aSDenis Bolotin 	if (!rc) {
79711ac4329aSDenis Bolotin 		*(u32 *)((u8 *)buffer + offset) =
79722d22bc83SMichal Kalderon 			qed_calc_regdump_header(cdev, NVM_META, cur_engine,
79731ac4329aSDenis Bolotin 						feature_size, omit_engine);
79741ac4329aSDenis Bolotin 		offset += (feature_size + REGDUMP_HEADER_SIZE);
79751ac4329aSDenis Bolotin 	} else if (rc != -ENOENT) {
79761ac4329aSDenis Bolotin 		DP_ERR(cdev,
79771ac4329aSDenis Bolotin 		       "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
79781ac4329aSDenis Bolotin 		       QED_NVM_IMAGE_NVM_META, "QED_NVM_IMAGE_NVM_META", rc);
79791ac4329aSDenis Bolotin 	}
79801ac4329aSDenis Bolotin 
79818a52bbabSMichal Kalderon 	/* nvm mdump */
79828a52bbabSMichal Kalderon 	rc = qed_dbg_nvm_image(cdev, (u8 *)buffer + offset +
79838a52bbabSMichal Kalderon 			       REGDUMP_HEADER_SIZE, &feature_size,
79848a52bbabSMichal Kalderon 			       QED_NVM_IMAGE_MDUMP);
79858a52bbabSMichal Kalderon 	if (!rc) {
79868a52bbabSMichal Kalderon 		*(u32 *)((u8 *)buffer + offset) =
79872d22bc83SMichal Kalderon 			qed_calc_regdump_header(cdev, MDUMP, cur_engine,
79888a52bbabSMichal Kalderon 						feature_size, omit_engine);
79898a52bbabSMichal Kalderon 		offset += (feature_size + REGDUMP_HEADER_SIZE);
79908a52bbabSMichal Kalderon 	} else if (rc != -ENOENT) {
79918a52bbabSMichal Kalderon 		DP_ERR(cdev,
79928a52bbabSMichal Kalderon 		       "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
79938a52bbabSMichal Kalderon 		       QED_NVM_IMAGE_MDUMP, "QED_NVM_IMAGE_MDUMP", rc);
79948a52bbabSMichal Kalderon 	}
79958a52bbabSMichal Kalderon 
79962d22bc83SMichal Kalderon 	mutex_unlock(&qed_dbg_lock);
79972d22bc83SMichal Kalderon 
7998c965db44STomer Tayar 	return 0;
7999c965db44STomer Tayar }
8000c965db44STomer Tayar 
8001c965db44STomer Tayar int qed_dbg_all_data_size(struct qed_dev *cdev)
8002c965db44STomer Tayar {
80031ac4329aSDenis Bolotin 	struct qed_hwfn *p_hwfn =
8004ca352f00SIgor Russkikh 		&cdev->hwfns[cdev->engine_for_debug];
80058a52bbabSMichal Kalderon 	u32 regs_len = 0, image_len = 0, ilt_len = 0, total_ilt_len = 0;
8006c965db44STomer Tayar 	u8 cur_engine, org_engine;
8007c965db44STomer Tayar 
80082d22bc83SMichal Kalderon 	cdev->disable_ilt_dump = false;
8009c965db44STomer Tayar 	org_engine = qed_get_debug_engine(cdev);
8010c965db44STomer Tayar 	for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
8011c965db44STomer Tayar 		/* Engine specific */
8012c965db44STomer Tayar 		DP_VERBOSE(cdev, QED_MSG_DEBUG,
8013c965db44STomer Tayar 			   "calculating idle_chk and grcdump register length for current engine\n");
8014c965db44STomer Tayar 		qed_set_debug_engine(cdev, cur_engine);
8015c965db44STomer Tayar 		regs_len += REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
8016c965db44STomer Tayar 			    REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
8017c965db44STomer Tayar 			    REGDUMP_HEADER_SIZE + qed_dbg_grc_size(cdev) +
8018c965db44STomer Tayar 			    REGDUMP_HEADER_SIZE + qed_dbg_reg_fifo_size(cdev) +
8019c965db44STomer Tayar 			    REGDUMP_HEADER_SIZE + qed_dbg_igu_fifo_size(cdev) +
8020c965db44STomer Tayar 			    REGDUMP_HEADER_SIZE +
8021c965db44STomer Tayar 			    qed_dbg_protection_override_size(cdev) +
8022c965db44STomer Tayar 			    REGDUMP_HEADER_SIZE + qed_dbg_fw_asserts_size(cdev);
80238a52bbabSMichal Kalderon 
80248a52bbabSMichal Kalderon 		ilt_len = REGDUMP_HEADER_SIZE + qed_dbg_ilt_size(cdev);
80258a52bbabSMichal Kalderon 		if (ilt_len < ILT_DUMP_MAX_SIZE) {
80268a52bbabSMichal Kalderon 			total_ilt_len += ilt_len;
80278a52bbabSMichal Kalderon 			regs_len += ilt_len;
80288a52bbabSMichal Kalderon 		}
8029c965db44STomer Tayar 	}
8030c965db44STomer Tayar 
803150bc60cbSMichal Kalderon 	qed_set_debug_engine(cdev, org_engine);
803250bc60cbSMichal Kalderon 
8033c965db44STomer Tayar 	/* Engine common */
8034c965db44STomer Tayar 	regs_len += REGDUMP_HEADER_SIZE + qed_dbg_mcp_trace_size(cdev);
80351ac4329aSDenis Bolotin 	qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_CFG1, &image_len);
80361ac4329aSDenis Bolotin 	if (image_len)
80371ac4329aSDenis Bolotin 		regs_len += REGDUMP_HEADER_SIZE + image_len;
80381ac4329aSDenis Bolotin 	qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_DEFAULT_CFG, &image_len);
80391ac4329aSDenis Bolotin 	if (image_len)
80401ac4329aSDenis Bolotin 		regs_len += REGDUMP_HEADER_SIZE + image_len;
80411ac4329aSDenis Bolotin 	qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_META, &image_len);
80421ac4329aSDenis Bolotin 	if (image_len)
80431ac4329aSDenis Bolotin 		regs_len += REGDUMP_HEADER_SIZE + image_len;
80448a52bbabSMichal Kalderon 	qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_MDUMP, &image_len);
80458a52bbabSMichal Kalderon 	if (image_len)
80468a52bbabSMichal Kalderon 		regs_len += REGDUMP_HEADER_SIZE + image_len;
80478a52bbabSMichal Kalderon 
80488a52bbabSMichal Kalderon 	if (regs_len > REGDUMP_MAX_SIZE) {
80498a52bbabSMichal Kalderon 		DP_VERBOSE(cdev, QED_MSG_DEBUG,
80508a52bbabSMichal Kalderon 			   "Dump exceeds max size 0x%x, disable ILT dump\n",
80518a52bbabSMichal Kalderon 			   REGDUMP_MAX_SIZE);
80528a52bbabSMichal Kalderon 		cdev->disable_ilt_dump = true;
80538a52bbabSMichal Kalderon 		regs_len -= total_ilt_len;
80548a52bbabSMichal Kalderon 	}
8055c965db44STomer Tayar 
8056c965db44STomer Tayar 	return regs_len;
8057c965db44STomer Tayar }
8058c965db44STomer Tayar 
8059c965db44STomer Tayar int qed_dbg_feature(struct qed_dev *cdev, void *buffer,
8060c965db44STomer Tayar 		    enum qed_dbg_features feature, u32 *num_dumped_bytes)
8061c965db44STomer Tayar {
8062c965db44STomer Tayar 	struct qed_hwfn *p_hwfn =
8063ca352f00SIgor Russkikh 		&cdev->hwfns[cdev->engine_for_debug];
8064c965db44STomer Tayar 	struct qed_dbg_feature *qed_feature =
8065ca352f00SIgor Russkikh 		&cdev->dbg_features[feature];
8066c965db44STomer Tayar 	enum dbg_status dbg_rc;
8067c965db44STomer Tayar 	struct qed_ptt *p_ptt;
8068c965db44STomer Tayar 	int rc = 0;
8069c965db44STomer Tayar 
8070c965db44STomer Tayar 	/* Acquire ptt */
8071c965db44STomer Tayar 	p_ptt = qed_ptt_acquire(p_hwfn);
8072c965db44STomer Tayar 	if (!p_ptt)
8073c965db44STomer Tayar 		return -EINVAL;
8074c965db44STomer Tayar 
8075c965db44STomer Tayar 	/* Get dump */
8076c965db44STomer Tayar 	dbg_rc = qed_dbg_dump(p_hwfn, p_ptt, feature);
8077c965db44STomer Tayar 	if (dbg_rc != DBG_STATUS_OK) {
8078c965db44STomer Tayar 		DP_VERBOSE(cdev, QED_MSG_DEBUG, "%s\n",
8079c965db44STomer Tayar 			   qed_dbg_get_status_str(dbg_rc));
8080c965db44STomer Tayar 		*num_dumped_bytes = 0;
8081c965db44STomer Tayar 		rc = -EINVAL;
8082c965db44STomer Tayar 		goto out;
8083c965db44STomer Tayar 	}
8084c965db44STomer Tayar 
8085c965db44STomer Tayar 	DP_VERBOSE(cdev, QED_MSG_DEBUG,
8086c965db44STomer Tayar 		   "copying debugfs feature to external buffer\n");
8087c965db44STomer Tayar 	memcpy(buffer, qed_feature->dump_buf, qed_feature->buf_size);
8088ca352f00SIgor Russkikh 	*num_dumped_bytes = cdev->dbg_features[feature].dumped_dwords *
8089c965db44STomer Tayar 			    4;
8090c965db44STomer Tayar 
8091c965db44STomer Tayar out:
8092c965db44STomer Tayar 	qed_ptt_release(p_hwfn, p_ptt);
8093c965db44STomer Tayar 	return rc;
8094c965db44STomer Tayar }
8095c965db44STomer Tayar 
8096c965db44STomer Tayar int qed_dbg_feature_size(struct qed_dev *cdev, enum qed_dbg_features feature)
8097c965db44STomer Tayar {
8098c965db44STomer Tayar 	struct qed_hwfn *p_hwfn =
8099ca352f00SIgor Russkikh 		&cdev->hwfns[cdev->engine_for_debug];
81002d22bc83SMichal Kalderon 	struct qed_dbg_feature *qed_feature = &cdev->dbg_features[feature];
8101c965db44STomer Tayar 	struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
8102c965db44STomer Tayar 	u32 buf_size_dwords;
8103c965db44STomer Tayar 	enum dbg_status rc;
8104c965db44STomer Tayar 
8105c965db44STomer Tayar 	if (!p_ptt)
8106c965db44STomer Tayar 		return -EINVAL;
8107c965db44STomer Tayar 
8108c965db44STomer Tayar 	rc = qed_features_lookup[feature].get_size(p_hwfn, p_ptt,
8109c965db44STomer Tayar 						   &buf_size_dwords);
8110c965db44STomer Tayar 	if (rc != DBG_STATUS_OK)
8111c965db44STomer Tayar 		buf_size_dwords = 0;
8112c965db44STomer Tayar 
81138a52bbabSMichal Kalderon 	/* Feature will not be dumped if it exceeds maximum size */
81148a52bbabSMichal Kalderon 	if (buf_size_dwords > MAX_DBG_FEATURE_SIZE_DWORDS)
81158a52bbabSMichal Kalderon 		buf_size_dwords = 0;
81168a52bbabSMichal Kalderon 
8117c965db44STomer Tayar 	qed_ptt_release(p_hwfn, p_ptt);
8118c965db44STomer Tayar 	qed_feature->buf_size = buf_size_dwords * sizeof(u32);
8119c965db44STomer Tayar 	return qed_feature->buf_size;
8120c965db44STomer Tayar }
8121c965db44STomer Tayar 
8122c965db44STomer Tayar u8 qed_get_debug_engine(struct qed_dev *cdev)
8123c965db44STomer Tayar {
8124ca352f00SIgor Russkikh 	return cdev->engine_for_debug;
8125c965db44STomer Tayar }
8126c965db44STomer Tayar 
8127c965db44STomer Tayar void qed_set_debug_engine(struct qed_dev *cdev, int engine_number)
8128c965db44STomer Tayar {
8129c965db44STomer Tayar 	DP_VERBOSE(cdev, QED_MSG_DEBUG, "set debug engine to %d\n",
8130c965db44STomer Tayar 		   engine_number);
8131ca352f00SIgor Russkikh 	cdev->engine_for_debug = engine_number;
8132c965db44STomer Tayar }
8133c965db44STomer Tayar 
8134c965db44STomer Tayar void qed_dbg_pf_init(struct qed_dev *cdev)
8135c965db44STomer Tayar {
81362d22bc83SMichal Kalderon 	const u8 *dbg_values = NULL;
81372d22bc83SMichal Kalderon 	int i;
8138c965db44STomer Tayar 
8139c965db44STomer Tayar 	/* Debug values are after init values.
8140c965db44STomer Tayar 	 * The offset is the first dword of the file.
8141c965db44STomer Tayar 	 */
8142c965db44STomer Tayar 	dbg_values = cdev->firmware->data + *(u32 *)cdev->firmware->data;
81432d22bc83SMichal Kalderon 
81442d22bc83SMichal Kalderon 	for_each_hwfn(cdev, i) {
81452d22bc83SMichal Kalderon 		qed_dbg_set_bin_ptr(&cdev->hwfns[i], dbg_values);
81462d22bc83SMichal Kalderon 		qed_dbg_user_set_bin_ptr(&cdev->hwfns[i], dbg_values);
81472d22bc83SMichal Kalderon 	}
81482d22bc83SMichal Kalderon 
81492d22bc83SMichal Kalderon 	/* Set the hwfn to be 0 as default */
8150ca352f00SIgor Russkikh 	cdev->engine_for_debug = 0;
8151c965db44STomer Tayar }
8152c965db44STomer Tayar 
8153c965db44STomer Tayar void qed_dbg_pf_exit(struct qed_dev *cdev)
8154c965db44STomer Tayar {
8155c965db44STomer Tayar 	struct qed_dbg_feature *feature = NULL;
8156c965db44STomer Tayar 	enum qed_dbg_features feature_idx;
8157c965db44STomer Tayar 
81582d22bc83SMichal Kalderon 	/* debug features' buffers may be allocated if debug feature was used
81592d22bc83SMichal Kalderon 	 * but dump wasn't called
8160c965db44STomer Tayar 	 */
8161c965db44STomer Tayar 	for (feature_idx = 0; feature_idx < DBG_FEATURE_NUM; feature_idx++) {
81622d22bc83SMichal Kalderon 		feature = &cdev->dbg_features[feature_idx];
8163c965db44STomer Tayar 		if (feature->dump_buf) {
8164c965db44STomer Tayar 			vfree(feature->dump_buf);
8165c965db44STomer Tayar 			feature->dump_buf = NULL;
8166c965db44STomer Tayar 		}
8167c965db44STomer Tayar 	}
8168c965db44STomer Tayar }
8169