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