1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 /* QLogic qed NIC Driver
3 * Copyright (c) 2015 QLogic Corporation
4 * Copyright (c) 2019-2021 Marvell International Ltd.
7 #include <linux/module.h>
8 #include <linux/vmalloc.h>
9 #include <linux/crc32.h>
13 #include "qed_dbg_hsi.h"
16 #include "qed_reg_addr.h"
18 /* Memory groups enum */
36 MEM_GROUP_CONN_CFC_MEM
,
39 MEM_GROUP_CAU_MEM_EXT
,
49 MEM_GROUP_TASK_CFC_MEM
,
53 /* Memory groups names */
54 static const char * const s_mem_group_names
[] = {
87 /* Idle check conditions */
89 static u32
cond5(const u32
*r
, const u32
*imm
)
91 return ((r
[0] & imm
[0]) != imm
[1]) && ((r
[1] & imm
[2]) != imm
[3]);
94 static u32
cond7(const u32
*r
, const u32
*imm
)
96 return ((r
[0] >> imm
[0]) & imm
[1]) != imm
[2];
99 static u32
cond6(const u32
*r
, const u32
*imm
)
101 return (r
[0] & imm
[0]) != imm
[1];
104 static u32
cond9(const u32
*r
, const u32
*imm
)
106 return ((r
[0] & imm
[0]) >> imm
[1]) !=
107 (((r
[0] & imm
[2]) >> imm
[3]) | ((r
[1] & imm
[4]) << imm
[5]));
110 static u32
cond10(const u32
*r
, const u32
*imm
)
112 return ((r
[0] & imm
[0]) >> imm
[1]) != (r
[0] & imm
[2]);
115 static u32
cond4(const u32
*r
, const u32
*imm
)
117 return (r
[0] & ~imm
[0]) != imm
[1];
120 static u32
cond0(const u32
*r
, const u32
*imm
)
122 return (r
[0] & ~r
[1]) != imm
[0];
125 static u32
cond14(const u32
*r
, const u32
*imm
)
127 return (r
[0] | imm
[0]) != imm
[1];
130 static u32
cond1(const u32
*r
, const u32
*imm
)
132 return r
[0] != imm
[0];
135 static u32
cond11(const u32
*r
, const u32
*imm
)
137 return r
[0] != r
[1] && r
[2] == imm
[0];
140 static u32
cond12(const u32
*r
, const u32
*imm
)
142 return r
[0] != r
[1] && r
[2] > imm
[0];
145 static u32
cond3(const u32
*r
, const u32
*imm
)
150 static u32
cond13(const u32
*r
, const u32
*imm
)
152 return r
[0] & imm
[0];
155 static u32
cond8(const u32
*r
, const u32
*imm
)
157 return r
[0] < (r
[1] - imm
[0]);
160 static u32
cond2(const u32
*r
, const u32
*imm
)
162 return r
[0] > imm
[0];
165 /* Array of Idle Check conditions */
166 static u32(*cond_arr
[]) (const u32
*r
, const u32
*imm
) = {
184 #define NUM_PHYS_BLOCKS 84
186 #define NUM_DBG_RESET_REGS 8
188 /******************************* Data Types **********************************/
199 /* CM context types */
208 /* Debug bus frame modes */
209 enum dbg_bus_frame_modes
{
210 DBG_BUS_FRAME_MODE_4ST
= 0, /* 4 Storm dwords (no HW) */
211 DBG_BUS_FRAME_MODE_2ST_2HW
= 1, /* 2 Storm dwords, 2 HW dwords */
212 DBG_BUS_FRAME_MODE_1ST_3HW
= 2, /* 1 Storm dwords, 3 HW dwords */
213 DBG_BUS_FRAME_MODE_4HW
= 3, /* 4 HW dwords (no Storms) */
214 DBG_BUS_FRAME_MODE_8HW
= 4, /* 8 HW dwords (no Storms) */
215 DBG_BUS_NUM_FRAME_MODES
218 /* Debug bus SEMI frame modes */
219 enum dbg_bus_semi_frame_modes
{
220 DBG_BUS_SEMI_FRAME_MODE_4FAST
= 0, /* 4 fast dw */
221 DBG_BUS_SEMI_FRAME_MODE_2FAST_2SLOW
= 1, /* 2 fast dw, 2 slow dw */
222 DBG_BUS_SEMI_FRAME_MODE_1FAST_3SLOW
= 2, /* 1 fast dw,3 slow dw */
223 DBG_BUS_SEMI_FRAME_MODE_4SLOW
= 3, /* 4 slow dw */
224 DBG_BUS_SEMI_NUM_FRAME_MODES
227 /* Debug bus filter types */
228 enum dbg_bus_filter_types
{
229 DBG_BUS_FILTER_TYPE_OFF
, /* Filter always off */
230 DBG_BUS_FILTER_TYPE_PRE
, /* Filter before trigger only */
231 DBG_BUS_FILTER_TYPE_POST
, /* Filter after trigger only */
232 DBG_BUS_FILTER_TYPE_ON
/* Filter always on */
235 /* Debug bus pre-trigger recording types */
236 enum dbg_bus_pre_trigger_types
{
237 DBG_BUS_PRE_TRIGGER_FROM_ZERO
, /* Record from time 0 */
238 DBG_BUS_PRE_TRIGGER_NUM_CHUNKS
, /* Record some chunks before trigger */
239 DBG_BUS_PRE_TRIGGER_DROP
/* Drop data before trigger */
242 /* Debug bus post-trigger recording types */
243 enum dbg_bus_post_trigger_types
{
244 DBG_BUS_POST_TRIGGER_RECORD
, /* Start recording after trigger */
245 DBG_BUS_POST_TRIGGER_DROP
/* Drop data after trigger */
248 /* Debug bus other engine mode */
249 enum dbg_bus_other_engine_modes
{
250 DBG_BUS_OTHER_ENGINE_MODE_NONE
,
251 DBG_BUS_OTHER_ENGINE_MODE_DOUBLE_BW_TX
,
252 DBG_BUS_OTHER_ENGINE_MODE_DOUBLE_BW_RX
,
253 DBG_BUS_OTHER_ENGINE_MODE_CROSS_ENGINE_TX
,
254 DBG_BUS_OTHER_ENGINE_MODE_CROSS_ENGINE_RX
257 /* DBG block Framing mode definitions */
258 struct framing_mode_defs
{
260 u8 blocks_dword_mask
;
261 u8 storms_dword_mask
;
262 u8 semi_framing_mode_id
;
266 /* Chip constant definitions */
270 u8 num_framing_modes
;
272 struct framing_mode_defs
*framing_modes
;
275 /* HW type constant definitions */
276 struct hw_type_defs
{
283 /* RBC reset definitions */
284 struct rbc_reset_defs
{
286 u32 reset_val
[MAX_CHIP_IDS
];
289 /* Storm constant definitions.
290 * Addresses are in bytes, sizes are in quad-regs.
294 enum block_id sem_block_id
;
295 enum dbg_bus_clients dbg_client_id
[MAX_CHIP_IDS
];
297 u32 sem_fast_mem_addr
;
298 u32 sem_frame_mode_addr
;
299 u32 sem_slow_enable_addr
;
300 u32 sem_slow_mode_addr
;
301 u32 sem_slow_mode1_conf_addr
;
302 u32 sem_sync_dbg_empty_addr
;
303 u32 sem_gpre_vect_addr
;
305 u32 cm_ctx_rd_addr
[NUM_CM_CTX_TYPES
];
306 u32 cm_ctx_lid_sizes
[MAX_CHIP_IDS
][NUM_CM_CTX_TYPES
];
309 /* Debug Bus Constraint operation constant definitions */
310 struct dbg_bus_constraint_op_defs
{
315 /* Storm Mode definitions */
316 struct storm_mode_defs
{
320 u32 src_disable_reg_addr
;
322 bool exists
[MAX_CHIP_IDS
];
325 struct grc_param_defs
{
326 u32 default_val
[MAX_CHIP_IDS
];
331 u32 exclude_all_preset_val
;
332 u32 crash_preset_val
[MAX_CHIP_IDS
];
335 /* Address is in 128b units. Width is in bits. */
336 struct rss_mem_defs
{
337 const char *mem_name
;
338 const char *type_name
;
341 u32 num_entries
[MAX_CHIP_IDS
];
344 struct vfc_ram_defs
{
345 const char *mem_name
;
346 const char *type_name
;
351 struct big_ram_defs
{
352 const char *instance_name
;
353 enum mem_groups mem_group_id
;
354 enum mem_groups ram_mem_group_id
;
355 enum dbg_grc_params grc_param
;
358 u32 is_256b_reg_addr
;
359 u32 is_256b_bit_offset
[MAX_CHIP_IDS
];
360 u32 ram_size
[MAX_CHIP_IDS
]; /* In dwords */
364 const char *phy_name
;
366 /* PHY base GRC address */
369 /* Relative address of indirect TBUS address register (bits 0..7) */
370 u32 tbus_addr_lo_addr
;
372 /* Relative address of indirect TBUS address register (bits 8..10) */
373 u32 tbus_addr_hi_addr
;
375 /* Relative address of indirect TBUS data register (bits 0..7) */
376 u32 tbus_data_lo_addr
;
378 /* Relative address of indirect TBUS data register (bits 8..11) */
379 u32 tbus_data_hi_addr
;
382 /* Split type definitions */
383 struct split_type_defs
{
387 /******************************** Constants **********************************/
389 #define BYTES_IN_DWORD sizeof(u32)
390 /* In the macros below, size and offset are specified in bits */
391 #define CEIL_DWORDS(size) DIV_ROUND_UP(size, 32)
392 #define FIELD_BIT_OFFSET(type, field) type ## _ ## field ## _ ## OFFSET
393 #define FIELD_BIT_SIZE(type, field) type ## _ ## field ## _ ## SIZE
394 #define FIELD_DWORD_OFFSET(type, field) \
395 ((int)(FIELD_BIT_OFFSET(type, field) / 32))
396 #define FIELD_DWORD_SHIFT(type, field) (FIELD_BIT_OFFSET(type, field) % 32)
397 #define FIELD_BIT_MASK(type, field) \
398 (((1 << FIELD_BIT_SIZE(type, field)) - 1) << \
399 FIELD_DWORD_SHIFT(type, field))
401 #define SET_VAR_FIELD(var, type, field, val) \
403 var[FIELD_DWORD_OFFSET(type, field)] &= \
404 (~FIELD_BIT_MASK(type, field)); \
405 var[FIELD_DWORD_OFFSET(type, field)] |= \
406 (val) << FIELD_DWORD_SHIFT(type, field); \
409 #define ARR_REG_WR(dev, ptt, addr, arr, arr_size) \
411 for (i = 0; i < (arr_size); i++) \
412 qed_wr(dev, ptt, addr, (arr)[i]); \
415 #define DWORDS_TO_BYTES(dwords) ((dwords) * BYTES_IN_DWORD)
416 #define BYTES_TO_DWORDS(bytes) ((bytes) / BYTES_IN_DWORD)
418 /* extra lines include a signature line + optional latency events line */
419 #define NUM_EXTRA_DBG_LINES(block) \
420 (GET_FIELD((block)->flags, DBG_BLOCK_CHIP_HAS_LATENCY_EVENTS) ? 2 : 1)
421 #define NUM_DBG_LINES(block) \
422 ((block)->num_of_dbg_bus_lines + NUM_EXTRA_DBG_LINES(block))
424 #define USE_DMAE true
425 #define PROTECT_WIDE_BUS true
427 #define RAM_LINES_TO_DWORDS(lines) ((lines) * 2)
428 #define RAM_LINES_TO_BYTES(lines) \
429 DWORDS_TO_BYTES(RAM_LINES_TO_DWORDS(lines))
431 #define REG_DUMP_LEN_SHIFT 24
432 #define MEM_DUMP_ENTRY_SIZE_DWORDS \
433 BYTES_TO_DWORDS(sizeof(struct dbg_dump_mem))
435 #define IDLE_CHK_RULE_SIZE_DWORDS \
436 BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_rule))
438 #define IDLE_CHK_RESULT_HDR_DWORDS \
439 BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_hdr))
441 #define IDLE_CHK_RESULT_REG_HDR_DWORDS \
442 BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_reg_hdr))
444 #define PAGE_MEM_DESC_SIZE_DWORDS \
445 BYTES_TO_DWORDS(sizeof(struct phys_mem_desc))
447 #define IDLE_CHK_MAX_ENTRIES_SIZE 32
449 /* The sizes and offsets below are specified in bits */
450 #define VFC_CAM_CMD_STRUCT_SIZE 64
451 #define VFC_CAM_CMD_ROW_OFFSET 48
452 #define VFC_CAM_CMD_ROW_SIZE 9
453 #define VFC_CAM_ADDR_STRUCT_SIZE 16
454 #define VFC_CAM_ADDR_OP_OFFSET 0
455 #define VFC_CAM_ADDR_OP_SIZE 4
456 #define VFC_CAM_RESP_STRUCT_SIZE 256
457 #define VFC_RAM_ADDR_STRUCT_SIZE 16
458 #define VFC_RAM_ADDR_OP_OFFSET 0
459 #define VFC_RAM_ADDR_OP_SIZE 2
460 #define VFC_RAM_ADDR_ROW_OFFSET 2
461 #define VFC_RAM_ADDR_ROW_SIZE 10
462 #define VFC_RAM_RESP_STRUCT_SIZE 256
464 #define VFC_CAM_CMD_DWORDS CEIL_DWORDS(VFC_CAM_CMD_STRUCT_SIZE)
465 #define VFC_CAM_ADDR_DWORDS CEIL_DWORDS(VFC_CAM_ADDR_STRUCT_SIZE)
466 #define VFC_CAM_RESP_DWORDS CEIL_DWORDS(VFC_CAM_RESP_STRUCT_SIZE)
467 #define VFC_RAM_CMD_DWORDS VFC_CAM_CMD_DWORDS
468 #define VFC_RAM_ADDR_DWORDS CEIL_DWORDS(VFC_RAM_ADDR_STRUCT_SIZE)
469 #define VFC_RAM_RESP_DWORDS CEIL_DWORDS(VFC_RAM_RESP_STRUCT_SIZE)
471 #define NUM_VFC_RAM_TYPES 4
473 #define VFC_CAM_NUM_ROWS 512
475 #define VFC_OPCODE_CAM_RD 14
476 #define VFC_OPCODE_RAM_RD 0
478 #define NUM_RSS_MEM_TYPES 5
480 #define NUM_BIG_RAM_TYPES 3
481 #define BIG_RAM_NAME_LEN 3
483 #define NUM_PHY_TBUS_ADDRESSES 2048
484 #define PHY_DUMP_SIZE_DWORDS (NUM_PHY_TBUS_ADDRESSES / 2)
486 #define RESET_REG_UNRESET_OFFSET 4
488 #define STALL_DELAY_MS 500
490 #define STATIC_DEBUG_LINE_DWORDS 9
492 #define NUM_COMMON_GLOBAL_PARAMS 10
494 #define MAX_RECURSION_DEPTH 10
496 #define FW_IMG_KUKU 0
497 #define FW_IMG_MAIN 1
500 #define REG_FIFO_ELEMENT_DWORDS 2
501 #define REG_FIFO_DEPTH_ELEMENTS 32
502 #define REG_FIFO_DEPTH_DWORDS \
503 (REG_FIFO_ELEMENT_DWORDS * REG_FIFO_DEPTH_ELEMENTS)
505 #define IGU_FIFO_ELEMENT_DWORDS 4
506 #define IGU_FIFO_DEPTH_ELEMENTS 64
507 #define IGU_FIFO_DEPTH_DWORDS \
508 (IGU_FIFO_ELEMENT_DWORDS * IGU_FIFO_DEPTH_ELEMENTS)
510 #define PROTECTION_OVERRIDE_ELEMENT_DWORDS 2
511 #define PROTECTION_OVERRIDE_DEPTH_ELEMENTS 20
512 #define PROTECTION_OVERRIDE_DEPTH_DWORDS \
513 (PROTECTION_OVERRIDE_DEPTH_ELEMENTS * \
514 PROTECTION_OVERRIDE_ELEMENT_DWORDS)
516 #define MCP_SPAD_TRACE_OFFSIZE_ADDR \
518 offsetof(struct static_init, sections[SPAD_SECTION_TRACE]))
520 #define MAX_SW_PLTAFORM_STR_SIZE 64
522 #define EMPTY_FW_VERSION_STR "???_???_???_???"
523 #define EMPTY_FW_IMAGE_STR "???????????????"
525 /***************************** Constant Arrays *******************************/
527 /* DBG block framing mode definitions, in descending preference order */
528 static struct framing_mode_defs s_framing_mode_defs
[4] = {
529 {DBG_BUS_FRAME_MODE_4ST
, 0x0, 0xf,
530 DBG_BUS_SEMI_FRAME_MODE_4FAST
,
532 {DBG_BUS_FRAME_MODE_4HW
, 0xf, 0x0, DBG_BUS_SEMI_FRAME_MODE_4SLOW
,
534 {DBG_BUS_FRAME_MODE_2ST_2HW
, 0x3, 0xc,
535 DBG_BUS_SEMI_FRAME_MODE_2FAST_2SLOW
, 10},
536 {DBG_BUS_FRAME_MODE_1ST_3HW
, 0x7, 0x8,
537 DBG_BUS_SEMI_FRAME_MODE_1FAST_3SLOW
, 10}
540 /* Chip constant definitions array */
541 static struct chip_defs s_chip_defs
[MAX_CHIP_IDS
] = {
542 {"bb", 4, DBG_BUS_NUM_FRAME_MODES
, PSWRQ2_REG_ILT_MEMORY_SIZE_BB
/ 2,
543 s_framing_mode_defs
},
544 {"ah", 4, DBG_BUS_NUM_FRAME_MODES
, PSWRQ2_REG_ILT_MEMORY_SIZE_K2
/ 2,
548 /* Storm constant definitions array */
549 static struct storm_defs s_storm_defs
[] = {
552 {DBG_BUS_CLIENT_RBCT
, DBG_BUS_CLIENT_RBCT
},
554 TSEM_REG_FAST_MEMORY
,
555 TSEM_REG_DBG_FRAME_MODE
, TSEM_REG_SLOW_DBG_ACTIVE
,
556 TSEM_REG_SLOW_DBG_MODE
, TSEM_REG_DBG_MODE1_CFG
,
557 TSEM_REG_SYNC_DBG_EMPTY
, TSEM_REG_DBG_GPRE_VECT
,
558 TCM_REG_CTX_RBC_ACCS
,
559 {TCM_REG_AGG_CON_CTX
, TCM_REG_SM_CON_CTX
, TCM_REG_AGG_TASK_CTX
,
560 TCM_REG_SM_TASK_CTX
},
561 {{4, 16, 2, 4}, {4, 16, 2, 4}} /* {bb} {k2} */
566 {DBG_BUS_CLIENT_RBCT
, DBG_BUS_CLIENT_RBCM
},
568 MSEM_REG_FAST_MEMORY
,
569 MSEM_REG_DBG_FRAME_MODE
,
570 MSEM_REG_SLOW_DBG_ACTIVE
,
571 MSEM_REG_SLOW_DBG_MODE
,
572 MSEM_REG_DBG_MODE1_CFG
,
573 MSEM_REG_SYNC_DBG_EMPTY
,
574 MSEM_REG_DBG_GPRE_VECT
,
575 MCM_REG_CTX_RBC_ACCS
,
576 {MCM_REG_AGG_CON_CTX
, MCM_REG_SM_CON_CTX
, MCM_REG_AGG_TASK_CTX
,
577 MCM_REG_SM_TASK_CTX
},
578 {{1, 10, 2, 7}, {1, 10, 2, 7}} /* {bb} {k2}*/
583 {DBG_BUS_CLIENT_RBCU
, DBG_BUS_CLIENT_RBCU
},
585 USEM_REG_FAST_MEMORY
,
586 USEM_REG_DBG_FRAME_MODE
,
587 USEM_REG_SLOW_DBG_ACTIVE
,
588 USEM_REG_SLOW_DBG_MODE
,
589 USEM_REG_DBG_MODE1_CFG
,
590 USEM_REG_SYNC_DBG_EMPTY
,
591 USEM_REG_DBG_GPRE_VECT
,
592 UCM_REG_CTX_RBC_ACCS
,
593 {UCM_REG_AGG_CON_CTX
, UCM_REG_SM_CON_CTX
, UCM_REG_AGG_TASK_CTX
,
594 UCM_REG_SM_TASK_CTX
},
595 {{2, 13, 3, 3}, {2, 13, 3, 3}} /* {bb} {k2} */
600 {DBG_BUS_CLIENT_RBCX
, DBG_BUS_CLIENT_RBCX
},
602 XSEM_REG_FAST_MEMORY
,
603 XSEM_REG_DBG_FRAME_MODE
,
604 XSEM_REG_SLOW_DBG_ACTIVE
,
605 XSEM_REG_SLOW_DBG_MODE
,
606 XSEM_REG_DBG_MODE1_CFG
,
607 XSEM_REG_SYNC_DBG_EMPTY
,
608 XSEM_REG_DBG_GPRE_VECT
,
609 XCM_REG_CTX_RBC_ACCS
,
610 {XCM_REG_AGG_CON_CTX
, XCM_REG_SM_CON_CTX
, 0, 0},
611 {{9, 15, 0, 0}, {9, 15, 0, 0}} /* {bb} {k2} */
616 {DBG_BUS_CLIENT_RBCX
, DBG_BUS_CLIENT_RBCY
},
618 YSEM_REG_FAST_MEMORY
,
619 YSEM_REG_DBG_FRAME_MODE
,
620 YSEM_REG_SLOW_DBG_ACTIVE
,
621 YSEM_REG_SLOW_DBG_MODE
,
622 YSEM_REG_DBG_MODE1_CFG
,
623 YSEM_REG_SYNC_DBG_EMPTY
,
624 YSEM_REG_DBG_GPRE_VECT
,
625 YCM_REG_CTX_RBC_ACCS
,
626 {YCM_REG_AGG_CON_CTX
, YCM_REG_SM_CON_CTX
, YCM_REG_AGG_TASK_CTX
,
627 YCM_REG_SM_TASK_CTX
},
628 {{2, 3, 2, 12}, {2, 3, 2, 12}} /* {bb} {k2} */
633 {DBG_BUS_CLIENT_RBCS
, DBG_BUS_CLIENT_RBCS
},
635 PSEM_REG_FAST_MEMORY
,
636 PSEM_REG_DBG_FRAME_MODE
,
637 PSEM_REG_SLOW_DBG_ACTIVE
,
638 PSEM_REG_SLOW_DBG_MODE
,
639 PSEM_REG_DBG_MODE1_CFG
,
640 PSEM_REG_SYNC_DBG_EMPTY
,
641 PSEM_REG_DBG_GPRE_VECT
,
642 PCM_REG_CTX_RBC_ACCS
,
643 {0, PCM_REG_SM_CON_CTX
, 0, 0},
644 {{0, 10, 0, 0}, {0, 10, 0, 0}} /* {bb} {k2} */
648 static struct hw_type_defs s_hw_type_defs
[] = {
650 {"asic", 1, 256, 32768},
651 {"reserved", 0, 0, 0},
652 {"reserved2", 0, 0, 0},
653 {"reserved3", 0, 0, 0},
654 {"reserved4", 0, 0, 0}
657 static struct grc_param_defs s_grc_param_defs
[] = {
658 /* DBG_GRC_PARAM_DUMP_TSTORM */
659 {{1, 1}, 0, 1, false, false, 1, {1, 1}},
661 /* DBG_GRC_PARAM_DUMP_MSTORM */
662 {{1, 1}, 0, 1, false, false, 1, {1, 1}},
664 /* DBG_GRC_PARAM_DUMP_USTORM */
665 {{1, 1}, 0, 1, false, false, 1, {1, 1}},
667 /* DBG_GRC_PARAM_DUMP_XSTORM */
668 {{1, 1}, 0, 1, false, false, 1, {1, 1}},
670 /* DBG_GRC_PARAM_DUMP_YSTORM */
671 {{1, 1}, 0, 1, false, false, 1, {1, 1}},
673 /* DBG_GRC_PARAM_DUMP_PSTORM */
674 {{1, 1}, 0, 1, false, false, 1, {1, 1}},
676 /* DBG_GRC_PARAM_DUMP_REGS */
677 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
679 /* DBG_GRC_PARAM_DUMP_RAM */
680 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
682 /* DBG_GRC_PARAM_DUMP_PBUF */
683 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
685 /* DBG_GRC_PARAM_DUMP_IOR */
686 {{0, 0}, 0, 1, false, false, 0, {1, 1}},
688 /* DBG_GRC_PARAM_DUMP_VFC */
689 {{0, 0}, 0, 1, false, false, 0, {1, 1}},
691 /* DBG_GRC_PARAM_DUMP_CM_CTX */
692 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
694 /* DBG_GRC_PARAM_DUMP_ILT */
695 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
697 /* DBG_GRC_PARAM_DUMP_RSS */
698 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
700 /* DBG_GRC_PARAM_DUMP_CAU */
701 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
703 /* DBG_GRC_PARAM_DUMP_QM */
704 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
706 /* DBG_GRC_PARAM_DUMP_MCP */
707 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
709 /* DBG_GRC_PARAM_DUMP_DORQ */
710 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
712 /* DBG_GRC_PARAM_DUMP_CFC */
713 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
715 /* DBG_GRC_PARAM_DUMP_IGU */
716 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
718 /* DBG_GRC_PARAM_DUMP_BRB */
719 {{0, 0}, 0, 1, false, false, 0, {1, 1}},
721 /* DBG_GRC_PARAM_DUMP_BTB */
722 {{0, 0}, 0, 1, false, false, 0, {1, 1}},
724 /* DBG_GRC_PARAM_DUMP_BMB */
725 {{0, 0}, 0, 1, false, false, 0, {0, 0}},
727 /* DBG_GRC_PARAM_RESERVED1 */
728 {{0, 0}, 0, 1, false, false, 0, {0, 0}},
730 /* DBG_GRC_PARAM_DUMP_MULD */
731 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
733 /* DBG_GRC_PARAM_DUMP_PRS */
734 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
736 /* DBG_GRC_PARAM_DUMP_DMAE */
737 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
739 /* DBG_GRC_PARAM_DUMP_TM */
740 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
742 /* DBG_GRC_PARAM_DUMP_SDM */
743 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
745 /* DBG_GRC_PARAM_DUMP_DIF */
746 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
748 /* DBG_GRC_PARAM_DUMP_STATIC */
749 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
751 /* DBG_GRC_PARAM_UNSTALL */
752 {{0, 0}, 0, 1, false, false, 0, {0, 0}},
754 /* DBG_GRC_PARAM_RESERVED2 */
755 {{0, 0}, 0, 1, false, false, 0, {0, 0}},
757 /* DBG_GRC_PARAM_MCP_TRACE_META_SIZE */
758 {{0, 0}, 1, 0xffffffff, false, true, 0, {0, 0}},
760 /* DBG_GRC_PARAM_EXCLUDE_ALL */
761 {{0, 0}, 0, 1, true, false, 0, {0, 0}},
763 /* DBG_GRC_PARAM_CRASH */
764 {{0, 0}, 0, 1, true, false, 0, {0, 0}},
766 /* DBG_GRC_PARAM_PARITY_SAFE */
767 {{0, 0}, 0, 1, false, false, 0, {0, 0}},
769 /* DBG_GRC_PARAM_DUMP_CM */
770 {{1, 1}, 0, 1, false, false, 0, {1, 1}},
772 /* DBG_GRC_PARAM_DUMP_PHY */
773 {{0, 0}, 0, 1, false, false, 0, {0, 0}},
775 /* DBG_GRC_PARAM_NO_MCP */
776 {{0, 0}, 0, 1, false, false, 0, {0, 0}},
778 /* DBG_GRC_PARAM_NO_FW_VER */
779 {{0, 0}, 0, 1, false, false, 0, {0, 0}},
781 /* DBG_GRC_PARAM_RESERVED3 */
782 {{0, 0}, 0, 1, false, false, 0, {0, 0}},
784 /* DBG_GRC_PARAM_DUMP_MCP_HW_DUMP */
785 {{0, 1}, 0, 1, false, false, 0, {0, 1}},
787 /* DBG_GRC_PARAM_DUMP_ILT_CDUC */
788 {{1, 1}, 0, 1, false, false, 0, {0, 0}},
790 /* DBG_GRC_PARAM_DUMP_ILT_CDUT */
791 {{1, 1}, 0, 1, false, false, 0, {0, 0}},
793 /* DBG_GRC_PARAM_DUMP_CAU_EXT */
794 {{0, 0}, 0, 1, false, false, 0, {1, 1}}
797 static struct rss_mem_defs s_rss_mem_defs
[] = {
798 {"rss_mem_cid", "rss_cid", 0, 32,
801 {"rss_mem_key_msb", "rss_key", 1024, 256,
804 {"rss_mem_key_lsb", "rss_key", 2048, 64,
807 {"rss_mem_info", "rss_info", 3072, 16,
810 {"rss_mem_ind", "rss_ind", 4096, 16,
814 static struct vfc_ram_defs s_vfc_ram_defs
[] = {
815 {"vfc_ram_tt1", "vfc_ram", 0, 512},
816 {"vfc_ram_mtt2", "vfc_ram", 512, 128},
817 {"vfc_ram_stt2", "vfc_ram", 640, 32},
818 {"vfc_ram_ro_vect", "vfc_ram", 672, 32}
821 static struct big_ram_defs s_big_ram_defs
[] = {
822 {"BRB", MEM_GROUP_BRB_MEM
, MEM_GROUP_BRB_RAM
, DBG_GRC_PARAM_DUMP_BRB
,
823 BRB_REG_BIG_RAM_ADDRESS
, BRB_REG_BIG_RAM_DATA
,
824 MISC_REG_BLOCK_256B_EN
, {0, 0},
827 {"BTB", MEM_GROUP_BTB_MEM
, MEM_GROUP_BTB_RAM
, DBG_GRC_PARAM_DUMP_BTB
,
828 BTB_REG_BIG_RAM_ADDRESS
, BTB_REG_BIG_RAM_DATA
,
829 MISC_REG_BLOCK_256B_EN
, {0, 1},
832 {"BMB", MEM_GROUP_BMB_MEM
, MEM_GROUP_BMB_RAM
, DBG_GRC_PARAM_DUMP_BMB
,
833 BMB_REG_BIG_RAM_ADDRESS
, BMB_REG_BIG_RAM_DATA
,
834 MISCS_REG_BLOCK_256B_EN
, {0, 0},
838 static struct rbc_reset_defs s_rbc_reset_defs
[] = {
839 {MISCS_REG_RESET_PL_HV
,
841 {MISC_REG_RESET_PL_PDA_VMAIN_1
,
842 {0x4404040, 0x4404040}},
843 {MISC_REG_RESET_PL_PDA_VMAIN_2
,
845 {MISC_REG_RESET_PL_PDA_VAUX
,
849 static struct phy_defs s_phy_defs
[] = {
850 {"nw_phy", NWS_REG_NWS_CMU_K2
,
851 PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_7_0_K2
,
852 PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_15_8_K2
,
853 PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_7_0_K2
,
854 PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_11_8_K2
},
855 {"sgmii_phy", MS_REG_MS_CMU_K2
,
856 PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X132_K2
,
857 PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X133_K2
,
858 PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X130_K2
,
859 PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X131_K2
},
860 {"pcie_phy0", PHY_PCIE_REG_PHY0_K2
,
861 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2
,
862 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2
,
863 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2
,
864 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2
},
865 {"pcie_phy1", PHY_PCIE_REG_PHY1_K2
,
866 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2
,
867 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2
,
868 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2
,
869 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2
},
872 static struct split_type_defs s_split_type_defs
[] = {
873 /* SPLIT_TYPE_NONE */
876 /* SPLIT_TYPE_PORT */
882 /* SPLIT_TYPE_PORT_PF */
889 /******************************** Variables **********************************/
891 /* The version of the calling app */
892 static u32 s_app_ver
;
894 /**************************** Private Functions ******************************/
896 static void qed_static_asserts(void)
900 /* Reads and returns a single dword from the specified unaligned buffer */
901 static u32
qed_read_unaligned_dword(u8
*buf
)
905 memcpy((u8
*)&dword
, buf
, sizeof(dword
));
909 /* Sets the value of the specified GRC param */
910 static void qed_grc_set_param(struct qed_hwfn
*p_hwfn
,
911 enum dbg_grc_params grc_param
, u32 val
)
913 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
915 dev_data
->grc
.param_val
[grc_param
] = val
;
918 /* Returns the value of the specified GRC param */
919 static u32
qed_grc_get_param(struct qed_hwfn
*p_hwfn
,
920 enum dbg_grc_params grc_param
)
922 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
924 return dev_data
->grc
.param_val
[grc_param
];
927 /* Initializes the GRC parameters */
928 static void qed_dbg_grc_init_params(struct qed_hwfn
*p_hwfn
)
930 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
932 if (!dev_data
->grc
.params_initialized
) {
933 qed_dbg_grc_set_params_default(p_hwfn
);
934 dev_data
->grc
.params_initialized
= 1;
938 /* Sets pointer and size for the specified binary buffer type */
939 static void qed_set_dbg_bin_buf(struct qed_hwfn
*p_hwfn
,
940 enum bin_dbg_buffer_type buf_type
,
941 const u32
*ptr
, u32 size
)
943 struct virt_mem_desc
*buf
= &p_hwfn
->dbg_arrays
[buf_type
];
945 buf
->ptr
= (void *)ptr
;
949 /* Initializes debug data for the specified device */
950 static enum dbg_status
qed_dbg_dev_init(struct qed_hwfn
*p_hwfn
)
952 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
953 u8 num_pfs
= 0, max_pfs_per_port
= 0;
955 if (dev_data
->initialized
)
956 return DBG_STATUS_OK
;
959 return DBG_STATUS_APP_VERSION_NOT_SET
;
962 if (QED_IS_K2(p_hwfn
->cdev
)) {
963 dev_data
->chip_id
= CHIP_K2
;
964 dev_data
->mode_enable
[MODE_K2
] = 1;
965 dev_data
->num_vfs
= MAX_NUM_VFS_K2
;
966 num_pfs
= MAX_NUM_PFS_K2
;
967 max_pfs_per_port
= MAX_NUM_PFS_K2
/ 2;
968 } else if (QED_IS_BB_B0(p_hwfn
->cdev
)) {
969 dev_data
->chip_id
= CHIP_BB
;
970 dev_data
->mode_enable
[MODE_BB
] = 1;
971 dev_data
->num_vfs
= MAX_NUM_VFS_BB
;
972 num_pfs
= MAX_NUM_PFS_BB
;
973 max_pfs_per_port
= MAX_NUM_PFS_BB
;
975 return DBG_STATUS_UNKNOWN_CHIP
;
979 dev_data
->hw_type
= HW_TYPE_ASIC
;
980 dev_data
->mode_enable
[MODE_ASIC
] = 1;
983 switch (p_hwfn
->cdev
->num_ports_in_engine
) {
985 dev_data
->mode_enable
[MODE_PORTS_PER_ENG_1
] = 1;
988 dev_data
->mode_enable
[MODE_PORTS_PER_ENG_2
] = 1;
991 dev_data
->mode_enable
[MODE_PORTS_PER_ENG_4
] = 1;
996 if (QED_IS_CMT(p_hwfn
->cdev
))
997 dev_data
->mode_enable
[MODE_100G
] = 1;
999 /* Set number of ports */
1000 if (dev_data
->mode_enable
[MODE_PORTS_PER_ENG_1
] ||
1001 dev_data
->mode_enable
[MODE_100G
])
1002 dev_data
->num_ports
= 1;
1003 else if (dev_data
->mode_enable
[MODE_PORTS_PER_ENG_2
])
1004 dev_data
->num_ports
= 2;
1005 else if (dev_data
->mode_enable
[MODE_PORTS_PER_ENG_4
])
1006 dev_data
->num_ports
= 4;
1008 /* Set number of PFs per port */
1009 dev_data
->num_pfs_per_port
= min_t(u32
,
1010 num_pfs
/ dev_data
->num_ports
,
1013 /* Initializes the GRC parameters */
1014 qed_dbg_grc_init_params(p_hwfn
);
1016 dev_data
->use_dmae
= true;
1017 dev_data
->initialized
= 1;
1019 return DBG_STATUS_OK
;
1022 static const struct dbg_block
*get_dbg_block(struct qed_hwfn
*p_hwfn
,
1023 enum block_id block_id
)
1025 const struct dbg_block
*dbg_block
;
1027 dbg_block
= p_hwfn
->dbg_arrays
[BIN_BUF_DBG_BLOCKS
].ptr
;
1028 return dbg_block
+ block_id
;
1031 static const struct dbg_block_chip
*qed_get_dbg_block_per_chip(struct qed_hwfn
1036 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
1038 return (const struct dbg_block_chip
*)
1039 p_hwfn
->dbg_arrays
[BIN_BUF_DBG_BLOCKS_CHIP_DATA
].ptr
+
1040 block_id
* MAX_CHIP_IDS
+ dev_data
->chip_id
;
1043 static const struct dbg_reset_reg
*qed_get_dbg_reset_reg(struct qed_hwfn
1047 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
1049 return (const struct dbg_reset_reg
*)
1050 p_hwfn
->dbg_arrays
[BIN_BUF_DBG_RESET_REGS
].ptr
+
1051 reset_reg_id
* MAX_CHIP_IDS
+ dev_data
->chip_id
;
1054 /* Reads the FW info structure for the specified Storm from the chip,
1055 * and writes it to the specified fw_info pointer.
1057 static void qed_read_storm_fw_info(struct qed_hwfn
*p_hwfn
,
1058 struct qed_ptt
*p_ptt
,
1059 u8 storm_id
, struct fw_info
*fw_info
)
1061 struct storm_defs
*storm
= &s_storm_defs
[storm_id
];
1062 struct fw_info_location fw_info_location
;
1063 u32 addr
, i
, size
, *dest
;
1065 memset(&fw_info_location
, 0, sizeof(fw_info_location
));
1066 memset(fw_info
, 0, sizeof(*fw_info
));
1068 /* Read first the address that points to fw_info location.
1069 * The address is located in the last line of the Storm RAM.
1071 addr
= storm
->sem_fast_mem_addr
+ SEM_FAST_REG_INT_RAM
+
1072 DWORDS_TO_BYTES(SEM_FAST_REG_INT_RAM_SIZE
) -
1073 sizeof(fw_info_location
);
1075 dest
= (u32
*)&fw_info_location
;
1076 size
= BYTES_TO_DWORDS(sizeof(fw_info_location
));
1078 for (i
= 0; i
< size
; i
++, addr
+= BYTES_IN_DWORD
)
1079 dest
[i
] = qed_rd(p_hwfn
, p_ptt
, addr
);
1081 /* Read FW version info from Storm RAM */
1082 size
= le32_to_cpu(fw_info_location
.size
);
1083 if (!size
|| size
> sizeof(*fw_info
))
1086 addr
= le32_to_cpu(fw_info_location
.grc_addr
);
1087 dest
= (u32
*)fw_info
;
1088 size
= BYTES_TO_DWORDS(size
);
1090 for (i
= 0; i
< size
; i
++, addr
+= BYTES_IN_DWORD
)
1091 dest
[i
] = qed_rd(p_hwfn
, p_ptt
, addr
);
1094 /* Dumps the specified string to the specified buffer.
1095 * Returns the dumped size in bytes.
1097 static u32
qed_dump_str(char *dump_buf
, bool dump
, const char *str
)
1100 strcpy(dump_buf
, str
);
1102 return (u32
)strlen(str
) + 1;
1105 /* Dumps zeros to align the specified buffer to dwords.
1106 * Returns the dumped size in bytes.
1108 static u32
qed_dump_align(char *dump_buf
, bool dump
, u32 byte_offset
)
1110 u8 offset_in_dword
, align_size
;
1112 offset_in_dword
= (u8
)(byte_offset
& 0x3);
1113 align_size
= offset_in_dword
? BYTES_IN_DWORD
- offset_in_dword
: 0;
1115 if (dump
&& align_size
)
1116 memset(dump_buf
, 0, align_size
);
1121 /* Writes the specified string param to the specified buffer.
1122 * Returns the dumped size in dwords.
1124 static u32
qed_dump_str_param(u32
*dump_buf
,
1126 const char *param_name
, const char *param_val
)
1128 char *char_buf
= (char *)dump_buf
;
1131 /* Dump param name */
1132 offset
+= qed_dump_str(char_buf
+ offset
, dump
, param_name
);
1134 /* Indicate a string param value */
1136 *(char_buf
+ offset
) = 1;
1139 /* Dump param value */
1140 offset
+= qed_dump_str(char_buf
+ offset
, dump
, param_val
);
1142 /* Align buffer to next dword */
1143 offset
+= qed_dump_align(char_buf
+ offset
, dump
, offset
);
1145 return BYTES_TO_DWORDS(offset
);
1148 /* Writes the specified numeric param to the specified buffer.
1149 * Returns the dumped size in dwords.
1151 static u32
qed_dump_num_param(u32
*dump_buf
,
1152 bool dump
, const char *param_name
, u32 param_val
)
1154 char *char_buf
= (char *)dump_buf
;
1157 /* Dump param name */
1158 offset
+= qed_dump_str(char_buf
+ offset
, dump
, param_name
);
1160 /* Indicate a numeric param value */
1162 *(char_buf
+ offset
) = 0;
1165 /* Align buffer to next dword */
1166 offset
+= qed_dump_align(char_buf
+ offset
, dump
, offset
);
1168 /* Dump param value (and change offset from bytes to dwords) */
1169 offset
= BYTES_TO_DWORDS(offset
);
1171 *(dump_buf
+ offset
) = param_val
;
1177 /* Reads the FW version and writes it as a param to the specified buffer.
1178 * Returns the dumped size in dwords.
1180 static u32
qed_dump_fw_ver_param(struct qed_hwfn
*p_hwfn
,
1181 struct qed_ptt
*p_ptt
,
1182 u32
*dump_buf
, bool dump
)
1184 char fw_ver_str
[16] = EMPTY_FW_VERSION_STR
;
1185 char fw_img_str
[16] = EMPTY_FW_IMAGE_STR
;
1186 struct fw_info fw_info
= { {0}, {0} };
1189 if (dump
&& !qed_grc_get_param(p_hwfn
, DBG_GRC_PARAM_NO_FW_VER
)) {
1190 /* Read FW info from chip */
1191 qed_read_fw_info(p_hwfn
, p_ptt
, &fw_info
);
1193 /* Create FW version/image strings */
1194 if (snprintf(fw_ver_str
, sizeof(fw_ver_str
),
1195 "%d_%d_%d_%d", fw_info
.ver
.num
.major
,
1196 fw_info
.ver
.num
.minor
, fw_info
.ver
.num
.rev
,
1197 fw_info
.ver
.num
.eng
) < 0)
1199 "Unexpected debug error: invalid FW version string\n");
1200 switch (fw_info
.ver
.image_id
) {
1202 strcpy(fw_img_str
, "kuku");
1205 strcpy(fw_img_str
, "main");
1208 strcpy(fw_img_str
, "l2b");
1211 strcpy(fw_img_str
, "unknown");
1216 /* Dump FW version, image and timestamp */
1217 offset
+= qed_dump_str_param(dump_buf
+ offset
,
1218 dump
, "fw-version", fw_ver_str
);
1219 offset
+= qed_dump_str_param(dump_buf
+ offset
,
1220 dump
, "fw-image", fw_img_str
);
1221 offset
+= qed_dump_num_param(dump_buf
+ offset
, dump
, "fw-timestamp",
1222 le32_to_cpu(fw_info
.ver
.timestamp
));
1227 /* Reads the MFW version and writes it as a param to the specified buffer.
1228 * Returns the dumped size in dwords.
1230 static u32
qed_dump_mfw_ver_param(struct qed_hwfn
*p_hwfn
,
1231 struct qed_ptt
*p_ptt
,
1232 u32
*dump_buf
, bool dump
)
1234 char mfw_ver_str
[16] = EMPTY_FW_VERSION_STR
;
1237 !qed_grc_get_param(p_hwfn
, DBG_GRC_PARAM_NO_FW_VER
)) {
1238 u32 global_section_offsize
, global_section_addr
, mfw_ver
;
1239 u32 public_data_addr
, global_section_offsize_addr
;
1241 /* Find MCP public data GRC address. Needs to be ORed with
1242 * MCP_REG_SCRATCH due to a HW bug.
1244 public_data_addr
= qed_rd(p_hwfn
,
1246 MISC_REG_SHARED_MEM_ADDR
) |
1249 /* Find MCP public global section offset */
1250 global_section_offsize_addr
= public_data_addr
+
1251 offsetof(struct mcp_public_data
,
1253 sizeof(offsize_t
) * PUBLIC_GLOBAL
;
1254 global_section_offsize
= qed_rd(p_hwfn
, p_ptt
,
1255 global_section_offsize_addr
);
1256 global_section_addr
=
1258 (global_section_offsize
& OFFSIZE_OFFSET_MASK
) * 4;
1260 /* Read MFW version from MCP public global section */
1261 mfw_ver
= qed_rd(p_hwfn
, p_ptt
,
1262 global_section_addr
+
1263 offsetof(struct public_global
, mfw_ver
));
1265 /* Dump MFW version param */
1266 if (snprintf(mfw_ver_str
, sizeof(mfw_ver_str
), "%d_%d_%d_%d",
1267 (u8
)(mfw_ver
>> 24), (u8
)(mfw_ver
>> 16),
1268 (u8
)(mfw_ver
>> 8), (u8
)mfw_ver
) < 0)
1270 "Unexpected debug error: invalid MFW version string\n");
1273 return qed_dump_str_param(dump_buf
, dump
, "mfw-version", mfw_ver_str
);
1276 /* Reads the chip revision from the chip and writes it as a param to the
1277 * specified buffer. Returns the dumped size in dwords.
1279 static u32
qed_dump_chip_revision_param(struct qed_hwfn
*p_hwfn
,
1280 struct qed_ptt
*p_ptt
,
1281 u32
*dump_buf
, bool dump
)
1283 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
1284 char param_str
[3] = "??";
1286 if (dev_data
->hw_type
== HW_TYPE_ASIC
) {
1287 u32 chip_rev
, chip_metal
;
1289 chip_rev
= qed_rd(p_hwfn
, p_ptt
, MISCS_REG_CHIP_REV
);
1290 chip_metal
= qed_rd(p_hwfn
, p_ptt
, MISCS_REG_CHIP_METAL
);
1292 param_str
[0] = 'a' + (u8
)chip_rev
;
1293 param_str
[1] = '0' + (u8
)chip_metal
;
1296 return qed_dump_str_param(dump_buf
, dump
, "chip-revision", param_str
);
1299 /* Writes a section header to the specified buffer.
1300 * Returns the dumped size in dwords.
1302 static u32
qed_dump_section_hdr(u32
*dump_buf
,
1303 bool dump
, const char *name
, u32 num_params
)
1305 return qed_dump_num_param(dump_buf
, dump
, name
, num_params
);
1308 /* Writes the common global params to the specified buffer.
1309 * Returns the dumped size in dwords.
1311 static u32
qed_dump_common_global_params(struct qed_hwfn
*p_hwfn
,
1312 struct qed_ptt
*p_ptt
,
1315 u8 num_specific_global_params
)
1317 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
1321 /* Dump global params section header */
1322 num_params
= NUM_COMMON_GLOBAL_PARAMS
+ num_specific_global_params
+
1323 (dev_data
->chip_id
== CHIP_BB
? 1 : 0);
1324 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
1325 dump
, "global_params", num_params
);
1328 offset
+= qed_dump_fw_ver_param(p_hwfn
, p_ptt
, dump_buf
+ offset
, dump
);
1329 offset
+= qed_dump_mfw_ver_param(p_hwfn
,
1330 p_ptt
, dump_buf
+ offset
, dump
);
1331 offset
+= qed_dump_chip_revision_param(p_hwfn
,
1332 p_ptt
, dump_buf
+ offset
, dump
);
1333 offset
+= qed_dump_num_param(dump_buf
+ offset
,
1334 dump
, "tools-version", TOOLS_VERSION
);
1335 offset
+= qed_dump_str_param(dump_buf
+ offset
,
1338 s_chip_defs
[dev_data
->chip_id
].name
);
1339 offset
+= qed_dump_str_param(dump_buf
+ offset
,
1342 s_hw_type_defs
[dev_data
->hw_type
].name
);
1343 offset
+= qed_dump_num_param(dump_buf
+ offset
,
1344 dump
, "pci-func", p_hwfn
->abs_pf_id
);
1345 offset
+= qed_dump_num_param(dump_buf
+ offset
,
1346 dump
, "epoch", qed_get_epoch_time());
1347 if (dev_data
->chip_id
== CHIP_BB
)
1348 offset
+= qed_dump_num_param(dump_buf
+ offset
,
1349 dump
, "path", QED_PATH_ID(p_hwfn
));
1354 /* Writes the "last" section (including CRC) to the specified buffer at the
1355 * given offset. Returns the dumped size in dwords.
1357 static u32
qed_dump_last_section(u32
*dump_buf
, u32 offset
, bool dump
)
1359 u32 start_offset
= offset
;
1361 /* Dump CRC section header */
1362 offset
+= qed_dump_section_hdr(dump_buf
+ offset
, dump
, "last", 0);
1364 /* Calculate CRC32 and add it to the dword after the "last" section */
1366 *(dump_buf
+ offset
) = ~crc32(0xffffffff,
1368 DWORDS_TO_BYTES(offset
));
1372 return offset
- start_offset
;
1375 /* Update blocks reset state */
1376 static void qed_update_blocks_reset_state(struct qed_hwfn
*p_hwfn
,
1377 struct qed_ptt
*p_ptt
)
1379 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
1380 u32 reg_val
[NUM_DBG_RESET_REGS
] = { 0 };
1384 /* Read reset registers */
1385 for (rst_reg_id
= 0; rst_reg_id
< NUM_DBG_RESET_REGS
; rst_reg_id
++) {
1386 const struct dbg_reset_reg
*rst_reg
;
1387 bool rst_reg_removed
;
1390 rst_reg
= qed_get_dbg_reset_reg(p_hwfn
, rst_reg_id
);
1391 rst_reg_removed
= GET_FIELD(rst_reg
->data
,
1392 DBG_RESET_REG_IS_REMOVED
);
1393 rst_reg_addr
= DWORDS_TO_BYTES(GET_FIELD(rst_reg
->data
,
1394 DBG_RESET_REG_ADDR
));
1396 if (!rst_reg_removed
)
1397 reg_val
[rst_reg_id
] = qed_rd(p_hwfn
, p_ptt
,
1401 /* Check if blocks are in reset */
1402 for (blk_id
= 0; blk_id
< NUM_PHYS_BLOCKS
; blk_id
++) {
1403 const struct dbg_block_chip
*blk
;
1407 blk
= qed_get_dbg_block_per_chip(p_hwfn
, (enum block_id
)blk_id
);
1408 is_removed
= GET_FIELD(blk
->flags
, DBG_BLOCK_CHIP_IS_REMOVED
);
1409 has_rst_reg
= GET_FIELD(blk
->flags
,
1410 DBG_BLOCK_CHIP_HAS_RESET_REG
);
1412 if (!is_removed
&& has_rst_reg
)
1413 dev_data
->block_in_reset
[blk_id
] =
1414 !(reg_val
[blk
->reset_reg_id
] &
1415 BIT(blk
->reset_reg_bit_offset
));
1419 /* is_mode_match recursive function */
1420 static bool qed_is_mode_match_rec(struct qed_hwfn
*p_hwfn
,
1421 u16
*modes_buf_offset
, u8 rec_depth
)
1423 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
1428 if (rec_depth
> MAX_RECURSION_DEPTH
) {
1430 "Unexpected error: is_mode_match_rec exceeded the max recursion depth. This is probably due to a corrupt init/debug buffer.\n");
1434 /* Get next element from modes tree buffer */
1435 dbg_array
= p_hwfn
->dbg_arrays
[BIN_BUF_DBG_MODE_TREE
].ptr
;
1436 tree_val
= dbg_array
[(*modes_buf_offset
)++];
1439 case INIT_MODE_OP_NOT
:
1440 return !qed_is_mode_match_rec(p_hwfn
,
1441 modes_buf_offset
, rec_depth
+ 1);
1442 case INIT_MODE_OP_OR
:
1443 case INIT_MODE_OP_AND
:
1444 arg1
= qed_is_mode_match_rec(p_hwfn
,
1445 modes_buf_offset
, rec_depth
+ 1);
1446 arg2
= qed_is_mode_match_rec(p_hwfn
,
1447 modes_buf_offset
, rec_depth
+ 1);
1448 return (tree_val
== INIT_MODE_OP_OR
) ? (arg1
||
1449 arg2
) : (arg1
&& arg2
);
1451 return dev_data
->mode_enable
[tree_val
- MAX_INIT_MODE_OPS
] > 0;
1455 /* Returns true if the mode (specified using modes_buf_offset) is enabled */
1456 static bool qed_is_mode_match(struct qed_hwfn
*p_hwfn
, u16
*modes_buf_offset
)
1458 return qed_is_mode_match_rec(p_hwfn
, modes_buf_offset
, 0);
1461 /* Enable / disable the Debug block */
1462 static void qed_bus_enable_dbg_block(struct qed_hwfn
*p_hwfn
,
1463 struct qed_ptt
*p_ptt
, bool enable
)
1465 qed_wr(p_hwfn
, p_ptt
, DBG_REG_DBG_BLOCK_ON
, enable
? 1 : 0);
1468 /* Resets the Debug block */
1469 static void qed_bus_reset_dbg_block(struct qed_hwfn
*p_hwfn
,
1470 struct qed_ptt
*p_ptt
)
1472 u32 reset_reg_addr
, old_reset_reg_val
, new_reset_reg_val
;
1473 const struct dbg_reset_reg
*reset_reg
;
1474 const struct dbg_block_chip
*block
;
1476 block
= qed_get_dbg_block_per_chip(p_hwfn
, BLOCK_DBG
);
1477 reset_reg
= qed_get_dbg_reset_reg(p_hwfn
, block
->reset_reg_id
);
1479 DWORDS_TO_BYTES(GET_FIELD(reset_reg
->data
, DBG_RESET_REG_ADDR
));
1481 old_reset_reg_val
= qed_rd(p_hwfn
, p_ptt
, reset_reg_addr
);
1483 old_reset_reg_val
& ~BIT(block
->reset_reg_bit_offset
);
1485 qed_wr(p_hwfn
, p_ptt
, reset_reg_addr
, new_reset_reg_val
);
1486 qed_wr(p_hwfn
, p_ptt
, reset_reg_addr
, old_reset_reg_val
);
1489 /* Enable / disable Debug Bus clients according to the specified mask
1490 * (1 = enable, 0 = disable).
1492 static void qed_bus_enable_clients(struct qed_hwfn
*p_hwfn
,
1493 struct qed_ptt
*p_ptt
, u32 client_mask
)
1495 qed_wr(p_hwfn
, p_ptt
, DBG_REG_CLIENT_ENABLE
, client_mask
);
1498 static void qed_bus_config_dbg_line(struct qed_hwfn
*p_hwfn
,
1499 struct qed_ptt
*p_ptt
,
1500 enum block_id block_id
,
1504 u8 force_valid_mask
, u8 force_frame_mask
)
1506 const struct dbg_block_chip
*block
=
1507 qed_get_dbg_block_per_chip(p_hwfn
, block_id
);
1509 qed_wr(p_hwfn
, p_ptt
, DWORDS_TO_BYTES(block
->dbg_select_reg_addr
),
1511 qed_wr(p_hwfn
, p_ptt
, DWORDS_TO_BYTES(block
->dbg_dword_enable_reg_addr
),
1513 qed_wr(p_hwfn
, p_ptt
, DWORDS_TO_BYTES(block
->dbg_shift_reg_addr
),
1515 qed_wr(p_hwfn
, p_ptt
, DWORDS_TO_BYTES(block
->dbg_force_valid_reg_addr
),
1517 qed_wr(p_hwfn
, p_ptt
, DWORDS_TO_BYTES(block
->dbg_force_frame_reg_addr
),
1521 /* Disable debug bus in all blocks */
1522 static void qed_bus_disable_blocks(struct qed_hwfn
*p_hwfn
,
1523 struct qed_ptt
*p_ptt
)
1525 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
1528 /* Disable all blocks */
1529 for (block_id
= 0; block_id
< MAX_BLOCK_ID
; block_id
++) {
1530 const struct dbg_block_chip
*block_per_chip
=
1531 qed_get_dbg_block_per_chip(p_hwfn
,
1532 (enum block_id
)block_id
);
1534 if (GET_FIELD(block_per_chip
->flags
,
1535 DBG_BLOCK_CHIP_IS_REMOVED
) ||
1536 dev_data
->block_in_reset
[block_id
])
1539 /* Disable debug bus */
1540 if (GET_FIELD(block_per_chip
->flags
,
1541 DBG_BLOCK_CHIP_HAS_DBG_BUS
)) {
1543 block_per_chip
->dbg_dword_enable_reg_addr
;
1544 u16 modes_buf_offset
=
1545 GET_FIELD(block_per_chip
->dbg_bus_mode
.data
,
1546 DBG_MODE_HDR_MODES_BUF_OFFSET
);
1548 GET_FIELD(block_per_chip
->dbg_bus_mode
.data
,
1549 DBG_MODE_HDR_EVAL_MODE
) > 0;
1552 qed_is_mode_match(p_hwfn
, &modes_buf_offset
))
1553 qed_wr(p_hwfn
, p_ptt
,
1554 DWORDS_TO_BYTES(dbg_en_addr
),
1560 /* Returns true if the specified entity (indicated by GRC param) should be
1561 * included in the dump, false otherwise.
1563 static bool qed_grc_is_included(struct qed_hwfn
*p_hwfn
,
1564 enum dbg_grc_params grc_param
)
1566 return qed_grc_get_param(p_hwfn
, grc_param
) > 0;
1569 /* Returns the storm_id that matches the specified Storm letter,
1570 * or MAX_DBG_STORMS if invalid storm letter.
1572 static enum dbg_storms
qed_get_id_from_letter(char storm_letter
)
1576 for (storm_id
= 0; storm_id
< MAX_DBG_STORMS
; storm_id
++)
1577 if (s_storm_defs
[storm_id
].letter
== storm_letter
)
1578 return (enum dbg_storms
)storm_id
;
1580 return MAX_DBG_STORMS
;
1583 /* Returns true of the specified Storm should be included in the dump, false
1586 static bool qed_grc_is_storm_included(struct qed_hwfn
*p_hwfn
,
1587 enum dbg_storms storm
)
1589 return qed_grc_get_param(p_hwfn
, (enum dbg_grc_params
)storm
) > 0;
1592 /* Returns true if the specified memory should be included in the dump, false
1595 static bool qed_grc_is_mem_included(struct qed_hwfn
*p_hwfn
,
1596 enum block_id block_id
, u8 mem_group_id
)
1598 const struct dbg_block
*block
;
1601 block
= get_dbg_block(p_hwfn
, block_id
);
1603 /* If the block is associated with a Storm, check Storm match */
1604 if (block
->associated_storm_letter
) {
1605 enum dbg_storms associated_storm_id
=
1606 qed_get_id_from_letter(block
->associated_storm_letter
);
1608 if (associated_storm_id
== MAX_DBG_STORMS
||
1609 !qed_grc_is_storm_included(p_hwfn
, associated_storm_id
))
1613 for (i
= 0; i
< NUM_BIG_RAM_TYPES
; i
++) {
1614 struct big_ram_defs
*big_ram
= &s_big_ram_defs
[i
];
1616 if (mem_group_id
== big_ram
->mem_group_id
||
1617 mem_group_id
== big_ram
->ram_mem_group_id
)
1618 return qed_grc_is_included(p_hwfn
, big_ram
->grc_param
);
1621 switch (mem_group_id
) {
1622 case MEM_GROUP_PXP_ILT
:
1623 case MEM_GROUP_PXP_MEM
:
1624 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_PXP
);
1626 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_RAM
);
1627 case MEM_GROUP_PBUF
:
1628 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_PBUF
);
1629 case MEM_GROUP_CAU_MEM
:
1630 case MEM_GROUP_CAU_SB
:
1631 case MEM_GROUP_CAU_PI
:
1632 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_CAU
);
1633 case MEM_GROUP_CAU_MEM_EXT
:
1634 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_CAU_EXT
);
1635 case MEM_GROUP_QM_MEM
:
1636 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_QM
);
1637 case MEM_GROUP_CFC_MEM
:
1638 case MEM_GROUP_CONN_CFC_MEM
:
1639 case MEM_GROUP_TASK_CFC_MEM
:
1640 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_CFC
) ||
1641 qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_CM_CTX
);
1642 case MEM_GROUP_DORQ_MEM
:
1643 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_DORQ
);
1644 case MEM_GROUP_IGU_MEM
:
1645 case MEM_GROUP_IGU_MSIX
:
1646 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_IGU
);
1647 case MEM_GROUP_MULD_MEM
:
1648 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_MULD
);
1649 case MEM_GROUP_PRS_MEM
:
1650 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_PRS
);
1651 case MEM_GROUP_DMAE_MEM
:
1652 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_DMAE
);
1653 case MEM_GROUP_TM_MEM
:
1654 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_TM
);
1655 case MEM_GROUP_SDM_MEM
:
1656 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_SDM
);
1657 case MEM_GROUP_TDIF_CTX
:
1658 case MEM_GROUP_RDIF_CTX
:
1659 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_DIF
);
1660 case MEM_GROUP_CM_MEM
:
1661 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_CM
);
1663 return qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_IOR
);
1669 /* Stalls all Storms */
1670 static void qed_grc_stall_storms(struct qed_hwfn
*p_hwfn
,
1671 struct qed_ptt
*p_ptt
, bool stall
)
1676 for (storm_id
= 0; storm_id
< MAX_DBG_STORMS
; storm_id
++) {
1677 if (!qed_grc_is_storm_included(p_hwfn
,
1678 (enum dbg_storms
)storm_id
))
1681 reg_addr
= s_storm_defs
[storm_id
].sem_fast_mem_addr
+
1682 SEM_FAST_REG_STALL_0
;
1683 qed_wr(p_hwfn
, p_ptt
, reg_addr
, stall
? 1 : 0);
1686 msleep(STALL_DELAY_MS
);
1689 /* Takes all blocks out of reset. If rbc_only is true, only RBC clients are
1690 * taken out of reset.
1692 static void qed_grc_unreset_blocks(struct qed_hwfn
*p_hwfn
,
1693 struct qed_ptt
*p_ptt
, bool rbc_only
)
1695 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
1696 u8 chip_id
= dev_data
->chip_id
;
1699 /* Take RBCs out of reset */
1700 for (i
= 0; i
< ARRAY_SIZE(s_rbc_reset_defs
); i
++)
1701 if (s_rbc_reset_defs
[i
].reset_val
[dev_data
->chip_id
])
1704 s_rbc_reset_defs
[i
].reset_reg_addr
+
1705 RESET_REG_UNRESET_OFFSET
,
1706 s_rbc_reset_defs
[i
].reset_val
[chip_id
]);
1709 u32 reg_val
[NUM_DBG_RESET_REGS
] = { 0 };
1713 /* Fill reset regs values */
1714 for (block_id
= 0; block_id
< NUM_PHYS_BLOCKS
; block_id
++) {
1715 bool is_removed
, has_reset_reg
, unreset_before_dump
;
1716 const struct dbg_block_chip
*block
;
1718 block
= qed_get_dbg_block_per_chip(p_hwfn
,
1722 GET_FIELD(block
->flags
, DBG_BLOCK_CHIP_IS_REMOVED
);
1724 GET_FIELD(block
->flags
,
1725 DBG_BLOCK_CHIP_HAS_RESET_REG
);
1726 unreset_before_dump
=
1727 GET_FIELD(block
->flags
,
1728 DBG_BLOCK_CHIP_UNRESET_BEFORE_DUMP
);
1730 if (!is_removed
&& has_reset_reg
&& unreset_before_dump
)
1731 reg_val
[block
->reset_reg_id
] |=
1732 BIT(block
->reset_reg_bit_offset
);
1735 /* Write reset registers */
1736 for (reset_reg_id
= 0; reset_reg_id
< NUM_DBG_RESET_REGS
;
1738 const struct dbg_reset_reg
*reset_reg
;
1741 reset_reg
= qed_get_dbg_reset_reg(p_hwfn
, reset_reg_id
);
1744 (reset_reg
->data
, DBG_RESET_REG_IS_REMOVED
))
1747 if (reg_val
[reset_reg_id
]) {
1749 GET_FIELD(reset_reg
->data
,
1750 DBG_RESET_REG_ADDR
);
1753 DWORDS_TO_BYTES(reset_reg_addr
) +
1754 RESET_REG_UNRESET_OFFSET
,
1755 reg_val
[reset_reg_id
]);
1761 /* Returns the attention block data of the specified block */
1762 static const struct dbg_attn_block_type_data
*
1763 qed_get_block_attn_data(struct qed_hwfn
*p_hwfn
,
1764 enum block_id block_id
, enum dbg_attn_type attn_type
)
1766 const struct dbg_attn_block
*base_attn_block_arr
=
1767 (const struct dbg_attn_block
*)
1768 p_hwfn
->dbg_arrays
[BIN_BUF_DBG_ATTN_BLOCKS
].ptr
;
1770 return &base_attn_block_arr
[block_id
].per_type_data
[attn_type
];
1773 /* Returns the attention registers of the specified block */
1774 static const struct dbg_attn_reg
*
1775 qed_get_block_attn_regs(struct qed_hwfn
*p_hwfn
,
1776 enum block_id block_id
, enum dbg_attn_type attn_type
,
1779 const struct dbg_attn_block_type_data
*block_type_data
=
1780 qed_get_block_attn_data(p_hwfn
, block_id
, attn_type
);
1782 *num_attn_regs
= block_type_data
->num_regs
;
1784 return (const struct dbg_attn_reg
*)
1785 p_hwfn
->dbg_arrays
[BIN_BUF_DBG_ATTN_REGS
].ptr
+
1786 block_type_data
->regs_offset
;
1789 /* For each block, clear the status of all parities */
1790 static void qed_grc_clear_all_prty(struct qed_hwfn
*p_hwfn
,
1791 struct qed_ptt
*p_ptt
)
1793 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
1794 const struct dbg_attn_reg
*attn_reg_arr
;
1795 u32 block_id
, sts_clr_address
;
1796 u8 reg_idx
, num_attn_regs
;
1798 for (block_id
= 0; block_id
< NUM_PHYS_BLOCKS
; block_id
++) {
1799 if (dev_data
->block_in_reset
[block_id
])
1802 attn_reg_arr
= qed_get_block_attn_regs(p_hwfn
,
1803 (enum block_id
)block_id
,
1807 for (reg_idx
= 0; reg_idx
< num_attn_regs
; reg_idx
++) {
1808 const struct dbg_attn_reg
*reg_data
=
1809 &attn_reg_arr
[reg_idx
];
1810 u16 modes_buf_offset
;
1814 eval_mode
= GET_FIELD(reg_data
->mode
.data
,
1815 DBG_MODE_HDR_EVAL_MODE
) > 0;
1817 GET_FIELD(reg_data
->mode
.data
,
1818 DBG_MODE_HDR_MODES_BUF_OFFSET
);
1820 sts_clr_address
= reg_data
->sts_clr_address
;
1821 /* If Mode match: clear parity status */
1823 qed_is_mode_match(p_hwfn
, &modes_buf_offset
))
1824 qed_rd(p_hwfn
, p_ptt
,
1825 DWORDS_TO_BYTES(sts_clr_address
));
1830 /* Finds the meta data image in NVRAM */
1831 static enum dbg_status
qed_find_nvram_image(struct qed_hwfn
*p_hwfn
,
1832 struct qed_ptt
*p_ptt
,
1834 u32
*nvram_offset_bytes
,
1835 u32
*nvram_size_bytes
,
1838 u32 ret_mcp_resp
, ret_mcp_param
, ret_txn_size
;
1839 struct mcp_file_att file_att
;
1842 /* Call NVRAM get file command */
1843 nvm_result
= qed_mcp_nvm_rd_cmd(p_hwfn
,
1845 DRV_MSG_CODE_NVM_GET_FILE_ATT
,
1853 /* Check response */
1854 if (nvm_result
|| (ret_mcp_resp
& FW_MSG_CODE_MASK
) !=
1856 return DBG_STATUS_NVRAM_GET_IMAGE_FAILED
;
1858 /* Update return values */
1859 *nvram_offset_bytes
= file_att
.nvm_start_addr
;
1860 *nvram_size_bytes
= file_att
.len
;
1864 "find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\n",
1865 image_type
, *nvram_offset_bytes
, *nvram_size_bytes
);
1867 /* Check alignment */
1868 if (*nvram_size_bytes
& 0x3)
1869 return DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE
;
1871 return DBG_STATUS_OK
;
1874 /* Reads data from NVRAM */
1875 static enum dbg_status
qed_nvram_read(struct qed_hwfn
*p_hwfn
,
1876 struct qed_ptt
*p_ptt
,
1877 u32 nvram_offset_bytes
,
1878 u32 nvram_size_bytes
,
1882 u32 ret_mcp_resp
, ret_mcp_param
, ret_read_size
, bytes_to_copy
;
1883 s32 bytes_left
= nvram_size_bytes
;
1884 u32 read_offset
= 0, param
= 0;
1888 "nvram_read: reading image of size %d bytes from NVRAM\n",
1894 MCP_DRV_NVM_BUF_LEN
) ? MCP_DRV_NVM_BUF_LEN
: bytes_left
;
1896 /* Call NVRAM read command */
1897 SET_MFW_FIELD(param
,
1898 DRV_MB_PARAM_NVM_OFFSET
,
1899 nvram_offset_bytes
+ read_offset
);
1900 SET_MFW_FIELD(param
, DRV_MB_PARAM_NVM_LEN
, bytes_to_copy
);
1901 if (qed_mcp_nvm_rd_cmd(p_hwfn
, p_ptt
,
1902 DRV_MSG_CODE_NVM_READ_NVRAM
, param
,
1904 &ret_mcp_param
, &ret_read_size
,
1905 (u32
*)((u8
*)ret_buf
+ read_offset
),
1907 return DBG_STATUS_NVRAM_READ_FAILED
;
1909 /* Check response */
1910 if ((ret_mcp_resp
& FW_MSG_CODE_MASK
) != FW_MSG_CODE_NVM_OK
)
1911 return DBG_STATUS_NVRAM_READ_FAILED
;
1913 /* Update read offset */
1914 read_offset
+= ret_read_size
;
1915 bytes_left
-= ret_read_size
;
1916 } while (bytes_left
> 0);
1918 return DBG_STATUS_OK
;
1921 /* Dumps GRC registers section header. Returns the dumped size in dwords.
1922 * the following parameters are dumped:
1923 * - count: no. of dumped entries
1924 * - split_type: split type
1925 * - split_id: split ID (dumped only if split_id != SPLIT_TYPE_NONE)
1926 * - reg_type_name: register type name (dumped only if reg_type_name != NULL)
1928 static u32
qed_grc_dump_regs_hdr(u32
*dump_buf
,
1930 u32 num_reg_entries
,
1931 enum init_split_types split_type
,
1932 u8 split_id
, const char *reg_type_name
)
1935 (split_type
!= SPLIT_TYPE_NONE
? 1 : 0) + (reg_type_name
? 1 : 0);
1938 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
1939 dump
, "grc_regs", num_params
);
1940 offset
+= qed_dump_num_param(dump_buf
+ offset
,
1941 dump
, "count", num_reg_entries
);
1942 offset
+= qed_dump_str_param(dump_buf
+ offset
,
1944 s_split_type_defs
[split_type
].name
);
1945 if (split_type
!= SPLIT_TYPE_NONE
)
1946 offset
+= qed_dump_num_param(dump_buf
+ offset
,
1947 dump
, "id", split_id
);
1949 offset
+= qed_dump_str_param(dump_buf
+ offset
,
1950 dump
, "type", reg_type_name
);
1955 /* Reads the specified registers into the specified buffer.
1956 * The addr and len arguments are specified in dwords.
1958 void qed_read_regs(struct qed_hwfn
*p_hwfn
,
1959 struct qed_ptt
*p_ptt
, u32
*buf
, u32 addr
, u32 len
)
1963 for (i
= 0; i
< len
; i
++)
1964 buf
[i
] = qed_rd(p_hwfn
, p_ptt
, DWORDS_TO_BYTES(addr
+ i
));
1967 /* Dumps the GRC registers in the specified address range.
1968 * Returns the dumped size in dwords.
1969 * The addr and len arguments are specified in dwords.
1971 static u32
qed_grc_dump_addr_range(struct qed_hwfn
*p_hwfn
,
1972 struct qed_ptt
*p_ptt
,
1974 bool dump
, u32 addr
, u32 len
, bool wide_bus
,
1975 enum init_split_types split_type
,
1978 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
1979 u8 port_id
= 0, pf_id
= 0, vf_id
= 0;
1980 bool read_using_dmae
= false;
1987 switch (split_type
) {
1988 case SPLIT_TYPE_PORT
:
1994 case SPLIT_TYPE_PORT_PF
:
1995 port_id
= split_id
/ dev_data
->num_pfs_per_port
;
1996 pf_id
= port_id
+ dev_data
->num_ports
*
1997 (split_id
% dev_data
->num_pfs_per_port
);
2006 /* Try reading using DMAE */
2007 if (dev_data
->use_dmae
&& split_type
!= SPLIT_TYPE_VF
&&
2008 (len
>= s_hw_type_defs
[dev_data
->hw_type
].dmae_thresh
||
2009 (PROTECT_WIDE_BUS
&& wide_bus
))) {
2010 struct qed_dmae_params dmae_params
;
2012 /* Set DMAE params */
2013 memset(&dmae_params
, 0, sizeof(dmae_params
));
2014 SET_FIELD(dmae_params
.flags
, QED_DMAE_PARAMS_COMPLETION_DST
, 1);
2015 switch (split_type
) {
2016 case SPLIT_TYPE_PORT
:
2017 SET_FIELD(dmae_params
.flags
, QED_DMAE_PARAMS_PORT_VALID
,
2019 dmae_params
.port_id
= port_id
;
2022 SET_FIELD(dmae_params
.flags
,
2023 QED_DMAE_PARAMS_SRC_PF_VALID
, 1);
2024 dmae_params
.src_pfid
= pf_id
;
2026 case SPLIT_TYPE_PORT_PF
:
2027 SET_FIELD(dmae_params
.flags
, QED_DMAE_PARAMS_PORT_VALID
,
2029 SET_FIELD(dmae_params
.flags
,
2030 QED_DMAE_PARAMS_SRC_PF_VALID
, 1);
2031 dmae_params
.port_id
= port_id
;
2032 dmae_params
.src_pfid
= pf_id
;
2038 /* Execute DMAE command */
2039 read_using_dmae
= !qed_dmae_grc2host(p_hwfn
,
2041 DWORDS_TO_BYTES(addr
),
2042 (u64
)(uintptr_t)(dump_buf
),
2044 if (!read_using_dmae
) {
2045 dev_data
->use_dmae
= 0;
2048 "Failed reading from chip using DMAE, using GRC instead\n");
2052 if (read_using_dmae
)
2055 /* If not read using DMAE, read using GRC */
2058 if (split_type
!= dev_data
->pretend
.split_type
||
2059 split_id
!= dev_data
->pretend
.split_id
) {
2060 switch (split_type
) {
2061 case SPLIT_TYPE_PORT
:
2062 qed_port_pretend(p_hwfn
, p_ptt
, port_id
);
2065 fid
= FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID
,
2067 qed_fid_pretend(p_hwfn
, p_ptt
, fid
);
2069 case SPLIT_TYPE_PORT_PF
:
2070 fid
= FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID
,
2072 qed_port_fid_pretend(p_hwfn
, p_ptt
, port_id
, fid
);
2075 fid
= FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFVALID
, 1)
2076 | FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFID
,
2078 qed_fid_pretend(p_hwfn
, p_ptt
, fid
);
2084 dev_data
->pretend
.split_type
= (u8
)split_type
;
2085 dev_data
->pretend
.split_id
= split_id
;
2088 /* Read registers using GRC */
2089 qed_read_regs(p_hwfn
, p_ptt
, dump_buf
, addr
, len
);
2093 dev_data
->num_regs_read
+= len
;
2094 thresh
= s_hw_type_defs
[dev_data
->hw_type
].log_thresh
;
2095 if ((dev_data
->num_regs_read
/ thresh
) >
2096 ((dev_data
->num_regs_read
- len
) / thresh
))
2099 "Dumped %d registers...\n", dev_data
->num_regs_read
);
2104 /* Dumps GRC registers sequence header. Returns the dumped size in dwords.
2105 * The addr and len arguments are specified in dwords.
2107 static u32
qed_grc_dump_reg_entry_hdr(u32
*dump_buf
,
2108 bool dump
, u32 addr
, u32 len
)
2111 *dump_buf
= addr
| (len
<< REG_DUMP_LEN_SHIFT
);
2116 /* Dumps GRC registers sequence. Returns the dumped size in dwords.
2117 * The addr and len arguments are specified in dwords.
2119 static u32
qed_grc_dump_reg_entry(struct qed_hwfn
*p_hwfn
,
2120 struct qed_ptt
*p_ptt
,
2122 bool dump
, u32 addr
, u32 len
, bool wide_bus
,
2123 enum init_split_types split_type
, u8 split_id
)
2127 offset
+= qed_grc_dump_reg_entry_hdr(dump_buf
, dump
, addr
, len
);
2128 offset
+= qed_grc_dump_addr_range(p_hwfn
,
2131 dump
, addr
, len
, wide_bus
,
2132 split_type
, split_id
);
2137 /* Dumps GRC registers sequence with skip cycle.
2138 * Returns the dumped size in dwords.
2139 * - addr: start GRC address in dwords
2140 * - total_len: total no. of dwords to dump
2141 * - read_len: no. consecutive dwords to read
2142 * - skip_len: no. of dwords to skip (and fill with zeros)
2144 static u32
qed_grc_dump_reg_entry_skip(struct qed_hwfn
*p_hwfn
,
2145 struct qed_ptt
*p_ptt
,
2150 u32 read_len
, u32 skip_len
)
2152 u32 offset
= 0, reg_offset
= 0;
2154 offset
+= qed_grc_dump_reg_entry_hdr(dump_buf
, dump
, addr
, total_len
);
2157 return offset
+ total_len
;
2159 while (reg_offset
< total_len
) {
2160 u32 curr_len
= min_t(u32
, read_len
, total_len
- reg_offset
);
2162 offset
+= qed_grc_dump_addr_range(p_hwfn
,
2165 dump
, addr
, curr_len
, false,
2166 SPLIT_TYPE_NONE
, 0);
2167 reg_offset
+= curr_len
;
2170 if (reg_offset
< total_len
) {
2171 curr_len
= min_t(u32
, skip_len
, total_len
- skip_len
);
2172 memset(dump_buf
+ offset
, 0, DWORDS_TO_BYTES(curr_len
));
2174 reg_offset
+= curr_len
;
2182 /* Dumps GRC registers entries. Returns the dumped size in dwords. */
2183 static u32
qed_grc_dump_regs_entries(struct qed_hwfn
*p_hwfn
,
2184 struct qed_ptt
*p_ptt
,
2185 struct virt_mem_desc input_regs_arr
,
2188 enum init_split_types split_type
,
2190 bool block_enable
[MAX_BLOCK_ID
],
2191 u32
*num_dumped_reg_entries
)
2193 u32 i
, offset
= 0, input_offset
= 0;
2194 bool mode_match
= true;
2196 *num_dumped_reg_entries
= 0;
2198 while (input_offset
< BYTES_TO_DWORDS(input_regs_arr
.size
)) {
2199 const struct dbg_dump_cond_hdr
*cond_hdr
=
2200 (const struct dbg_dump_cond_hdr
*)
2201 input_regs_arr
.ptr
+ input_offset
++;
2202 u16 modes_buf_offset
;
2205 /* Check mode/block */
2206 eval_mode
= GET_FIELD(cond_hdr
->mode
.data
,
2207 DBG_MODE_HDR_EVAL_MODE
) > 0;
2210 GET_FIELD(cond_hdr
->mode
.data
,
2211 DBG_MODE_HDR_MODES_BUF_OFFSET
);
2212 mode_match
= qed_is_mode_match(p_hwfn
,
2216 if (!mode_match
|| !block_enable
[cond_hdr
->block_id
]) {
2217 input_offset
+= cond_hdr
->data_size
;
2221 for (i
= 0; i
< cond_hdr
->data_size
; i
++, input_offset
++) {
2222 const struct dbg_dump_reg
*reg
=
2223 (const struct dbg_dump_reg
*)
2224 input_regs_arr
.ptr
+ input_offset
;
2228 addr
= GET_FIELD(reg
->data
, DBG_DUMP_REG_ADDRESS
);
2229 len
= GET_FIELD(reg
->data
, DBG_DUMP_REG_LENGTH
);
2230 wide_bus
= GET_FIELD(reg
->data
, DBG_DUMP_REG_WIDE_BUS
);
2231 offset
+= qed_grc_dump_reg_entry(p_hwfn
,
2238 split_type
, split_id
);
2239 (*num_dumped_reg_entries
)++;
2246 /* Dumps GRC registers entries. Returns the dumped size in dwords. */
2247 static u32
qed_grc_dump_split_data(struct qed_hwfn
*p_hwfn
,
2248 struct qed_ptt
*p_ptt
,
2249 struct virt_mem_desc input_regs_arr
,
2252 bool block_enable
[MAX_BLOCK_ID
],
2253 enum init_split_types split_type
,
2254 u8 split_id
, const char *reg_type_name
)
2256 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
2257 enum init_split_types hdr_split_type
= split_type
;
2258 u32 num_dumped_reg_entries
, offset
;
2259 u8 hdr_split_id
= split_id
;
2261 /* In PORT_PF split type, print a port split header */
2262 if (split_type
== SPLIT_TYPE_PORT_PF
) {
2263 hdr_split_type
= SPLIT_TYPE_PORT
;
2264 hdr_split_id
= split_id
/ dev_data
->num_pfs_per_port
;
2267 /* Calculate register dump header size (and skip it for now) */
2268 offset
= qed_grc_dump_regs_hdr(dump_buf
,
2272 hdr_split_id
, reg_type_name
);
2274 /* Dump registers */
2275 offset
+= qed_grc_dump_regs_entries(p_hwfn
,
2283 &num_dumped_reg_entries
);
2285 /* Write register dump header */
2286 if (dump
&& num_dumped_reg_entries
> 0)
2287 qed_grc_dump_regs_hdr(dump_buf
,
2289 num_dumped_reg_entries
,
2291 hdr_split_id
, reg_type_name
);
2293 return num_dumped_reg_entries
> 0 ? offset
: 0;
2296 /* Dumps registers according to the input registers array. Returns the dumped
2299 static u32
qed_grc_dump_registers(struct qed_hwfn
*p_hwfn
,
2300 struct qed_ptt
*p_ptt
,
2303 bool block_enable
[MAX_BLOCK_ID
],
2304 const char *reg_type_name
)
2306 struct virt_mem_desc
*dbg_buf
=
2307 &p_hwfn
->dbg_arrays
[BIN_BUF_DBG_DUMP_REG
];
2308 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
2309 u32 offset
= 0, input_offset
= 0;
2311 while (input_offset
< BYTES_TO_DWORDS(dbg_buf
->size
)) {
2312 const struct dbg_dump_split_hdr
*split_hdr
;
2313 struct virt_mem_desc curr_input_regs_arr
;
2314 enum init_split_types split_type
;
2315 u16 split_count
= 0;
2316 u32 split_data_size
;
2320 (const struct dbg_dump_split_hdr
*)
2321 dbg_buf
->ptr
+ input_offset
++;
2323 GET_FIELD(split_hdr
->hdr
,
2324 DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID
);
2325 split_data_size
= GET_FIELD(split_hdr
->hdr
,
2326 DBG_DUMP_SPLIT_HDR_DATA_SIZE
);
2327 curr_input_regs_arr
.ptr
=
2328 (u32
*)p_hwfn
->dbg_arrays
[BIN_BUF_DBG_DUMP_REG
].ptr
+
2330 curr_input_regs_arr
.size
= DWORDS_TO_BYTES(split_data_size
);
2332 switch (split_type
) {
2333 case SPLIT_TYPE_NONE
:
2336 case SPLIT_TYPE_PORT
:
2337 split_count
= dev_data
->num_ports
;
2340 case SPLIT_TYPE_PORT_PF
:
2341 split_count
= dev_data
->num_ports
*
2342 dev_data
->num_pfs_per_port
;
2345 split_count
= dev_data
->num_vfs
;
2351 for (split_id
= 0; split_id
< split_count
; split_id
++)
2352 offset
+= qed_grc_dump_split_data(p_hwfn
, p_ptt
,
2353 curr_input_regs_arr
,
2360 input_offset
+= split_data_size
;
2363 /* Cancel pretends (pretend to original PF) */
2365 qed_fid_pretend(p_hwfn
, p_ptt
,
2366 FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID
,
2367 p_hwfn
->rel_pf_id
));
2368 dev_data
->pretend
.split_type
= SPLIT_TYPE_NONE
;
2369 dev_data
->pretend
.split_id
= 0;
2375 /* Dump reset registers. Returns the dumped size in dwords. */
2376 static u32
qed_grc_dump_reset_regs(struct qed_hwfn
*p_hwfn
,
2377 struct qed_ptt
*p_ptt
,
2378 u32
*dump_buf
, bool dump
)
2380 u32 offset
= 0, num_regs
= 0;
2383 /* Calculate header size */
2384 offset
+= qed_grc_dump_regs_hdr(dump_buf
,
2386 0, SPLIT_TYPE_NONE
, 0, "RESET_REGS");
2388 /* Write reset registers */
2389 for (reset_reg_id
= 0; reset_reg_id
< NUM_DBG_RESET_REGS
;
2391 const struct dbg_reset_reg
*reset_reg
;
2394 reset_reg
= qed_get_dbg_reset_reg(p_hwfn
, reset_reg_id
);
2396 if (GET_FIELD(reset_reg
->data
, DBG_RESET_REG_IS_REMOVED
))
2399 reset_reg_addr
= GET_FIELD(reset_reg
->data
, DBG_RESET_REG_ADDR
);
2400 offset
+= qed_grc_dump_reg_entry(p_hwfn
,
2405 1, false, SPLIT_TYPE_NONE
, 0);
2411 qed_grc_dump_regs_hdr(dump_buf
,
2412 true, num_regs
, SPLIT_TYPE_NONE
,
2418 /* Dump registers that are modified during GRC Dump and therefore must be
2419 * dumped first. Returns the dumped size in dwords.
2421 static u32
qed_grc_dump_modified_regs(struct qed_hwfn
*p_hwfn
,
2422 struct qed_ptt
*p_ptt
,
2423 u32
*dump_buf
, bool dump
)
2425 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
2426 u32 block_id
, offset
= 0, stall_regs_offset
;
2427 const struct dbg_attn_reg
*attn_reg_arr
;
2428 u8 storm_id
, reg_idx
, num_attn_regs
;
2429 u32 num_reg_entries
= 0;
2431 /* Write empty header for attention registers */
2432 offset
+= qed_grc_dump_regs_hdr(dump_buf
,
2434 0, SPLIT_TYPE_NONE
, 0, "ATTN_REGS");
2436 /* Write parity registers */
2437 for (block_id
= 0; block_id
< NUM_PHYS_BLOCKS
; block_id
++) {
2438 if (dev_data
->block_in_reset
[block_id
] && dump
)
2441 attn_reg_arr
= qed_get_block_attn_regs(p_hwfn
,
2442 (enum block_id
)block_id
,
2446 for (reg_idx
= 0; reg_idx
< num_attn_regs
; reg_idx
++) {
2447 const struct dbg_attn_reg
*reg_data
=
2448 &attn_reg_arr
[reg_idx
];
2449 u16 modes_buf_offset
;
2454 eval_mode
= GET_FIELD(reg_data
->mode
.data
,
2455 DBG_MODE_HDR_EVAL_MODE
) > 0;
2457 GET_FIELD(reg_data
->mode
.data
,
2458 DBG_MODE_HDR_MODES_BUF_OFFSET
);
2460 !qed_is_mode_match(p_hwfn
, &modes_buf_offset
))
2463 /* Mode match: read & dump registers */
2464 addr
= reg_data
->mask_address
;
2465 offset
+= qed_grc_dump_reg_entry(p_hwfn
,
2471 SPLIT_TYPE_NONE
, 0);
2472 addr
= GET_FIELD(reg_data
->data
,
2473 DBG_ATTN_REG_STS_ADDRESS
);
2474 offset
+= qed_grc_dump_reg_entry(p_hwfn
,
2480 SPLIT_TYPE_NONE
, 0);
2481 num_reg_entries
+= 2;
2485 /* Overwrite header for attention registers */
2487 qed_grc_dump_regs_hdr(dump_buf
,
2490 SPLIT_TYPE_NONE
, 0, "ATTN_REGS");
2492 /* Write empty header for stall registers */
2493 stall_regs_offset
= offset
;
2494 offset
+= qed_grc_dump_regs_hdr(dump_buf
,
2495 false, 0, SPLIT_TYPE_NONE
, 0, "REGS");
2497 /* Write Storm stall status registers */
2498 for (storm_id
= 0, num_reg_entries
= 0; storm_id
< MAX_DBG_STORMS
;
2500 struct storm_defs
*storm
= &s_storm_defs
[storm_id
];
2503 if (dev_data
->block_in_reset
[storm
->sem_block_id
] && dump
)
2507 BYTES_TO_DWORDS(storm
->sem_fast_mem_addr
+
2508 SEM_FAST_REG_STALLED
);
2509 offset
+= qed_grc_dump_reg_entry(p_hwfn
,
2515 false, SPLIT_TYPE_NONE
, 0);
2519 /* Overwrite header for stall registers */
2521 qed_grc_dump_regs_hdr(dump_buf
+ stall_regs_offset
,
2524 SPLIT_TYPE_NONE
, 0, "REGS");
2529 /* Dumps registers that can't be represented in the debug arrays */
2530 static u32
qed_grc_dump_special_regs(struct qed_hwfn
*p_hwfn
,
2531 struct qed_ptt
*p_ptt
,
2532 u32
*dump_buf
, bool dump
)
2534 u32 offset
= 0, addr
;
2536 offset
+= qed_grc_dump_regs_hdr(dump_buf
,
2537 dump
, 2, SPLIT_TYPE_NONE
, 0, "REGS");
2539 /* Dump R/TDIF_REG_DEBUG_ERROR_INFO_SIZE (every 8'th register should be
2542 addr
= BYTES_TO_DWORDS(RDIF_REG_DEBUG_ERROR_INFO
);
2543 offset
+= qed_grc_dump_reg_entry_skip(p_hwfn
,
2548 RDIF_REG_DEBUG_ERROR_INFO_SIZE
,
2551 addr
= BYTES_TO_DWORDS(TDIF_REG_DEBUG_ERROR_INFO
);
2553 qed_grc_dump_reg_entry_skip(p_hwfn
,
2558 TDIF_REG_DEBUG_ERROR_INFO_SIZE
,
2565 /* Dumps a GRC memory header (section and params). Returns the dumped size in
2566 * dwords. The following parameters are dumped:
2567 * - name: dumped only if it's not NULL.
2568 * - addr: in dwords, dumped only if name is NULL.
2569 * - len: in dwords, always dumped.
2570 * - width: dumped if it's not zero.
2571 * - packed: dumped only if it's not false.
2572 * - mem_group: always dumped.
2573 * - is_storm: true only if the memory is related to a Storm.
2574 * - storm_letter: valid only if is_storm is true.
2577 static u32
qed_grc_dump_mem_hdr(struct qed_hwfn
*p_hwfn
,
2585 const char *mem_group
, char storm_letter
)
2593 "Unexpected GRC Dump error: dumped memory size must be non-zero\n");
2600 /* Dump section header */
2601 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
2602 dump
, "grc_mem", num_params
);
2607 strcpy(buf
, "?STORM_");
2608 buf
[0] = storm_letter
;
2609 strcpy(buf
+ strlen(buf
), name
);
2614 offset
+= qed_dump_str_param(dump_buf
+ offset
,
2618 u32 addr_in_bytes
= DWORDS_TO_BYTES(addr
);
2620 offset
+= qed_dump_num_param(dump_buf
+ offset
,
2621 dump
, "addr", addr_in_bytes
);
2625 offset
+= qed_dump_num_param(dump_buf
+ offset
, dump
, "len", len
);
2627 /* Dump bit width */
2629 offset
+= qed_dump_num_param(dump_buf
+ offset
,
2630 dump
, "width", bit_width
);
2634 offset
+= qed_dump_num_param(dump_buf
+ offset
,
2639 strcpy(buf
, "?STORM_");
2640 buf
[0] = storm_letter
;
2641 strcpy(buf
+ strlen(buf
), mem_group
);
2643 strcpy(buf
, mem_group
);
2646 offset
+= qed_dump_str_param(dump_buf
+ offset
, dump
, "type", buf
);
2651 /* Dumps a single GRC memory. If name is NULL, the memory is stored by address.
2652 * Returns the dumped size in dwords.
2653 * The addr and len arguments are specified in dwords.
2655 static u32
qed_grc_dump_mem(struct qed_hwfn
*p_hwfn
,
2656 struct qed_ptt
*p_ptt
,
2665 const char *mem_group
, char storm_letter
)
2669 offset
+= qed_grc_dump_mem_hdr(p_hwfn
,
2676 packed
, mem_group
, storm_letter
);
2677 offset
+= qed_grc_dump_addr_range(p_hwfn
,
2680 dump
, addr
, len
, wide_bus
,
2681 SPLIT_TYPE_NONE
, 0);
2686 /* Dumps GRC memories entries. Returns the dumped size in dwords. */
2687 static u32
qed_grc_dump_mem_entries(struct qed_hwfn
*p_hwfn
,
2688 struct qed_ptt
*p_ptt
,
2689 struct virt_mem_desc input_mems_arr
,
2690 u32
*dump_buf
, bool dump
)
2692 u32 i
, offset
= 0, input_offset
= 0;
2693 bool mode_match
= true;
2695 while (input_offset
< BYTES_TO_DWORDS(input_mems_arr
.size
)) {
2696 const struct dbg_dump_cond_hdr
*cond_hdr
;
2697 u16 modes_buf_offset
;
2702 (const struct dbg_dump_cond_hdr
*)input_mems_arr
.ptr
+
2704 num_entries
= cond_hdr
->data_size
/ MEM_DUMP_ENTRY_SIZE_DWORDS
;
2706 /* Check required mode */
2707 eval_mode
= GET_FIELD(cond_hdr
->mode
.data
,
2708 DBG_MODE_HDR_EVAL_MODE
) > 0;
2711 GET_FIELD(cond_hdr
->mode
.data
,
2712 DBG_MODE_HDR_MODES_BUF_OFFSET
);
2713 mode_match
= qed_is_mode_match(p_hwfn
,
2718 input_offset
+= cond_hdr
->data_size
;
2722 for (i
= 0; i
< num_entries
;
2723 i
++, input_offset
+= MEM_DUMP_ENTRY_SIZE_DWORDS
) {
2724 const struct dbg_dump_mem
*mem
=
2725 (const struct dbg_dump_mem
*)((u32
*)
2728 const struct dbg_block
*block
;
2729 char storm_letter
= 0;
2730 u32 mem_addr
, mem_len
;
2734 mem_group_id
= GET_FIELD(mem
->dword0
,
2735 DBG_DUMP_MEM_MEM_GROUP_ID
);
2736 if (mem_group_id
>= MEM_GROUPS_NUM
) {
2737 DP_NOTICE(p_hwfn
, "Invalid mem_group_id\n");
2741 if (!qed_grc_is_mem_included(p_hwfn
,
2747 mem_addr
= GET_FIELD(mem
->dword0
, DBG_DUMP_MEM_ADDRESS
);
2748 mem_len
= GET_FIELD(mem
->dword1
, DBG_DUMP_MEM_LENGTH
);
2749 mem_wide_bus
= GET_FIELD(mem
->dword1
,
2750 DBG_DUMP_MEM_WIDE_BUS
);
2752 block
= get_dbg_block(p_hwfn
,
2753 cond_hdr
->block_id
);
2755 /* If memory is associated with Storm,
2756 * update storm details
2758 if (block
->associated_storm_letter
)
2759 storm_letter
= block
->associated_storm_letter
;
2762 offset
+= qed_grc_dump_mem(p_hwfn
,
2772 s_mem_group_names
[mem_group_id
],
2780 /* Dumps GRC memories according to the input array dump_mem.
2781 * Returns the dumped size in dwords.
2783 static u32
qed_grc_dump_memories(struct qed_hwfn
*p_hwfn
,
2784 struct qed_ptt
*p_ptt
,
2785 u32
*dump_buf
, bool dump
)
2787 struct virt_mem_desc
*dbg_buf
=
2788 &p_hwfn
->dbg_arrays
[BIN_BUF_DBG_DUMP_MEM
];
2789 u32 offset
= 0, input_offset
= 0;
2791 while (input_offset
< BYTES_TO_DWORDS(dbg_buf
->size
)) {
2792 const struct dbg_dump_split_hdr
*split_hdr
;
2793 struct virt_mem_desc curr_input_mems_arr
;
2794 enum init_split_types split_type
;
2795 u32 split_data_size
;
2798 (const struct dbg_dump_split_hdr
*)dbg_buf
->ptr
+
2800 split_type
= GET_FIELD(split_hdr
->hdr
,
2801 DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID
);
2802 split_data_size
= GET_FIELD(split_hdr
->hdr
,
2803 DBG_DUMP_SPLIT_HDR_DATA_SIZE
);
2804 curr_input_mems_arr
.ptr
= (u32
*)dbg_buf
->ptr
+ input_offset
;
2805 curr_input_mems_arr
.size
= DWORDS_TO_BYTES(split_data_size
);
2807 if (split_type
== SPLIT_TYPE_NONE
)
2808 offset
+= qed_grc_dump_mem_entries(p_hwfn
,
2810 curr_input_mems_arr
,
2815 "Dumping split memories is currently not supported\n");
2817 input_offset
+= split_data_size
;
2823 /* Dumps GRC context data for the specified Storm.
2824 * Returns the dumped size in dwords.
2825 * The lid_size argument is specified in quad-regs.
2827 static u32
qed_grc_dump_ctx_data(struct qed_hwfn
*p_hwfn
,
2828 struct qed_ptt
*p_ptt
,
2833 enum cm_ctx_types ctx_type
, u8 storm_id
)
2835 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
2836 struct storm_defs
*storm
= &s_storm_defs
[storm_id
];
2837 u32 i
, lid
, lid_size
, total_size
;
2838 u32 rd_reg_addr
, offset
= 0;
2840 /* Convert quad-regs to dwords */
2841 lid_size
= storm
->cm_ctx_lid_sizes
[dev_data
->chip_id
][ctx_type
] * 4;
2846 total_size
= num_lids
* lid_size
;
2848 offset
+= qed_grc_dump_mem_hdr(p_hwfn
,
2855 false, name
, storm
->letter
);
2858 return offset
+ total_size
;
2860 rd_reg_addr
= BYTES_TO_DWORDS(storm
->cm_ctx_rd_addr
[ctx_type
]);
2862 /* Dump context data */
2863 for (lid
= 0; lid
< num_lids
; lid
++) {
2864 for (i
= 0; i
< lid_size
; i
++) {
2866 p_ptt
, storm
->cm_ctx_wr_addr
, (i
<< 9) | lid
);
2867 offset
+= qed_grc_dump_addr_range(p_hwfn
,
2874 SPLIT_TYPE_NONE
, 0);
2882 /* Dumps GRC contexts. Returns the dumped size in dwords. */
2883 static u32
qed_grc_dump_ctx(struct qed_hwfn
*p_hwfn
,
2884 struct qed_ptt
*p_ptt
, u32
*dump_buf
, bool dump
)
2889 for (storm_id
= 0; storm_id
< MAX_DBG_STORMS
; storm_id
++) {
2890 if (!qed_grc_is_storm_included(p_hwfn
,
2891 (enum dbg_storms
)storm_id
))
2894 /* Dump Conn AG context size */
2895 offset
+= qed_grc_dump_ctx_data(p_hwfn
,
2901 CM_CTX_CONN_AG
, storm_id
);
2903 /* Dump Conn ST context size */
2904 offset
+= qed_grc_dump_ctx_data(p_hwfn
,
2910 CM_CTX_CONN_ST
, storm_id
);
2912 /* Dump Task AG context size */
2913 offset
+= qed_grc_dump_ctx_data(p_hwfn
,
2919 CM_CTX_TASK_AG
, storm_id
);
2921 /* Dump Task ST context size */
2922 offset
+= qed_grc_dump_ctx_data(p_hwfn
,
2928 CM_CTX_TASK_ST
, storm_id
);
2934 #define VFC_STATUS_RESP_READY_BIT 0
2935 #define VFC_STATUS_BUSY_BIT 1
2936 #define VFC_STATUS_SENDING_CMD_BIT 2
2938 #define VFC_POLLING_DELAY_MS 1
2939 #define VFC_POLLING_COUNT 20
2941 /* Reads data from VFC. Returns the number of dwords read (0 on error).
2942 * Sizes are specified in dwords.
2944 static u32
qed_grc_dump_read_from_vfc(struct qed_hwfn
*p_hwfn
,
2945 struct qed_ptt
*p_ptt
,
2946 struct storm_defs
*storm
,
2951 u32 resp_size
, u32
*dump_buf
)
2953 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
2954 u32 vfc_status
, polling_ms
, polling_count
= 0, i
;
2955 u32 reg_addr
, sem_base
;
2956 bool is_ready
= false;
2958 sem_base
= storm
->sem_fast_mem_addr
;
2959 polling_ms
= VFC_POLLING_DELAY_MS
*
2960 s_hw_type_defs
[dev_data
->hw_type
].delay_factor
;
2962 /* Write VFC command */
2965 sem_base
+ SEM_FAST_REG_VFC_DATA_WR
,
2966 cmd_data
, cmd_size
);
2968 /* Write VFC address */
2971 sem_base
+ SEM_FAST_REG_VFC_ADDR
,
2972 addr_data
, addr_size
);
2975 for (i
= 0; i
< resp_size
; i
++) {
2976 /* Poll until ready */
2978 reg_addr
= sem_base
+ SEM_FAST_REG_VFC_STATUS
;
2979 qed_grc_dump_addr_range(p_hwfn
,
2983 BYTES_TO_DWORDS(reg_addr
),
2985 false, SPLIT_TYPE_NONE
, 0);
2986 is_ready
= vfc_status
& BIT(VFC_STATUS_RESP_READY_BIT
);
2989 if (polling_count
++ == VFC_POLLING_COUNT
)
2994 } while (!is_ready
);
2996 reg_addr
= sem_base
+ SEM_FAST_REG_VFC_DATA_RD
;
2997 qed_grc_dump_addr_range(p_hwfn
,
3001 BYTES_TO_DWORDS(reg_addr
),
3002 1, false, SPLIT_TYPE_NONE
, 0);
3008 /* Dump VFC CAM. Returns the dumped size in dwords. */
3009 static u32
qed_grc_dump_vfc_cam(struct qed_hwfn
*p_hwfn
,
3010 struct qed_ptt
*p_ptt
,
3011 u32
*dump_buf
, bool dump
, u8 storm_id
)
3013 u32 total_size
= VFC_CAM_NUM_ROWS
* VFC_CAM_RESP_DWORDS
;
3014 struct storm_defs
*storm
= &s_storm_defs
[storm_id
];
3015 u32 cam_addr
[VFC_CAM_ADDR_DWORDS
] = { 0 };
3016 u32 cam_cmd
[VFC_CAM_CMD_DWORDS
] = { 0 };
3017 u32 row
, offset
= 0;
3019 offset
+= qed_grc_dump_mem_hdr(p_hwfn
,
3026 false, "vfc_cam", storm
->letter
);
3029 return offset
+ total_size
;
3031 /* Prepare CAM address */
3032 SET_VAR_FIELD(cam_addr
, VFC_CAM_ADDR
, OP
, VFC_OPCODE_CAM_RD
);
3034 /* Read VFC CAM data */
3035 for (row
= 0; row
< VFC_CAM_NUM_ROWS
; row
++) {
3036 SET_VAR_FIELD(cam_cmd
, VFC_CAM_CMD
, ROW
, row
);
3037 offset
+= qed_grc_dump_read_from_vfc(p_hwfn
,
3043 VFC_CAM_ADDR_DWORDS
,
3044 VFC_CAM_RESP_DWORDS
,
3051 /* Dump VFC RAM. Returns the dumped size in dwords. */
3052 static u32
qed_grc_dump_vfc_ram(struct qed_hwfn
*p_hwfn
,
3053 struct qed_ptt
*p_ptt
,
3056 u8 storm_id
, struct vfc_ram_defs
*ram_defs
)
3058 u32 total_size
= ram_defs
->num_rows
* VFC_RAM_RESP_DWORDS
;
3059 struct storm_defs
*storm
= &s_storm_defs
[storm_id
];
3060 u32 ram_addr
[VFC_RAM_ADDR_DWORDS
] = { 0 };
3061 u32 ram_cmd
[VFC_RAM_CMD_DWORDS
] = { 0 };
3062 u32 row
, offset
= 0;
3064 offset
+= qed_grc_dump_mem_hdr(p_hwfn
,
3072 ram_defs
->type_name
,
3076 return offset
+ total_size
;
3078 /* Prepare RAM address */
3079 SET_VAR_FIELD(ram_addr
, VFC_RAM_ADDR
, OP
, VFC_OPCODE_RAM_RD
);
3081 /* Read VFC RAM data */
3082 for (row
= ram_defs
->base_row
;
3083 row
< ram_defs
->base_row
+ ram_defs
->num_rows
; row
++) {
3084 SET_VAR_FIELD(ram_addr
, VFC_RAM_ADDR
, ROW
, row
);
3085 offset
+= qed_grc_dump_read_from_vfc(p_hwfn
,
3091 VFC_RAM_ADDR_DWORDS
,
3092 VFC_RAM_RESP_DWORDS
,
3099 /* Dumps GRC VFC data. Returns the dumped size in dwords. */
3100 static u32
qed_grc_dump_vfc(struct qed_hwfn
*p_hwfn
,
3101 struct qed_ptt
*p_ptt
, u32
*dump_buf
, bool dump
)
3106 for (storm_id
= 0; storm_id
< MAX_DBG_STORMS
; storm_id
++) {
3107 if (!qed_grc_is_storm_included(p_hwfn
,
3108 (enum dbg_storms
)storm_id
) ||
3109 !s_storm_defs
[storm_id
].has_vfc
)
3113 offset
+= qed_grc_dump_vfc_cam(p_hwfn
,
3119 for (i
= 0; i
< NUM_VFC_RAM_TYPES
; i
++)
3120 offset
+= qed_grc_dump_vfc_ram(p_hwfn
,
3125 &s_vfc_ram_defs
[i
]);
3131 /* Dumps GRC RSS data. Returns the dumped size in dwords. */
3132 static u32
qed_grc_dump_rss(struct qed_hwfn
*p_hwfn
,
3133 struct qed_ptt
*p_ptt
, u32
*dump_buf
, bool dump
)
3135 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
3139 for (rss_mem_id
= 0; rss_mem_id
< NUM_RSS_MEM_TYPES
; rss_mem_id
++) {
3140 u32 rss_addr
, num_entries
, total_dwords
;
3141 struct rss_mem_defs
*rss_defs
;
3142 u32 addr
, num_dwords_to_read
;
3145 rss_defs
= &s_rss_mem_defs
[rss_mem_id
];
3146 rss_addr
= rss_defs
->addr
;
3147 num_entries
= rss_defs
->num_entries
[dev_data
->chip_id
];
3148 total_dwords
= (num_entries
* rss_defs
->entry_width
) / 32;
3149 packed
= (rss_defs
->entry_width
== 16);
3151 offset
+= qed_grc_dump_mem_hdr(p_hwfn
,
3157 rss_defs
->entry_width
,
3159 rss_defs
->type_name
, 0);
3163 offset
+= total_dwords
;
3167 addr
= BYTES_TO_DWORDS(RSS_REG_RSS_RAM_DATA
);
3168 while (total_dwords
) {
3169 num_dwords_to_read
= min_t(u32
,
3170 RSS_REG_RSS_RAM_DATA_SIZE
,
3172 qed_wr(p_hwfn
, p_ptt
, RSS_REG_RSS_RAM_ADDR
, rss_addr
);
3173 offset
+= qed_grc_dump_addr_range(p_hwfn
,
3180 SPLIT_TYPE_NONE
, 0);
3181 total_dwords
-= num_dwords_to_read
;
3189 /* Dumps GRC Big RAM. Returns the dumped size in dwords. */
3190 static u32
qed_grc_dump_big_ram(struct qed_hwfn
*p_hwfn
,
3191 struct qed_ptt
*p_ptt
,
3192 u32
*dump_buf
, bool dump
, u8 big_ram_id
)
3194 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
3195 u32 block_size
, ram_size
, offset
= 0, reg_val
, i
;
3196 char mem_name
[12] = "???_BIG_RAM";
3197 char type_name
[8] = "???_RAM";
3198 struct big_ram_defs
*big_ram
;
3200 big_ram
= &s_big_ram_defs
[big_ram_id
];
3201 ram_size
= big_ram
->ram_size
[dev_data
->chip_id
];
3203 reg_val
= qed_rd(p_hwfn
, p_ptt
, big_ram
->is_256b_reg_addr
);
3204 block_size
= reg_val
&
3205 BIT(big_ram
->is_256b_bit_offset
[dev_data
->chip_id
]) ? 256
3208 memcpy(type_name
, big_ram
->instance_name
, BIG_RAM_NAME_LEN
);
3209 memcpy(mem_name
, big_ram
->instance_name
, BIG_RAM_NAME_LEN
);
3211 /* Dump memory header */
3212 offset
+= qed_grc_dump_mem_hdr(p_hwfn
,
3219 false, type_name
, 0);
3221 /* Read and dump Big RAM data */
3223 return offset
+ ram_size
;
3226 for (i
= 0; i
< DIV_ROUND_UP(ram_size
, BRB_REG_BIG_RAM_DATA_SIZE
);
3230 qed_wr(p_hwfn
, p_ptt
, big_ram
->addr_reg_addr
, i
);
3231 addr
= BYTES_TO_DWORDS(big_ram
->data_reg_addr
);
3232 len
= BRB_REG_BIG_RAM_DATA_SIZE
;
3233 offset
+= qed_grc_dump_addr_range(p_hwfn
,
3239 false, SPLIT_TYPE_NONE
, 0);
3245 /* Dumps MCP scratchpad. Returns the dumped size in dwords. */
3246 static u32
qed_grc_dump_mcp(struct qed_hwfn
*p_hwfn
,
3247 struct qed_ptt
*p_ptt
, u32
*dump_buf
, bool dump
)
3249 bool block_enable
[MAX_BLOCK_ID
] = { 0 };
3250 u32 offset
= 0, addr
;
3251 bool halted
= false;
3254 if (dump
&& !qed_grc_get_param(p_hwfn
, DBG_GRC_PARAM_NO_MCP
)) {
3255 halted
= !qed_mcp_halt(p_hwfn
, p_ptt
);
3257 DP_NOTICE(p_hwfn
, "MCP halt failed!\n");
3260 /* Dump MCP scratchpad */
3261 offset
+= qed_grc_dump_mem(p_hwfn
,
3266 BYTES_TO_DWORDS(MCP_REG_SCRATCH
),
3267 MCP_REG_SCRATCH_SIZE
,
3268 false, 0, false, "MCP", 0);
3270 /* Dump MCP cpu_reg_file */
3271 offset
+= qed_grc_dump_mem(p_hwfn
,
3276 BYTES_TO_DWORDS(MCP_REG_CPU_REG_FILE
),
3277 MCP_REG_CPU_REG_FILE_SIZE
,
3278 false, 0, false, "MCP", 0);
3280 /* Dump MCP registers */
3281 block_enable
[BLOCK_MCP
] = true;
3282 offset
+= qed_grc_dump_registers(p_hwfn
,
3285 dump
, block_enable
, "MCP");
3287 /* Dump required non-MCP registers */
3288 offset
+= qed_grc_dump_regs_hdr(dump_buf
+ offset
,
3289 dump
, 1, SPLIT_TYPE_NONE
, 0,
3291 addr
= BYTES_TO_DWORDS(MISC_REG_SHARED_MEM_ADDR
);
3292 offset
+= qed_grc_dump_reg_entry(p_hwfn
,
3298 false, SPLIT_TYPE_NONE
, 0);
3301 if (halted
&& qed_mcp_resume(p_hwfn
, p_ptt
))
3302 DP_NOTICE(p_hwfn
, "Failed to resume MCP after halt!\n");
3307 /* Dumps the tbus indirect memory for all PHYs.
3308 * Returns the dumped size in dwords.
3310 static u32
qed_grc_dump_phy(struct qed_hwfn
*p_hwfn
,
3311 struct qed_ptt
*p_ptt
, u32
*dump_buf
, bool dump
)
3313 u32 offset
= 0, tbus_lo_offset
, tbus_hi_offset
;
3317 for (phy_id
= 0; phy_id
< ARRAY_SIZE(s_phy_defs
); phy_id
++) {
3318 u32 addr_lo_addr
, addr_hi_addr
, data_lo_addr
, data_hi_addr
;
3319 struct phy_defs
*phy_defs
;
3322 phy_defs
= &s_phy_defs
[phy_id
];
3323 addr_lo_addr
= phy_defs
->base_addr
+
3324 phy_defs
->tbus_addr_lo_addr
;
3325 addr_hi_addr
= phy_defs
->base_addr
+
3326 phy_defs
->tbus_addr_hi_addr
;
3327 data_lo_addr
= phy_defs
->base_addr
+
3328 phy_defs
->tbus_data_lo_addr
;
3329 data_hi_addr
= phy_defs
->base_addr
+
3330 phy_defs
->tbus_data_hi_addr
;
3332 if (snprintf(mem_name
, sizeof(mem_name
), "tbus_%s",
3333 phy_defs
->phy_name
) < 0)
3335 "Unexpected debug error: invalid PHY memory name\n");
3337 offset
+= qed_grc_dump_mem_hdr(p_hwfn
,
3342 PHY_DUMP_SIZE_DWORDS
,
3343 16, true, mem_name
, 0);
3346 offset
+= PHY_DUMP_SIZE_DWORDS
;
3350 bytes_buf
= (u8
*)(dump_buf
+ offset
);
3351 for (tbus_hi_offset
= 0;
3352 tbus_hi_offset
< (NUM_PHY_TBUS_ADDRESSES
>> 8);
3354 qed_wr(p_hwfn
, p_ptt
, addr_hi_addr
, tbus_hi_offset
);
3355 for (tbus_lo_offset
= 0; tbus_lo_offset
< 256;
3358 p_ptt
, addr_lo_addr
, tbus_lo_offset
);
3359 *(bytes_buf
++) = (u8
)qed_rd(p_hwfn
,
3362 *(bytes_buf
++) = (u8
)qed_rd(p_hwfn
,
3368 offset
+= PHY_DUMP_SIZE_DWORDS
;
3374 /* Dumps the MCP HW dump from NVRAM. Returns the dumped size in dwords. */
3375 static u32
qed_grc_dump_mcp_hw_dump(struct qed_hwfn
*p_hwfn
,
3376 struct qed_ptt
*p_ptt
,
3377 u32
*dump_buf
, bool dump
)
3379 u32 hw_dump_offset_bytes
= 0, hw_dump_size_bytes
= 0;
3380 u32 hw_dump_size_dwords
= 0, offset
= 0;
3381 enum dbg_status status
;
3383 /* Read HW dump image from NVRAM */
3384 status
= qed_find_nvram_image(p_hwfn
,
3386 NVM_TYPE_HW_DUMP_OUT
,
3387 &hw_dump_offset_bytes
,
3388 &hw_dump_size_bytes
,
3390 if (status
!= DBG_STATUS_OK
)
3393 hw_dump_size_dwords
= BYTES_TO_DWORDS(hw_dump_size_bytes
);
3395 /* Dump HW dump image section */
3396 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
3397 dump
, "mcp_hw_dump", 1);
3398 offset
+= qed_dump_num_param(dump_buf
+ offset
,
3399 dump
, "size", hw_dump_size_dwords
);
3401 /* Read MCP HW dump image into dump buffer */
3402 if (dump
&& hw_dump_size_dwords
) {
3403 status
= qed_nvram_read(p_hwfn
,
3405 hw_dump_offset_bytes
,
3409 if (status
!= DBG_STATUS_OK
) {
3411 "Failed to read MCP HW Dump image from NVRAM\n");
3415 offset
+= hw_dump_size_dwords
;
3420 /* Dumps Static Debug data. Returns the dumped size in dwords. */
3421 static u32
qed_grc_dump_static_debug(struct qed_hwfn
*p_hwfn
,
3422 struct qed_ptt
*p_ptt
,
3423 u32
*dump_buf
, bool dump
)
3425 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
3426 u32 block_id
, line_id
, offset
= 0, addr
, len
;
3428 /* Don't dump static debug if a debug bus recording is in progress */
3429 if (dump
&& qed_rd(p_hwfn
, p_ptt
, DBG_REG_DBG_BLOCK_ON
))
3433 /* Disable debug bus in all blocks */
3434 qed_bus_disable_blocks(p_hwfn
, p_ptt
);
3436 qed_bus_reset_dbg_block(p_hwfn
, p_ptt
);
3438 p_ptt
, DBG_REG_FRAMING_MODE
, DBG_BUS_FRAME_MODE_8HW
);
3440 p_ptt
, DBG_REG_DEBUG_TARGET
, DBG_BUS_TARGET_ID_INT_BUF
);
3441 qed_wr(p_hwfn
, p_ptt
, DBG_REG_FULL_MODE
, 1);
3442 qed_bus_enable_dbg_block(p_hwfn
, p_ptt
, true);
3445 /* Dump all static debug lines for each relevant block */
3446 for (block_id
= 0; block_id
< MAX_BLOCK_ID
; block_id
++) {
3447 const struct dbg_block_chip
*block_per_chip
;
3448 const struct dbg_block
*block
;
3449 bool is_removed
, has_dbg_bus
;
3450 u16 modes_buf_offset
;
3454 qed_get_dbg_block_per_chip(p_hwfn
, (enum block_id
)block_id
);
3455 is_removed
= GET_FIELD(block_per_chip
->flags
,
3456 DBG_BLOCK_CHIP_IS_REMOVED
);
3457 has_dbg_bus
= GET_FIELD(block_per_chip
->flags
,
3458 DBG_BLOCK_CHIP_HAS_DBG_BUS
);
3460 if (!is_removed
&& has_dbg_bus
&&
3461 GET_FIELD(block_per_chip
->dbg_bus_mode
.data
,
3462 DBG_MODE_HDR_EVAL_MODE
) > 0) {
3464 GET_FIELD(block_per_chip
->dbg_bus_mode
.data
,
3465 DBG_MODE_HDR_MODES_BUF_OFFSET
);
3466 if (!qed_is_mode_match(p_hwfn
, &modes_buf_offset
))
3467 has_dbg_bus
= false;
3470 if (is_removed
|| !has_dbg_bus
)
3473 block_dwords
= NUM_DBG_LINES(block_per_chip
) *
3474 STATIC_DEBUG_LINE_DWORDS
;
3476 /* Dump static section params */
3477 block
= get_dbg_block(p_hwfn
, (enum block_id
)block_id
);
3478 offset
+= qed_grc_dump_mem_hdr(p_hwfn
,
3484 32, false, "STATIC", 0);
3487 offset
+= block_dwords
;
3491 /* If all lines are invalid - dump zeros */
3492 if (dev_data
->block_in_reset
[block_id
]) {
3493 memset(dump_buf
+ offset
, 0,
3494 DWORDS_TO_BYTES(block_dwords
));
3495 offset
+= block_dwords
;
3499 /* Enable block's client */
3500 qed_bus_enable_clients(p_hwfn
,
3502 BIT(block_per_chip
->dbg_client_id
));
3504 addr
= BYTES_TO_DWORDS(DBG_REG_CALENDAR_OUT_DATA
);
3505 len
= STATIC_DEBUG_LINE_DWORDS
;
3506 for (line_id
= 0; line_id
< (u32
)NUM_DBG_LINES(block_per_chip
);
3508 /* Configure debug line ID */
3509 qed_bus_config_dbg_line(p_hwfn
,
3511 (enum block_id
)block_id
,
3512 (u8
)line_id
, 0xf, 0, 0, 0);
3514 /* Read debug line info */
3515 offset
+= qed_grc_dump_addr_range(p_hwfn
,
3521 true, SPLIT_TYPE_NONE
,
3525 /* Disable block's client and debug output */
3526 qed_bus_enable_clients(p_hwfn
, p_ptt
, 0);
3527 qed_bus_config_dbg_line(p_hwfn
, p_ptt
,
3528 (enum block_id
)block_id
, 0, 0, 0, 0, 0);
3532 qed_bus_enable_dbg_block(p_hwfn
, p_ptt
, false);
3533 qed_bus_enable_clients(p_hwfn
, p_ptt
, 0);
3539 /* Performs GRC Dump to the specified buffer.
3540 * Returns the dumped size in dwords.
3542 static enum dbg_status
qed_grc_dump(struct qed_hwfn
*p_hwfn
,
3543 struct qed_ptt
*p_ptt
,
3545 bool dump
, u32
*num_dumped_dwords
)
3547 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
3548 bool parities_masked
= false;
3549 u32 dwords_read
, offset
= 0;
3552 *num_dumped_dwords
= 0;
3553 dev_data
->num_regs_read
= 0;
3555 /* Update reset state */
3557 qed_update_blocks_reset_state(p_hwfn
, p_ptt
);
3559 /* Dump global params */
3560 offset
+= qed_dump_common_global_params(p_hwfn
,
3562 dump_buf
+ offset
, dump
, 4);
3563 offset
+= qed_dump_str_param(dump_buf
+ offset
,
3564 dump
, "dump-type", "grc-dump");
3565 offset
+= qed_dump_num_param(dump_buf
+ offset
,
3569 offset
+= qed_dump_num_param(dump_buf
+ offset
,
3573 offset
+= qed_dump_num_param(dump_buf
+ offset
,
3574 dump
, "num-ports", dev_data
->num_ports
);
3576 /* Dump reset registers (dumped before taking blocks out of reset ) */
3577 if (qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_REGS
))
3578 offset
+= qed_grc_dump_reset_regs(p_hwfn
,
3580 dump_buf
+ offset
, dump
);
3582 /* Take all blocks out of reset (using reset registers) */
3584 qed_grc_unreset_blocks(p_hwfn
, p_ptt
, false);
3585 qed_update_blocks_reset_state(p_hwfn
, p_ptt
);
3588 /* Disable all parities using MFW command */
3590 !qed_grc_get_param(p_hwfn
, DBG_GRC_PARAM_NO_MCP
)) {
3591 parities_masked
= !qed_mcp_mask_parities(p_hwfn
, p_ptt
, 1);
3592 if (!parities_masked
) {
3594 "Failed to mask parities using MFW\n");
3595 if (qed_grc_get_param
3596 (p_hwfn
, DBG_GRC_PARAM_PARITY_SAFE
))
3597 return DBG_STATUS_MCP_COULD_NOT_MASK_PRTY
;
3601 /* Dump modified registers (dumped before modifying them) */
3602 if (qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_REGS
))
3603 offset
+= qed_grc_dump_modified_regs(p_hwfn
,
3605 dump_buf
+ offset
, dump
);
3609 (qed_grc_is_included(p_hwfn
,
3610 DBG_GRC_PARAM_DUMP_IOR
) ||
3611 qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_VFC
)))
3612 qed_grc_stall_storms(p_hwfn
, p_ptt
, true);
3615 if (qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_REGS
)) {
3616 bool block_enable
[MAX_BLOCK_ID
];
3618 /* Dump all blocks except MCP */
3619 for (i
= 0; i
< MAX_BLOCK_ID
; i
++)
3620 block_enable
[i
] = true;
3621 block_enable
[BLOCK_MCP
] = false;
3622 offset
+= qed_grc_dump_registers(p_hwfn
,
3627 block_enable
, NULL
);
3629 /* Dump special registers */
3630 offset
+= qed_grc_dump_special_regs(p_hwfn
,
3632 dump_buf
+ offset
, dump
);
3636 offset
+= qed_grc_dump_memories(p_hwfn
, p_ptt
, dump_buf
+ offset
, dump
);
3639 if (qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_MCP
))
3640 offset
+= qed_grc_dump_mcp(p_hwfn
,
3641 p_ptt
, dump_buf
+ offset
, dump
);
3644 if (qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_CM_CTX
))
3645 offset
+= qed_grc_dump_ctx(p_hwfn
,
3646 p_ptt
, dump_buf
+ offset
, dump
);
3648 /* Dump RSS memories */
3649 if (qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_RSS
))
3650 offset
+= qed_grc_dump_rss(p_hwfn
,
3651 p_ptt
, dump_buf
+ offset
, dump
);
3654 for (i
= 0; i
< NUM_BIG_RAM_TYPES
; i
++)
3655 if (qed_grc_is_included(p_hwfn
, s_big_ram_defs
[i
].grc_param
))
3656 offset
+= qed_grc_dump_big_ram(p_hwfn
,
3662 if (qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_VFC
)) {
3663 dwords_read
= qed_grc_dump_vfc(p_hwfn
,
3664 p_ptt
, dump_buf
+ offset
, dump
);
3665 offset
+= dwords_read
;
3667 return DBG_STATUS_VFC_READ_ERROR
;
3671 if (qed_grc_is_included(p_hwfn
,
3672 DBG_GRC_PARAM_DUMP_PHY
) && dev_data
->chip_id
==
3673 CHIP_K2
&& dev_data
->hw_type
== HW_TYPE_ASIC
)
3674 offset
+= qed_grc_dump_phy(p_hwfn
,
3675 p_ptt
, dump_buf
+ offset
, dump
);
3677 /* Dump MCP HW Dump */
3678 if (qed_grc_is_included(p_hwfn
, DBG_GRC_PARAM_DUMP_MCP_HW_DUMP
) &&
3679 !qed_grc_get_param(p_hwfn
, DBG_GRC_PARAM_NO_MCP
) && 1)
3680 offset
+= qed_grc_dump_mcp_hw_dump(p_hwfn
,
3682 dump_buf
+ offset
, dump
);
3684 /* Dump static debug data (only if not during debug bus recording) */
3685 if (qed_grc_is_included(p_hwfn
,
3686 DBG_GRC_PARAM_DUMP_STATIC
) &&
3687 (!dump
|| dev_data
->bus
.state
== DBG_BUS_STATE_IDLE
))
3688 offset
+= qed_grc_dump_static_debug(p_hwfn
,
3690 dump_buf
+ offset
, dump
);
3692 /* Dump last section */
3693 offset
+= qed_dump_last_section(dump_buf
, offset
, dump
);
3696 /* Unstall storms */
3697 if (qed_grc_get_param(p_hwfn
, DBG_GRC_PARAM_UNSTALL
))
3698 qed_grc_stall_storms(p_hwfn
, p_ptt
, false);
3700 /* Clear parity status */
3701 qed_grc_clear_all_prty(p_hwfn
, p_ptt
);
3703 /* Enable all parities using MFW command */
3704 if (parities_masked
)
3705 qed_mcp_mask_parities(p_hwfn
, p_ptt
, 0);
3708 *num_dumped_dwords
= offset
;
3710 return DBG_STATUS_OK
;
3713 /* Writes the specified failing Idle Check rule to the specified buffer.
3714 * Returns the dumped size in dwords.
3716 static u32
qed_idle_chk_dump_failure(struct qed_hwfn
*p_hwfn
,
3717 struct qed_ptt
*p_ptt
,
3721 const struct dbg_idle_chk_rule
*rule
,
3722 u16 fail_entry_id
, u32
*cond_reg_values
)
3724 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
3725 const struct dbg_idle_chk_cond_reg
*cond_regs
;
3726 const struct dbg_idle_chk_info_reg
*info_regs
;
3727 u32 i
, next_reg_offset
= 0, offset
= 0;
3728 struct dbg_idle_chk_result_hdr
*hdr
;
3729 const union dbg_idle_chk_reg
*regs
;
3732 hdr
= (struct dbg_idle_chk_result_hdr
*)dump_buf
;
3733 regs
= (const union dbg_idle_chk_reg
*)
3734 p_hwfn
->dbg_arrays
[BIN_BUF_DBG_IDLE_CHK_REGS
].ptr
+
3736 cond_regs
= ®s
[0].cond_reg
;
3737 info_regs
= ®s
[rule
->num_cond_regs
].info_reg
;
3739 /* Dump rule data */
3741 memset(hdr
, 0, sizeof(*hdr
));
3742 hdr
->rule_id
= rule_id
;
3743 hdr
->mem_entry_id
= fail_entry_id
;
3744 hdr
->severity
= rule
->severity
;
3745 hdr
->num_dumped_cond_regs
= rule
->num_cond_regs
;
3748 offset
+= IDLE_CHK_RESULT_HDR_DWORDS
;
3750 /* Dump condition register values */
3751 for (reg_id
= 0; reg_id
< rule
->num_cond_regs
; reg_id
++) {
3752 const struct dbg_idle_chk_cond_reg
*reg
= &cond_regs
[reg_id
];
3753 struct dbg_idle_chk_result_reg_hdr
*reg_hdr
;
3756 (struct dbg_idle_chk_result_reg_hdr
*)(dump_buf
+ offset
);
3758 /* Write register header */
3760 offset
+= IDLE_CHK_RESULT_REG_HDR_DWORDS
+
3765 offset
+= IDLE_CHK_RESULT_REG_HDR_DWORDS
;
3766 memset(reg_hdr
, 0, sizeof(*reg_hdr
));
3767 reg_hdr
->start_entry
= reg
->start_entry
;
3768 reg_hdr
->size
= reg
->entry_size
;
3769 SET_FIELD(reg_hdr
->data
,
3770 DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM
,
3771 reg
->num_entries
> 1 || reg
->start_entry
> 0 ? 1 : 0);
3772 SET_FIELD(reg_hdr
->data
,
3773 DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID
, reg_id
);
3775 /* Write register values */
3776 for (i
= 0; i
< reg_hdr
->size
; i
++, next_reg_offset
++, offset
++)
3777 dump_buf
[offset
] = cond_reg_values
[next_reg_offset
];
3780 /* Dump info register values */
3781 for (reg_id
= 0; reg_id
< rule
->num_info_regs
; reg_id
++) {
3782 const struct dbg_idle_chk_info_reg
*reg
= &info_regs
[reg_id
];
3785 /* Check if register's block is in reset */
3787 offset
+= IDLE_CHK_RESULT_REG_HDR_DWORDS
+ reg
->size
;
3791 block_id
= GET_FIELD(reg
->data
, DBG_IDLE_CHK_INFO_REG_BLOCK_ID
);
3792 if (block_id
>= MAX_BLOCK_ID
) {
3793 DP_NOTICE(p_hwfn
, "Invalid block_id\n");
3797 if (!dev_data
->block_in_reset
[block_id
]) {
3798 struct dbg_idle_chk_result_reg_hdr
*reg_hdr
;
3799 bool wide_bus
, eval_mode
, mode_match
= true;
3800 u16 modes_buf_offset
;
3803 reg_hdr
= (struct dbg_idle_chk_result_reg_hdr
*)
3804 (dump_buf
+ offset
);
3807 eval_mode
= GET_FIELD(reg
->mode
.data
,
3808 DBG_MODE_HDR_EVAL_MODE
) > 0;
3811 GET_FIELD(reg
->mode
.data
,
3812 DBG_MODE_HDR_MODES_BUF_OFFSET
);
3814 qed_is_mode_match(p_hwfn
,
3821 addr
= GET_FIELD(reg
->data
,
3822 DBG_IDLE_CHK_INFO_REG_ADDRESS
);
3823 wide_bus
= GET_FIELD(reg
->data
,
3824 DBG_IDLE_CHK_INFO_REG_WIDE_BUS
);
3826 /* Write register header */
3827 offset
+= IDLE_CHK_RESULT_REG_HDR_DWORDS
;
3828 hdr
->num_dumped_info_regs
++;
3829 memset(reg_hdr
, 0, sizeof(*reg_hdr
));
3830 reg_hdr
->size
= reg
->size
;
3831 SET_FIELD(reg_hdr
->data
,
3832 DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID
,
3833 rule
->num_cond_regs
+ reg_id
);
3835 /* Write register values */
3836 offset
+= qed_grc_dump_addr_range(p_hwfn
,
3841 reg
->size
, wide_bus
,
3842 SPLIT_TYPE_NONE
, 0);
3849 /* Dumps idle check rule entries. Returns the dumped size in dwords. */
3851 qed_idle_chk_dump_rule_entries(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
,
3852 u32
*dump_buf
, bool dump
,
3853 const struct dbg_idle_chk_rule
*input_rules
,
3854 u32 num_input_rules
, u32
*num_failing_rules
)
3856 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
3857 u32 cond_reg_values
[IDLE_CHK_MAX_ENTRIES_SIZE
];
3862 *num_failing_rules
= 0;
3864 for (i
= 0; i
< num_input_rules
; i
++) {
3865 const struct dbg_idle_chk_cond_reg
*cond_regs
;
3866 const struct dbg_idle_chk_rule
*rule
;
3867 const union dbg_idle_chk_reg
*regs
;
3868 u16 num_reg_entries
= 1;
3869 bool check_rule
= true;
3870 const u32
*imm_values
;
3872 rule
= &input_rules
[i
];
3873 regs
= (const union dbg_idle_chk_reg
*)
3874 p_hwfn
->dbg_arrays
[BIN_BUF_DBG_IDLE_CHK_REGS
].ptr
+
3876 cond_regs
= ®s
[0].cond_reg
;
3878 (u32
*)p_hwfn
->dbg_arrays
[BIN_BUF_DBG_IDLE_CHK_IMMS
].ptr
+
3881 /* Check if all condition register blocks are out of reset, and
3882 * find maximal number of entries (all condition registers that
3883 * are memories must have the same size, which is > 1).
3885 for (reg_id
= 0; reg_id
< rule
->num_cond_regs
&& check_rule
;
3888 GET_FIELD(cond_regs
[reg_id
].data
,
3889 DBG_IDLE_CHK_COND_REG_BLOCK_ID
);
3891 if (block_id
>= MAX_BLOCK_ID
) {
3892 DP_NOTICE(p_hwfn
, "Invalid block_id\n");
3896 check_rule
= !dev_data
->block_in_reset
[block_id
];
3897 if (cond_regs
[reg_id
].num_entries
> num_reg_entries
)
3898 num_reg_entries
= cond_regs
[reg_id
].num_entries
;
3901 if (!check_rule
&& dump
)
3905 u32 entry_dump_size
=
3906 qed_idle_chk_dump_failure(p_hwfn
,
3915 offset
+= num_reg_entries
* entry_dump_size
;
3916 (*num_failing_rules
) += num_reg_entries
;
3920 /* Go over all register entries (number of entries is the same
3921 * for all condition registers).
3923 for (entry_id
= 0; entry_id
< num_reg_entries
; entry_id
++) {
3924 u32 next_reg_offset
= 0;
3926 /* Read current entry of all condition registers */
3927 for (reg_id
= 0; reg_id
< rule
->num_cond_regs
;
3929 const struct dbg_idle_chk_cond_reg
*reg
=
3931 u32 padded_entry_size
, addr
;
3934 /* Find GRC address (if it's a memory, the
3935 * address of the specific entry is calculated).
3937 addr
= GET_FIELD(reg
->data
,
3938 DBG_IDLE_CHK_COND_REG_ADDRESS
);
3940 GET_FIELD(reg
->data
,
3941 DBG_IDLE_CHK_COND_REG_WIDE_BUS
);
3942 if (reg
->num_entries
> 1 ||
3943 reg
->start_entry
> 0) {
3945 reg
->entry_size
> 1 ?
3946 roundup_pow_of_two(reg
->entry_size
) :
3948 addr
+= (reg
->start_entry
+ entry_id
) *
3952 /* Read registers */
3953 if (next_reg_offset
+ reg
->entry_size
>=
3954 IDLE_CHK_MAX_ENTRIES_SIZE
) {
3956 "idle check registers entry is too large\n");
3961 qed_grc_dump_addr_range(p_hwfn
, p_ptt
,
3967 SPLIT_TYPE_NONE
, 0);
3970 /* Call rule condition function.
3971 * If returns true, it's a failure.
3973 if ((*cond_arr
[rule
->cond_id
]) (cond_reg_values
,
3975 offset
+= qed_idle_chk_dump_failure(p_hwfn
,
3983 (*num_failing_rules
)++;
3991 /* Performs Idle Check Dump to the specified buffer.
3992 * Returns the dumped size in dwords.
3994 static u32
qed_idle_chk_dump(struct qed_hwfn
*p_hwfn
,
3995 struct qed_ptt
*p_ptt
, u32
*dump_buf
, bool dump
)
3997 struct virt_mem_desc
*dbg_buf
=
3998 &p_hwfn
->dbg_arrays
[BIN_BUF_DBG_IDLE_CHK_RULES
];
3999 u32 num_failing_rules_offset
, offset
= 0,
4000 input_offset
= 0, num_failing_rules
= 0;
4002 /* Dump global params - 1 must match below amount of params */
4003 offset
+= qed_dump_common_global_params(p_hwfn
,
4005 dump_buf
+ offset
, dump
, 1);
4006 offset
+= qed_dump_str_param(dump_buf
+ offset
,
4007 dump
, "dump-type", "idle-chk");
4009 /* Dump idle check section header with a single parameter */
4010 offset
+= qed_dump_section_hdr(dump_buf
+ offset
, dump
, "idle_chk", 1);
4011 num_failing_rules_offset
= offset
;
4012 offset
+= qed_dump_num_param(dump_buf
+ offset
, dump
, "num_rules", 0);
4014 while (input_offset
< BYTES_TO_DWORDS(dbg_buf
->size
)) {
4015 const struct dbg_idle_chk_cond_hdr
*cond_hdr
=
4016 (const struct dbg_idle_chk_cond_hdr
*)dbg_buf
->ptr
+
4018 bool eval_mode
, mode_match
= true;
4019 u32 curr_failing_rules
;
4020 u16 modes_buf_offset
;
4023 eval_mode
= GET_FIELD(cond_hdr
->mode
.data
,
4024 DBG_MODE_HDR_EVAL_MODE
) > 0;
4027 GET_FIELD(cond_hdr
->mode
.data
,
4028 DBG_MODE_HDR_MODES_BUF_OFFSET
);
4029 mode_match
= qed_is_mode_match(p_hwfn
,
4034 const struct dbg_idle_chk_rule
*rule
=
4035 (const struct dbg_idle_chk_rule
*)((u32
*)
4038 u32 num_input_rules
=
4039 cond_hdr
->data_size
/ IDLE_CHK_RULE_SIZE_DWORDS
;
4041 qed_idle_chk_dump_rule_entries(p_hwfn
,
4048 &curr_failing_rules
);
4049 num_failing_rules
+= curr_failing_rules
;
4052 input_offset
+= cond_hdr
->data_size
;
4055 /* Overwrite num_rules parameter */
4057 qed_dump_num_param(dump_buf
+ num_failing_rules_offset
,
4058 dump
, "num_rules", num_failing_rules
);
4060 /* Dump last section */
4061 offset
+= qed_dump_last_section(dump_buf
, offset
, dump
);
4066 /* Get info on the MCP Trace data in the scratchpad:
4067 * - trace_data_grc_addr (OUT): trace data GRC address in bytes
4068 * - trace_data_size (OUT): trace data size in bytes (without the header)
4070 static enum dbg_status
qed_mcp_trace_get_data_info(struct qed_hwfn
*p_hwfn
,
4071 struct qed_ptt
*p_ptt
,
4072 u32
*trace_data_grc_addr
,
4073 u32
*trace_data_size
)
4075 u32 spad_trace_offsize
, signature
;
4077 /* Read trace section offsize structure from MCP scratchpad */
4078 spad_trace_offsize
= qed_rd(p_hwfn
, p_ptt
, MCP_SPAD_TRACE_OFFSIZE_ADDR
);
4080 /* Extract trace section address from offsize (in scratchpad) */
4081 *trace_data_grc_addr
=
4082 MCP_REG_SCRATCH
+ SECTION_OFFSET(spad_trace_offsize
);
4084 /* Read signature from MCP trace section */
4085 signature
= qed_rd(p_hwfn
, p_ptt
,
4086 *trace_data_grc_addr
+
4087 offsetof(struct mcp_trace
, signature
));
4089 if (signature
!= MFW_TRACE_SIGNATURE
)
4090 return DBG_STATUS_INVALID_TRACE_SIGNATURE
;
4092 /* Read trace size from MCP trace section */
4093 *trace_data_size
= qed_rd(p_hwfn
,
4095 *trace_data_grc_addr
+
4096 offsetof(struct mcp_trace
, size
));
4098 return DBG_STATUS_OK
;
4101 /* Reads MCP trace meta data image from NVRAM
4102 * - running_bundle_id (OUT): running bundle ID (invalid when loaded from file)
4103 * - trace_meta_offset (OUT): trace meta offset in NVRAM in bytes (invalid when
4104 * loaded from file).
4105 * - trace_meta_size (OUT): size in bytes of the trace meta data.
4107 static enum dbg_status
qed_mcp_trace_get_meta_info(struct qed_hwfn
*p_hwfn
,
4108 struct qed_ptt
*p_ptt
,
4109 u32 trace_data_size_bytes
,
4110 u32
*running_bundle_id
,
4111 u32
*trace_meta_offset
,
4112 u32
*trace_meta_size
)
4114 u32 spad_trace_offsize
, nvram_image_type
, running_mfw_addr
;
4116 /* Read MCP trace section offsize structure from MCP scratchpad */
4117 spad_trace_offsize
= qed_rd(p_hwfn
, p_ptt
, MCP_SPAD_TRACE_OFFSIZE_ADDR
);
4119 /* Find running bundle ID */
4121 MCP_REG_SCRATCH
+ SECTION_OFFSET(spad_trace_offsize
) +
4122 QED_SECTION_SIZE(spad_trace_offsize
) + trace_data_size_bytes
;
4123 *running_bundle_id
= qed_rd(p_hwfn
, p_ptt
, running_mfw_addr
);
4124 if (*running_bundle_id
> 1)
4125 return DBG_STATUS_INVALID_NVRAM_BUNDLE
;
4127 /* Find image in NVRAM */
4129 (*running_bundle_id
==
4130 DIR_ID_1
) ? NVM_TYPE_MFW_TRACE1
: NVM_TYPE_MFW_TRACE2
;
4131 return qed_find_nvram_image(p_hwfn
,
4139 /* Reads the MCP Trace meta data from NVRAM into the specified buffer */
4140 static enum dbg_status
qed_mcp_trace_read_meta(struct qed_hwfn
*p_hwfn
,
4141 struct qed_ptt
*p_ptt
,
4142 u32 nvram_offset_in_bytes
,
4143 u32 size_in_bytes
, u32
*buf
)
4145 u8 modules_num
, module_len
, i
, *byte_buf
= (u8
*)buf
;
4146 enum dbg_status status
;
4149 /* Read meta data from NVRAM */
4150 status
= qed_nvram_read(p_hwfn
,
4152 nvram_offset_in_bytes
,
4156 if (status
!= DBG_STATUS_OK
)
4159 /* Extract and check first signature */
4160 signature
= qed_read_unaligned_dword(byte_buf
);
4161 byte_buf
+= sizeof(signature
);
4162 if (signature
!= NVM_MAGIC_VALUE
)
4163 return DBG_STATUS_INVALID_TRACE_SIGNATURE
;
4165 /* Extract number of modules */
4166 modules_num
= *(byte_buf
++);
4168 /* Skip all modules */
4169 for (i
= 0; i
< modules_num
; i
++) {
4170 module_len
= *(byte_buf
++);
4171 byte_buf
+= module_len
;
4174 /* Extract and check second signature */
4175 signature
= qed_read_unaligned_dword(byte_buf
);
4176 byte_buf
+= sizeof(signature
);
4177 if (signature
!= NVM_MAGIC_VALUE
)
4178 return DBG_STATUS_INVALID_TRACE_SIGNATURE
;
4180 return DBG_STATUS_OK
;
4183 /* Dump MCP Trace */
4184 static enum dbg_status
qed_mcp_trace_dump(struct qed_hwfn
*p_hwfn
,
4185 struct qed_ptt
*p_ptt
,
4187 bool dump
, u32
*num_dumped_dwords
)
4189 u32 trace_data_grc_addr
, trace_data_size_bytes
, trace_data_size_dwords
;
4190 u32 trace_meta_size_dwords
= 0, running_bundle_id
, offset
= 0;
4191 u32 trace_meta_offset_bytes
= 0, trace_meta_size_bytes
= 0;
4192 enum dbg_status status
;
4196 *num_dumped_dwords
= 0;
4198 use_mfw
= !qed_grc_get_param(p_hwfn
, DBG_GRC_PARAM_NO_MCP
);
4200 /* Get trace data info */
4201 status
= qed_mcp_trace_get_data_info(p_hwfn
,
4203 &trace_data_grc_addr
,
4204 &trace_data_size_bytes
);
4205 if (status
!= DBG_STATUS_OK
)
4208 /* Dump global params */
4209 offset
+= qed_dump_common_global_params(p_hwfn
,
4211 dump_buf
+ offset
, dump
, 1);
4212 offset
+= qed_dump_str_param(dump_buf
+ offset
,
4213 dump
, "dump-type", "mcp-trace");
4215 /* Halt MCP while reading from scratchpad so the read data will be
4216 * consistent. if halt fails, MCP trace is taken anyway, with a small
4217 * risk that it may be corrupt.
4219 if (dump
&& use_mfw
) {
4220 halted
= !qed_mcp_halt(p_hwfn
, p_ptt
);
4222 DP_NOTICE(p_hwfn
, "MCP halt failed!\n");
4225 /* Find trace data size */
4226 trace_data_size_dwords
=
4227 DIV_ROUND_UP(trace_data_size_bytes
+ sizeof(struct mcp_trace
),
4230 /* Dump trace data section header and param */
4231 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
4232 dump
, "mcp_trace_data", 1);
4233 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4234 dump
, "size", trace_data_size_dwords
);
4236 /* Read trace data from scratchpad into dump buffer */
4237 offset
+= qed_grc_dump_addr_range(p_hwfn
,
4241 BYTES_TO_DWORDS(trace_data_grc_addr
),
4242 trace_data_size_dwords
, false,
4243 SPLIT_TYPE_NONE
, 0);
4245 /* Resume MCP (only if halt succeeded) */
4246 if (halted
&& qed_mcp_resume(p_hwfn
, p_ptt
))
4247 DP_NOTICE(p_hwfn
, "Failed to resume MCP after halt!\n");
4249 /* Dump trace meta section header */
4250 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
4251 dump
, "mcp_trace_meta", 1);
4253 /* If MCP Trace meta size parameter was set, use it.
4254 * Otherwise, read trace meta.
4255 * trace_meta_size_bytes is dword-aligned.
4257 trace_meta_size_bytes
=
4258 qed_grc_get_param(p_hwfn
, DBG_GRC_PARAM_MCP_TRACE_META_SIZE
);
4259 if ((!trace_meta_size_bytes
|| dump
) && use_mfw
)
4260 status
= qed_mcp_trace_get_meta_info(p_hwfn
,
4262 trace_data_size_bytes
,
4264 &trace_meta_offset_bytes
,
4265 &trace_meta_size_bytes
);
4266 if (status
== DBG_STATUS_OK
)
4267 trace_meta_size_dwords
= BYTES_TO_DWORDS(trace_meta_size_bytes
);
4269 /* Dump trace meta size param */
4270 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4271 dump
, "size", trace_meta_size_dwords
);
4273 /* Read trace meta image into dump buffer */
4274 if (dump
&& trace_meta_size_dwords
)
4275 status
= qed_mcp_trace_read_meta(p_hwfn
,
4277 trace_meta_offset_bytes
,
4278 trace_meta_size_bytes
,
4280 if (status
== DBG_STATUS_OK
)
4281 offset
+= trace_meta_size_dwords
;
4283 /* Dump last section */
4284 offset
+= qed_dump_last_section(dump_buf
, offset
, dump
);
4286 *num_dumped_dwords
= offset
;
4288 /* If no mcp access, indicate that the dump doesn't contain the meta
4291 return use_mfw
? status
: DBG_STATUS_NVRAM_GET_IMAGE_FAILED
;
4295 static enum dbg_status
qed_reg_fifo_dump(struct qed_hwfn
*p_hwfn
,
4296 struct qed_ptt
*p_ptt
,
4298 bool dump
, u32
*num_dumped_dwords
)
4300 u32 dwords_read
, size_param_offset
, offset
= 0, addr
, len
;
4303 *num_dumped_dwords
= 0;
4305 /* Dump global params */
4306 offset
+= qed_dump_common_global_params(p_hwfn
,
4308 dump_buf
+ offset
, dump
, 1);
4309 offset
+= qed_dump_str_param(dump_buf
+ offset
,
4310 dump
, "dump-type", "reg-fifo");
4312 /* Dump fifo data section header and param. The size param is 0 for
4313 * now, and is overwritten after reading the FIFO.
4315 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
4316 dump
, "reg_fifo_data", 1);
4317 size_param_offset
= offset
;
4318 offset
+= qed_dump_num_param(dump_buf
+ offset
, dump
, "size", 0);
4321 /* FIFO max size is REG_FIFO_DEPTH_DWORDS. There is no way to
4322 * test how much data is available, except for reading it.
4324 offset
+= REG_FIFO_DEPTH_DWORDS
;
4328 fifo_has_data
= qed_rd(p_hwfn
, p_ptt
,
4329 GRC_REG_TRACE_FIFO_VALID_DATA
) > 0;
4331 /* Pull available data from fifo. Use DMAE since this is widebus memory
4332 * and must be accessed atomically. Test for dwords_read not passing
4333 * buffer size since more entries could be added to the buffer as we are
4336 addr
= BYTES_TO_DWORDS(GRC_REG_TRACE_FIFO
);
4337 len
= REG_FIFO_ELEMENT_DWORDS
;
4338 for (dwords_read
= 0;
4339 fifo_has_data
&& dwords_read
< REG_FIFO_DEPTH_DWORDS
;
4340 dwords_read
+= REG_FIFO_ELEMENT_DWORDS
) {
4341 offset
+= qed_grc_dump_addr_range(p_hwfn
,
4347 true, SPLIT_TYPE_NONE
,
4349 fifo_has_data
= qed_rd(p_hwfn
, p_ptt
,
4350 GRC_REG_TRACE_FIFO_VALID_DATA
) > 0;
4353 qed_dump_num_param(dump_buf
+ size_param_offset
, dump
, "size",
4356 /* Dump last section */
4357 offset
+= qed_dump_last_section(dump_buf
, offset
, dump
);
4359 *num_dumped_dwords
= offset
;
4361 return DBG_STATUS_OK
;
4365 static enum dbg_status
qed_igu_fifo_dump(struct qed_hwfn
*p_hwfn
,
4366 struct qed_ptt
*p_ptt
,
4368 bool dump
, u32
*num_dumped_dwords
)
4370 u32 dwords_read
, size_param_offset
, offset
= 0, addr
, len
;
4373 *num_dumped_dwords
= 0;
4375 /* Dump global params */
4376 offset
+= qed_dump_common_global_params(p_hwfn
,
4378 dump_buf
+ offset
, dump
, 1);
4379 offset
+= qed_dump_str_param(dump_buf
+ offset
,
4380 dump
, "dump-type", "igu-fifo");
4382 /* Dump fifo data section header and param. The size param is 0 for
4383 * now, and is overwritten after reading the FIFO.
4385 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
4386 dump
, "igu_fifo_data", 1);
4387 size_param_offset
= offset
;
4388 offset
+= qed_dump_num_param(dump_buf
+ offset
, dump
, "size", 0);
4391 /* FIFO max size is IGU_FIFO_DEPTH_DWORDS. There is no way to
4392 * test how much data is available, except for reading it.
4394 offset
+= IGU_FIFO_DEPTH_DWORDS
;
4398 fifo_has_data
= qed_rd(p_hwfn
, p_ptt
,
4399 IGU_REG_ERROR_HANDLING_DATA_VALID
) > 0;
4401 /* Pull available data from fifo. Use DMAE since this is widebus memory
4402 * and must be accessed atomically. Test for dwords_read not passing
4403 * buffer size since more entries could be added to the buffer as we are
4406 addr
= BYTES_TO_DWORDS(IGU_REG_ERROR_HANDLING_MEMORY
);
4407 len
= IGU_FIFO_ELEMENT_DWORDS
;
4408 for (dwords_read
= 0;
4409 fifo_has_data
&& dwords_read
< IGU_FIFO_DEPTH_DWORDS
;
4410 dwords_read
+= IGU_FIFO_ELEMENT_DWORDS
) {
4411 offset
+= qed_grc_dump_addr_range(p_hwfn
,
4417 true, SPLIT_TYPE_NONE
,
4419 fifo_has_data
= qed_rd(p_hwfn
, p_ptt
,
4420 IGU_REG_ERROR_HANDLING_DATA_VALID
) > 0;
4423 qed_dump_num_param(dump_buf
+ size_param_offset
, dump
, "size",
4426 /* Dump last section */
4427 offset
+= qed_dump_last_section(dump_buf
, offset
, dump
);
4429 *num_dumped_dwords
= offset
;
4431 return DBG_STATUS_OK
;
4434 /* Protection Override dump */
4435 static enum dbg_status
qed_protection_override_dump(struct qed_hwfn
*p_hwfn
,
4436 struct qed_ptt
*p_ptt
,
4439 u32
*num_dumped_dwords
)
4441 u32 size_param_offset
, override_window_dwords
, offset
= 0, addr
;
4443 *num_dumped_dwords
= 0;
4445 /* Dump global params */
4446 offset
+= qed_dump_common_global_params(p_hwfn
,
4448 dump_buf
+ offset
, dump
, 1);
4449 offset
+= qed_dump_str_param(dump_buf
+ offset
,
4450 dump
, "dump-type", "protection-override");
4452 /* Dump data section header and param. The size param is 0 for now,
4453 * and is overwritten after reading the data.
4455 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
4456 dump
, "protection_override_data", 1);
4457 size_param_offset
= offset
;
4458 offset
+= qed_dump_num_param(dump_buf
+ offset
, dump
, "size", 0);
4461 offset
+= PROTECTION_OVERRIDE_DEPTH_DWORDS
;
4465 /* Add override window info to buffer */
4466 override_window_dwords
=
4467 qed_rd(p_hwfn
, p_ptt
, GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW
) *
4468 PROTECTION_OVERRIDE_ELEMENT_DWORDS
;
4469 if (override_window_dwords
) {
4470 addr
= BYTES_TO_DWORDS(GRC_REG_PROTECTION_OVERRIDE_WINDOW
);
4471 offset
+= qed_grc_dump_addr_range(p_hwfn
,
4476 override_window_dwords
,
4477 true, SPLIT_TYPE_NONE
, 0);
4478 qed_dump_num_param(dump_buf
+ size_param_offset
, dump
, "size",
4479 override_window_dwords
);
4482 /* Dump last section */
4483 offset
+= qed_dump_last_section(dump_buf
, offset
, dump
);
4485 *num_dumped_dwords
= offset
;
4487 return DBG_STATUS_OK
;
4490 /* Performs FW Asserts Dump to the specified buffer.
4491 * Returns the dumped size in dwords.
4493 static u32
qed_fw_asserts_dump(struct qed_hwfn
*p_hwfn
,
4494 struct qed_ptt
*p_ptt
, u32
*dump_buf
, bool dump
)
4496 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
4497 struct fw_asserts_ram_section
*asserts
;
4498 char storm_letter_str
[2] = "?";
4499 struct fw_info fw_info
;
4503 /* Dump global params */
4504 offset
+= qed_dump_common_global_params(p_hwfn
,
4506 dump_buf
+ offset
, dump
, 1);
4507 offset
+= qed_dump_str_param(dump_buf
+ offset
,
4508 dump
, "dump-type", "fw-asserts");
4510 /* Find Storm dump size */
4511 for (storm_id
= 0; storm_id
< MAX_DBG_STORMS
; storm_id
++) {
4512 u32 fw_asserts_section_addr
, next_list_idx_addr
, next_list_idx
;
4513 struct storm_defs
*storm
= &s_storm_defs
[storm_id
];
4514 u32 last_list_idx
, addr
;
4516 if (dev_data
->block_in_reset
[storm
->sem_block_id
])
4519 /* Read FW info for the current Storm */
4520 qed_read_storm_fw_info(p_hwfn
, p_ptt
, storm_id
, &fw_info
);
4522 asserts
= &fw_info
.fw_asserts_section
;
4524 /* Dump FW Asserts section header and params */
4525 storm_letter_str
[0] = storm
->letter
;
4526 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
4527 dump
, "fw_asserts", 2);
4528 offset
+= qed_dump_str_param(dump_buf
+ offset
,
4529 dump
, "storm", storm_letter_str
);
4530 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4533 asserts
->list_element_dword_size
);
4535 /* Read and dump FW Asserts data */
4537 offset
+= asserts
->list_element_dword_size
;
4541 addr
= le16_to_cpu(asserts
->section_ram_line_offset
);
4542 fw_asserts_section_addr
= storm
->sem_fast_mem_addr
+
4543 SEM_FAST_REG_INT_RAM
+
4544 RAM_LINES_TO_BYTES(addr
);
4546 next_list_idx_addr
= fw_asserts_section_addr
+
4547 DWORDS_TO_BYTES(asserts
->list_next_index_dword_offset
);
4548 next_list_idx
= qed_rd(p_hwfn
, p_ptt
, next_list_idx_addr
);
4549 last_list_idx
= (next_list_idx
> 0 ?
4551 asserts
->list_num_elements
) - 1;
4552 addr
= BYTES_TO_DWORDS(fw_asserts_section_addr
) +
4553 asserts
->list_dword_offset
+
4554 last_list_idx
* asserts
->list_element_dword_size
;
4556 qed_grc_dump_addr_range(p_hwfn
, p_ptt
,
4559 asserts
->list_element_dword_size
,
4560 false, SPLIT_TYPE_NONE
, 0);
4563 /* Dump last section */
4564 offset
+= qed_dump_last_section(dump_buf
, offset
, dump
);
4569 /* Dumps the specified ILT pages to the specified buffer.
4570 * Returns the dumped size in dwords.
4572 static u32
qed_ilt_dump_pages_range(u32
*dump_buf
, u32
*given_offset
,
4573 bool *dump
, u32 start_page_id
,
4575 struct phys_mem_desc
*ilt_pages
,
4576 bool dump_page_ids
, u32 buf_size_in_dwords
,
4577 u32
*given_actual_dump_size_in_dwords
)
4579 u32 actual_dump_size_in_dwords
= *given_actual_dump_size_in_dwords
;
4580 u32 page_id
, end_page_id
, offset
= *given_offset
;
4581 struct phys_mem_desc
*mem_desc
= NULL
;
4582 bool continue_dump
= *dump
;
4583 u32 partial_page_size
= 0;
4588 end_page_id
= start_page_id
+ num_pages
- 1;
4590 for (page_id
= start_page_id
; page_id
<= end_page_id
; page_id
++) {
4591 mem_desc
= &ilt_pages
[page_id
];
4592 if (!ilt_pages
[page_id
].virt_addr
)
4595 if (dump_page_ids
) {
4596 /* Copy page ID to dump buffer
4597 * (if dump is needed and buffer is not full)
4599 if ((continue_dump
) &&
4600 (offset
+ 1 > buf_size_in_dwords
)) {
4601 continue_dump
= false;
4602 actual_dump_size_in_dwords
= offset
;
4605 *(dump_buf
+ offset
) = page_id
;
4608 /* Copy page memory to dump buffer */
4609 if ((continue_dump
) &&
4610 (offset
+ BYTES_TO_DWORDS(mem_desc
->size
) >
4611 buf_size_in_dwords
)) {
4612 if (offset
+ BYTES_TO_DWORDS(mem_desc
->size
) >
4613 buf_size_in_dwords
) {
4615 buf_size_in_dwords
- offset
;
4616 memcpy(dump_buf
+ offset
,
4617 mem_desc
->virt_addr
,
4619 continue_dump
= false;
4620 actual_dump_size_in_dwords
=
4621 offset
+ partial_page_size
;
4626 memcpy(dump_buf
+ offset
,
4627 mem_desc
->virt_addr
, mem_desc
->size
);
4628 offset
+= BYTES_TO_DWORDS(mem_desc
->size
);
4632 *dump
= continue_dump
;
4633 *given_offset
= offset
;
4634 *given_actual_dump_size_in_dwords
= actual_dump_size_in_dwords
;
4639 /* Dumps a section containing the dumped ILT pages.
4640 * Returns the dumped size in dwords.
4642 static u32
qed_ilt_dump_pages_section(struct qed_hwfn
*p_hwfn
,
4646 u32 valid_conn_pf_pages
,
4647 u32 valid_conn_vf_pages
,
4648 struct phys_mem_desc
*ilt_pages
,
4650 u32 buf_size_in_dwords
,
4651 u32
*given_actual_dump_size_in_dwords
)
4653 struct qed_ilt_client_cfg
*clients
= p_hwfn
->p_cxt_mngr
->clients
;
4654 u32 pf_start_line
, start_page_id
, offset
= *given_offset
;
4655 u32 cdut_pf_init_pages
, cdut_vf_init_pages
;
4656 u32 cdut_pf_work_pages
, cdut_vf_work_pages
;
4657 u32 base_data_offset
, size_param_offset
;
4659 u32 section_header_and_param_size
;
4660 u32 cdut_pf_pages
, cdut_vf_pages
;
4661 u32 actual_dump_size_in_dwords
;
4662 bool continue_dump
= *dump
;
4663 bool update_size
= *dump
;
4664 const char *section_name
;
4667 actual_dump_size_in_dwords
= *given_actual_dump_size_in_dwords
;
4668 section_name
= dump_page_ids
? "ilt_page_ids" : "ilt_page_mem";
4669 cdut_pf_init_pages
= qed_get_cdut_num_pf_init_pages(p_hwfn
);
4670 cdut_vf_init_pages
= qed_get_cdut_num_vf_init_pages(p_hwfn
);
4671 cdut_pf_work_pages
= qed_get_cdut_num_pf_work_pages(p_hwfn
);
4672 cdut_vf_work_pages
= qed_get_cdut_num_vf_work_pages(p_hwfn
);
4673 cdut_pf_pages
= cdut_pf_init_pages
+ cdut_pf_work_pages
;
4674 cdut_vf_pages
= cdut_vf_init_pages
+ cdut_vf_work_pages
;
4675 pf_start_line
= p_hwfn
->p_cxt_mngr
->pf_start_line
;
4676 section_header_and_param_size
= qed_dump_section_hdr(NULL
,
4680 qed_dump_num_param(NULL
, false, "size", 0);
4682 if ((continue_dump
) &&
4683 (offset
+ section_header_and_param_size
> buf_size_in_dwords
)) {
4684 continue_dump
= false;
4685 update_size
= false;
4686 actual_dump_size_in_dwords
= offset
;
4689 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
4690 continue_dump
, section_name
, 1);
4692 /* Dump size parameter (0 for now, overwritten with real size later) */
4693 size_param_offset
= offset
;
4694 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4695 continue_dump
, "size", 0);
4696 base_data_offset
= offset
;
4698 /* CDUC pages are ordered as follows:
4699 * - PF pages - valid section (included in PF connection type mapping)
4700 * - PF pages - invalid section (not dumped)
4701 * - For each VF in the PF:
4702 * - VF pages - valid section (included in VF connection type mapping)
4703 * - VF pages - invalid section (not dumped)
4705 if (qed_grc_get_param(p_hwfn
, DBG_GRC_PARAM_DUMP_ILT_CDUC
)) {
4706 /* Dump connection PF pages */
4707 start_page_id
= clients
[ILT_CLI_CDUC
].first
.val
- pf_start_line
;
4708 qed_ilt_dump_pages_range(dump_buf
, &offset
, &continue_dump
,
4709 start_page_id
, valid_conn_pf_pages
,
4710 ilt_pages
, dump_page_ids
,
4712 &actual_dump_size_in_dwords
);
4714 /* Dump connection VF pages */
4715 start_page_id
+= clients
[ILT_CLI_CDUC
].pf_total_lines
;
4716 for (i
= 0; i
< p_hwfn
->p_cxt_mngr
->vf_count
;
4717 i
++, start_page_id
+= clients
[ILT_CLI_CDUC
].vf_total_lines
)
4718 qed_ilt_dump_pages_range(dump_buf
, &offset
,
4719 &continue_dump
, start_page_id
,
4720 valid_conn_vf_pages
,
4721 ilt_pages
, dump_page_ids
,
4723 &actual_dump_size_in_dwords
);
4726 /* CDUT pages are ordered as follows:
4727 * - PF init pages (not dumped)
4729 * - For each VF in the PF:
4730 * - VF init pages (not dumped)
4733 if (qed_grc_get_param(p_hwfn
, DBG_GRC_PARAM_DUMP_ILT_CDUT
)) {
4734 /* Dump task PF pages */
4735 start_page_id
= clients
[ILT_CLI_CDUT
].first
.val
+
4736 cdut_pf_init_pages
- pf_start_line
;
4737 qed_ilt_dump_pages_range(dump_buf
, &offset
, &continue_dump
,
4738 start_page_id
, cdut_pf_work_pages
,
4739 ilt_pages
, dump_page_ids
,
4741 &actual_dump_size_in_dwords
);
4743 /* Dump task VF pages */
4744 start_page_id
= clients
[ILT_CLI_CDUT
].first
.val
+
4745 cdut_pf_pages
+ cdut_vf_init_pages
- pf_start_line
;
4746 for (i
= 0; i
< p_hwfn
->p_cxt_mngr
->vf_count
;
4747 i
++, start_page_id
+= cdut_vf_pages
)
4748 qed_ilt_dump_pages_range(dump_buf
, &offset
,
4749 &continue_dump
, start_page_id
,
4750 cdut_vf_work_pages
, ilt_pages
,
4753 &actual_dump_size_in_dwords
);
4756 /*Dump Searcher pages */
4757 if (clients
[ILT_CLI_SRC
].active
) {
4758 start_page_id
= clients
[ILT_CLI_SRC
].first
.val
- pf_start_line
;
4759 src_pages
= clients
[ILT_CLI_SRC
].last
.val
-
4760 clients
[ILT_CLI_SRC
].first
.val
+ 1;
4761 qed_ilt_dump_pages_range(dump_buf
, &offset
, &continue_dump
,
4762 start_page_id
, src_pages
, ilt_pages
,
4763 dump_page_ids
, buf_size_in_dwords
,
4764 &actual_dump_size_in_dwords
);
4767 /* Overwrite size param */
4769 u32 section_size
= (*dump
== continue_dump
) ?
4770 offset
- base_data_offset
:
4771 actual_dump_size_in_dwords
- base_data_offset
;
4772 if (section_size
> 0)
4773 qed_dump_num_param(dump_buf
+ size_param_offset
,
4774 *dump
, "size", section_size
);
4775 else if ((section_size
== 0) && (*dump
!= continue_dump
))
4776 actual_dump_size_in_dwords
-=
4777 section_header_and_param_size
;
4780 *dump
= continue_dump
;
4781 *given_offset
= offset
;
4782 *given_actual_dump_size_in_dwords
= actual_dump_size_in_dwords
;
4787 /* Dumps a section containing the global parameters.
4788 * Part of ilt dump process
4789 * Returns the dumped size in dwords.
4792 qed_ilt_dump_dump_common_global_params(struct qed_hwfn
*p_hwfn
,
4793 struct qed_ptt
*p_ptt
,
4799 u32
*full_dump_size_param_offset
,
4800 u32
*actual_dump_size_param_offset
)
4802 struct qed_ilt_client_cfg
*clients
= p_hwfn
->p_cxt_mngr
->clients
;
4805 offset
+= qed_dump_common_global_params(p_hwfn
, p_ptt
,
4808 offset
+= qed_dump_str_param(dump_buf
+ offset
,
4810 "dump-type", "ilt-dump");
4811 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4815 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4817 "cduc-first-page-id",
4818 clients
[ILT_CLI_CDUC
].first
.val
);
4819 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4821 "cduc-last-page-id",
4822 clients
[ILT_CLI_CDUC
].last
.val
);
4823 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4825 "cduc-num-pf-pages",
4826 clients
[ILT_CLI_CDUC
].pf_total_lines
);
4827 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4829 "cduc-num-vf-pages",
4830 clients
[ILT_CLI_CDUC
].vf_total_lines
);
4831 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4833 "max-conn-ctx-size",
4835 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4839 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4841 "cdut-first-page-id",
4842 clients
[ILT_CLI_CDUT
].first
.val
);
4843 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4845 "cdut-last-page-id",
4846 clients
[ILT_CLI_CDUT
].last
.val
);
4847 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4849 "cdut-num-pf-init-pages",
4850 qed_get_cdut_num_pf_init_pages(p_hwfn
));
4851 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4853 "cdut-num-vf-init-pages",
4854 qed_get_cdut_num_vf_init_pages(p_hwfn
));
4855 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4857 "cdut-num-pf-work-pages",
4858 qed_get_cdut_num_pf_work_pages(p_hwfn
));
4859 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4861 "cdut-num-vf-work-pages",
4862 qed_get_cdut_num_vf_work_pages(p_hwfn
));
4863 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4865 "max-task-ctx-size",
4866 p_hwfn
->p_cxt_mngr
->task_ctx_size
);
4867 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4869 "first-vf-id-in-pf",
4870 p_hwfn
->p_cxt_mngr
->first_vf_in_pf
);
4871 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4874 p_hwfn
->p_cxt_mngr
->vf_count
);
4875 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4879 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4882 p_hwfn
->p_cxt_mngr
->pf_start_line
);
4883 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4885 "page-mem-desc-size-dwords",
4886 PAGE_MEM_DESC_SIZE_DWORDS
);
4887 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4890 p_hwfn
->p_cxt_mngr
->ilt_shadow_size
);
4892 *full_dump_size_param_offset
= offset
;
4894 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4895 dump
, "dump-size-full", 0);
4897 *actual_dump_size_param_offset
= offset
;
4899 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4901 "dump-size-actual", 0);
4902 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4905 p_hwfn
->p_cxt_mngr
->iscsi_task_pages
);
4906 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4909 p_hwfn
->p_cxt_mngr
->fcoe_task_pages
);
4910 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4913 p_hwfn
->p_cxt_mngr
->roce_task_pages
);
4914 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4917 p_hwfn
->p_cxt_mngr
->eth_task_pages
);
4918 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4920 "src-first-page-id",
4921 clients
[ILT_CLI_SRC
].first
.val
);
4922 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4925 clients
[ILT_CLI_SRC
].last
.val
);
4926 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4929 clients
[ILT_CLI_SRC
].active
);
4931 /* Additional/Less parameters require matching of number in call to
4932 * dump_common_global_params()
4938 /* Dump section containing number of PF CIDs per connection type.
4939 * Part of ilt dump process.
4940 * Returns the dumped size in dwords.
4942 static u32
qed_ilt_dump_dump_num_pf_cids(struct qed_hwfn
*p_hwfn
,
4944 bool dump
, u32
*valid_conn_pf_cids
)
4946 u32 num_pf_cids
= 0;
4950 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
4951 dump
, "num_pf_cids_per_conn_type", 1);
4952 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4953 dump
, "size", NUM_OF_CONNECTION_TYPES
);
4954 for (conn_type
= 0, *valid_conn_pf_cids
= 0;
4955 conn_type
< NUM_OF_CONNECTION_TYPES
; conn_type
++, offset
++) {
4956 num_pf_cids
= p_hwfn
->p_cxt_mngr
->conn_cfg
[conn_type
].cid_count
;
4958 *(dump_buf
+ offset
) = num_pf_cids
;
4959 *valid_conn_pf_cids
+= num_pf_cids
;
4965 /* Dump section containing number of VF CIDs per connection type
4966 * Part of ilt dump process.
4967 * Returns the dumped size in dwords.
4969 static u32
qed_ilt_dump_dump_num_vf_cids(struct qed_hwfn
*p_hwfn
,
4971 bool dump
, u32
*valid_conn_vf_cids
)
4973 u32 num_vf_cids
= 0;
4977 offset
+= qed_dump_section_hdr(dump_buf
+ offset
, dump
,
4978 "num_vf_cids_per_conn_type", 1);
4979 offset
+= qed_dump_num_param(dump_buf
+ offset
,
4980 dump
, "size", NUM_OF_CONNECTION_TYPES
);
4981 for (conn_type
= 0, *valid_conn_vf_cids
= 0;
4982 conn_type
< NUM_OF_CONNECTION_TYPES
; conn_type
++, offset
++) {
4984 p_hwfn
->p_cxt_mngr
->conn_cfg
[conn_type
].cids_per_vf
;
4986 *(dump_buf
+ offset
) = num_vf_cids
;
4987 *valid_conn_vf_cids
+= num_vf_cids
;
4993 /* Performs ILT Dump to the specified buffer.
4994 * buf_size_in_dwords - The dumped buffer size.
4995 * Returns the dumped size in dwords.
4997 static u32
qed_ilt_dump(struct qed_hwfn
*p_hwfn
,
4998 struct qed_ptt
*p_ptt
,
4999 u32
*dump_buf
, u32 buf_size_in_dwords
, bool dump
)
5001 #if ((!defined VMWARE) && (!defined UEFI))
5002 struct qed_ilt_client_cfg
*clients
= p_hwfn
->p_cxt_mngr
->clients
;
5004 u32 valid_conn_vf_cids
= 0,
5005 valid_conn_vf_pages
, offset
= 0, real_dumped_size
= 0;
5006 u32 valid_conn_pf_cids
= 0, valid_conn_pf_pages
, num_pages
;
5007 u32 num_cids_per_page
, conn_ctx_size
;
5008 u32 cduc_page_size
, cdut_page_size
;
5009 u32 actual_dump_size_in_dwords
= 0;
5010 struct phys_mem_desc
*ilt_pages
;
5011 u32 actul_dump_off
= 0;
5012 u32 last_section_size
;
5013 u32 full_dump_off
= 0;
5014 u32 section_size
= 0;
5018 last_section_size
= qed_dump_last_section(NULL
, 0, false);
5019 cduc_page_size
= 1 <<
5020 (clients
[ILT_CLI_CDUC
].p_size
.val
+ PXP_ILT_PAGE_SIZE_NUM_BITS_MIN
);
5021 cdut_page_size
= 1 <<
5022 (clients
[ILT_CLI_CDUT
].p_size
.val
+ PXP_ILT_PAGE_SIZE_NUM_BITS_MIN
);
5023 conn_ctx_size
= p_hwfn
->p_cxt_mngr
->conn_ctx_size
;
5024 num_cids_per_page
= (int)(cduc_page_size
/ conn_ctx_size
);
5025 ilt_pages
= p_hwfn
->p_cxt_mngr
->ilt_shadow
;
5026 continue_dump
= dump
;
5028 /* if need to dump then save memory for the last section
5029 * (last section calculates CRC of dumped data)
5032 if (buf_size_in_dwords
>= last_section_size
) {
5033 buf_size_in_dwords
-= last_section_size
;
5035 continue_dump
= false;
5036 actual_dump_size_in_dwords
= offset
;
5040 /* Dump global params */
5042 /* if need to dump then first check that there is enough memory
5043 * in dumped buffer for this section calculate the size of this
5044 * section without dumping. if there is not enough memory - then
5047 if (continue_dump
) {
5049 qed_ilt_dump_dump_common_global_params(p_hwfn
,
5058 if (offset
+ section_size
> buf_size_in_dwords
) {
5059 continue_dump
= false;
5060 actual_dump_size_in_dwords
= offset
;
5064 offset
+= qed_ilt_dump_dump_common_global_params(p_hwfn
,
5074 /* Dump section containing number of PF CIDs per connection type
5075 * If need to dump then first check that there is enough memory in
5076 * dumped buffer for this section.
5078 if (continue_dump
) {
5080 qed_ilt_dump_dump_num_pf_cids(p_hwfn
,
5083 &valid_conn_pf_cids
);
5084 if (offset
+ section_size
> buf_size_in_dwords
) {
5085 continue_dump
= false;
5086 actual_dump_size_in_dwords
= offset
;
5090 offset
+= qed_ilt_dump_dump_num_pf_cids(p_hwfn
,
5093 &valid_conn_pf_cids
);
5095 /* Dump section containing number of VF CIDs per connection type
5096 * If need to dump then first check that there is enough memory in
5097 * dumped buffer for this section.
5099 if (continue_dump
) {
5101 qed_ilt_dump_dump_num_vf_cids(p_hwfn
,
5104 &valid_conn_vf_cids
);
5105 if (offset
+ section_size
> buf_size_in_dwords
) {
5106 continue_dump
= false;
5107 actual_dump_size_in_dwords
= offset
;
5111 offset
+= qed_ilt_dump_dump_num_vf_cids(p_hwfn
,
5114 &valid_conn_vf_cids
);
5116 /* Dump section containing physical memory descriptors for each
5119 num_pages
= p_hwfn
->p_cxt_mngr
->ilt_shadow_size
;
5121 /* If need to dump then first check that there is enough memory
5122 * in dumped buffer for the section header.
5124 if (continue_dump
) {
5125 section_size
= qed_dump_section_hdr(NULL
,
5129 qed_dump_num_param(NULL
,
5132 num_pages
* PAGE_MEM_DESC_SIZE_DWORDS
);
5133 if (offset
+ section_size
> buf_size_in_dwords
) {
5134 continue_dump
= false;
5135 actual_dump_size_in_dwords
= offset
;
5139 offset
+= qed_dump_section_hdr(dump_buf
+ offset
,
5140 continue_dump
, "ilt_page_desc", 1);
5141 offset
+= qed_dump_num_param(dump_buf
+ offset
,
5144 num_pages
* PAGE_MEM_DESC_SIZE_DWORDS
);
5146 /* Copy memory descriptors to dump buffer
5147 * If need to dump then dump till the dump buffer size
5149 if (continue_dump
) {
5150 for (page_id
= 0; page_id
< num_pages
;
5151 page_id
++, offset
+= PAGE_MEM_DESC_SIZE_DWORDS
) {
5152 if (continue_dump
&&
5153 (offset
+ PAGE_MEM_DESC_SIZE_DWORDS
<=
5154 buf_size_in_dwords
)) {
5155 memcpy(dump_buf
+ offset
,
5156 &ilt_pages
[page_id
],
5158 (PAGE_MEM_DESC_SIZE_DWORDS
));
5160 if (continue_dump
) {
5161 continue_dump
= false;
5162 actual_dump_size_in_dwords
= offset
;
5167 offset
+= num_pages
* PAGE_MEM_DESC_SIZE_DWORDS
;
5170 valid_conn_pf_pages
= DIV_ROUND_UP(valid_conn_pf_cids
,
5172 valid_conn_vf_pages
= DIV_ROUND_UP(valid_conn_vf_cids
,
5175 /* Dump ILT pages IDs */
5176 qed_ilt_dump_pages_section(p_hwfn
, dump_buf
, &offset
, &continue_dump
,
5177 valid_conn_pf_pages
, valid_conn_vf_pages
,
5178 ilt_pages
, true, buf_size_in_dwords
,
5179 &actual_dump_size_in_dwords
);
5181 /* Dump ILT pages memory */
5182 qed_ilt_dump_pages_section(p_hwfn
, dump_buf
, &offset
, &continue_dump
,
5183 valid_conn_pf_pages
, valid_conn_vf_pages
,
5184 ilt_pages
, false, buf_size_in_dwords
,
5185 &actual_dump_size_in_dwords
);
5188 (continue_dump
== dump
) ? offset
: actual_dump_size_in_dwords
;
5189 qed_dump_num_param(dump_buf
+ full_dump_off
, dump
,
5190 "full-dump-size", offset
+ last_section_size
);
5191 qed_dump_num_param(dump_buf
+ actul_dump_off
,
5194 real_dumped_size
+ last_section_size
);
5196 /* Dump last section */
5197 real_dumped_size
+= qed_dump_last_section(dump_buf
,
5198 real_dumped_size
, dump
);
5200 return real_dumped_size
;
5203 /***************************** Public Functions *******************************/
5205 enum dbg_status
qed_dbg_set_bin_ptr(struct qed_hwfn
*p_hwfn
,
5206 const u8
* const bin_ptr
)
5208 struct bin_buffer_hdr
*buf_hdrs
= (struct bin_buffer_hdr
*)bin_ptr
;
5211 /* Convert binary data to debug arrays */
5212 for (buf_id
= 0; buf_id
< MAX_BIN_DBG_BUFFER_TYPE
; buf_id
++)
5213 qed_set_dbg_bin_buf(p_hwfn
,
5215 (u32
*)(bin_ptr
+ buf_hdrs
[buf_id
].offset
),
5216 buf_hdrs
[buf_id
].length
);
5218 return DBG_STATUS_OK
;
5221 static enum dbg_status
qed_dbg_set_app_ver(u32 ver
)
5223 if (ver
< TOOLS_VERSION
)
5224 return DBG_STATUS_UNSUPPORTED_APP_VERSION
;
5228 return DBG_STATUS_OK
;
5231 bool qed_read_fw_info(struct qed_hwfn
*p_hwfn
,
5232 struct qed_ptt
*p_ptt
, struct fw_info
*fw_info
)
5234 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
5237 for (storm_id
= 0; storm_id
< MAX_DBG_STORMS
; storm_id
++) {
5238 struct storm_defs
*storm
= &s_storm_defs
[storm_id
];
5240 /* Skip Storm if it's in reset */
5241 if (dev_data
->block_in_reset
[storm
->sem_block_id
])
5244 /* Read FW info for the current Storm */
5245 qed_read_storm_fw_info(p_hwfn
, p_ptt
, storm_id
, fw_info
);
5253 enum dbg_status
qed_dbg_grc_config(struct qed_hwfn
*p_hwfn
,
5254 enum dbg_grc_params grc_param
, u32 val
)
5256 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
5257 enum dbg_status status
;
5262 "dbg_grc_config: paramId = %d, val = %d\n", grc_param
, val
);
5264 status
= qed_dbg_dev_init(p_hwfn
);
5265 if (status
!= DBG_STATUS_OK
)
5268 /* Initializes the GRC parameters (if not initialized). Needed in order
5269 * to set the default parameter values for the first time.
5271 qed_dbg_grc_init_params(p_hwfn
);
5273 if (grc_param
>= MAX_DBG_GRC_PARAMS
)
5274 return DBG_STATUS_INVALID_ARGS
;
5275 if (val
< s_grc_param_defs
[grc_param
].min
||
5276 val
> s_grc_param_defs
[grc_param
].max
)
5277 return DBG_STATUS_INVALID_ARGS
;
5279 if (s_grc_param_defs
[grc_param
].is_preset
) {
5282 /* Disabling a preset is not allowed. Call
5283 * dbg_grc_set_params_default instead.
5286 return DBG_STATUS_INVALID_ARGS
;
5288 /* Update all params with the preset values */
5289 for (i
= 0; i
< MAX_DBG_GRC_PARAMS
; i
++) {
5290 struct grc_param_defs
*defs
= &s_grc_param_defs
[i
];
5292 /* Skip persistent params */
5293 if (defs
->is_persistent
)
5296 /* Find preset value */
5297 if (grc_param
== DBG_GRC_PARAM_EXCLUDE_ALL
)
5299 defs
->exclude_all_preset_val
;
5300 else if (grc_param
== DBG_GRC_PARAM_CRASH
)
5302 defs
->crash_preset_val
[dev_data
->chip_id
];
5304 return DBG_STATUS_INVALID_ARGS
;
5306 qed_grc_set_param(p_hwfn
, i
, preset_val
);
5309 /* Regular param - set its value */
5310 qed_grc_set_param(p_hwfn
, grc_param
, val
);
5313 return DBG_STATUS_OK
;
5316 /* Assign default GRC param values */
5317 void qed_dbg_grc_set_params_default(struct qed_hwfn
*p_hwfn
)
5319 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
5322 for (i
= 0; i
< MAX_DBG_GRC_PARAMS
; i
++)
5323 if (!s_grc_param_defs
[i
].is_persistent
)
5324 dev_data
->grc
.param_val
[i
] =
5325 s_grc_param_defs
[i
].default_val
[dev_data
->chip_id
];
5328 enum dbg_status
qed_dbg_grc_get_dump_buf_size(struct qed_hwfn
*p_hwfn
,
5329 struct qed_ptt
*p_ptt
,
5332 enum dbg_status status
= qed_dbg_dev_init(p_hwfn
);
5336 if (status
!= DBG_STATUS_OK
)
5339 if (!p_hwfn
->dbg_arrays
[BIN_BUF_DBG_MODE_TREE
].ptr
||
5340 !p_hwfn
->dbg_arrays
[BIN_BUF_DBG_DUMP_REG
].ptr
||
5341 !p_hwfn
->dbg_arrays
[BIN_BUF_DBG_DUMP_MEM
].ptr
||
5342 !p_hwfn
->dbg_arrays
[BIN_BUF_DBG_ATTN_BLOCKS
].ptr
||
5343 !p_hwfn
->dbg_arrays
[BIN_BUF_DBG_ATTN_REGS
].ptr
)
5344 return DBG_STATUS_DBG_ARRAY_NOT_SET
;
5346 return qed_grc_dump(p_hwfn
, p_ptt
, NULL
, false, buf_size
);
5349 enum dbg_status
qed_dbg_grc_dump(struct qed_hwfn
*p_hwfn
,
5350 struct qed_ptt
*p_ptt
,
5352 u32 buf_size_in_dwords
,
5353 u32
*num_dumped_dwords
)
5355 u32 needed_buf_size_in_dwords
;
5356 enum dbg_status status
;
5358 *num_dumped_dwords
= 0;
5360 status
= qed_dbg_grc_get_dump_buf_size(p_hwfn
,
5362 &needed_buf_size_in_dwords
);
5363 if (status
!= DBG_STATUS_OK
)
5366 if (buf_size_in_dwords
< needed_buf_size_in_dwords
)
5367 return DBG_STATUS_DUMP_BUF_TOO_SMALL
;
5369 /* Doesn't do anything, needed for compile time asserts */
5370 qed_static_asserts();
5373 status
= qed_grc_dump(p_hwfn
, p_ptt
, dump_buf
, true, num_dumped_dwords
);
5375 /* Revert GRC params to their default */
5376 qed_dbg_grc_set_params_default(p_hwfn
);
5381 enum dbg_status
qed_dbg_idle_chk_get_dump_buf_size(struct qed_hwfn
*p_hwfn
,
5382 struct qed_ptt
*p_ptt
,
5385 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
5386 struct idle_chk_data
*idle_chk
= &dev_data
->idle_chk
;
5387 enum dbg_status status
;
5391 status
= qed_dbg_dev_init(p_hwfn
);
5392 if (status
!= DBG_STATUS_OK
)
5395 if (!p_hwfn
->dbg_arrays
[BIN_BUF_DBG_MODE_TREE
].ptr
||
5396 !p_hwfn
->dbg_arrays
[BIN_BUF_DBG_IDLE_CHK_REGS
].ptr
||
5397 !p_hwfn
->dbg_arrays
[BIN_BUF_DBG_IDLE_CHK_IMMS
].ptr
||
5398 !p_hwfn
->dbg_arrays
[BIN_BUF_DBG_IDLE_CHK_RULES
].ptr
)
5399 return DBG_STATUS_DBG_ARRAY_NOT_SET
;
5401 if (!idle_chk
->buf_size_set
) {
5402 idle_chk
->buf_size
= qed_idle_chk_dump(p_hwfn
,
5403 p_ptt
, NULL
, false);
5404 idle_chk
->buf_size_set
= true;
5407 *buf_size
= idle_chk
->buf_size
;
5409 return DBG_STATUS_OK
;
5412 enum dbg_status
qed_dbg_idle_chk_dump(struct qed_hwfn
*p_hwfn
,
5413 struct qed_ptt
*p_ptt
,
5415 u32 buf_size_in_dwords
,
5416 u32
*num_dumped_dwords
)
5418 u32 needed_buf_size_in_dwords
;
5419 enum dbg_status status
;
5421 *num_dumped_dwords
= 0;
5423 status
= qed_dbg_idle_chk_get_dump_buf_size(p_hwfn
,
5425 &needed_buf_size_in_dwords
);
5426 if (status
!= DBG_STATUS_OK
)
5429 if (buf_size_in_dwords
< needed_buf_size_in_dwords
)
5430 return DBG_STATUS_DUMP_BUF_TOO_SMALL
;
5432 /* Update reset state */
5433 qed_grc_unreset_blocks(p_hwfn
, p_ptt
, true);
5434 qed_update_blocks_reset_state(p_hwfn
, p_ptt
);
5436 /* Idle Check Dump */
5437 *num_dumped_dwords
= qed_idle_chk_dump(p_hwfn
, p_ptt
, dump_buf
, true);
5439 /* Revert GRC params to their default */
5440 qed_dbg_grc_set_params_default(p_hwfn
);
5442 return DBG_STATUS_OK
;
5445 enum dbg_status
qed_dbg_mcp_trace_get_dump_buf_size(struct qed_hwfn
*p_hwfn
,
5446 struct qed_ptt
*p_ptt
,
5449 enum dbg_status status
= qed_dbg_dev_init(p_hwfn
);
5453 if (status
!= DBG_STATUS_OK
)
5456 return qed_mcp_trace_dump(p_hwfn
, p_ptt
, NULL
, false, buf_size
);
5459 enum dbg_status
qed_dbg_mcp_trace_dump(struct qed_hwfn
*p_hwfn
,
5460 struct qed_ptt
*p_ptt
,
5462 u32 buf_size_in_dwords
,
5463 u32
*num_dumped_dwords
)
5465 u32 needed_buf_size_in_dwords
;
5466 enum dbg_status status
;
5469 qed_dbg_mcp_trace_get_dump_buf_size(p_hwfn
,
5471 &needed_buf_size_in_dwords
);
5472 if (status
!= DBG_STATUS_OK
&& status
!=
5473 DBG_STATUS_NVRAM_GET_IMAGE_FAILED
)
5476 if (buf_size_in_dwords
< needed_buf_size_in_dwords
)
5477 return DBG_STATUS_DUMP_BUF_TOO_SMALL
;
5479 /* Update reset state */
5480 qed_update_blocks_reset_state(p_hwfn
, p_ptt
);
5483 status
= qed_mcp_trace_dump(p_hwfn
,
5484 p_ptt
, dump_buf
, true, num_dumped_dwords
);
5486 /* Revert GRC params to their default */
5487 qed_dbg_grc_set_params_default(p_hwfn
);
5492 enum dbg_status
qed_dbg_reg_fifo_get_dump_buf_size(struct qed_hwfn
*p_hwfn
,
5493 struct qed_ptt
*p_ptt
,
5496 enum dbg_status status
= qed_dbg_dev_init(p_hwfn
);
5500 if (status
!= DBG_STATUS_OK
)
5503 return qed_reg_fifo_dump(p_hwfn
, p_ptt
, NULL
, false, buf_size
);
5506 enum dbg_status
qed_dbg_reg_fifo_dump(struct qed_hwfn
*p_hwfn
,
5507 struct qed_ptt
*p_ptt
,
5509 u32 buf_size_in_dwords
,
5510 u32
*num_dumped_dwords
)
5512 u32 needed_buf_size_in_dwords
;
5513 enum dbg_status status
;
5515 *num_dumped_dwords
= 0;
5517 status
= qed_dbg_reg_fifo_get_dump_buf_size(p_hwfn
,
5519 &needed_buf_size_in_dwords
);
5520 if (status
!= DBG_STATUS_OK
)
5523 if (buf_size_in_dwords
< needed_buf_size_in_dwords
)
5524 return DBG_STATUS_DUMP_BUF_TOO_SMALL
;
5526 /* Update reset state */
5527 qed_update_blocks_reset_state(p_hwfn
, p_ptt
);
5529 status
= qed_reg_fifo_dump(p_hwfn
,
5530 p_ptt
, dump_buf
, true, num_dumped_dwords
);
5532 /* Revert GRC params to their default */
5533 qed_dbg_grc_set_params_default(p_hwfn
);
5538 enum dbg_status
qed_dbg_igu_fifo_get_dump_buf_size(struct qed_hwfn
*p_hwfn
,
5539 struct qed_ptt
*p_ptt
,
5542 enum dbg_status status
= qed_dbg_dev_init(p_hwfn
);
5546 if (status
!= DBG_STATUS_OK
)
5549 return qed_igu_fifo_dump(p_hwfn
, p_ptt
, NULL
, false, buf_size
);
5552 enum dbg_status
qed_dbg_igu_fifo_dump(struct qed_hwfn
*p_hwfn
,
5553 struct qed_ptt
*p_ptt
,
5555 u32 buf_size_in_dwords
,
5556 u32
*num_dumped_dwords
)
5558 u32 needed_buf_size_in_dwords
;
5559 enum dbg_status status
;
5561 *num_dumped_dwords
= 0;
5563 status
= qed_dbg_igu_fifo_get_dump_buf_size(p_hwfn
,
5565 &needed_buf_size_in_dwords
);
5566 if (status
!= DBG_STATUS_OK
)
5569 if (buf_size_in_dwords
< needed_buf_size_in_dwords
)
5570 return DBG_STATUS_DUMP_BUF_TOO_SMALL
;
5572 /* Update reset state */
5573 qed_update_blocks_reset_state(p_hwfn
, p_ptt
);
5575 status
= qed_igu_fifo_dump(p_hwfn
,
5576 p_ptt
, dump_buf
, true, num_dumped_dwords
);
5577 /* Revert GRC params to their default */
5578 qed_dbg_grc_set_params_default(p_hwfn
);
5584 qed_dbg_protection_override_get_dump_buf_size(struct qed_hwfn
*p_hwfn
,
5585 struct qed_ptt
*p_ptt
,
5588 enum dbg_status status
= qed_dbg_dev_init(p_hwfn
);
5592 if (status
!= DBG_STATUS_OK
)
5595 return qed_protection_override_dump(p_hwfn
,
5596 p_ptt
, NULL
, false, buf_size
);
5599 enum dbg_status
qed_dbg_protection_override_dump(struct qed_hwfn
*p_hwfn
,
5600 struct qed_ptt
*p_ptt
,
5602 u32 buf_size_in_dwords
,
5603 u32
*num_dumped_dwords
)
5605 u32 needed_buf_size_in_dwords
, *p_size
= &needed_buf_size_in_dwords
;
5606 enum dbg_status status
;
5608 *num_dumped_dwords
= 0;
5611 qed_dbg_protection_override_get_dump_buf_size(p_hwfn
,
5614 if (status
!= DBG_STATUS_OK
)
5617 if (buf_size_in_dwords
< needed_buf_size_in_dwords
)
5618 return DBG_STATUS_DUMP_BUF_TOO_SMALL
;
5620 /* Update reset state */
5621 qed_update_blocks_reset_state(p_hwfn
, p_ptt
);
5623 status
= qed_protection_override_dump(p_hwfn
,
5626 true, num_dumped_dwords
);
5628 /* Revert GRC params to their default */
5629 qed_dbg_grc_set_params_default(p_hwfn
);
5634 enum dbg_status
qed_dbg_fw_asserts_get_dump_buf_size(struct qed_hwfn
*p_hwfn
,
5635 struct qed_ptt
*p_ptt
,
5638 enum dbg_status status
= qed_dbg_dev_init(p_hwfn
);
5642 if (status
!= DBG_STATUS_OK
)
5645 /* Update reset state */
5646 qed_update_blocks_reset_state(p_hwfn
, p_ptt
);
5648 *buf_size
= qed_fw_asserts_dump(p_hwfn
, p_ptt
, NULL
, false);
5650 return DBG_STATUS_OK
;
5653 enum dbg_status
qed_dbg_fw_asserts_dump(struct qed_hwfn
*p_hwfn
,
5654 struct qed_ptt
*p_ptt
,
5656 u32 buf_size_in_dwords
,
5657 u32
*num_dumped_dwords
)
5659 u32 needed_buf_size_in_dwords
, *p_size
= &needed_buf_size_in_dwords
;
5660 enum dbg_status status
;
5662 *num_dumped_dwords
= 0;
5665 qed_dbg_fw_asserts_get_dump_buf_size(p_hwfn
,
5668 if (status
!= DBG_STATUS_OK
)
5671 if (buf_size_in_dwords
< needed_buf_size_in_dwords
)
5672 return DBG_STATUS_DUMP_BUF_TOO_SMALL
;
5674 *num_dumped_dwords
= qed_fw_asserts_dump(p_hwfn
, p_ptt
, dump_buf
, true);
5676 /* Revert GRC params to their default */
5677 qed_dbg_grc_set_params_default(p_hwfn
);
5679 return DBG_STATUS_OK
;
5682 static enum dbg_status
qed_dbg_ilt_get_dump_buf_size(struct qed_hwfn
*p_hwfn
,
5683 struct qed_ptt
*p_ptt
,
5686 enum dbg_status status
= qed_dbg_dev_init(p_hwfn
);
5690 if (status
!= DBG_STATUS_OK
)
5693 *buf_size
= qed_ilt_dump(p_hwfn
, p_ptt
, NULL
, 0, false);
5695 return DBG_STATUS_OK
;
5698 static enum dbg_status
qed_dbg_ilt_dump(struct qed_hwfn
*p_hwfn
,
5699 struct qed_ptt
*p_ptt
,
5701 u32 buf_size_in_dwords
,
5702 u32
*num_dumped_dwords
)
5704 *num_dumped_dwords
= qed_ilt_dump(p_hwfn
,
5706 dump_buf
, buf_size_in_dwords
, true);
5708 /* Reveret GRC params to their default */
5709 qed_dbg_grc_set_params_default(p_hwfn
);
5711 return DBG_STATUS_OK
;
5714 enum dbg_status
qed_dbg_read_attn(struct qed_hwfn
*p_hwfn
,
5715 struct qed_ptt
*p_ptt
,
5716 enum block_id block_id
,
5717 enum dbg_attn_type attn_type
,
5719 struct dbg_attn_block_result
*results
)
5721 enum dbg_status status
= qed_dbg_dev_init(p_hwfn
);
5722 u8 reg_idx
, num_attn_regs
, num_result_regs
= 0;
5723 const struct dbg_attn_reg
*attn_reg_arr
;
5725 if (status
!= DBG_STATUS_OK
)
5728 if (!p_hwfn
->dbg_arrays
[BIN_BUF_DBG_MODE_TREE
].ptr
||
5729 !p_hwfn
->dbg_arrays
[BIN_BUF_DBG_ATTN_BLOCKS
].ptr
||
5730 !p_hwfn
->dbg_arrays
[BIN_BUF_DBG_ATTN_REGS
].ptr
)
5731 return DBG_STATUS_DBG_ARRAY_NOT_SET
;
5733 attn_reg_arr
= qed_get_block_attn_regs(p_hwfn
,
5735 attn_type
, &num_attn_regs
);
5737 for (reg_idx
= 0; reg_idx
< num_attn_regs
; reg_idx
++) {
5738 const struct dbg_attn_reg
*reg_data
= &attn_reg_arr
[reg_idx
];
5739 struct dbg_attn_reg_result
*reg_result
;
5740 u32 sts_addr
, sts_val
;
5741 u16 modes_buf_offset
;
5745 eval_mode
= GET_FIELD(reg_data
->mode
.data
,
5746 DBG_MODE_HDR_EVAL_MODE
) > 0;
5747 modes_buf_offset
= GET_FIELD(reg_data
->mode
.data
,
5748 DBG_MODE_HDR_MODES_BUF_OFFSET
);
5749 if (eval_mode
&& !qed_is_mode_match(p_hwfn
, &modes_buf_offset
))
5752 /* Mode match - read attention status register */
5753 sts_addr
= DWORDS_TO_BYTES(clear_status
?
5754 reg_data
->sts_clr_address
:
5755 GET_FIELD(reg_data
->data
,
5756 DBG_ATTN_REG_STS_ADDRESS
));
5757 sts_val
= qed_rd(p_hwfn
, p_ptt
, sts_addr
);
5761 /* Non-zero attention status - add to results */
5762 reg_result
= &results
->reg_results
[num_result_regs
];
5763 SET_FIELD(reg_result
->data
,
5764 DBG_ATTN_REG_RESULT_STS_ADDRESS
, sts_addr
);
5765 SET_FIELD(reg_result
->data
,
5766 DBG_ATTN_REG_RESULT_NUM_REG_ATTN
,
5767 GET_FIELD(reg_data
->data
, DBG_ATTN_REG_NUM_REG_ATTN
));
5768 reg_result
->block_attn_offset
= reg_data
->block_attn_offset
;
5769 reg_result
->sts_val
= sts_val
;
5770 reg_result
->mask_val
= qed_rd(p_hwfn
,
5773 (reg_data
->mask_address
));
5777 results
->block_id
= (u8
)block_id
;
5778 results
->names_offset
=
5779 qed_get_block_attn_data(p_hwfn
, block_id
, attn_type
)->names_offset
;
5780 SET_FIELD(results
->data
, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE
, attn_type
);
5781 SET_FIELD(results
->data
,
5782 DBG_ATTN_BLOCK_RESULT_NUM_REGS
, num_result_regs
);
5784 return DBG_STATUS_OK
;
5787 /******************************* Data Types **********************************/
5789 /* REG fifo element */
5790 struct reg_fifo_element
{
5792 #define REG_FIFO_ELEMENT_ADDRESS_SHIFT 0
5793 #define REG_FIFO_ELEMENT_ADDRESS_MASK 0x7fffff
5794 #define REG_FIFO_ELEMENT_ACCESS_SHIFT 23
5795 #define REG_FIFO_ELEMENT_ACCESS_MASK 0x1
5796 #define REG_FIFO_ELEMENT_PF_SHIFT 24
5797 #define REG_FIFO_ELEMENT_PF_MASK 0xf
5798 #define REG_FIFO_ELEMENT_VF_SHIFT 28
5799 #define REG_FIFO_ELEMENT_VF_MASK 0xff
5800 #define REG_FIFO_ELEMENT_PORT_SHIFT 36
5801 #define REG_FIFO_ELEMENT_PORT_MASK 0x3
5802 #define REG_FIFO_ELEMENT_PRIVILEGE_SHIFT 38
5803 #define REG_FIFO_ELEMENT_PRIVILEGE_MASK 0x3
5804 #define REG_FIFO_ELEMENT_PROTECTION_SHIFT 40
5805 #define REG_FIFO_ELEMENT_PROTECTION_MASK 0x7
5806 #define REG_FIFO_ELEMENT_MASTER_SHIFT 43
5807 #define REG_FIFO_ELEMENT_MASTER_MASK 0xf
5808 #define REG_FIFO_ELEMENT_ERROR_SHIFT 47
5809 #define REG_FIFO_ELEMENT_ERROR_MASK 0x1f
5812 /* REG fifo error element */
5813 struct reg_fifo_err
{
5815 const char *err_msg
;
5818 /* IGU fifo element */
5819 struct igu_fifo_element
{
5821 #define IGU_FIFO_ELEMENT_DWORD0_FID_SHIFT 0
5822 #define IGU_FIFO_ELEMENT_DWORD0_FID_MASK 0xff
5823 #define IGU_FIFO_ELEMENT_DWORD0_IS_PF_SHIFT 8
5824 #define IGU_FIFO_ELEMENT_DWORD0_IS_PF_MASK 0x1
5825 #define IGU_FIFO_ELEMENT_DWORD0_SOURCE_SHIFT 9
5826 #define IGU_FIFO_ELEMENT_DWORD0_SOURCE_MASK 0xf
5827 #define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_SHIFT 13
5828 #define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_MASK 0xf
5829 #define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_SHIFT 17
5830 #define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_MASK 0x7fff
5833 #define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_SHIFT 0
5834 #define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_MASK 0x1
5835 #define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_SHIFT 1
5836 #define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_MASK 0xffffffff
5840 struct igu_fifo_wr_data
{
5842 #define IGU_FIFO_WR_DATA_PROD_CONS_SHIFT 0
5843 #define IGU_FIFO_WR_DATA_PROD_CONS_MASK 0xffffff
5844 #define IGU_FIFO_WR_DATA_UPDATE_FLAG_SHIFT 24
5845 #define IGU_FIFO_WR_DATA_UPDATE_FLAG_MASK 0x1
5846 #define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_SHIFT 25
5847 #define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_MASK 0x3
5848 #define IGU_FIFO_WR_DATA_SEGMENT_SHIFT 27
5849 #define IGU_FIFO_WR_DATA_SEGMENT_MASK 0x1
5850 #define IGU_FIFO_WR_DATA_TIMER_MASK_SHIFT 28
5851 #define IGU_FIFO_WR_DATA_TIMER_MASK_MASK 0x1
5852 #define IGU_FIFO_WR_DATA_CMD_TYPE_SHIFT 31
5853 #define IGU_FIFO_WR_DATA_CMD_TYPE_MASK 0x1
5856 struct igu_fifo_cleanup_wr_data
{
5858 #define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_SHIFT 0
5859 #define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_MASK 0x7ffffff
5860 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_SHIFT 27
5861 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_MASK 0x1
5862 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_SHIFT 28
5863 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_MASK 0x7
5864 #define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_SHIFT 31
5865 #define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_MASK 0x1
5868 /* Protection override element */
5869 struct protection_override_element
{
5871 #define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_SHIFT 0
5872 #define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_MASK 0x7fffff
5873 #define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_SHIFT 23
5874 #define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_MASK 0xffffff
5875 #define PROTECTION_OVERRIDE_ELEMENT_READ_SHIFT 47
5876 #define PROTECTION_OVERRIDE_ELEMENT_READ_MASK 0x1
5877 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_SHIFT 48
5878 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_MASK 0x1
5879 #define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_SHIFT 49
5880 #define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_MASK 0x7
5881 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_SHIFT 52
5882 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_MASK 0x7
5885 enum igu_fifo_sources
{
5899 enum igu_fifo_addr_types
{
5900 IGU_ADDR_TYPE_MSIX_MEM
,
5901 IGU_ADDR_TYPE_WRITE_PBA
,
5902 IGU_ADDR_TYPE_WRITE_INT_ACK
,
5903 IGU_ADDR_TYPE_WRITE_ATTN_BITS
,
5904 IGU_ADDR_TYPE_READ_INT
,
5905 IGU_ADDR_TYPE_WRITE_PROD_UPDATE
,
5906 IGU_ADDR_TYPE_RESERVED
5909 struct igu_fifo_addr_data
{
5914 enum igu_fifo_addr_types type
;
5917 /******************************** Constants **********************************/
5919 #define MAX_MSG_LEN 1024
5921 #define MCP_TRACE_MAX_MODULE_LEN 8
5922 #define MCP_TRACE_FORMAT_MAX_PARAMS 3
5923 #define MCP_TRACE_FORMAT_PARAM_WIDTH \
5924 (MCP_TRACE_FORMAT_P2_SIZE_OFFSET - MCP_TRACE_FORMAT_P1_SIZE_OFFSET)
5926 #define REG_FIFO_ELEMENT_ADDR_FACTOR 4
5927 #define REG_FIFO_ELEMENT_IS_PF_VF_VAL 127
5929 #define PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR 4
5931 /***************************** Constant Arrays *******************************/
5933 /* Status string array */
5934 static const char * const s_status_str
[] = {
5936 "Operation completed successfully",
5938 /* DBG_STATUS_APP_VERSION_NOT_SET */
5939 "Debug application version wasn't set",
5941 /* DBG_STATUS_UNSUPPORTED_APP_VERSION */
5942 "Unsupported debug application version",
5944 /* DBG_STATUS_DBG_BLOCK_NOT_RESET */
5945 "The debug block wasn't reset since the last recording",
5947 /* DBG_STATUS_INVALID_ARGS */
5948 "Invalid arguments",
5950 /* DBG_STATUS_OUTPUT_ALREADY_SET */
5951 "The debug output was already set",
5953 /* DBG_STATUS_INVALID_PCI_BUF_SIZE */
5954 "Invalid PCI buffer size",
5956 /* DBG_STATUS_PCI_BUF_ALLOC_FAILED */
5957 "PCI buffer allocation failed",
5959 /* DBG_STATUS_PCI_BUF_NOT_ALLOCATED */
5960 "A PCI buffer wasn't allocated",
5962 /* DBG_STATUS_INVALID_FILTER_TRIGGER_DWORDS */
5963 "The filter/trigger constraint dword offsets are not enabled for recording",
5964 /* DBG_STATUS_NO_MATCHING_FRAMING_MODE */
5965 "No matching framing mode",
5967 /* DBG_STATUS_VFC_READ_ERROR */
5968 "Error reading from VFC",
5970 /* DBG_STATUS_STORM_ALREADY_ENABLED */
5971 "The Storm was already enabled",
5973 /* DBG_STATUS_STORM_NOT_ENABLED */
5974 "The specified Storm wasn't enabled",
5976 /* DBG_STATUS_BLOCK_ALREADY_ENABLED */
5977 "The block was already enabled",
5979 /* DBG_STATUS_BLOCK_NOT_ENABLED */
5980 "The specified block wasn't enabled",
5982 /* DBG_STATUS_NO_INPUT_ENABLED */
5983 "No input was enabled for recording",
5985 /* DBG_STATUS_NO_FILTER_TRIGGER_256B */
5986 "Filters and triggers are not allowed in E4 256-bit mode",
5988 /* DBG_STATUS_FILTER_ALREADY_ENABLED */
5989 "The filter was already enabled",
5991 /* DBG_STATUS_TRIGGER_ALREADY_ENABLED */
5992 "The trigger was already enabled",
5994 /* DBG_STATUS_TRIGGER_NOT_ENABLED */
5995 "The trigger wasn't enabled",
5997 /* DBG_STATUS_CANT_ADD_CONSTRAINT */
5998 "A constraint can be added only after a filter was enabled or a trigger state was added",
6000 /* DBG_STATUS_TOO_MANY_TRIGGER_STATES */
6001 "Cannot add more than 3 trigger states",
6003 /* DBG_STATUS_TOO_MANY_CONSTRAINTS */
6004 "Cannot add more than 4 constraints per filter or trigger state",
6006 /* DBG_STATUS_RECORDING_NOT_STARTED */
6007 "The recording wasn't started",
6009 /* DBG_STATUS_DATA_DIDNT_TRIGGER */
6010 "A trigger was configured, but it didn't trigger",
6012 /* DBG_STATUS_NO_DATA_RECORDED */
6013 "No data was recorded",
6015 /* DBG_STATUS_DUMP_BUF_TOO_SMALL */
6016 "Dump buffer is too small",
6018 /* DBG_STATUS_DUMP_NOT_CHUNK_ALIGNED */
6019 "Dumped data is not aligned to chunks",
6021 /* DBG_STATUS_UNKNOWN_CHIP */
6024 /* DBG_STATUS_VIRT_MEM_ALLOC_FAILED */
6025 "Failed allocating virtual memory",
6027 /* DBG_STATUS_BLOCK_IN_RESET */
6028 "The input block is in reset",
6030 /* DBG_STATUS_INVALID_TRACE_SIGNATURE */
6031 "Invalid MCP trace signature found in NVRAM",
6033 /* DBG_STATUS_INVALID_NVRAM_BUNDLE */
6034 "Invalid bundle ID found in NVRAM",
6036 /* DBG_STATUS_NVRAM_GET_IMAGE_FAILED */
6037 "Failed getting NVRAM image",
6039 /* DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE */
6040 "NVRAM image is not dword-aligned",
6042 /* DBG_STATUS_NVRAM_READ_FAILED */
6043 "Failed reading from NVRAM",
6045 /* DBG_STATUS_IDLE_CHK_PARSE_FAILED */
6046 "Idle check parsing failed",
6048 /* DBG_STATUS_MCP_TRACE_BAD_DATA */
6049 "MCP Trace data is corrupt",
6051 /* DBG_STATUS_MCP_TRACE_NO_META */
6052 "Dump doesn't contain meta data - it must be provided in image file",
6054 /* DBG_STATUS_MCP_COULD_NOT_HALT */
6055 "Failed to halt MCP",
6057 /* DBG_STATUS_MCP_COULD_NOT_RESUME */
6058 "Failed to resume MCP after halt",
6060 /* DBG_STATUS_RESERVED0 */
6063 /* DBG_STATUS_SEMI_FIFO_NOT_EMPTY */
6064 "Failed to empty SEMI sync FIFO",
6066 /* DBG_STATUS_IGU_FIFO_BAD_DATA */
6067 "IGU FIFO data is corrupt",
6069 /* DBG_STATUS_MCP_COULD_NOT_MASK_PRTY */
6070 "MCP failed to mask parities",
6072 /* DBG_STATUS_FW_ASSERTS_PARSE_FAILED */
6073 "FW Asserts parsing failed",
6075 /* DBG_STATUS_REG_FIFO_BAD_DATA */
6076 "GRC FIFO data is corrupt",
6078 /* DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA */
6079 "Protection Override data is corrupt",
6081 /* DBG_STATUS_DBG_ARRAY_NOT_SET */
6082 "Debug arrays were not set (when using binary files, dbg_set_bin_ptr must be called)",
6084 /* DBG_STATUS_RESERVED1 */
6087 /* DBG_STATUS_NON_MATCHING_LINES */
6088 "Non-matching debug lines - in E4, all lines must be of the same type (either 128b or 256b)",
6090 /* DBG_STATUS_INSUFFICIENT_HW_IDS */
6091 "Insufficient HW IDs. Try to record less Storms/blocks",
6093 /* DBG_STATUS_DBG_BUS_IN_USE */
6094 "The debug bus is in use",
6096 /* DBG_STATUS_INVALID_STORM_DBG_MODE */
6097 "The storm debug mode is not supported in the current chip",
6099 /* DBG_STATUS_OTHER_ENGINE_BB_ONLY */
6100 "Other engine is supported only in BB",
6102 /* DBG_STATUS_FILTER_SINGLE_HW_ID */
6103 "The configured filter mode requires a single Storm/block input",
6105 /* DBG_STATUS_TRIGGER_SINGLE_HW_ID */
6106 "The configured filter mode requires that all the constraints of a single trigger state will be defined on a single Storm/block input",
6108 /* DBG_STATUS_MISSING_TRIGGER_STATE_STORM */
6109 "When triggering on Storm data, the Storm to trigger on must be specified",
6111 /* DBG_STATUS_MDUMP2_FAILED_TO_REQUEST_OFFSIZE */
6112 "Failed to request MDUMP2 Offsize",
6114 /* DBG_STATUS_MDUMP2_FAILED_VALIDATION_OF_DATA_CRC */
6115 "Expected CRC (part of the MDUMP2 data) is different than the calculated CRC over that data",
6117 /* DBG_STATUS_MDUMP2_INVALID_SIGNATURE */
6118 "Invalid Signature found at start of MDUMP2",
6120 /* DBG_STATUS_MDUMP2_INVALID_LOG_SIZE */
6121 "Invalid Log Size of MDUMP2",
6123 /* DBG_STATUS_MDUMP2_INVALID_LOG_HDR */
6124 "Invalid Log Header of MDUMP2",
6126 /* DBG_STATUS_MDUMP2_INVALID_LOG_DATA */
6127 "Invalid Log Data of MDUMP2",
6129 /* DBG_STATUS_MDUMP2_ERROR_EXTRACTING_NUM_PORTS */
6130 "Could not extract number of ports from regval buf of MDUMP2",
6132 /* DBG_STATUS_MDUMP2_ERROR_EXTRACTING_MFW_STATUS */
6133 "Could not extract MFW (link) status from regval buf of MDUMP2",
6135 /* DBG_STATUS_MDUMP2_ERROR_DISPLAYING_LINKDUMP */
6136 "Could not display linkdump of MDUMP2",
6138 /* DBG_STATUS_MDUMP2_ERROR_READING_PHY_CFG */
6139 "Could not read PHY CFG of MDUMP2",
6141 /* DBG_STATUS_MDUMP2_ERROR_READING_PLL_MODE */
6142 "Could not read PLL Mode of MDUMP2",
6144 /* DBG_STATUS_MDUMP2_ERROR_READING_LANE_REGS */
6145 "Could not read TSCF/TSCE Lane Regs of MDUMP2",
6147 /* DBG_STATUS_MDUMP2_ERROR_ALLOCATING_BUF */
6148 "Could not allocate MDUMP2 reg-val internal buffer"
6151 /* Idle check severity names array */
6152 static const char * const s_idle_chk_severity_str
[] = {
6154 "Error if no traffic",
6158 /* MCP Trace level names array */
6159 static const char * const s_mcp_trace_level_str
[] = {
6165 /* Access type names array */
6166 static const char * const s_access_strs
[] = {
6171 /* Privilege type names array */
6172 static const char * const s_privilege_strs
[] = {
6179 /* Protection type names array */
6180 static const char * const s_protection_strs
[] = {
6191 /* Master type names array */
6192 static const char * const s_master_strs
[] = {
6211 /* REG FIFO error messages array */
6212 static struct reg_fifo_err s_reg_fifo_errors
[] = {
6214 {2, "address doesn't belong to any block"},
6215 {4, "reserved address in block or write to read-only address"},
6216 {8, "privilege/protection mismatch"},
6217 {16, "path isolation error"},
6221 /* IGU FIFO sources array */
6222 static const char * const s_igu_fifo_source_strs
[] = {
6236 /* IGU FIFO error messages */
6237 static const char * const s_igu_fifo_error_strs
[] = {
6240 "function disabled",
6241 "VF sent command to attention address",
6242 "host sent prod update command",
6243 "read of during interrupt register while in MIMD mode",
6244 "access to PXP BAR reserved address",
6245 "producer update command to attention index",
6247 "SB index not valid",
6248 "SB relative index and FID not found",
6250 "command with error flag asserted (PCI error or CAU discard)",
6251 "VF sent cleanup and RF cleanup is disabled",
6252 "cleanup command on type bigger than 4"
6255 /* IGU FIFO address data */
6256 static const struct igu_fifo_addr_data s_igu_fifo_addr_data
[] = {
6257 {0x0, 0x101, "MSI-X Memory", NULL
,
6258 IGU_ADDR_TYPE_MSIX_MEM
},
6259 {0x102, 0x1ff, "reserved", NULL
,
6260 IGU_ADDR_TYPE_RESERVED
},
6261 {0x200, 0x200, "Write PBA[0:63]", NULL
,
6262 IGU_ADDR_TYPE_WRITE_PBA
},
6263 {0x201, 0x201, "Write PBA[64:127]", "reserved",
6264 IGU_ADDR_TYPE_WRITE_PBA
},
6265 {0x202, 0x202, "Write PBA[128]", "reserved",
6266 IGU_ADDR_TYPE_WRITE_PBA
},
6267 {0x203, 0x3ff, "reserved", NULL
,
6268 IGU_ADDR_TYPE_RESERVED
},
6269 {0x400, 0x5ef, "Write interrupt acknowledgment", NULL
,
6270 IGU_ADDR_TYPE_WRITE_INT_ACK
},
6271 {0x5f0, 0x5f0, "Attention bits update", NULL
,
6272 IGU_ADDR_TYPE_WRITE_ATTN_BITS
},
6273 {0x5f1, 0x5f1, "Attention bits set", NULL
,
6274 IGU_ADDR_TYPE_WRITE_ATTN_BITS
},
6275 {0x5f2, 0x5f2, "Attention bits clear", NULL
,
6276 IGU_ADDR_TYPE_WRITE_ATTN_BITS
},
6277 {0x5f3, 0x5f3, "Read interrupt 0:63 with mask", NULL
,
6278 IGU_ADDR_TYPE_READ_INT
},
6279 {0x5f4, 0x5f4, "Read interrupt 0:31 with mask", NULL
,
6280 IGU_ADDR_TYPE_READ_INT
},
6281 {0x5f5, 0x5f5, "Read interrupt 32:63 with mask", NULL
,
6282 IGU_ADDR_TYPE_READ_INT
},
6283 {0x5f6, 0x5f6, "Read interrupt 0:63 without mask", NULL
,
6284 IGU_ADDR_TYPE_READ_INT
},
6285 {0x5f7, 0x5ff, "reserved", NULL
,
6286 IGU_ADDR_TYPE_RESERVED
},
6287 {0x600, 0x7ff, "Producer update", NULL
,
6288 IGU_ADDR_TYPE_WRITE_PROD_UPDATE
}
6291 /******************************** Variables **********************************/
6293 /* Temporary buffer, used for print size calculations */
6294 static char s_temp_buf
[MAX_MSG_LEN
];
6296 /**************************** Private Functions ******************************/
6298 static void qed_user_static_asserts(void)
6302 static u32
qed_cyclic_add(u32 a
, u32 b
, u32 size
)
6304 return (a
+ b
) % size
;
6307 static u32
qed_cyclic_sub(u32 a
, u32 b
, u32 size
)
6309 return (size
+ a
- b
) % size
;
6312 /* Reads the specified number of bytes from the specified cyclic buffer (up to 4
6313 * bytes) and returns them as a dword value. the specified buffer offset is
6316 static u32
qed_read_from_cyclic_buf(void *buf
,
6318 u32 buf_size
, u8 num_bytes_to_read
)
6320 u8 i
, *val_ptr
, *bytes_buf
= (u8
*)buf
;
6323 val_ptr
= (u8
*)&val
;
6325 /* Assume running on a LITTLE ENDIAN and the buffer is network order
6326 * (BIG ENDIAN), as high order bytes are placed in lower memory address.
6328 for (i
= 0; i
< num_bytes_to_read
; i
++) {
6329 val_ptr
[i
] = bytes_buf
[*offset
];
6330 *offset
= qed_cyclic_add(*offset
, 1, buf_size
);
6336 /* Reads and returns the next byte from the specified buffer.
6337 * The specified buffer offset is updated.
6339 static u8
qed_read_byte_from_buf(void *buf
, u32
*offset
)
6341 return ((u8
*)buf
)[(*offset
)++];
6344 /* Reads and returns the next dword from the specified buffer.
6345 * The specified buffer offset is updated.
6347 static u32
qed_read_dword_from_buf(void *buf
, u32
*offset
)
6349 u32 dword_val
= *(u32
*)&((u8
*)buf
)[*offset
];
6356 /* Reads the next string from the specified buffer, and copies it to the
6357 * specified pointer. The specified buffer offset is updated.
6359 static void qed_read_str_from_buf(void *buf
, u32
*offset
, u32 size
, char *dest
)
6361 const char *source_str
= &((const char *)buf
)[*offset
];
6363 strscpy(dest
, source_str
, size
);
6367 /* Returns a pointer to the specified offset (in bytes) of the specified buffer.
6368 * If the specified buffer in NULL, a temporary buffer pointer is returned.
6370 static char *qed_get_buf_ptr(void *buf
, u32 offset
)
6372 return buf
? (char *)buf
+ offset
: s_temp_buf
;
6375 /* Reads a param from the specified buffer. Returns the number of dwords read.
6376 * If the returned str_param is NULL, the param is numeric and its value is
6377 * returned in num_param.
6378 * Otheriwise, the param is a string and its pointer is returned in str_param.
6380 static u32
qed_read_param(u32
*dump_buf
,
6381 const char **param_name
,
6382 const char **param_str_val
, u32
*param_num_val
)
6384 char *char_buf
= (char *)dump_buf
;
6387 /* Extract param name */
6388 *param_name
= char_buf
;
6389 offset
+= strlen(*param_name
) + 1;
6391 /* Check param type */
6392 if (*(char_buf
+ offset
++)) {
6394 *param_str_val
= char_buf
+ offset
;
6396 offset
+= strlen(*param_str_val
) + 1;
6398 offset
+= (4 - (offset
& 0x3));
6401 *param_str_val
= NULL
;
6403 offset
+= (4 - (offset
& 0x3));
6404 *param_num_val
= *(u32
*)(char_buf
+ offset
);
6408 return (u32
)offset
/ 4;
6411 /* Reads a section header from the specified buffer.
6412 * Returns the number of dwords read.
6414 static u32
qed_read_section_hdr(u32
*dump_buf
,
6415 const char **section_name
,
6416 u32
*num_section_params
)
6418 const char *param_str_val
;
6420 return qed_read_param(dump_buf
,
6421 section_name
, ¶m_str_val
, num_section_params
);
6424 /* Reads section params from the specified buffer and prints them to the results
6425 * buffer. Returns the number of dwords read.
6427 static u32
qed_print_section_params(u32
*dump_buf
,
6428 u32 num_section_params
,
6429 char *results_buf
, u32
*num_chars_printed
)
6431 u32 i
, dump_offset
= 0, results_offset
= 0;
6433 for (i
= 0; i
< num_section_params
; i
++) {
6434 const char *param_name
, *param_str_val
;
6435 u32 param_num_val
= 0;
6437 dump_offset
+= qed_read_param(dump_buf
+ dump_offset
,
6439 ¶m_str_val
, ¶m_num_val
);
6443 sprintf(qed_get_buf_ptr(results_buf
,
6445 "%s: %s\n", param_name
, param_str_val
);
6446 else if (strcmp(param_name
, "fw-timestamp"))
6448 sprintf(qed_get_buf_ptr(results_buf
,
6450 "%s: %d\n", param_name
, param_num_val
);
6453 results_offset
+= sprintf(qed_get_buf_ptr(results_buf
, results_offset
),
6456 *num_chars_printed
= results_offset
;
6461 /* Returns the block name that matches the specified block ID,
6462 * or NULL if not found.
6464 static const char *qed_dbg_get_block_name(struct qed_hwfn
*p_hwfn
,
6465 enum block_id block_id
)
6467 const struct dbg_block_user
*block
=
6468 (const struct dbg_block_user
*)
6469 p_hwfn
->dbg_arrays
[BIN_BUF_DBG_BLOCKS_USER_DATA
].ptr
+ block_id
;
6471 return (const char *)block
->name
;
6474 static struct dbg_tools_user_data
*qed_dbg_get_user_data(struct qed_hwfn
6477 return (struct dbg_tools_user_data
*)p_hwfn
->dbg_user_info
;
6480 /* Parses the idle check rules and returns the number of characters printed.
6481 * In case of parsing error, returns 0.
6483 static u32
qed_parse_idle_chk_dump_rules(struct qed_hwfn
*p_hwfn
,
6487 bool print_fw_idle_chk
,
6489 u32
*num_errors
, u32
*num_warnings
)
6491 /* Offset in results_buf in bytes */
6492 u32 results_offset
= 0;
6500 /* Go over dumped results */
6501 for (rule_idx
= 0; rule_idx
< num_rules
&& dump_buf
< dump_buf_end
;
6503 const struct dbg_idle_chk_rule_parsing_data
*rule_parsing_data
;
6504 struct dbg_idle_chk_result_hdr
*hdr
;
6505 const char *parsing_str
, *lsi_msg
;
6506 u32 parsing_str_offset
;
6510 hdr
= (struct dbg_idle_chk_result_hdr
*)dump_buf
;
6512 (const struct dbg_idle_chk_rule_parsing_data
*)
6513 p_hwfn
->dbg_arrays
[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA
].ptr
+
6515 parsing_str_offset
=
6516 GET_FIELD(rule_parsing_data
->data
,
6517 DBG_IDLE_CHK_RULE_PARSING_DATA_STR_OFFSET
);
6519 GET_FIELD(rule_parsing_data
->data
,
6520 DBG_IDLE_CHK_RULE_PARSING_DATA_HAS_FW_MSG
) > 0;
6521 parsing_str
= (const char *)
6522 p_hwfn
->dbg_arrays
[BIN_BUF_DBG_PARSING_STRINGS
].ptr
+
6524 lsi_msg
= parsing_str
;
6527 if (hdr
->severity
>= MAX_DBG_IDLE_CHK_SEVERITY_TYPES
)
6530 /* Skip rule header */
6531 dump_buf
+= BYTES_TO_DWORDS(sizeof(*hdr
));
6533 /* Update errors/warnings count */
6534 if (hdr
->severity
== IDLE_CHK_SEVERITY_ERROR
||
6535 hdr
->severity
== IDLE_CHK_SEVERITY_ERROR_NO_TRAFFIC
)
6540 /* Print rule severity */
6542 sprintf(qed_get_buf_ptr(results_buf
,
6543 results_offset
), "%s: ",
6544 s_idle_chk_severity_str
[hdr
->severity
]);
6546 /* Print rule message */
6548 parsing_str
+= strlen(parsing_str
) + 1;
6550 sprintf(qed_get_buf_ptr(results_buf
,
6551 results_offset
), "%s.",
6553 print_fw_idle_chk
? parsing_str
: lsi_msg
);
6554 parsing_str
+= strlen(parsing_str
) + 1;
6556 /* Print register values */
6558 sprintf(qed_get_buf_ptr(results_buf
,
6559 results_offset
), " Registers:");
6561 i
< hdr
->num_dumped_cond_regs
+ hdr
->num_dumped_info_regs
;
6563 struct dbg_idle_chk_result_reg_hdr
*reg_hdr
;
6568 (struct dbg_idle_chk_result_reg_hdr
*)dump_buf
;
6569 is_mem
= GET_FIELD(reg_hdr
->data
,
6570 DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM
);
6571 reg_id
= GET_FIELD(reg_hdr
->data
,
6572 DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID
);
6574 /* Skip reg header */
6575 dump_buf
+= BYTES_TO_DWORDS(sizeof(*reg_hdr
));
6577 /* Skip register names until the required reg_id is
6580 for (; reg_id
> curr_reg_id
; curr_reg_id
++)
6581 parsing_str
+= strlen(parsing_str
) + 1;
6584 sprintf(qed_get_buf_ptr(results_buf
,
6585 results_offset
), " %s",
6587 if (i
< hdr
->num_dumped_cond_regs
&& is_mem
)
6589 sprintf(qed_get_buf_ptr(results_buf
,
6591 "[%d]", hdr
->mem_entry_id
+
6592 reg_hdr
->start_entry
);
6594 sprintf(qed_get_buf_ptr(results_buf
,
6595 results_offset
), "=");
6596 for (j
= 0; j
< reg_hdr
->size
; j
++, dump_buf
++) {
6598 sprintf(qed_get_buf_ptr(results_buf
,
6601 if (j
< reg_hdr
->size
- 1)
6603 sprintf(qed_get_buf_ptr
6605 results_offset
), ",");
6610 sprintf(qed_get_buf_ptr(results_buf
, results_offset
), "\n");
6613 /* Check if end of dump buffer was exceeded */
6614 if (dump_buf
> dump_buf_end
)
6617 return results_offset
;
6620 /* Parses an idle check dump buffer.
6621 * If result_buf is not NULL, the idle check results are printed to it.
6622 * In any case, the required results buffer size is assigned to
6623 * parsed_results_bytes.
6624 * The parsing status is returned.
6626 static enum dbg_status
qed_parse_idle_chk_dump(struct qed_hwfn
*p_hwfn
,
6628 u32 num_dumped_dwords
,
6630 u32
*parsed_results_bytes
,
6634 u32 num_section_params
= 0, num_rules
, num_rules_not_dumped
;
6635 const char *section_name
, *param_name
, *param_str_val
;
6636 u32
*dump_buf_end
= dump_buf
+ num_dumped_dwords
;
6638 /* Offset in results_buf in bytes */
6639 u32 results_offset
= 0;
6641 *parsed_results_bytes
= 0;
6645 if (!p_hwfn
->dbg_arrays
[BIN_BUF_DBG_PARSING_STRINGS
].ptr
||
6646 !p_hwfn
->dbg_arrays
[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA
].ptr
)
6647 return DBG_STATUS_DBG_ARRAY_NOT_SET
;
6649 /* Read global_params section */
6650 dump_buf
+= qed_read_section_hdr(dump_buf
,
6651 §ion_name
, &num_section_params
);
6652 if (strcmp(section_name
, "global_params"))
6653 return DBG_STATUS_IDLE_CHK_PARSE_FAILED
;
6655 /* Print global params */
6656 dump_buf
+= qed_print_section_params(dump_buf
,
6658 results_buf
, &results_offset
);
6660 /* Read idle_chk section
6661 * There may be 1 or 2 idle_chk section parameters:
6662 * - 1st is "num_rules"
6663 * - 2nd is "num_rules_not_dumped" (optional)
6666 dump_buf
+= qed_read_section_hdr(dump_buf
,
6667 §ion_name
, &num_section_params
);
6668 if (strcmp(section_name
, "idle_chk") ||
6669 (num_section_params
!= 2 && num_section_params
!= 1))
6670 return DBG_STATUS_IDLE_CHK_PARSE_FAILED
;
6671 dump_buf
+= qed_read_param(dump_buf
,
6672 ¶m_name
, ¶m_str_val
, &num_rules
);
6673 if (strcmp(param_name
, "num_rules"))
6674 return DBG_STATUS_IDLE_CHK_PARSE_FAILED
;
6675 if (num_section_params
> 1) {
6676 dump_buf
+= qed_read_param(dump_buf
,
6679 &num_rules_not_dumped
);
6680 if (strcmp(param_name
, "num_rules_not_dumped"))
6681 return DBG_STATUS_IDLE_CHK_PARSE_FAILED
;
6683 num_rules_not_dumped
= 0;
6687 u32 rules_print_size
;
6689 /* Print FW output */
6691 sprintf(qed_get_buf_ptr(results_buf
,
6693 "FW_IDLE_CHECK:\n");
6695 qed_parse_idle_chk_dump_rules(p_hwfn
,
6706 results_offset
+= rules_print_size
;
6707 if (!rules_print_size
)
6708 return DBG_STATUS_IDLE_CHK_PARSE_FAILED
;
6710 /* Print LSI output */
6712 sprintf(qed_get_buf_ptr(results_buf
,
6714 "\nLSI_IDLE_CHECK:\n");
6716 qed_parse_idle_chk_dump_rules(p_hwfn
,
6727 results_offset
+= rules_print_size
;
6728 if (!rules_print_size
)
6729 return DBG_STATUS_IDLE_CHK_PARSE_FAILED
;
6732 /* Print errors/warnings count */
6735 sprintf(qed_get_buf_ptr(results_buf
,
6737 "\nIdle Check failed!!! (with %d errors and %d warnings)\n",
6738 *num_errors
, *num_warnings
);
6739 else if (*num_warnings
)
6741 sprintf(qed_get_buf_ptr(results_buf
,
6743 "\nIdle Check completed successfully (with %d warnings)\n",
6747 sprintf(qed_get_buf_ptr(results_buf
,
6749 "\nIdle Check completed successfully\n");
6751 if (num_rules_not_dumped
)
6753 sprintf(qed_get_buf_ptr(results_buf
,
6755 "\nIdle Check Partially dumped : num_rules_not_dumped = %d\n",
6756 num_rules_not_dumped
);
6758 /* Add 1 for string NULL termination */
6759 *parsed_results_bytes
= results_offset
+ 1;
6761 return DBG_STATUS_OK
;
6764 /* Allocates and fills MCP Trace meta data based on the specified meta data
6766 * Returns debug status code.
6768 static enum dbg_status
6769 qed_mcp_trace_alloc_meta_data(struct qed_hwfn
*p_hwfn
,
6770 const u32
*meta_buf
)
6772 struct dbg_tools_user_data
*dev_user_data
;
6773 u32 offset
= 0, signature
, i
;
6774 struct mcp_trace_meta
*meta
;
6777 dev_user_data
= qed_dbg_get_user_data(p_hwfn
);
6778 meta
= &dev_user_data
->mcp_trace_meta
;
6779 meta_buf_bytes
= (u8
*)meta_buf
;
6781 /* Free the previous meta before loading a new one. */
6782 if (meta
->is_allocated
)
6783 qed_mcp_trace_free_meta_data(p_hwfn
);
6785 memset(meta
, 0, sizeof(*meta
));
6787 /* Read first signature */
6788 signature
= qed_read_dword_from_buf(meta_buf_bytes
, &offset
);
6789 if (signature
!= NVM_MAGIC_VALUE
)
6790 return DBG_STATUS_INVALID_TRACE_SIGNATURE
;
6792 /* Read no. of modules and allocate memory for their pointers */
6793 meta
->modules_num
= qed_read_byte_from_buf(meta_buf_bytes
, &offset
);
6794 meta
->modules
= kcalloc(meta
->modules_num
, sizeof(char *),
6797 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED
;
6799 /* Allocate and read all module strings */
6800 for (i
= 0; i
< meta
->modules_num
; i
++) {
6801 u8 module_len
= qed_read_byte_from_buf(meta_buf_bytes
, &offset
);
6803 *(meta
->modules
+ i
) = kzalloc(module_len
, GFP_KERNEL
);
6804 if (!(*(meta
->modules
+ i
))) {
6805 /* Update number of modules to be released */
6806 meta
->modules_num
= i
? i
- 1 : 0;
6807 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED
;
6810 qed_read_str_from_buf(meta_buf_bytes
, &offset
, module_len
,
6811 *(meta
->modules
+ i
));
6812 if (module_len
> MCP_TRACE_MAX_MODULE_LEN
)
6813 (*(meta
->modules
+ i
))[MCP_TRACE_MAX_MODULE_LEN
] = '\0';
6816 /* Read second signature */
6817 signature
= qed_read_dword_from_buf(meta_buf_bytes
, &offset
);
6818 if (signature
!= NVM_MAGIC_VALUE
)
6819 return DBG_STATUS_INVALID_TRACE_SIGNATURE
;
6821 /* Read number of formats and allocate memory for all formats */
6822 meta
->formats_num
= qed_read_dword_from_buf(meta_buf_bytes
, &offset
);
6823 meta
->formats
= kcalloc(meta
->formats_num
,
6824 sizeof(struct mcp_trace_format
),
6827 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED
;
6829 /* Allocate and read all strings */
6830 for (i
= 0; i
< meta
->formats_num
; i
++) {
6831 struct mcp_trace_format
*format_ptr
= &meta
->formats
[i
];
6834 format_ptr
->data
= qed_read_dword_from_buf(meta_buf_bytes
,
6836 format_len
= GET_MFW_FIELD(format_ptr
->data
,
6837 MCP_TRACE_FORMAT_LEN
);
6838 format_ptr
->format_str
= kzalloc(format_len
, GFP_KERNEL
);
6839 if (!format_ptr
->format_str
) {
6840 /* Update number of modules to be released */
6841 meta
->formats_num
= i
? i
- 1 : 0;
6842 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED
;
6845 qed_read_str_from_buf(meta_buf_bytes
,
6847 format_len
, format_ptr
->format_str
);
6850 meta
->is_allocated
= true;
6851 return DBG_STATUS_OK
;
6854 /* Parses an MCP trace buffer. If result_buf is not NULL, the MCP Trace results
6855 * are printed to it. The parsing status is returned.
6857 * trace_buf - MCP trace cyclic buffer
6858 * trace_buf_size - MCP trace cyclic buffer size in bytes
6859 * data_offset - offset in bytes of the data to parse in the MCP trace cyclic
6861 * data_size - size in bytes of data to parse.
6862 * parsed_buf - destination buffer for parsed data.
6863 * parsed_results_bytes - size of parsed data in bytes.
6865 static enum dbg_status
qed_parse_mcp_trace_buf(struct qed_hwfn
*p_hwfn
,
6871 u32
*parsed_results_bytes
)
6873 struct dbg_tools_user_data
*dev_user_data
;
6874 struct mcp_trace_meta
*meta
;
6875 u32 param_mask
, param_shift
;
6876 enum dbg_status status
;
6878 dev_user_data
= qed_dbg_get_user_data(p_hwfn
);
6879 meta
= &dev_user_data
->mcp_trace_meta
;
6880 *parsed_results_bytes
= 0;
6882 if (!meta
->is_allocated
)
6883 return DBG_STATUS_MCP_TRACE_BAD_DATA
;
6885 status
= DBG_STATUS_OK
;
6888 struct mcp_trace_format
*format_ptr
;
6889 u8 format_level
, format_module
;
6890 u32 params
[3] = { 0, 0, 0 };
6891 u32 header
, format_idx
, i
;
6893 if (data_size
< MFW_TRACE_ENTRY_SIZE
)
6894 return DBG_STATUS_MCP_TRACE_BAD_DATA
;
6896 header
= qed_read_from_cyclic_buf(trace_buf
,
6899 MFW_TRACE_ENTRY_SIZE
);
6900 data_size
-= MFW_TRACE_ENTRY_SIZE
;
6901 format_idx
= header
& MFW_TRACE_EVENTID_MASK
;
6903 /* Skip message if its index doesn't exist in the meta data */
6904 if (format_idx
>= meta
->formats_num
) {
6905 u8 format_size
= (u8
)GET_MFW_FIELD(header
,
6906 MFW_TRACE_PRM_SIZE
);
6908 if (data_size
< format_size
)
6909 return DBG_STATUS_MCP_TRACE_BAD_DATA
;
6911 data_offset
= qed_cyclic_add(data_offset
,
6914 data_size
-= format_size
;
6918 format_ptr
= &meta
->formats
[format_idx
];
6921 param_mask
= MCP_TRACE_FORMAT_P1_SIZE_MASK
, param_shift
=
6922 MCP_TRACE_FORMAT_P1_SIZE_OFFSET
;
6923 i
< MCP_TRACE_FORMAT_MAX_PARAMS
;
6924 i
++, param_mask
<<= MCP_TRACE_FORMAT_PARAM_WIDTH
,
6925 param_shift
+= MCP_TRACE_FORMAT_PARAM_WIDTH
) {
6926 /* Extract param size (0..3) */
6927 u8 param_size
= (u8
)((format_ptr
->data
& param_mask
) >>
6930 /* If the param size is zero, there are no other
6936 /* Size is encoded using 2 bits, where 3 is used to
6939 if (param_size
== 3)
6942 if (data_size
< param_size
)
6943 return DBG_STATUS_MCP_TRACE_BAD_DATA
;
6945 params
[i
] = qed_read_from_cyclic_buf(trace_buf
,
6949 data_size
-= param_size
;
6952 format_level
= (u8
)GET_MFW_FIELD(format_ptr
->data
,
6953 MCP_TRACE_FORMAT_LEVEL
);
6954 format_module
= (u8
)GET_MFW_FIELD(format_ptr
->data
,
6955 MCP_TRACE_FORMAT_MODULE
);
6956 if (format_level
>= ARRAY_SIZE(s_mcp_trace_level_str
))
6957 return DBG_STATUS_MCP_TRACE_BAD_DATA
;
6959 /* Print current message to results buffer */
6960 *parsed_results_bytes
+=
6961 sprintf(qed_get_buf_ptr(parsed_buf
,
6962 *parsed_results_bytes
),
6964 s_mcp_trace_level_str
[format_level
],
6965 meta
->modules
[format_module
]);
6966 *parsed_results_bytes
+=
6967 sprintf(qed_get_buf_ptr(parsed_buf
, *parsed_results_bytes
),
6968 format_ptr
->format_str
,
6969 params
[0], params
[1], params
[2]);
6972 /* Add string NULL terminator */
6973 (*parsed_results_bytes
)++;
6978 /* Parses an MCP Trace dump buffer.
6979 * If result_buf is not NULL, the MCP Trace results are printed to it.
6980 * In any case, the required results buffer size is assigned to
6981 * parsed_results_bytes.
6982 * The parsing status is returned.
6984 static enum dbg_status
qed_parse_mcp_trace_dump(struct qed_hwfn
*p_hwfn
,
6987 u32
*parsed_results_bytes
,
6988 bool free_meta_data
)
6990 const char *section_name
, *param_name
, *param_str_val
;
6991 u32 data_size
, trace_data_dwords
, trace_meta_dwords
;
6992 u32 offset
, results_offset
, results_buf_bytes
;
6993 u32 param_num_val
, num_section_params
;
6994 struct mcp_trace
*trace
;
6995 enum dbg_status status
;
6996 const u32
*meta_buf
;
6999 *parsed_results_bytes
= 0;
7001 /* Read global_params section */
7002 dump_buf
+= qed_read_section_hdr(dump_buf
,
7003 §ion_name
, &num_section_params
);
7004 if (strcmp(section_name
, "global_params"))
7005 return DBG_STATUS_MCP_TRACE_BAD_DATA
;
7007 /* Print global params */
7008 dump_buf
+= qed_print_section_params(dump_buf
,
7010 results_buf
, &results_offset
);
7012 /* Read trace_data section */
7013 dump_buf
+= qed_read_section_hdr(dump_buf
,
7014 §ion_name
, &num_section_params
);
7015 if (strcmp(section_name
, "mcp_trace_data") || num_section_params
!= 1)
7016 return DBG_STATUS_MCP_TRACE_BAD_DATA
;
7017 dump_buf
+= qed_read_param(dump_buf
,
7018 ¶m_name
, ¶m_str_val
, ¶m_num_val
);
7019 if (strcmp(param_name
, "size"))
7020 return DBG_STATUS_MCP_TRACE_BAD_DATA
;
7021 trace_data_dwords
= param_num_val
;
7023 /* Prepare trace info */
7024 trace
= (struct mcp_trace
*)dump_buf
;
7025 if (trace
->signature
!= MFW_TRACE_SIGNATURE
|| !trace
->size
)
7026 return DBG_STATUS_MCP_TRACE_BAD_DATA
;
7028 trace_buf
= (u8
*)dump_buf
+ sizeof(*trace
);
7029 offset
= trace
->trace_oldest
;
7030 data_size
= qed_cyclic_sub(trace
->trace_prod
, offset
, trace
->size
);
7031 dump_buf
+= trace_data_dwords
;
7033 /* Read meta_data section */
7034 dump_buf
+= qed_read_section_hdr(dump_buf
,
7035 §ion_name
, &num_section_params
);
7036 if (strcmp(section_name
, "mcp_trace_meta"))
7037 return DBG_STATUS_MCP_TRACE_BAD_DATA
;
7038 dump_buf
+= qed_read_param(dump_buf
,
7039 ¶m_name
, ¶m_str_val
, ¶m_num_val
);
7040 if (strcmp(param_name
, "size"))
7041 return DBG_STATUS_MCP_TRACE_BAD_DATA
;
7042 trace_meta_dwords
= param_num_val
;
7044 /* Choose meta data buffer */
7045 if (!trace_meta_dwords
) {
7046 /* Dump doesn't include meta data */
7047 struct dbg_tools_user_data
*dev_user_data
=
7048 qed_dbg_get_user_data(p_hwfn
);
7050 if (!dev_user_data
->mcp_trace_user_meta_buf
)
7051 return DBG_STATUS_MCP_TRACE_NO_META
;
7053 meta_buf
= dev_user_data
->mcp_trace_user_meta_buf
;
7055 /* Dump includes meta data */
7056 meta_buf
= dump_buf
;
7059 /* Allocate meta data memory */
7060 status
= qed_mcp_trace_alloc_meta_data(p_hwfn
, meta_buf
);
7061 if (status
!= DBG_STATUS_OK
)
7064 status
= qed_parse_mcp_trace_buf(p_hwfn
,
7070 results_buf
+ results_offset
:
7072 &results_buf_bytes
);
7073 if (status
!= DBG_STATUS_OK
)
7077 qed_mcp_trace_free_meta_data(p_hwfn
);
7079 *parsed_results_bytes
= results_offset
+ results_buf_bytes
;
7081 return DBG_STATUS_OK
;
7084 /* Parses a Reg FIFO dump buffer.
7085 * If result_buf is not NULL, the Reg FIFO results are printed to it.
7086 * In any case, the required results buffer size is assigned to
7087 * parsed_results_bytes.
7088 * The parsing status is returned.
7090 static enum dbg_status
qed_parse_reg_fifo_dump(u32
*dump_buf
,
7092 u32
*parsed_results_bytes
)
7094 const char *section_name
, *param_name
, *param_str_val
;
7095 u32 param_num_val
, num_section_params
, num_elements
;
7096 struct reg_fifo_element
*elements
;
7097 u8 i
, j
, err_code
, vf_val
;
7098 u32 results_offset
= 0;
7101 /* Read global_params section */
7102 dump_buf
+= qed_read_section_hdr(dump_buf
,
7103 §ion_name
, &num_section_params
);
7104 if (strcmp(section_name
, "global_params"))
7105 return DBG_STATUS_REG_FIFO_BAD_DATA
;
7107 /* Print global params */
7108 dump_buf
+= qed_print_section_params(dump_buf
,
7110 results_buf
, &results_offset
);
7112 /* Read reg_fifo_data section */
7113 dump_buf
+= qed_read_section_hdr(dump_buf
,
7114 §ion_name
, &num_section_params
);
7115 if (strcmp(section_name
, "reg_fifo_data"))
7116 return DBG_STATUS_REG_FIFO_BAD_DATA
;
7117 dump_buf
+= qed_read_param(dump_buf
,
7118 ¶m_name
, ¶m_str_val
, ¶m_num_val
);
7119 if (strcmp(param_name
, "size"))
7120 return DBG_STATUS_REG_FIFO_BAD_DATA
;
7121 if (param_num_val
% REG_FIFO_ELEMENT_DWORDS
)
7122 return DBG_STATUS_REG_FIFO_BAD_DATA
;
7123 num_elements
= param_num_val
/ REG_FIFO_ELEMENT_DWORDS
;
7124 elements
= (struct reg_fifo_element
*)dump_buf
;
7126 /* Decode elements */
7127 for (i
= 0; i
< num_elements
; i
++) {
7128 const char *err_msg
= NULL
;
7130 /* Discover if element belongs to a VF or a PF */
7131 vf_val
= GET_FIELD(elements
[i
].data
, REG_FIFO_ELEMENT_VF
);
7132 if (vf_val
== REG_FIFO_ELEMENT_IS_PF_VF_VAL
)
7133 sprintf(vf_str
, "%s", "N/A");
7135 sprintf(vf_str
, "%d", vf_val
);
7137 /* Find error message */
7138 err_code
= GET_FIELD(elements
[i
].data
, REG_FIFO_ELEMENT_ERROR
);
7139 for (j
= 0; j
< ARRAY_SIZE(s_reg_fifo_errors
) && !err_msg
; j
++)
7140 if (err_code
== s_reg_fifo_errors
[j
].err_code
)
7141 err_msg
= s_reg_fifo_errors
[j
].err_msg
;
7143 /* Add parsed element to parsed buffer */
7145 sprintf(qed_get_buf_ptr(results_buf
,
7147 "raw: 0x%016llx, address: 0x%07x, access: %-5s, pf: %2d, vf: %s, port: %d, privilege: %-3s, protection: %-12s, master: %-4s, error: %s\n",
7149 (u32
)GET_FIELD(elements
[i
].data
,
7150 REG_FIFO_ELEMENT_ADDRESS
) *
7151 REG_FIFO_ELEMENT_ADDR_FACTOR
,
7152 s_access_strs
[GET_FIELD(elements
[i
].data
,
7153 REG_FIFO_ELEMENT_ACCESS
)],
7154 (u32
)GET_FIELD(elements
[i
].data
,
7155 REG_FIFO_ELEMENT_PF
),
7157 (u32
)GET_FIELD(elements
[i
].data
,
7158 REG_FIFO_ELEMENT_PORT
),
7159 s_privilege_strs
[GET_FIELD(elements
[i
].data
,
7160 REG_FIFO_ELEMENT_PRIVILEGE
)],
7161 s_protection_strs
[GET_FIELD(elements
[i
].data
,
7162 REG_FIFO_ELEMENT_PROTECTION
)],
7163 s_master_strs
[GET_FIELD(elements
[i
].data
,
7164 REG_FIFO_ELEMENT_MASTER
)],
7165 err_msg
? err_msg
: "unknown error code");
7168 results_offset
+= sprintf(qed_get_buf_ptr(results_buf
,
7170 "fifo contained %d elements", num_elements
);
7172 /* Add 1 for string NULL termination */
7173 *parsed_results_bytes
= results_offset
+ 1;
7175 return DBG_STATUS_OK
;
7178 static enum dbg_status
qed_parse_igu_fifo_element(struct igu_fifo_element
7181 u32
*results_offset
)
7183 const struct igu_fifo_addr_data
*found_addr
= NULL
;
7184 u8 source
, err_type
, i
, is_cleanup
;
7185 char parsed_addr_data
[32];
7186 char parsed_wr_data
[256];
7187 u32 wr_data
, prod_cons
;
7188 bool is_wr_cmd
, is_pf
;
7192 /* Dword12 (dword index 1 and 2) contains bits 32..95 of the
7195 dword12
= ((u64
)element
->dword2
<< 32) | element
->dword1
;
7196 is_wr_cmd
= GET_FIELD(dword12
, IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD
);
7197 is_pf
= GET_FIELD(element
->dword0
, IGU_FIFO_ELEMENT_DWORD0_IS_PF
);
7198 cmd_addr
= GET_FIELD(element
->dword0
, IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR
);
7199 source
= GET_FIELD(element
->dword0
, IGU_FIFO_ELEMENT_DWORD0_SOURCE
);
7200 err_type
= GET_FIELD(element
->dword0
, IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE
);
7202 if (source
>= ARRAY_SIZE(s_igu_fifo_source_strs
))
7203 return DBG_STATUS_IGU_FIFO_BAD_DATA
;
7204 if (err_type
>= ARRAY_SIZE(s_igu_fifo_error_strs
))
7205 return DBG_STATUS_IGU_FIFO_BAD_DATA
;
7207 /* Find address data */
7208 for (i
= 0; i
< ARRAY_SIZE(s_igu_fifo_addr_data
) && !found_addr
; i
++) {
7209 const struct igu_fifo_addr_data
*curr_addr
=
7210 &s_igu_fifo_addr_data
[i
];
7212 if (cmd_addr
>= curr_addr
->start_addr
&& cmd_addr
<=
7213 curr_addr
->end_addr
)
7214 found_addr
= curr_addr
;
7218 return DBG_STATUS_IGU_FIFO_BAD_DATA
;
7220 /* Prepare parsed address data */
7221 switch (found_addr
->type
) {
7222 case IGU_ADDR_TYPE_MSIX_MEM
:
7223 sprintf(parsed_addr_data
, " vector_num = 0x%x", cmd_addr
/ 2);
7225 case IGU_ADDR_TYPE_WRITE_INT_ACK
:
7226 case IGU_ADDR_TYPE_WRITE_PROD_UPDATE
:
7227 sprintf(parsed_addr_data
,
7228 " SB = 0x%x", cmd_addr
- found_addr
->start_addr
);
7231 parsed_addr_data
[0] = '\0';
7235 parsed_wr_data
[0] = '\0';
7239 /* Prepare parsed write data */
7240 wr_data
= GET_FIELD(dword12
, IGU_FIFO_ELEMENT_DWORD12_WR_DATA
);
7241 prod_cons
= GET_FIELD(wr_data
, IGU_FIFO_WR_DATA_PROD_CONS
);
7242 is_cleanup
= GET_FIELD(wr_data
, IGU_FIFO_WR_DATA_CMD_TYPE
);
7244 if (source
== IGU_SRC_ATTN
) {
7245 sprintf(parsed_wr_data
, "prod: 0x%x, ", prod_cons
);
7248 u8 cleanup_val
, cleanup_type
;
7252 IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL
);
7255 IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE
);
7257 sprintf(parsed_wr_data
,
7258 "cmd_type: cleanup, cleanup_val: %s, cleanup_type : %d, ",
7259 cleanup_val
? "set" : "clear",
7262 u8 update_flag
, en_dis_int_for_sb
, segment
;
7265 update_flag
= GET_FIELD(wr_data
,
7266 IGU_FIFO_WR_DATA_UPDATE_FLAG
);
7269 IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB
);
7270 segment
= GET_FIELD(wr_data
,
7271 IGU_FIFO_WR_DATA_SEGMENT
);
7272 timer_mask
= GET_FIELD(wr_data
,
7273 IGU_FIFO_WR_DATA_TIMER_MASK
);
7275 sprintf(parsed_wr_data
,
7276 "cmd_type: prod/cons update, prod/cons: 0x%x, update_flag: %s, en_dis_int_for_sb : %s, segment : %s, timer_mask = %d, ",
7278 update_flag
? "update" : "nop",
7280 (en_dis_int_for_sb
== 1 ? "disable" : "nop") :
7282 segment
? "attn" : "regular",
7287 /* Add parsed element to parsed buffer */
7288 *results_offset
+= sprintf(qed_get_buf_ptr(results_buf
,
7290 "raw: 0x%01x%08x%08x, %s: %d, source : %s, type : %s, cmd_addr : 0x%x(%s%s), %serror: %s\n",
7291 element
->dword2
, element
->dword1
,
7293 is_pf
? "pf" : "vf",
7294 GET_FIELD(element
->dword0
,
7295 IGU_FIFO_ELEMENT_DWORD0_FID
),
7296 s_igu_fifo_source_strs
[source
],
7297 is_wr_cmd
? "wr" : "rd",
7299 (!is_pf
&& found_addr
->vf_desc
)
7300 ? found_addr
->vf_desc
7304 s_igu_fifo_error_strs
[err_type
]);
7306 return DBG_STATUS_OK
;
7309 /* Parses an IGU FIFO dump buffer.
7310 * If result_buf is not NULL, the IGU FIFO results are printed to it.
7311 * In any case, the required results buffer size is assigned to
7312 * parsed_results_bytes.
7313 * The parsing status is returned.
7315 static enum dbg_status
qed_parse_igu_fifo_dump(u32
*dump_buf
,
7317 u32
*parsed_results_bytes
)
7319 const char *section_name
, *param_name
, *param_str_val
;
7320 u32 param_num_val
, num_section_params
, num_elements
;
7321 struct igu_fifo_element
*elements
;
7322 enum dbg_status status
;
7323 u32 results_offset
= 0;
7326 /* Read global_params section */
7327 dump_buf
+= qed_read_section_hdr(dump_buf
,
7328 §ion_name
, &num_section_params
);
7329 if (strcmp(section_name
, "global_params"))
7330 return DBG_STATUS_IGU_FIFO_BAD_DATA
;
7332 /* Print global params */
7333 dump_buf
+= qed_print_section_params(dump_buf
,
7335 results_buf
, &results_offset
);
7337 /* Read igu_fifo_data section */
7338 dump_buf
+= qed_read_section_hdr(dump_buf
,
7339 §ion_name
, &num_section_params
);
7340 if (strcmp(section_name
, "igu_fifo_data"))
7341 return DBG_STATUS_IGU_FIFO_BAD_DATA
;
7342 dump_buf
+= qed_read_param(dump_buf
,
7343 ¶m_name
, ¶m_str_val
, ¶m_num_val
);
7344 if (strcmp(param_name
, "size"))
7345 return DBG_STATUS_IGU_FIFO_BAD_DATA
;
7346 if (param_num_val
% IGU_FIFO_ELEMENT_DWORDS
)
7347 return DBG_STATUS_IGU_FIFO_BAD_DATA
;
7348 num_elements
= param_num_val
/ IGU_FIFO_ELEMENT_DWORDS
;
7349 elements
= (struct igu_fifo_element
*)dump_buf
;
7351 /* Decode elements */
7352 for (i
= 0; i
< num_elements
; i
++) {
7353 status
= qed_parse_igu_fifo_element(&elements
[i
],
7356 if (status
!= DBG_STATUS_OK
)
7360 results_offset
+= sprintf(qed_get_buf_ptr(results_buf
,
7362 "fifo contained %d elements", num_elements
);
7364 /* Add 1 for string NULL termination */
7365 *parsed_results_bytes
= results_offset
+ 1;
7367 return DBG_STATUS_OK
;
7370 static enum dbg_status
7371 qed_parse_protection_override_dump(u32
*dump_buf
,
7373 u32
*parsed_results_bytes
)
7375 const char *section_name
, *param_name
, *param_str_val
;
7376 u32 param_num_val
, num_section_params
, num_elements
;
7377 struct protection_override_element
*elements
;
7378 u32 results_offset
= 0;
7381 /* Read global_params section */
7382 dump_buf
+= qed_read_section_hdr(dump_buf
,
7383 §ion_name
, &num_section_params
);
7384 if (strcmp(section_name
, "global_params"))
7385 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA
;
7387 /* Print global params */
7388 dump_buf
+= qed_print_section_params(dump_buf
,
7390 results_buf
, &results_offset
);
7392 /* Read protection_override_data section */
7393 dump_buf
+= qed_read_section_hdr(dump_buf
,
7394 §ion_name
, &num_section_params
);
7395 if (strcmp(section_name
, "protection_override_data"))
7396 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA
;
7397 dump_buf
+= qed_read_param(dump_buf
,
7398 ¶m_name
, ¶m_str_val
, ¶m_num_val
);
7399 if (strcmp(param_name
, "size"))
7400 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA
;
7401 if (param_num_val
% PROTECTION_OVERRIDE_ELEMENT_DWORDS
)
7402 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA
;
7403 num_elements
= param_num_val
/ PROTECTION_OVERRIDE_ELEMENT_DWORDS
;
7404 elements
= (struct protection_override_element
*)dump_buf
;
7406 /* Decode elements */
7407 for (i
= 0; i
< num_elements
; i
++) {
7408 u32 address
= GET_FIELD(elements
[i
].data
,
7409 PROTECTION_OVERRIDE_ELEMENT_ADDRESS
) *
7410 PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR
;
7413 sprintf(qed_get_buf_ptr(results_buf
,
7415 "window %2d, address: 0x%07x, size: %7d regs, read: %d, write: %d, read protection: %-12s, write protection: %-12s\n",
7417 (u32
)GET_FIELD(elements
[i
].data
,
7418 PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE
),
7419 (u32
)GET_FIELD(elements
[i
].data
,
7420 PROTECTION_OVERRIDE_ELEMENT_READ
),
7421 (u32
)GET_FIELD(elements
[i
].data
,
7422 PROTECTION_OVERRIDE_ELEMENT_WRITE
),
7423 s_protection_strs
[GET_FIELD(elements
[i
].data
,
7424 PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION
)],
7425 s_protection_strs
[GET_FIELD(elements
[i
].data
,
7426 PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION
)]);
7429 results_offset
+= sprintf(qed_get_buf_ptr(results_buf
,
7431 "protection override contained %d elements",
7434 /* Add 1 for string NULL termination */
7435 *parsed_results_bytes
= results_offset
+ 1;
7437 return DBG_STATUS_OK
;
7440 /* Parses a FW Asserts dump buffer.
7441 * If result_buf is not NULL, the FW Asserts results are printed to it.
7442 * In any case, the required results buffer size is assigned to
7443 * parsed_results_bytes.
7444 * The parsing status is returned.
7446 static enum dbg_status
qed_parse_fw_asserts_dump(u32
*dump_buf
,
7448 u32
*parsed_results_bytes
)
7450 u32 num_section_params
, param_num_val
, i
, results_offset
= 0;
7451 const char *param_name
, *param_str_val
, *section_name
;
7452 bool last_section_found
= false;
7454 *parsed_results_bytes
= 0;
7456 /* Read global_params section */
7457 dump_buf
+= qed_read_section_hdr(dump_buf
,
7458 §ion_name
, &num_section_params
);
7459 if (strcmp(section_name
, "global_params"))
7460 return DBG_STATUS_FW_ASSERTS_PARSE_FAILED
;
7462 /* Print global params */
7463 dump_buf
+= qed_print_section_params(dump_buf
,
7465 results_buf
, &results_offset
);
7467 while (!last_section_found
) {
7468 dump_buf
+= qed_read_section_hdr(dump_buf
,
7470 &num_section_params
);
7471 if (!strcmp(section_name
, "fw_asserts")) {
7472 /* Extract params */
7473 const char *storm_letter
= NULL
;
7474 u32 storm_dump_size
= 0;
7476 for (i
= 0; i
< num_section_params
; i
++) {
7477 dump_buf
+= qed_read_param(dump_buf
,
7481 if (!strcmp(param_name
, "storm"))
7482 storm_letter
= param_str_val
;
7483 else if (!strcmp(param_name
, "size"))
7484 storm_dump_size
= param_num_val
;
7487 DBG_STATUS_FW_ASSERTS_PARSE_FAILED
;
7490 if (!storm_letter
|| !storm_dump_size
)
7491 return DBG_STATUS_FW_ASSERTS_PARSE_FAILED
;
7495 sprintf(qed_get_buf_ptr(results_buf
,
7497 "\n%sSTORM_ASSERT: size=%d\n",
7498 storm_letter
, storm_dump_size
);
7499 for (i
= 0; i
< storm_dump_size
; i
++, dump_buf
++)
7501 sprintf(qed_get_buf_ptr(results_buf
,
7503 "%08x\n", *dump_buf
);
7504 } else if (!strcmp(section_name
, "last")) {
7505 last_section_found
= true;
7507 return DBG_STATUS_FW_ASSERTS_PARSE_FAILED
;
7511 /* Add 1 for string NULL termination */
7512 *parsed_results_bytes
= results_offset
+ 1;
7514 return DBG_STATUS_OK
;
7517 /***************************** Public Functions *******************************/
7519 enum dbg_status
qed_dbg_user_set_bin_ptr(struct qed_hwfn
*p_hwfn
,
7520 const u8
* const bin_ptr
)
7522 struct bin_buffer_hdr
*buf_hdrs
= (struct bin_buffer_hdr
*)bin_ptr
;
7525 /* Convert binary data to debug arrays */
7526 for (buf_id
= 0; buf_id
< MAX_BIN_DBG_BUFFER_TYPE
; buf_id
++)
7527 qed_set_dbg_bin_buf(p_hwfn
,
7528 (enum bin_dbg_buffer_type
)buf_id
,
7529 (u32
*)(bin_ptr
+ buf_hdrs
[buf_id
].offset
),
7530 buf_hdrs
[buf_id
].length
);
7532 return DBG_STATUS_OK
;
7535 enum dbg_status
qed_dbg_alloc_user_data(struct qed_hwfn
*p_hwfn
,
7536 void **user_data_ptr
)
7538 *user_data_ptr
= kzalloc(sizeof(struct dbg_tools_user_data
),
7540 if (!(*user_data_ptr
))
7541 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED
;
7543 return DBG_STATUS_OK
;
7546 const char *qed_dbg_get_status_str(enum dbg_status status
)
7549 MAX_DBG_STATUS
) ? s_status_str
[status
] : "Invalid debug status";
7552 enum dbg_status
qed_get_idle_chk_results_buf_size(struct qed_hwfn
*p_hwfn
,
7554 u32 num_dumped_dwords
,
7555 u32
*results_buf_size
)
7557 u32 num_errors
, num_warnings
;
7559 return qed_parse_idle_chk_dump(p_hwfn
,
7564 &num_errors
, &num_warnings
);
7567 enum dbg_status
qed_print_idle_chk_results(struct qed_hwfn
*p_hwfn
,
7569 u32 num_dumped_dwords
,
7574 u32 parsed_buf_size
;
7576 return qed_parse_idle_chk_dump(p_hwfn
,
7581 num_errors
, num_warnings
);
7584 void qed_dbg_mcp_trace_set_meta_data(struct qed_hwfn
*p_hwfn
,
7585 const u32
*meta_buf
)
7587 struct dbg_tools_user_data
*dev_user_data
=
7588 qed_dbg_get_user_data(p_hwfn
);
7590 dev_user_data
->mcp_trace_user_meta_buf
= meta_buf
;
7593 enum dbg_status
qed_get_mcp_trace_results_buf_size(struct qed_hwfn
*p_hwfn
,
7595 u32 num_dumped_dwords
,
7596 u32
*results_buf_size
)
7598 return qed_parse_mcp_trace_dump(p_hwfn
,
7599 dump_buf
, NULL
, results_buf_size
, true);
7602 enum dbg_status
qed_print_mcp_trace_results(struct qed_hwfn
*p_hwfn
,
7604 u32 num_dumped_dwords
,
7607 u32 parsed_buf_size
;
7609 /* Doesn't do anything, needed for compile time asserts */
7610 qed_user_static_asserts();
7612 return qed_parse_mcp_trace_dump(p_hwfn
,
7614 results_buf
, &parsed_buf_size
, true);
7617 enum dbg_status
qed_print_mcp_trace_results_cont(struct qed_hwfn
*p_hwfn
,
7621 u32 parsed_buf_size
;
7623 return qed_parse_mcp_trace_dump(p_hwfn
, dump_buf
, results_buf
,
7624 &parsed_buf_size
, false);
7627 enum dbg_status
qed_print_mcp_trace_line(struct qed_hwfn
*p_hwfn
,
7629 u32 num_dumped_bytes
,
7632 u32 parsed_results_bytes
;
7634 return qed_parse_mcp_trace_buf(p_hwfn
,
7639 results_buf
, &parsed_results_bytes
);
7642 /* Frees the specified MCP Trace meta data */
7643 void qed_mcp_trace_free_meta_data(struct qed_hwfn
*p_hwfn
)
7645 struct dbg_tools_user_data
*dev_user_data
;
7646 struct mcp_trace_meta
*meta
;
7649 dev_user_data
= qed_dbg_get_user_data(p_hwfn
);
7650 meta
= &dev_user_data
->mcp_trace_meta
;
7651 if (!meta
->is_allocated
)
7654 /* Release modules */
7655 if (meta
->modules
) {
7656 for (i
= 0; i
< meta
->modules_num
; i
++)
7657 kfree(meta
->modules
[i
]);
7658 kfree(meta
->modules
);
7661 /* Release formats */
7662 if (meta
->formats
) {
7663 for (i
= 0; i
< meta
->formats_num
; i
++)
7664 kfree(meta
->formats
[i
].format_str
);
7665 kfree(meta
->formats
);
7668 meta
->is_allocated
= false;
7671 enum dbg_status
qed_get_reg_fifo_results_buf_size(struct qed_hwfn
*p_hwfn
,
7673 u32 num_dumped_dwords
,
7674 u32
*results_buf_size
)
7676 return qed_parse_reg_fifo_dump(dump_buf
, NULL
, results_buf_size
);
7679 enum dbg_status
qed_print_reg_fifo_results(struct qed_hwfn
*p_hwfn
,
7681 u32 num_dumped_dwords
,
7684 u32 parsed_buf_size
;
7686 return qed_parse_reg_fifo_dump(dump_buf
, results_buf
, &parsed_buf_size
);
7689 enum dbg_status
qed_get_igu_fifo_results_buf_size(struct qed_hwfn
*p_hwfn
,
7691 u32 num_dumped_dwords
,
7692 u32
*results_buf_size
)
7694 return qed_parse_igu_fifo_dump(dump_buf
, NULL
, results_buf_size
);
7697 enum dbg_status
qed_print_igu_fifo_results(struct qed_hwfn
*p_hwfn
,
7699 u32 num_dumped_dwords
,
7702 u32 parsed_buf_size
;
7704 return qed_parse_igu_fifo_dump(dump_buf
, results_buf
, &parsed_buf_size
);
7708 qed_get_protection_override_results_buf_size(struct qed_hwfn
*p_hwfn
,
7710 u32 num_dumped_dwords
,
7711 u32
*results_buf_size
)
7713 return qed_parse_protection_override_dump(dump_buf
,
7714 NULL
, results_buf_size
);
7717 enum dbg_status
qed_print_protection_override_results(struct qed_hwfn
*p_hwfn
,
7719 u32 num_dumped_dwords
,
7722 u32 parsed_buf_size
;
7724 return qed_parse_protection_override_dump(dump_buf
,
7729 enum dbg_status
qed_get_fw_asserts_results_buf_size(struct qed_hwfn
*p_hwfn
,
7731 u32 num_dumped_dwords
,
7732 u32
*results_buf_size
)
7734 return qed_parse_fw_asserts_dump(dump_buf
, NULL
, results_buf_size
);
7737 enum dbg_status
qed_print_fw_asserts_results(struct qed_hwfn
*p_hwfn
,
7739 u32 num_dumped_dwords
,
7742 u32 parsed_buf_size
;
7744 return qed_parse_fw_asserts_dump(dump_buf
,
7745 results_buf
, &parsed_buf_size
);
7748 enum dbg_status
qed_dbg_parse_attn(struct qed_hwfn
*p_hwfn
,
7749 struct dbg_attn_block_result
*results
)
7751 const u32
*block_attn_name_offsets
;
7752 const char *attn_name_base
;
7753 const char *block_name
;
7754 enum dbg_attn_type attn_type
;
7757 num_regs
= GET_FIELD(results
->data
, DBG_ATTN_BLOCK_RESULT_NUM_REGS
);
7758 attn_type
= GET_FIELD(results
->data
, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE
);
7759 block_name
= qed_dbg_get_block_name(p_hwfn
, results
->block_id
);
7761 return DBG_STATUS_INVALID_ARGS
;
7763 if (!p_hwfn
->dbg_arrays
[BIN_BUF_DBG_ATTN_INDEXES
].ptr
||
7764 !p_hwfn
->dbg_arrays
[BIN_BUF_DBG_ATTN_NAME_OFFSETS
].ptr
||
7765 !p_hwfn
->dbg_arrays
[BIN_BUF_DBG_PARSING_STRINGS
].ptr
)
7766 return DBG_STATUS_DBG_ARRAY_NOT_SET
;
7768 block_attn_name_offsets
=
7769 (u32
*)p_hwfn
->dbg_arrays
[BIN_BUF_DBG_ATTN_NAME_OFFSETS
].ptr
+
7770 results
->names_offset
;
7772 attn_name_base
= p_hwfn
->dbg_arrays
[BIN_BUF_DBG_PARSING_STRINGS
].ptr
;
7774 /* Go over registers with a non-zero attention status */
7775 for (i
= 0; i
< num_regs
; i
++) {
7776 struct dbg_attn_bit_mapping
*bit_mapping
;
7777 struct dbg_attn_reg_result
*reg_result
;
7778 u8 num_reg_attn
, bit_idx
= 0;
7780 reg_result
= &results
->reg_results
[i
];
7781 num_reg_attn
= GET_FIELD(reg_result
->data
,
7782 DBG_ATTN_REG_RESULT_NUM_REG_ATTN
);
7783 bit_mapping
= (struct dbg_attn_bit_mapping
*)
7784 p_hwfn
->dbg_arrays
[BIN_BUF_DBG_ATTN_INDEXES
].ptr
+
7785 reg_result
->block_attn_offset
;
7787 /* Go over attention status bits */
7788 for (j
= 0; j
< num_reg_attn
; j
++) {
7789 u16 attn_idx_val
= GET_FIELD(bit_mapping
[j
].data
,
7790 DBG_ATTN_BIT_MAPPING_VAL
);
7791 const char *attn_name
, *attn_type_str
, *masked_str
;
7792 u32 attn_name_offset
;
7795 /* Check if bit mask should be advanced (due to unused
7798 if (GET_FIELD(bit_mapping
[j
].data
,
7799 DBG_ATTN_BIT_MAPPING_IS_UNUSED_BIT_CNT
)) {
7800 bit_idx
+= (u8
)attn_idx_val
;
7804 /* Check current bit index */
7805 if (reg_result
->sts_val
& BIT(bit_idx
)) {
7806 /* An attention bit with value=1 was found
7807 * Find attention name
7810 block_attn_name_offsets
[attn_idx_val
];
7811 attn_name
= attn_name_base
+ attn_name_offset
;
7814 ATTN_TYPE_INTERRUPT
? "Interrupt" :
7816 masked_str
= reg_result
->mask_val
&
7820 GET_FIELD(reg_result
->data
,
7821 DBG_ATTN_REG_RESULT_STS_ADDRESS
);
7823 "%s (%s) : %s [address 0x%08x, bit %d]%s\n",
7824 block_name
, attn_type_str
, attn_name
,
7825 sts_addr
* 4, bit_idx
, masked_str
);
7832 return DBG_STATUS_OK
;
7835 /* Wrapper for unifying the idle_chk and mcp_trace api */
7836 static enum dbg_status
7837 qed_print_idle_chk_results_wrapper(struct qed_hwfn
*p_hwfn
,
7839 u32 num_dumped_dwords
,
7842 u32 num_errors
, num_warnnings
;
7844 return qed_print_idle_chk_results(p_hwfn
, dump_buf
, num_dumped_dwords
,
7845 results_buf
, &num_errors
,
7849 static DEFINE_MUTEX(qed_dbg_lock
);
7851 #define MAX_PHY_RESULT_BUFFER 9000
7853 /******************************** Feature Meta data section ******************/
7855 #define GRC_NUM_STR_FUNCS 2
7856 #define IDLE_CHK_NUM_STR_FUNCS 1
7857 #define MCP_TRACE_NUM_STR_FUNCS 1
7858 #define REG_FIFO_NUM_STR_FUNCS 1
7859 #define IGU_FIFO_NUM_STR_FUNCS 1
7860 #define PROTECTION_OVERRIDE_NUM_STR_FUNCS 1
7861 #define FW_ASSERTS_NUM_STR_FUNCS 1
7862 #define ILT_NUM_STR_FUNCS 1
7863 #define PHY_NUM_STR_FUNCS 20
7865 /* Feature meta data lookup table */
7869 enum dbg_status (*get_size
)(struct qed_hwfn
*p_hwfn
,
7870 struct qed_ptt
*p_ptt
, u32
*size
);
7871 enum dbg_status (*perform_dump
)(struct qed_hwfn
*p_hwfn
,
7872 struct qed_ptt
*p_ptt
, u32
*dump_buf
,
7873 u32 buf_size
, u32
*dumped_dwords
);
7874 enum dbg_status (*print_results
)(struct qed_hwfn
*p_hwfn
,
7875 u32
*dump_buf
, u32 num_dumped_dwords
,
7877 enum dbg_status (*results_buf_size
)(struct qed_hwfn
*p_hwfn
,
7879 u32 num_dumped_dwords
,
7880 u32
*results_buf_size
);
7881 const struct qed_func_lookup
*hsi_func_lookup
;
7882 } qed_features_lookup
[] = {
7884 "grc", GRC_NUM_STR_FUNCS
, qed_dbg_grc_get_dump_buf_size
,
7885 qed_dbg_grc_dump
, NULL
, NULL
, NULL
}, {
7886 "idle_chk", IDLE_CHK_NUM_STR_FUNCS
,
7887 qed_dbg_idle_chk_get_dump_buf_size
,
7888 qed_dbg_idle_chk_dump
,
7889 qed_print_idle_chk_results_wrapper
,
7890 qed_get_idle_chk_results_buf_size
,
7892 "mcp_trace", MCP_TRACE_NUM_STR_FUNCS
,
7893 qed_dbg_mcp_trace_get_dump_buf_size
,
7894 qed_dbg_mcp_trace_dump
, qed_print_mcp_trace_results
,
7895 qed_get_mcp_trace_results_buf_size
,
7897 "reg_fifo", REG_FIFO_NUM_STR_FUNCS
,
7898 qed_dbg_reg_fifo_get_dump_buf_size
,
7899 qed_dbg_reg_fifo_dump
, qed_print_reg_fifo_results
,
7900 qed_get_reg_fifo_results_buf_size
,
7902 "igu_fifo", IGU_FIFO_NUM_STR_FUNCS
,
7903 qed_dbg_igu_fifo_get_dump_buf_size
,
7904 qed_dbg_igu_fifo_dump
, qed_print_igu_fifo_results
,
7905 qed_get_igu_fifo_results_buf_size
,
7907 "protection_override", PROTECTION_OVERRIDE_NUM_STR_FUNCS
,
7908 qed_dbg_protection_override_get_dump_buf_size
,
7909 qed_dbg_protection_override_dump
,
7910 qed_print_protection_override_results
,
7911 qed_get_protection_override_results_buf_size
,
7913 "fw_asserts", FW_ASSERTS_NUM_STR_FUNCS
,
7914 qed_dbg_fw_asserts_get_dump_buf_size
,
7915 qed_dbg_fw_asserts_dump
,
7916 qed_print_fw_asserts_results
,
7917 qed_get_fw_asserts_results_buf_size
,
7919 "ilt", ILT_NUM_STR_FUNCS
, qed_dbg_ilt_get_dump_buf_size
,
7920 qed_dbg_ilt_dump
, NULL
, NULL
, NULL
},};
7922 static void qed_dbg_print_feature(u8
*p_text_buf
, u32 text_size
)
7924 u32 i
, precision
= 80;
7929 pr_notice("\n%.*s", precision
, p_text_buf
);
7930 for (i
= precision
; i
< text_size
; i
+= precision
)
7931 pr_cont("%.*s", precision
, p_text_buf
+ i
);
7935 #define QED_RESULTS_BUF_MIN_SIZE 16
7936 /* Generic function for decoding debug feature info */
7937 static enum dbg_status
format_feature(struct qed_hwfn
*p_hwfn
,
7938 enum qed_dbg_features feature_idx
)
7940 struct qed_dbg_feature
*feature
=
7941 &p_hwfn
->cdev
->dbg_features
[feature_idx
];
7942 u32 txt_size_bytes
, null_char_pos
, i
;
7947 /* Check if feature supports formatting capability */
7948 if (!qed_features_lookup
[feature_idx
].results_buf_size
)
7949 return DBG_STATUS_OK
;
7951 dbuf
= (u32
*)feature
->dump_buf
;
7952 dwords
= feature
->dumped_dwords
;
7954 /* Obtain size of formatted output */
7955 rc
= qed_features_lookup
[feature_idx
].results_buf_size(p_hwfn
,
7959 if (rc
!= DBG_STATUS_OK
)
7962 /* Make sure that the allocated size is a multiple of dword
7965 null_char_pos
= txt_size_bytes
- 1;
7966 txt_size_bytes
= (txt_size_bytes
+ 3) & ~0x3;
7968 if (txt_size_bytes
< QED_RESULTS_BUF_MIN_SIZE
) {
7969 DP_NOTICE(p_hwfn
->cdev
,
7970 "formatted size of feature was too small %d. Aborting\n",
7972 return DBG_STATUS_INVALID_ARGS
;
7975 /* allocate temp text buf */
7976 text_buf
= vzalloc(txt_size_bytes
);
7978 DP_NOTICE(p_hwfn
->cdev
,
7979 "failed to allocate text buffer. Aborting\n");
7980 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED
;
7983 /* Decode feature opcodes to string on temp buf */
7984 rc
= qed_features_lookup
[feature_idx
].print_results(p_hwfn
,
7988 if (rc
!= DBG_STATUS_OK
) {
7993 /* Replace the original null character with a '\n' character.
7994 * The bytes that were added as a result of the dword alignment are also
7995 * padded with '\n' characters.
7997 for (i
= null_char_pos
; i
< txt_size_bytes
; i
++)
8000 /* Dump printable feature to log */
8001 if (p_hwfn
->cdev
->print_dbg_data
)
8002 qed_dbg_print_feature(text_buf
, txt_size_bytes
);
8004 /* Dump binary data as is to the output file */
8005 if (p_hwfn
->cdev
->dbg_bin_dump
) {
8010 /* Free the old dump_buf and point the dump_buf to the newly allocated
8011 * and formatted text buffer.
8013 vfree(feature
->dump_buf
);
8014 feature
->dump_buf
= text_buf
;
8015 feature
->buf_size
= txt_size_bytes
;
8016 feature
->dumped_dwords
= txt_size_bytes
/ 4;
8021 #define MAX_DBG_FEATURE_SIZE_DWORDS 0x3FFFFFFF
8023 /* Generic function for performing the dump of a debug feature. */
8024 static enum dbg_status
qed_dbg_dump(struct qed_hwfn
*p_hwfn
,
8025 struct qed_ptt
*p_ptt
,
8026 enum qed_dbg_features feature_idx
)
8028 struct qed_dbg_feature
*feature
=
8029 &p_hwfn
->cdev
->dbg_features
[feature_idx
];
8030 u32 buf_size_dwords
, *dbuf
, *dwords
;
8033 DP_NOTICE(p_hwfn
->cdev
, "Collecting a debug feature [\"%s\"]\n",
8034 qed_features_lookup
[feature_idx
].name
);
8036 /* Dump_buf was already allocated need to free (this can happen if dump
8037 * was called but file was never read).
8038 * We can't use the buffer as is since size may have changed.
8040 if (feature
->dump_buf
) {
8041 vfree(feature
->dump_buf
);
8042 feature
->dump_buf
= NULL
;
8045 /* Get buffer size from hsi, allocate accordingly, and perform the
8048 rc
= qed_features_lookup
[feature_idx
].get_size(p_hwfn
, p_ptt
,
8050 if (rc
!= DBG_STATUS_OK
&& rc
!= DBG_STATUS_NVRAM_GET_IMAGE_FAILED
)
8053 if (buf_size_dwords
> MAX_DBG_FEATURE_SIZE_DWORDS
) {
8054 feature
->buf_size
= 0;
8055 DP_NOTICE(p_hwfn
->cdev
,
8056 "Debug feature [\"%s\"] size (0x%x dwords) exceeds maximum size (0x%x dwords)\n",
8057 qed_features_lookup
[feature_idx
].name
,
8058 buf_size_dwords
, MAX_DBG_FEATURE_SIZE_DWORDS
);
8060 return DBG_STATUS_OK
;
8063 feature
->buf_size
= buf_size_dwords
* sizeof(u32
);
8064 feature
->dump_buf
= vmalloc(feature
->buf_size
);
8065 if (!feature
->dump_buf
)
8066 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED
;
8068 dbuf
= (u32
*)feature
->dump_buf
;
8069 dwords
= &feature
->dumped_dwords
;
8070 rc
= qed_features_lookup
[feature_idx
].perform_dump(p_hwfn
, p_ptt
,
8076 /* If mcp is stuck we get DBG_STATUS_NVRAM_GET_IMAGE_FAILED error.
8077 * In this case the buffer holds valid binary data, but we won't able
8078 * to parse it (since parsing relies on data in NVRAM which is only
8079 * accessible when MFW is responsive). skip the formatting but return
8080 * success so that binary data is provided.
8082 if (rc
== DBG_STATUS_NVRAM_GET_IMAGE_FAILED
)
8083 return DBG_STATUS_OK
;
8085 if (rc
!= DBG_STATUS_OK
)
8089 rc
= format_feature(p_hwfn
, feature_idx
);
8093 int qed_dbg_grc(struct qed_dev
*cdev
, void *buffer
, u32
*num_dumped_bytes
)
8095 return qed_dbg_feature(cdev
, buffer
, DBG_FEATURE_GRC
, num_dumped_bytes
);
8098 int qed_dbg_grc_size(struct qed_dev
*cdev
)
8100 return qed_dbg_feature_size(cdev
, DBG_FEATURE_GRC
);
8103 int qed_dbg_idle_chk(struct qed_dev
*cdev
, void *buffer
, u32
*num_dumped_bytes
)
8105 return qed_dbg_feature(cdev
, buffer
, DBG_FEATURE_IDLE_CHK
,
8109 int qed_dbg_idle_chk_size(struct qed_dev
*cdev
)
8111 return qed_dbg_feature_size(cdev
, DBG_FEATURE_IDLE_CHK
);
8114 int qed_dbg_reg_fifo(struct qed_dev
*cdev
, void *buffer
, u32
*num_dumped_bytes
)
8116 return qed_dbg_feature(cdev
, buffer
, DBG_FEATURE_REG_FIFO
,
8120 int qed_dbg_reg_fifo_size(struct qed_dev
*cdev
)
8122 return qed_dbg_feature_size(cdev
, DBG_FEATURE_REG_FIFO
);
8125 int qed_dbg_igu_fifo(struct qed_dev
*cdev
, void *buffer
, u32
*num_dumped_bytes
)
8127 return qed_dbg_feature(cdev
, buffer
, DBG_FEATURE_IGU_FIFO
,
8131 int qed_dbg_igu_fifo_size(struct qed_dev
*cdev
)
8133 return qed_dbg_feature_size(cdev
, DBG_FEATURE_IGU_FIFO
);
8136 static int qed_dbg_nvm_image_length(struct qed_hwfn
*p_hwfn
,
8137 enum qed_nvm_images image_id
, u32
*length
)
8139 struct qed_nvm_image_att image_att
;
8143 rc
= qed_mcp_get_nvm_image_att(p_hwfn
, image_id
, &image_att
);
8147 *length
= image_att
.length
;
8152 static int qed_dbg_nvm_image(struct qed_dev
*cdev
, void *buffer
,
8153 u32
*num_dumped_bytes
,
8154 enum qed_nvm_images image_id
)
8156 struct qed_hwfn
*p_hwfn
=
8157 &cdev
->hwfns
[cdev
->engine_for_debug
];
8161 *num_dumped_bytes
= 0;
8162 rc
= qed_dbg_nvm_image_length(p_hwfn
, image_id
, &len_rounded
);
8166 DP_NOTICE(p_hwfn
->cdev
,
8167 "Collecting a debug feature [\"nvram image %d\"]\n",
8170 len_rounded
= roundup(len_rounded
, sizeof(u32
));
8171 rc
= qed_mcp_get_nvm_image(p_hwfn
, image_id
, buffer
, len_rounded
);
8175 /* QED_NVM_IMAGE_NVM_META image is not swapped like other images */
8176 if (image_id
!= QED_NVM_IMAGE_NVM_META
)
8177 cpu_to_be32_array((__force __be32
*)buffer
,
8178 (const u32
*)buffer
,
8179 len_rounded
/ sizeof(u32
));
8181 *num_dumped_bytes
= len_rounded
;
8186 int qed_dbg_protection_override(struct qed_dev
*cdev
, void *buffer
,
8187 u32
*num_dumped_bytes
)
8189 return qed_dbg_feature(cdev
, buffer
, DBG_FEATURE_PROTECTION_OVERRIDE
,
8193 int qed_dbg_protection_override_size(struct qed_dev
*cdev
)
8195 return qed_dbg_feature_size(cdev
, DBG_FEATURE_PROTECTION_OVERRIDE
);
8198 int qed_dbg_fw_asserts(struct qed_dev
*cdev
, void *buffer
,
8199 u32
*num_dumped_bytes
)
8201 return qed_dbg_feature(cdev
, buffer
, DBG_FEATURE_FW_ASSERTS
,
8205 int qed_dbg_fw_asserts_size(struct qed_dev
*cdev
)
8207 return qed_dbg_feature_size(cdev
, DBG_FEATURE_FW_ASSERTS
);
8210 int qed_dbg_ilt(struct qed_dev
*cdev
, void *buffer
, u32
*num_dumped_bytes
)
8212 return qed_dbg_feature(cdev
, buffer
, DBG_FEATURE_ILT
, num_dumped_bytes
);
8215 int qed_dbg_ilt_size(struct qed_dev
*cdev
)
8217 return qed_dbg_feature_size(cdev
, DBG_FEATURE_ILT
);
8220 int qed_dbg_mcp_trace(struct qed_dev
*cdev
, void *buffer
,
8221 u32
*num_dumped_bytes
)
8223 return qed_dbg_feature(cdev
, buffer
, DBG_FEATURE_MCP_TRACE
,
8227 int qed_dbg_mcp_trace_size(struct qed_dev
*cdev
)
8229 return qed_dbg_feature_size(cdev
, DBG_FEATURE_MCP_TRACE
);
8232 /* Defines the amount of bytes allocated for recording the length of debugfs
8235 #define REGDUMP_HEADER_SIZE sizeof(u32)
8236 #define REGDUMP_HEADER_SIZE_SHIFT 0
8237 #define REGDUMP_HEADER_SIZE_MASK 0xffffff
8238 #define REGDUMP_HEADER_FEATURE_SHIFT 24
8239 #define REGDUMP_HEADER_FEATURE_MASK 0x1f
8240 #define REGDUMP_HEADER_BIN_DUMP_SHIFT 29
8241 #define REGDUMP_HEADER_BIN_DUMP_MASK 0x1
8242 #define REGDUMP_HEADER_OMIT_ENGINE_SHIFT 30
8243 #define REGDUMP_HEADER_OMIT_ENGINE_MASK 0x1
8244 #define REGDUMP_HEADER_ENGINE_SHIFT 31
8245 #define REGDUMP_HEADER_ENGINE_MASK 0x1
8246 #define REGDUMP_MAX_SIZE 0x1000000
8247 #define ILT_DUMP_MAX_SIZE (1024 * 1024 * 15)
8249 enum debug_print_features
{
8255 PROTECTION_OVERRIDE
= 5,
8266 static u32
qed_calc_regdump_header(struct qed_dev
*cdev
,
8267 enum debug_print_features feature
,
8268 int engine
, u32 feature_size
,
8269 u8 omit_engine
, u8 dbg_bin_dump
)
8273 SET_FIELD(res
, REGDUMP_HEADER_SIZE
, feature_size
);
8274 if (res
!= feature_size
)
8276 "Feature %d is too large (size 0x%x) and will corrupt the dump\n",
8277 feature
, feature_size
);
8279 SET_FIELD(res
, REGDUMP_HEADER_FEATURE
, feature
);
8280 SET_FIELD(res
, REGDUMP_HEADER_BIN_DUMP
, dbg_bin_dump
);
8281 SET_FIELD(res
, REGDUMP_HEADER_OMIT_ENGINE
, omit_engine
);
8282 SET_FIELD(res
, REGDUMP_HEADER_ENGINE
, engine
);
8287 int qed_dbg_all_data(struct qed_dev
*cdev
, void *buffer
)
8289 u8 cur_engine
, omit_engine
= 0, org_engine
;
8290 struct qed_hwfn
*p_hwfn
= &cdev
->hwfns
[cdev
->engine_for_debug
];
8291 struct dbg_tools_data
*dev_data
= &p_hwfn
->dbg_info
;
8292 int grc_params
[MAX_DBG_GRC_PARAMS
], rc
, i
;
8293 u32 offset
= 0, feature_size
;
8295 for (i
= 0; i
< MAX_DBG_GRC_PARAMS
; i
++)
8296 grc_params
[i
] = dev_data
->grc
.param_val
[i
];
8298 if (!QED_IS_CMT(cdev
))
8301 cdev
->dbg_bin_dump
= 1;
8302 mutex_lock(&qed_dbg_lock
);
8304 org_engine
= qed_get_debug_engine(cdev
);
8305 for (cur_engine
= 0; cur_engine
< cdev
->num_hwfns
; cur_engine
++) {
8306 /* Collect idle_chks and grcDump for each hw function */
8307 DP_VERBOSE(cdev
, QED_MSG_DEBUG
,
8308 "obtaining idle_chk and grcdump for current engine\n");
8309 qed_set_debug_engine(cdev
, cur_engine
);
8311 /* First idle_chk */
8312 rc
= qed_dbg_idle_chk(cdev
, (u8
*)buffer
+ offset
+
8313 REGDUMP_HEADER_SIZE
, &feature_size
);
8315 *(u32
*)((u8
*)buffer
+ offset
) =
8316 qed_calc_regdump_header(cdev
, IDLE_CHK
,
8320 cdev
->dbg_bin_dump
);
8321 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8323 DP_ERR(cdev
, "qed_dbg_idle_chk failed. rc = %d\n", rc
);
8326 /* Second idle_chk */
8327 rc
= qed_dbg_idle_chk(cdev
, (u8
*)buffer
+ offset
+
8328 REGDUMP_HEADER_SIZE
, &feature_size
);
8330 *(u32
*)((u8
*)buffer
+ offset
) =
8331 qed_calc_regdump_header(cdev
, IDLE_CHK
,
8335 cdev
->dbg_bin_dump
);
8336 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8338 DP_ERR(cdev
, "qed_dbg_idle_chk failed. rc = %d\n", rc
);
8342 rc
= qed_dbg_reg_fifo(cdev
, (u8
*)buffer
+ offset
+
8343 REGDUMP_HEADER_SIZE
, &feature_size
);
8345 *(u32
*)((u8
*)buffer
+ offset
) =
8346 qed_calc_regdump_header(cdev
, REG_FIFO
,
8350 cdev
->dbg_bin_dump
);
8351 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8353 DP_ERR(cdev
, "qed_dbg_reg_fifo failed. rc = %d\n", rc
);
8357 rc
= qed_dbg_igu_fifo(cdev
, (u8
*)buffer
+ offset
+
8358 REGDUMP_HEADER_SIZE
, &feature_size
);
8360 *(u32
*)((u8
*)buffer
+ offset
) =
8361 qed_calc_regdump_header(cdev
, IGU_FIFO
,
8365 cdev
->dbg_bin_dump
);
8366 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8368 DP_ERR(cdev
, "qed_dbg_igu_fifo failed. rc = %d", rc
);
8371 /* protection_override dump */
8372 rc
= qed_dbg_protection_override(cdev
, (u8
*)buffer
+ offset
+
8373 REGDUMP_HEADER_SIZE
,
8376 *(u32
*)((u8
*)buffer
+ offset
) =
8377 qed_calc_regdump_header(cdev
,
8378 PROTECTION_OVERRIDE
,
8382 cdev
->dbg_bin_dump
);
8383 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8386 "qed_dbg_protection_override failed. rc = %d\n",
8390 /* fw_asserts dump */
8391 rc
= qed_dbg_fw_asserts(cdev
, (u8
*)buffer
+ offset
+
8392 REGDUMP_HEADER_SIZE
, &feature_size
);
8394 *(u32
*)((u8
*)buffer
+ offset
) =
8395 qed_calc_regdump_header(cdev
, FW_ASSERTS
,
8399 cdev
->dbg_bin_dump
);
8400 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8402 DP_ERR(cdev
, "qed_dbg_fw_asserts failed. rc = %d\n",
8406 feature_size
= qed_dbg_ilt_size(cdev
);
8407 if (!cdev
->disable_ilt_dump
&& feature_size
<
8408 ILT_DUMP_MAX_SIZE
) {
8409 rc
= qed_dbg_ilt(cdev
, (u8
*)buffer
+ offset
+
8410 REGDUMP_HEADER_SIZE
, &feature_size
);
8412 *(u32
*)((u8
*)buffer
+ offset
) =
8413 qed_calc_regdump_header(cdev
, ILT_DUMP
,
8417 cdev
->dbg_bin_dump
);
8418 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8420 DP_ERR(cdev
, "qed_dbg_ilt failed. rc = %d\n",
8425 /* Grc dump - must be last because when mcp stuck it will
8426 * clutter idle_chk, reg_fifo, ...
8428 for (i
= 0; i
< MAX_DBG_GRC_PARAMS
; i
++)
8429 dev_data
->grc
.param_val
[i
] = grc_params
[i
];
8431 rc
= qed_dbg_grc(cdev
, (u8
*)buffer
+ offset
+
8432 REGDUMP_HEADER_SIZE
, &feature_size
);
8434 *(u32
*)((u8
*)buffer
+ offset
) =
8435 qed_calc_regdump_header(cdev
, GRC_DUMP
,
8439 cdev
->dbg_bin_dump
);
8440 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8442 DP_ERR(cdev
, "qed_dbg_grc failed. rc = %d", rc
);
8446 qed_set_debug_engine(cdev
, org_engine
);
8449 rc
= qed_dbg_mcp_trace(cdev
, (u8
*)buffer
+ offset
+
8450 REGDUMP_HEADER_SIZE
, &feature_size
);
8452 *(u32
*)((u8
*)buffer
+ offset
) =
8453 qed_calc_regdump_header(cdev
, MCP_TRACE
, cur_engine
,
8454 feature_size
, omit_engine
,
8455 cdev
->dbg_bin_dump
);
8456 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8458 DP_ERR(cdev
, "qed_dbg_mcp_trace failed. rc = %d\n", rc
);
8462 rc
= qed_dbg_nvm_image(cdev
,
8463 (u8
*)buffer
+ offset
+
8464 REGDUMP_HEADER_SIZE
, &feature_size
,
8465 QED_NVM_IMAGE_NVM_CFG1
);
8467 *(u32
*)((u8
*)buffer
+ offset
) =
8468 qed_calc_regdump_header(cdev
, NVM_CFG1
, cur_engine
,
8469 feature_size
, omit_engine
,
8470 cdev
->dbg_bin_dump
);
8471 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8472 } else if (rc
!= -ENOENT
) {
8474 "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
8475 QED_NVM_IMAGE_NVM_CFG1
, "QED_NVM_IMAGE_NVM_CFG1",
8480 rc
= qed_dbg_nvm_image(cdev
,
8481 (u8
*)buffer
+ offset
+
8482 REGDUMP_HEADER_SIZE
, &feature_size
,
8483 QED_NVM_IMAGE_DEFAULT_CFG
);
8485 *(u32
*)((u8
*)buffer
+ offset
) =
8486 qed_calc_regdump_header(cdev
, DEFAULT_CFG
,
8487 cur_engine
, feature_size
,
8489 cdev
->dbg_bin_dump
);
8490 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8491 } else if (rc
!= -ENOENT
) {
8493 "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
8494 QED_NVM_IMAGE_DEFAULT_CFG
,
8495 "QED_NVM_IMAGE_DEFAULT_CFG", rc
);
8499 rc
= qed_dbg_nvm_image(cdev
,
8500 (u8
*)buffer
+ offset
+
8501 REGDUMP_HEADER_SIZE
, &feature_size
,
8502 QED_NVM_IMAGE_NVM_META
);
8504 *(u32
*)((u8
*)buffer
+ offset
) =
8505 qed_calc_regdump_header(cdev
, NVM_META
, cur_engine
,
8506 feature_size
, omit_engine
,
8507 cdev
->dbg_bin_dump
);
8508 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8509 } else if (rc
!= -ENOENT
) {
8511 "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
8512 QED_NVM_IMAGE_NVM_META
, "QED_NVM_IMAGE_NVM_META",
8517 rc
= qed_dbg_nvm_image(cdev
, (u8
*)buffer
+ offset
+
8518 REGDUMP_HEADER_SIZE
, &feature_size
,
8519 QED_NVM_IMAGE_MDUMP
);
8521 *(u32
*)((u8
*)buffer
+ offset
) =
8522 qed_calc_regdump_header(cdev
, MDUMP
, cur_engine
,
8523 feature_size
, omit_engine
,
8524 cdev
->dbg_bin_dump
);
8525 offset
+= (feature_size
+ REGDUMP_HEADER_SIZE
);
8526 } else if (rc
!= -ENOENT
) {
8528 "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
8529 QED_NVM_IMAGE_MDUMP
, "QED_NVM_IMAGE_MDUMP", rc
);
8532 mutex_unlock(&qed_dbg_lock
);
8533 cdev
->dbg_bin_dump
= 0;
8538 int qed_dbg_all_data_size(struct qed_dev
*cdev
)
8540 u32 regs_len
= 0, image_len
= 0, ilt_len
= 0, total_ilt_len
= 0;
8541 struct qed_hwfn
*p_hwfn
= &cdev
->hwfns
[cdev
->engine_for_debug
];
8542 u8 cur_engine
, org_engine
;
8544 cdev
->disable_ilt_dump
= false;
8545 org_engine
= qed_get_debug_engine(cdev
);
8546 for (cur_engine
= 0; cur_engine
< cdev
->num_hwfns
; cur_engine
++) {
8547 /* Engine specific */
8548 DP_VERBOSE(cdev
, QED_MSG_DEBUG
,
8549 "calculating idle_chk and grcdump register length for current engine\n");
8550 qed_set_debug_engine(cdev
, cur_engine
);
8551 regs_len
+= REGDUMP_HEADER_SIZE
+ qed_dbg_idle_chk_size(cdev
) +
8552 REGDUMP_HEADER_SIZE
+ qed_dbg_idle_chk_size(cdev
) +
8553 REGDUMP_HEADER_SIZE
+ qed_dbg_grc_size(cdev
) +
8554 REGDUMP_HEADER_SIZE
+ qed_dbg_reg_fifo_size(cdev
) +
8555 REGDUMP_HEADER_SIZE
+ qed_dbg_igu_fifo_size(cdev
) +
8556 REGDUMP_HEADER_SIZE
+
8557 qed_dbg_protection_override_size(cdev
) +
8558 REGDUMP_HEADER_SIZE
+ qed_dbg_fw_asserts_size(cdev
);
8559 ilt_len
= REGDUMP_HEADER_SIZE
+ qed_dbg_ilt_size(cdev
);
8560 if (ilt_len
< ILT_DUMP_MAX_SIZE
) {
8561 total_ilt_len
+= ilt_len
;
8562 regs_len
+= ilt_len
;
8566 qed_set_debug_engine(cdev
, org_engine
);
8569 regs_len
+= REGDUMP_HEADER_SIZE
+ qed_dbg_mcp_trace_size(cdev
) +
8570 REGDUMP_HEADER_SIZE
+ qed_dbg_phy_size(cdev
);
8571 qed_dbg_nvm_image_length(p_hwfn
, QED_NVM_IMAGE_NVM_CFG1
, &image_len
);
8573 regs_len
+= REGDUMP_HEADER_SIZE
+ image_len
;
8574 qed_dbg_nvm_image_length(p_hwfn
, QED_NVM_IMAGE_DEFAULT_CFG
, &image_len
);
8576 regs_len
+= REGDUMP_HEADER_SIZE
+ image_len
;
8577 qed_dbg_nvm_image_length(p_hwfn
, QED_NVM_IMAGE_NVM_META
, &image_len
);
8579 regs_len
+= REGDUMP_HEADER_SIZE
+ image_len
;
8580 qed_dbg_nvm_image_length(p_hwfn
, QED_NVM_IMAGE_MDUMP
, &image_len
);
8582 regs_len
+= REGDUMP_HEADER_SIZE
+ image_len
;
8584 if (regs_len
> REGDUMP_MAX_SIZE
) {
8585 DP_VERBOSE(cdev
, QED_MSG_DEBUG
,
8586 "Dump exceeds max size 0x%x, disable ILT dump\n",
8588 cdev
->disable_ilt_dump
= true;
8589 regs_len
-= total_ilt_len
;
8595 int qed_dbg_feature(struct qed_dev
*cdev
, void *buffer
,
8596 enum qed_dbg_features feature
, u32
*num_dumped_bytes
)
8598 struct qed_dbg_feature
*qed_feature
= &cdev
->dbg_features
[feature
];
8599 struct qed_hwfn
*p_hwfn
= &cdev
->hwfns
[cdev
->engine_for_debug
];
8600 enum dbg_status dbg_rc
;
8601 struct qed_ptt
*p_ptt
;
8605 p_ptt
= qed_ptt_acquire(p_hwfn
);
8610 dbg_rc
= qed_dbg_dump(p_hwfn
, p_ptt
, feature
);
8611 if (dbg_rc
!= DBG_STATUS_OK
) {
8612 DP_VERBOSE(cdev
, QED_MSG_DEBUG
, "%s\n",
8613 qed_dbg_get_status_str(dbg_rc
));
8614 *num_dumped_bytes
= 0;
8619 DP_VERBOSE(cdev
, QED_MSG_DEBUG
,
8620 "copying debugfs feature to external buffer\n");
8621 memcpy(buffer
, qed_feature
->dump_buf
, qed_feature
->buf_size
);
8622 *num_dumped_bytes
= cdev
->dbg_features
[feature
].dumped_dwords
*
8626 qed_ptt_release(p_hwfn
, p_ptt
);
8630 int qed_dbg_feature_size(struct qed_dev
*cdev
, enum qed_dbg_features feature
)
8632 struct qed_dbg_feature
*qed_feature
= &cdev
->dbg_features
[feature
];
8633 struct qed_hwfn
*p_hwfn
= &cdev
->hwfns
[cdev
->engine_for_debug
];
8634 struct qed_ptt
*p_ptt
= qed_ptt_acquire(p_hwfn
);
8635 u32 buf_size_dwords
;
8641 rc
= qed_features_lookup
[feature
].get_size(p_hwfn
, p_ptt
,
8643 if (rc
!= DBG_STATUS_OK
)
8644 buf_size_dwords
= 0;
8646 /* Feature will not be dumped if it exceeds maximum size */
8647 if (buf_size_dwords
> MAX_DBG_FEATURE_SIZE_DWORDS
)
8648 buf_size_dwords
= 0;
8650 qed_ptt_release(p_hwfn
, p_ptt
);
8651 qed_feature
->buf_size
= buf_size_dwords
* sizeof(u32
);
8652 return qed_feature
->buf_size
;
8655 int qed_dbg_phy_size(struct qed_dev
*cdev
)
8657 /* return max size of phy info and
8658 * phy mac_stat multiplied by the number of ports
8660 return MAX_PHY_RESULT_BUFFER
* (1 + qed_device_num_ports(cdev
));
8663 u8
qed_get_debug_engine(struct qed_dev
*cdev
)
8665 return cdev
->engine_for_debug
;
8668 void qed_set_debug_engine(struct qed_dev
*cdev
, int engine_number
)
8670 DP_VERBOSE(cdev
, QED_MSG_DEBUG
, "set debug engine to %d\n",
8672 cdev
->engine_for_debug
= engine_number
;
8675 void qed_dbg_pf_init(struct qed_dev
*cdev
)
8677 const u8
*dbg_values
= NULL
;
8680 /* Sync ver with debugbus qed code */
8681 qed_dbg_set_app_ver(TOOLS_VERSION
);
8683 /* Debug values are after init values.
8684 * The offset is the first dword of the file.
8686 dbg_values
= cdev
->firmware
->data
+ *(u32
*)cdev
->firmware
->data
;
8688 for_each_hwfn(cdev
, i
) {
8689 qed_dbg_set_bin_ptr(&cdev
->hwfns
[i
], dbg_values
);
8690 qed_dbg_user_set_bin_ptr(&cdev
->hwfns
[i
], dbg_values
);
8693 /* Set the hwfn to be 0 as default */
8694 cdev
->engine_for_debug
= 0;
8697 void qed_dbg_pf_exit(struct qed_dev
*cdev
)
8699 struct qed_dbg_feature
*feature
= NULL
;
8700 enum qed_dbg_features feature_idx
;
8702 /* debug features' buffers may be allocated if debug feature was used
8703 * but dump wasn't called
8705 for (feature_idx
= 0; feature_idx
< DBG_FEATURE_NUM
; feature_idx
++) {
8706 feature
= &cdev
->dbg_features
[feature_idx
];
8707 if (feature
->dump_buf
) {
8708 vfree(feature
->dump_buf
);
8709 feature
->dump_buf
= NULL
;