diff options
Diffstat (limited to 'drivers/net/ethernet/qlogic/qed/qed_debug.c')
| -rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_debug.c | 5993 |
1 files changed, 3338 insertions, 2655 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c b/drivers/net/ethernet/qlogic/qed/qed_debug.c index 03c3cf77aaff..1f0cea3cae92 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_debug.c +++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c @@ -1,16 +1,16 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) /* QLogic qed NIC Driver * Copyright (c) 2015 QLogic Corporation - * - * This software is available under the terms of the GNU General Public License - * (GPL) Version 2, available from the file COPYING in the main directory of - * this source tree. + * Copyright (c) 2019-2021 Marvell International Ltd. */ #include <linux/module.h> #include <linux/vmalloc.h> #include <linux/crc32.h> #include "qed.h" +#include "qed_cxt.h" #include "qed_hsi.h" +#include "qed_dbg_hsi.h" #include "qed_hw.h" #include "qed_mcp.h" #include "qed_reg_addr.h" @@ -21,11 +21,12 @@ enum mem_groups { MEM_GROUP_DMAE_MEM, MEM_GROUP_CM_MEM, MEM_GROUP_QM_MEM, - MEM_GROUP_TM_MEM, + MEM_GROUP_DORQ_MEM, MEM_GROUP_BRB_RAM, MEM_GROUP_BRB_MEM, MEM_GROUP_PRS_MEM, MEM_GROUP_SDM_MEM, + MEM_GROUP_PBUF, MEM_GROUP_IOR, MEM_GROUP_RAM, MEM_GROUP_BTB_RAM, @@ -33,11 +34,10 @@ enum mem_groups { MEM_GROUP_TDIF_CTX, MEM_GROUP_CFC_MEM, MEM_GROUP_CONN_CFC_MEM, - MEM_GROUP_TASK_CFC_MEM, MEM_GROUP_CAU_PI, MEM_GROUP_CAU_MEM, + MEM_GROUP_CAU_MEM_EXT, MEM_GROUP_PXP_ILT, - MEM_GROUP_PBUF, MEM_GROUP_MULD_MEM, MEM_GROUP_BTB_MEM, MEM_GROUP_IGU_MEM, @@ -45,6 +45,8 @@ enum mem_groups { MEM_GROUP_CAU_SB, MEM_GROUP_BMB_RAM, MEM_GROUP_BMB_MEM, + MEM_GROUP_TM_MEM, + MEM_GROUP_TASK_CFC_MEM, MEM_GROUPS_NUM }; @@ -54,11 +56,12 @@ static const char * const s_mem_group_names[] = { "DMAE_MEM", "CM_MEM", "QM_MEM", - "TM_MEM", + "DORQ_MEM", "BRB_RAM", "BRB_MEM", "PRS_MEM", "SDM_MEM", + "PBUF", "IOR", "RAM", "BTB_RAM", @@ -66,11 +69,10 @@ static const char * const s_mem_group_names[] = { "TDIF_CTX", "CFC_MEM", "CONN_CFC_MEM", - "TASK_CFC_MEM", "CAU_PI", "CAU_MEM", + "CAU_MEM_EXT", "PXP_ILT", - "PBUF", "MULD_MEM", "BTB_MEM", "IGU_MEM", @@ -78,6 +80,8 @@ static const char * const s_mem_group_names[] = { "CAU_SB", "BMB_RAM", "BMB_MEM", + "TM_MEM", + "TASK_CFC_MEM", }; /* Idle check conditions */ @@ -92,11 +96,6 @@ static u32 cond7(const u32 *r, const u32 *imm) return ((r[0] >> imm[0]) & imm[1]) != imm[2]; } -static u32 cond14(const u32 *r, const u32 *imm) -{ - return (r[0] != imm[0]) && (((r[1] >> imm[1]) & imm[2]) == imm[3]); -} - static u32 cond6(const u32 *r, const u32 *imm) { return (r[0] & imm[0]) != imm[1]; @@ -123,6 +122,11 @@ static u32 cond0(const u32 *r, const u32 *imm) return (r[0] & ~r[1]) != imm[0]; } +static u32 cond14(const u32 *r, const u32 *imm) +{ + return (r[0] | imm[0]) != imm[1]; +} + static u32 cond1(const u32 *r, const u32 *imm) { return r[0] != imm[0]; @@ -177,32 +181,109 @@ static u32(*cond_arr[]) (const u32 *r, const u32 *imm) = { cond14, }; +#define NUM_PHYS_BLOCKS 84 + +#define NUM_DBG_RESET_REGS 8 + /******************************* Data Types **********************************/ -enum platform_ids { - PLATFORM_ASIC, +enum hw_types { + HW_TYPE_ASIC, PLATFORM_RESERVED, PLATFORM_RESERVED2, PLATFORM_RESERVED3, - MAX_PLATFORM_IDS + PLATFORM_RESERVED4, + MAX_HW_TYPES +}; + +/* CM context types */ +enum cm_ctx_types { + CM_CTX_CONN_AG, + CM_CTX_CONN_ST, + CM_CTX_TASK_AG, + CM_CTX_TASK_ST, + NUM_CM_CTX_TYPES +}; + +/* Debug bus frame modes */ +enum dbg_bus_frame_modes { + DBG_BUS_FRAME_MODE_4ST = 0, /* 4 Storm dwords (no HW) */ + DBG_BUS_FRAME_MODE_2ST_2HW = 1, /* 2 Storm dwords, 2 HW dwords */ + DBG_BUS_FRAME_MODE_1ST_3HW = 2, /* 1 Storm dwords, 3 HW dwords */ + DBG_BUS_FRAME_MODE_4HW = 3, /* 4 HW dwords (no Storms) */ + DBG_BUS_FRAME_MODE_8HW = 4, /* 8 HW dwords (no Storms) */ + DBG_BUS_NUM_FRAME_MODES +}; + +/* Debug bus SEMI frame modes */ +enum dbg_bus_semi_frame_modes { + DBG_BUS_SEMI_FRAME_MODE_4FAST = 0, /* 4 fast dw */ + DBG_BUS_SEMI_FRAME_MODE_2FAST_2SLOW = 1, /* 2 fast dw, 2 slow dw */ + DBG_BUS_SEMI_FRAME_MODE_1FAST_3SLOW = 2, /* 1 fast dw,3 slow dw */ + DBG_BUS_SEMI_FRAME_MODE_4SLOW = 3, /* 4 slow dw */ + DBG_BUS_SEMI_NUM_FRAME_MODES +}; + +/* Debug bus filter types */ +enum dbg_bus_filter_types { + DBG_BUS_FILTER_TYPE_OFF, /* Filter always off */ + DBG_BUS_FILTER_TYPE_PRE, /* Filter before trigger only */ + DBG_BUS_FILTER_TYPE_POST, /* Filter after trigger only */ + DBG_BUS_FILTER_TYPE_ON /* Filter always on */ +}; + +/* Debug bus pre-trigger recording types */ +enum dbg_bus_pre_trigger_types { + DBG_BUS_PRE_TRIGGER_FROM_ZERO, /* Record from time 0 */ + DBG_BUS_PRE_TRIGGER_NUM_CHUNKS, /* Record some chunks before trigger */ + DBG_BUS_PRE_TRIGGER_DROP /* Drop data before trigger */ +}; + +/* Debug bus post-trigger recording types */ +enum dbg_bus_post_trigger_types { + DBG_BUS_POST_TRIGGER_RECORD, /* Start recording after trigger */ + DBG_BUS_POST_TRIGGER_DROP /* Drop data after trigger */ +}; + +/* Debug bus other engine mode */ +enum dbg_bus_other_engine_modes { + DBG_BUS_OTHER_ENGINE_MODE_NONE, + DBG_BUS_OTHER_ENGINE_MODE_DOUBLE_BW_TX, + DBG_BUS_OTHER_ENGINE_MODE_DOUBLE_BW_RX, + DBG_BUS_OTHER_ENGINE_MODE_CROSS_ENGINE_TX, + DBG_BUS_OTHER_ENGINE_MODE_CROSS_ENGINE_RX }; -struct chip_platform_defs { - u8 num_ports; - u8 num_pfs; - u8 num_vfs; +/* DBG block Framing mode definitions */ +struct framing_mode_defs { + u8 id; + u8 blocks_dword_mask; + u8 storms_dword_mask; + u8 semi_framing_mode_id; + u8 full_buf_thr; }; /* Chip constant definitions */ struct chip_defs { const char *name; - struct chip_platform_defs per_platform[MAX_PLATFORM_IDS]; + u8 dwords_per_cycle; + u8 num_framing_modes; + u32 num_ilt_pages; + struct framing_mode_defs *framing_modes; }; -/* Platform constant definitions */ -struct platform_defs { +/* HW type constant definitions */ +struct hw_type_defs { const char *name; u32 delay_factor; + u32 dmae_thresh; + u32 log_thresh; +}; + +/* RBC reset definitions */ +struct rbc_reset_defs { + u32 reset_reg_addr; + u32 reset_val[MAX_CHIP_IDS]; }; /* Storm constant definitions. @@ -210,7 +291,7 @@ struct platform_defs { */ struct storm_defs { char letter; - enum block_id block_id; + enum block_id sem_block_id; enum dbg_bus_clients dbg_client_id[MAX_CHIP_IDS]; bool has_vfc; u32 sem_fast_mem_addr; @@ -219,46 +300,25 @@ struct storm_defs { u32 sem_slow_mode_addr; u32 sem_slow_mode1_conf_addr; u32 sem_sync_dbg_empty_addr; - u32 sem_slow_dbg_empty_addr; + u32 sem_gpre_vect_addr; u32 cm_ctx_wr_addr; - u32 cm_conn_ag_ctx_lid_size; - u32 cm_conn_ag_ctx_rd_addr; - u32 cm_conn_st_ctx_lid_size; - u32 cm_conn_st_ctx_rd_addr; - u32 cm_task_ag_ctx_lid_size; - u32 cm_task_ag_ctx_rd_addr; - u32 cm_task_st_ctx_lid_size; - u32 cm_task_st_ctx_rd_addr; + u32 cm_ctx_rd_addr[NUM_CM_CTX_TYPES]; + u32 cm_ctx_lid_sizes[MAX_CHIP_IDS][NUM_CM_CTX_TYPES]; }; -/* Block constant definitions */ -struct block_defs { - const char *name; - bool has_dbg_bus[MAX_CHIP_IDS]; - bool associated_to_storm; - - /* Valid only if associated_to_storm is true */ - u32 storm_id; - enum dbg_bus_clients dbg_client_id[MAX_CHIP_IDS]; - u32 dbg_select_addr; - u32 dbg_enable_addr; - u32 dbg_shift_addr; - u32 dbg_force_valid_addr; - u32 dbg_force_frame_addr; - bool has_reset_bit; - - /* If true, block is taken out of reset before dump */ - bool unreset; - enum dbg_reset_regs reset_reg; - - /* Bit offset in reset register */ - u8 reset_bit_offset; +/* Debug Bus Constraint operation constant definitions */ +struct dbg_bus_constraint_op_defs { + u8 hw_op_val; + bool is_cyclic; }; -/* Reset register definitions */ -struct reset_reg_defs { - u32 addr; - u32 unreset_val; +/* Storm Mode definitions */ +struct storm_mode_defs { + const char *name; + bool is_fast_dbg; + u8 id_in_hw; + u32 src_disable_reg_addr; + u32 src_enable_val; bool exists[MAX_CHIP_IDS]; }; @@ -267,8 +327,9 @@ struct grc_param_defs { u32 min; u32 max; bool is_preset; + bool is_persistent; u32 exclude_all_preset_val; - u32 crash_preset_val; + u32 crash_preset_val[MAX_CHIP_IDS]; }; /* Address is in 128b units. Width is in bits. */ @@ -276,8 +337,8 @@ struct rss_mem_defs { const char *mem_name; const char *type_name; u32 addr; + u32 entry_width; u32 num_entries[MAX_CHIP_IDS]; - u32 entry_width[MAX_CHIP_IDS]; }; struct vfc_ram_defs { @@ -294,7 +355,9 @@ struct big_ram_defs { enum dbg_grc_params grc_param; u32 addr_reg_addr; u32 data_reg_addr; - u32 num_of_blocks[MAX_CHIP_IDS]; + u32 is_256b_reg_addr; + u32 is_256b_bit_offset[MAX_CHIP_IDS]; + u32 ram_size[MAX_CHIP_IDS]; /* In dwords */ }; struct phy_defs { @@ -316,23 +379,20 @@ struct phy_defs { u32 tbus_data_hi_addr; }; -/******************************** Constants **********************************/ - -#define MAX_LCIDS 320 -#define MAX_LTIDS 320 +/* Split type definitions */ +struct split_type_defs { + const char *name; +}; -#define NUM_IOR_SETS 2 -#define IORS_PER_SET 176 -#define IOR_SET_OFFSET(set_id) ((set_id) * 256) +/******************************** Constants **********************************/ #define BYTES_IN_DWORD sizeof(u32) - /* In the macros below, size and offset are specified in bits */ #define CEIL_DWORDS(size) DIV_ROUND_UP(size, 32) #define FIELD_BIT_OFFSET(type, field) type ## _ ## field ## _ ## OFFSET #define FIELD_BIT_SIZE(type, field) type ## _ ## field ## _ ## SIZE #define FIELD_DWORD_OFFSET(type, field) \ - (int)(FIELD_BIT_OFFSET(type, field) / 32) + ((int)(FIELD_BIT_OFFSET(type, field) / 32)) #define FIELD_DWORD_SHIFT(type, field) (FIELD_BIT_OFFSET(type, field) % 32) #define FIELD_BIT_MASK(type, field) \ (((1 << FIELD_BIT_SIZE(type, field)) - 1) << \ @@ -352,26 +412,17 @@ struct phy_defs { qed_wr(dev, ptt, addr, (arr)[i]); \ } while (0) -#define ARR_REG_RD(dev, ptt, addr, arr, arr_size) \ - do { \ - for (i = 0; i < (arr_size); i++) \ - (arr)[i] = qed_rd(dev, ptt, addr); \ - } while (0) - -#ifndef DWORDS_TO_BYTES #define DWORDS_TO_BYTES(dwords) ((dwords) * BYTES_IN_DWORD) -#endif -#ifndef BYTES_TO_DWORDS #define BYTES_TO_DWORDS(bytes) ((bytes) / BYTES_IN_DWORD) -#endif /* extra lines include a signature line + optional latency events line */ -#ifndef NUM_DBG_LINES -#define NUM_EXTRA_DBG_LINES(block_desc) \ - (1 + ((block_desc)->has_latency_events ? 1 : 0)) -#define NUM_DBG_LINES(block_desc) \ - ((block_desc)->num_of_lines + NUM_EXTRA_DBG_LINES(block_desc)) -#endif +#define NUM_EXTRA_DBG_LINES(block) \ + (GET_FIELD((block)->flags, DBG_BLOCK_CHIP_HAS_LATENCY_EVENTS) ? 2 : 1) +#define NUM_DBG_LINES(block) \ + ((block)->num_of_dbg_bus_lines + NUM_EXTRA_DBG_LINES(block)) + +#define USE_DMAE true +#define PROTECT_WIDE_BUS true #define RAM_LINES_TO_DWORDS(lines) ((lines) * 2) #define RAM_LINES_TO_BYTES(lines) \ @@ -390,6 +441,9 @@ struct phy_defs { #define IDLE_CHK_RESULT_REG_HDR_DWORDS \ BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_reg_hdr)) +#define PAGE_MEM_DESC_SIZE_DWORDS \ + BYTES_TO_DWORDS(sizeof(struct phys_mem_desc)) + #define IDLE_CHK_MAX_ENTRIES_SIZE 32 /* The sizes and offsets below are specified in bits */ @@ -424,9 +478,7 @@ struct phy_defs { #define NUM_RSS_MEM_TYPES 5 #define NUM_BIG_RAM_TYPES 3 -#define BIG_RAM_BLOCK_SIZE_BYTES 128 -#define BIG_RAM_BLOCK_SIZE_DWORDS \ - BYTES_TO_DWORDS(BIG_RAM_BLOCK_SIZE_BYTES) +#define BIG_RAM_NAME_LEN 3 #define NUM_PHY_TBUS_ADDRESSES 2048 #define PHY_DUMP_SIZE_DWORDS (NUM_PHY_TBUS_ADDRESSES / 2) @@ -437,27 +489,25 @@ struct phy_defs { #define STATIC_DEBUG_LINE_DWORDS 9 -#define NUM_COMMON_GLOBAL_PARAMS 8 +#define NUM_COMMON_GLOBAL_PARAMS 10 + +#define MAX_RECURSION_DEPTH 10 +#define FW_IMG_KUKU 0 #define FW_IMG_MAIN 1 +#define FW_IMG_L2B 2 -#ifndef REG_FIFO_ELEMENT_DWORDS #define REG_FIFO_ELEMENT_DWORDS 2 -#endif #define REG_FIFO_DEPTH_ELEMENTS 32 #define REG_FIFO_DEPTH_DWORDS \ (REG_FIFO_ELEMENT_DWORDS * REG_FIFO_DEPTH_ELEMENTS) -#ifndef IGU_FIFO_ELEMENT_DWORDS #define IGU_FIFO_ELEMENT_DWORDS 4 -#endif #define IGU_FIFO_DEPTH_ELEMENTS 64 #define IGU_FIFO_DEPTH_DWORDS \ (IGU_FIFO_ELEMENT_DWORDS * IGU_FIFO_DEPTH_ELEMENTS) -#ifndef PROTECTION_OVERRIDE_ELEMENT_DWORDS #define PROTECTION_OVERRIDE_ELEMENT_DWORDS 2 -#endif #define PROTECTION_OVERRIDE_DEPTH_ELEMENTS 20 #define PROTECTION_OVERRIDE_DEPTH_DWORDS \ (PROTECTION_OVERRIDE_DEPTH_ELEMENTS * \ @@ -467,1177 +517,298 @@ struct phy_defs { (MCP_REG_SCRATCH + \ offsetof(struct static_init, sections[SPAD_SECTION_TRACE])) +#define MAX_SW_PLTAFORM_STR_SIZE 64 + #define EMPTY_FW_VERSION_STR "???_???_???_???" #define EMPTY_FW_IMAGE_STR "???????????????" /***************************** Constant Arrays *******************************/ -struct dbg_array { - const u32 *ptr; - u32 size_in_dwords; +/* DBG block framing mode definitions, in descending preference order */ +static struct framing_mode_defs s_framing_mode_defs[4] = { + {DBG_BUS_FRAME_MODE_4ST, 0x0, 0xf, + DBG_BUS_SEMI_FRAME_MODE_4FAST, + 10}, + {DBG_BUS_FRAME_MODE_4HW, 0xf, 0x0, DBG_BUS_SEMI_FRAME_MODE_4SLOW, + 10}, + {DBG_BUS_FRAME_MODE_2ST_2HW, 0x3, 0xc, + DBG_BUS_SEMI_FRAME_MODE_2FAST_2SLOW, 10}, + {DBG_BUS_FRAME_MODE_1ST_3HW, 0x7, 0x8, + DBG_BUS_SEMI_FRAME_MODE_1FAST_3SLOW, 10} }; -/* Debug arrays */ -static struct dbg_array s_dbg_arrays[MAX_BIN_DBG_BUFFER_TYPE] = { {NULL} }; - /* Chip constant definitions array */ static struct chip_defs s_chip_defs[MAX_CHIP_IDS] = { - { "bb", - {{MAX_NUM_PORTS_BB, MAX_NUM_PFS_BB, MAX_NUM_VFS_BB}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0} } }, - { "ah", - {{MAX_NUM_PORTS_K2, MAX_NUM_PFS_K2, MAX_NUM_VFS_K2}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0} } } + {"bb", 4, DBG_BUS_NUM_FRAME_MODES, PSWRQ2_REG_ILT_MEMORY_SIZE_BB / 2, + s_framing_mode_defs}, + {"ah", 4, DBG_BUS_NUM_FRAME_MODES, PSWRQ2_REG_ILT_MEMORY_SIZE_K2 / 2, + s_framing_mode_defs} }; /* Storm constant definitions array */ static struct storm_defs s_storm_defs[] = { /* Tstorm */ {'T', BLOCK_TSEM, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT}, true, - TSEM_REG_FAST_MEMORY, - TSEM_REG_DBG_FRAME_MODE_BB_K2, TSEM_REG_SLOW_DBG_ACTIVE_BB_K2, - TSEM_REG_SLOW_DBG_MODE_BB_K2, TSEM_REG_DBG_MODE1_CFG_BB_K2, - TSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_SLOW_DBG_EMPTY_BB_K2, - TCM_REG_CTX_RBC_ACCS, - 4, TCM_REG_AGG_CON_CTX, - 16, TCM_REG_SM_CON_CTX, - 2, TCM_REG_AGG_TASK_CTX, - 4, TCM_REG_SM_TASK_CTX}, + {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT}, + true, + TSEM_REG_FAST_MEMORY, + TSEM_REG_DBG_FRAME_MODE, TSEM_REG_SLOW_DBG_ACTIVE, + TSEM_REG_SLOW_DBG_MODE, TSEM_REG_DBG_MODE1_CFG, + TSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_DBG_GPRE_VECT, + TCM_REG_CTX_RBC_ACCS, + {TCM_REG_AGG_CON_CTX, TCM_REG_SM_CON_CTX, TCM_REG_AGG_TASK_CTX, + TCM_REG_SM_TASK_CTX}, + {{4, 16, 2, 4}, {4, 16, 2, 4}} /* {bb} {k2} */ + }, /* Mstorm */ {'M', BLOCK_MSEM, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM}, false, - MSEM_REG_FAST_MEMORY, - MSEM_REG_DBG_FRAME_MODE_BB_K2, MSEM_REG_SLOW_DBG_ACTIVE_BB_K2, - MSEM_REG_SLOW_DBG_MODE_BB_K2, MSEM_REG_DBG_MODE1_CFG_BB_K2, - MSEM_REG_SYNC_DBG_EMPTY, MSEM_REG_SLOW_DBG_EMPTY_BB_K2, - MCM_REG_CTX_RBC_ACCS, - 1, MCM_REG_AGG_CON_CTX, - 10, MCM_REG_SM_CON_CTX, - 2, MCM_REG_AGG_TASK_CTX, - 7, MCM_REG_SM_TASK_CTX}, + {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM}, + false, + MSEM_REG_FAST_MEMORY, + MSEM_REG_DBG_FRAME_MODE, + MSEM_REG_SLOW_DBG_ACTIVE, + MSEM_REG_SLOW_DBG_MODE, + MSEM_REG_DBG_MODE1_CFG, + MSEM_REG_SYNC_DBG_EMPTY, + MSEM_REG_DBG_GPRE_VECT, + MCM_REG_CTX_RBC_ACCS, + {MCM_REG_AGG_CON_CTX, MCM_REG_SM_CON_CTX, MCM_REG_AGG_TASK_CTX, + MCM_REG_SM_TASK_CTX }, + {{1, 10, 2, 7}, {1, 10, 2, 7}} /* {bb} {k2}*/ + }, /* Ustorm */ {'U', BLOCK_USEM, - {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU}, false, - USEM_REG_FAST_MEMORY, - USEM_REG_DBG_FRAME_MODE_BB_K2, USEM_REG_SLOW_DBG_ACTIVE_BB_K2, - USEM_REG_SLOW_DBG_MODE_BB_K2, USEM_REG_DBG_MODE1_CFG_BB_K2, - USEM_REG_SYNC_DBG_EMPTY, USEM_REG_SLOW_DBG_EMPTY_BB_K2, - UCM_REG_CTX_RBC_ACCS, - 2, UCM_REG_AGG_CON_CTX, - 13, UCM_REG_SM_CON_CTX, - 3, UCM_REG_AGG_TASK_CTX, - 3, UCM_REG_SM_TASK_CTX}, + {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU}, + false, + USEM_REG_FAST_MEMORY, + USEM_REG_DBG_FRAME_MODE, + USEM_REG_SLOW_DBG_ACTIVE, + USEM_REG_SLOW_DBG_MODE, + USEM_REG_DBG_MODE1_CFG, + USEM_REG_SYNC_DBG_EMPTY, + USEM_REG_DBG_GPRE_VECT, + UCM_REG_CTX_RBC_ACCS, + {UCM_REG_AGG_CON_CTX, UCM_REG_SM_CON_CTX, UCM_REG_AGG_TASK_CTX, + UCM_REG_SM_TASK_CTX}, + {{2, 13, 3, 3}, {2, 13, 3, 3}} /* {bb} {k2} */ + }, /* Xstorm */ {'X', BLOCK_XSEM, - {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX}, false, - XSEM_REG_FAST_MEMORY, - XSEM_REG_DBG_FRAME_MODE_BB_K2, XSEM_REG_SLOW_DBG_ACTIVE_BB_K2, - XSEM_REG_SLOW_DBG_MODE_BB_K2, XSEM_REG_DBG_MODE1_CFG_BB_K2, - XSEM_REG_SYNC_DBG_EMPTY, XSEM_REG_SLOW_DBG_EMPTY_BB_K2, - XCM_REG_CTX_RBC_ACCS, - 9, XCM_REG_AGG_CON_CTX, - 15, XCM_REG_SM_CON_CTX, - 0, 0, - 0, 0}, + {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX}, + false, + XSEM_REG_FAST_MEMORY, + XSEM_REG_DBG_FRAME_MODE, + XSEM_REG_SLOW_DBG_ACTIVE, + XSEM_REG_SLOW_DBG_MODE, + XSEM_REG_DBG_MODE1_CFG, + XSEM_REG_SYNC_DBG_EMPTY, + XSEM_REG_DBG_GPRE_VECT, + XCM_REG_CTX_RBC_ACCS, + {XCM_REG_AGG_CON_CTX, XCM_REG_SM_CON_CTX, 0, 0}, + {{9, 15, 0, 0}, {9, 15, 0, 0}} /* {bb} {k2} */ + }, /* Ystorm */ {'Y', BLOCK_YSEM, - {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY}, false, - YSEM_REG_FAST_MEMORY, - YSEM_REG_DBG_FRAME_MODE_BB_K2, YSEM_REG_SLOW_DBG_ACTIVE_BB_K2, - YSEM_REG_SLOW_DBG_MODE_BB_K2, YSEM_REG_DBG_MODE1_CFG_BB_K2, - YSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_SLOW_DBG_EMPTY_BB_K2, - YCM_REG_CTX_RBC_ACCS, - 2, YCM_REG_AGG_CON_CTX, - 3, YCM_REG_SM_CON_CTX, - 2, YCM_REG_AGG_TASK_CTX, - 12, YCM_REG_SM_TASK_CTX}, + {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY}, + false, + YSEM_REG_FAST_MEMORY, + YSEM_REG_DBG_FRAME_MODE, + YSEM_REG_SLOW_DBG_ACTIVE, + YSEM_REG_SLOW_DBG_MODE, + YSEM_REG_DBG_MODE1_CFG, + YSEM_REG_SYNC_DBG_EMPTY, + YSEM_REG_DBG_GPRE_VECT, + YCM_REG_CTX_RBC_ACCS, + {YCM_REG_AGG_CON_CTX, YCM_REG_SM_CON_CTX, YCM_REG_AGG_TASK_CTX, + YCM_REG_SM_TASK_CTX}, + {{2, 3, 2, 12}, {2, 3, 2, 12}} /* {bb} {k2} */ + }, /* Pstorm */ {'P', BLOCK_PSEM, - {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS}, true, - PSEM_REG_FAST_MEMORY, - PSEM_REG_DBG_FRAME_MODE_BB_K2, PSEM_REG_SLOW_DBG_ACTIVE_BB_K2, - PSEM_REG_SLOW_DBG_MODE_BB_K2, PSEM_REG_DBG_MODE1_CFG_BB_K2, - PSEM_REG_SYNC_DBG_EMPTY, PSEM_REG_SLOW_DBG_EMPTY_BB_K2, - PCM_REG_CTX_RBC_ACCS, - 0, 0, - 10, PCM_REG_SM_CON_CTX, - 0, 0, - 0, 0} -}; - -/* Block definitions array */ - -static struct block_defs block_grc_defs = { - "grc", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCN, DBG_BUS_CLIENT_RBCN}, - GRC_REG_DBG_SELECT, GRC_REG_DBG_DWORD_ENABLE, - GRC_REG_DBG_SHIFT, GRC_REG_DBG_FORCE_VALID, - GRC_REG_DBG_FORCE_FRAME, - true, false, DBG_RESET_REG_MISC_PL_UA, 1 -}; - -static struct block_defs block_miscs_defs = { - "miscs", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_misc_defs = { - "misc", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_dbu_defs = { - "dbu", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_pglue_b_defs = { - "pglue_b", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCH, DBG_BUS_CLIENT_RBCH}, - PGLUE_B_REG_DBG_SELECT, PGLUE_B_REG_DBG_DWORD_ENABLE, - PGLUE_B_REG_DBG_SHIFT, PGLUE_B_REG_DBG_FORCE_VALID, - PGLUE_B_REG_DBG_FORCE_FRAME, - true, false, DBG_RESET_REG_MISCS_PL_HV, 1 -}; - -static struct block_defs block_cnig_defs = { - "cnig", - {false, true}, false, 0, - {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCW}, - CNIG_REG_DBG_SELECT_K2, CNIG_REG_DBG_DWORD_ENABLE_K2, - CNIG_REG_DBG_SHIFT_K2, CNIG_REG_DBG_FORCE_VALID_K2, - CNIG_REG_DBG_FORCE_FRAME_K2, - true, false, DBG_RESET_REG_MISCS_PL_HV, 0 -}; - -static struct block_defs block_cpmu_defs = { - "cpmu", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - true, false, DBG_RESET_REG_MISCS_PL_HV, 8 -}; - -static struct block_defs block_ncsi_defs = { - "ncsi", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCZ}, - NCSI_REG_DBG_SELECT, NCSI_REG_DBG_DWORD_ENABLE, - NCSI_REG_DBG_SHIFT, NCSI_REG_DBG_FORCE_VALID, - NCSI_REG_DBG_FORCE_FRAME, - true, false, DBG_RESET_REG_MISCS_PL_HV, 5 -}; - -static struct block_defs block_opte_defs = { - "opte", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - true, false, DBG_RESET_REG_MISCS_PL_HV, 4 -}; - -static struct block_defs block_bmb_defs = { - "bmb", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCB}, - BMB_REG_DBG_SELECT, BMB_REG_DBG_DWORD_ENABLE, - BMB_REG_DBG_SHIFT, BMB_REG_DBG_FORCE_VALID, - BMB_REG_DBG_FORCE_FRAME, - true, false, DBG_RESET_REG_MISCS_PL_UA, 7 -}; - -static struct block_defs block_pcie_defs = { - "pcie", - {false, true}, false, 0, - {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH}, - PCIE_REG_DBG_COMMON_SELECT_K2, - PCIE_REG_DBG_COMMON_DWORD_ENABLE_K2, - PCIE_REG_DBG_COMMON_SHIFT_K2, - PCIE_REG_DBG_COMMON_FORCE_VALID_K2, - PCIE_REG_DBG_COMMON_FORCE_FRAME_K2, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_mcp_defs = { - "mcp", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_mcp2_defs = { - "mcp2", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCZ}, - MCP2_REG_DBG_SELECT, MCP2_REG_DBG_DWORD_ENABLE, - MCP2_REG_DBG_SHIFT, MCP2_REG_DBG_FORCE_VALID, - MCP2_REG_DBG_FORCE_FRAME, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_pswhst_defs = { - "pswhst", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP}, - PSWHST_REG_DBG_SELECT, PSWHST_REG_DBG_DWORD_ENABLE, - PSWHST_REG_DBG_SHIFT, PSWHST_REG_DBG_FORCE_VALID, - PSWHST_REG_DBG_FORCE_FRAME, - true, false, DBG_RESET_REG_MISC_PL_HV, 0 -}; - -static struct block_defs block_pswhst2_defs = { - "pswhst2", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP}, - PSWHST2_REG_DBG_SELECT, PSWHST2_REG_DBG_DWORD_ENABLE, - PSWHST2_REG_DBG_SHIFT, PSWHST2_REG_DBG_FORCE_VALID, - PSWHST2_REG_DBG_FORCE_FRAME, - true, false, DBG_RESET_REG_MISC_PL_HV, 0 -}; - -static struct block_defs block_pswrd_defs = { - "pswrd", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP}, - PSWRD_REG_DBG_SELECT, PSWRD_REG_DBG_DWORD_ENABLE, - PSWRD_REG_DBG_SHIFT, PSWRD_REG_DBG_FORCE_VALID, - PSWRD_REG_DBG_FORCE_FRAME, - true, false, DBG_RESET_REG_MISC_PL_HV, 2 -}; - -static struct block_defs block_pswrd2_defs = { - "pswrd2", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP}, - PSWRD2_REG_DBG_SELECT, PSWRD2_REG_DBG_DWORD_ENABLE, - PSWRD2_REG_DBG_SHIFT, PSWRD2_REG_DBG_FORCE_VALID, - PSWRD2_REG_DBG_FORCE_FRAME, - true, false, DBG_RESET_REG_MISC_PL_HV, 2 -}; - -static struct block_defs block_pswwr_defs = { - "pswwr", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP}, - PSWWR_REG_DBG_SELECT, PSWWR_REG_DBG_DWORD_ENABLE, - PSWWR_REG_DBG_SHIFT, PSWWR_REG_DBG_FORCE_VALID, - PSWWR_REG_DBG_FORCE_FRAME, - true, false, DBG_RESET_REG_MISC_PL_HV, 3 -}; - -static struct block_defs block_pswwr2_defs = { - "pswwr2", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - true, false, DBG_RESET_REG_MISC_PL_HV, 3 -}; - -static struct block_defs block_pswrq_defs = { - "pswrq", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP}, - PSWRQ_REG_DBG_SELECT, PSWRQ_REG_DBG_DWORD_ENABLE, - PSWRQ_REG_DBG_SHIFT, PSWRQ_REG_DBG_FORCE_VALID, - PSWRQ_REG_DBG_FORCE_FRAME, - true, false, DBG_RESET_REG_MISC_PL_HV, 1 -}; - -static struct block_defs block_pswrq2_defs = { - "pswrq2", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP}, - PSWRQ2_REG_DBG_SELECT, PSWRQ2_REG_DBG_DWORD_ENABLE, - PSWRQ2_REG_DBG_SHIFT, PSWRQ2_REG_DBG_FORCE_VALID, - PSWRQ2_REG_DBG_FORCE_FRAME, - true, false, DBG_RESET_REG_MISC_PL_HV, 1 -}; - -static struct block_defs block_pglcs_defs = { - "pglcs", - {false, true}, false, 0, - {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH}, - PGLCS_REG_DBG_SELECT_K2, PGLCS_REG_DBG_DWORD_ENABLE_K2, - PGLCS_REG_DBG_SHIFT_K2, PGLCS_REG_DBG_FORCE_VALID_K2, - PGLCS_REG_DBG_FORCE_FRAME_K2, - true, false, DBG_RESET_REG_MISCS_PL_HV, 2 -}; - -static struct block_defs block_ptu_defs = { - "ptu", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP}, - PTU_REG_DBG_SELECT, PTU_REG_DBG_DWORD_ENABLE, - PTU_REG_DBG_SHIFT, PTU_REG_DBG_FORCE_VALID, - PTU_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 20 -}; - -static struct block_defs block_dmae_defs = { - "dmae", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP}, - DMAE_REG_DBG_SELECT, DMAE_REG_DBG_DWORD_ENABLE, - DMAE_REG_DBG_SHIFT, DMAE_REG_DBG_FORCE_VALID, - DMAE_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 28 -}; - -static struct block_defs block_tcm_defs = { - "tcm", - {true, true}, true, DBG_TSTORM_ID, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT}, - TCM_REG_DBG_SELECT, TCM_REG_DBG_DWORD_ENABLE, - TCM_REG_DBG_SHIFT, TCM_REG_DBG_FORCE_VALID, - TCM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 5 -}; - -static struct block_defs block_mcm_defs = { - "mcm", - {true, true}, true, DBG_MSTORM_ID, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM}, - MCM_REG_DBG_SELECT, MCM_REG_DBG_DWORD_ENABLE, - MCM_REG_DBG_SHIFT, MCM_REG_DBG_FORCE_VALID, - MCM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 3 -}; - -static struct block_defs block_ucm_defs = { - "ucm", - {true, true}, true, DBG_USTORM_ID, - {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU}, - UCM_REG_DBG_SELECT, UCM_REG_DBG_DWORD_ENABLE, - UCM_REG_DBG_SHIFT, UCM_REG_DBG_FORCE_VALID, - UCM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 8 -}; - -static struct block_defs block_xcm_defs = { - "xcm", - {true, true}, true, DBG_XSTORM_ID, - {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX}, - XCM_REG_DBG_SELECT, XCM_REG_DBG_DWORD_ENABLE, - XCM_REG_DBG_SHIFT, XCM_REG_DBG_FORCE_VALID, - XCM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 19 -}; - -static struct block_defs block_ycm_defs = { - "ycm", - {true, true}, true, DBG_YSTORM_ID, - {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY}, - YCM_REG_DBG_SELECT, YCM_REG_DBG_DWORD_ENABLE, - YCM_REG_DBG_SHIFT, YCM_REG_DBG_FORCE_VALID, - YCM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 5 -}; - -static struct block_defs block_pcm_defs = { - "pcm", - {true, true}, true, DBG_PSTORM_ID, - {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS}, - PCM_REG_DBG_SELECT, PCM_REG_DBG_DWORD_ENABLE, - PCM_REG_DBG_SHIFT, PCM_REG_DBG_FORCE_VALID, - PCM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 4 -}; - -static struct block_defs block_qm_defs = { - "qm", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCQ}, - QM_REG_DBG_SELECT, QM_REG_DBG_DWORD_ENABLE, - QM_REG_DBG_SHIFT, QM_REG_DBG_FORCE_VALID, - QM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 16 -}; - -static struct block_defs block_tm_defs = { - "tm", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS}, - TM_REG_DBG_SELECT, TM_REG_DBG_DWORD_ENABLE, - TM_REG_DBG_SHIFT, TM_REG_DBG_FORCE_VALID, - TM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 17 -}; - -static struct block_defs block_dorq_defs = { - "dorq", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY}, - DORQ_REG_DBG_SELECT, DORQ_REG_DBG_DWORD_ENABLE, - DORQ_REG_DBG_SHIFT, DORQ_REG_DBG_FORCE_VALID, - DORQ_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 18 -}; - -static struct block_defs block_brb_defs = { - "brb", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCR}, - BRB_REG_DBG_SELECT, BRB_REG_DBG_DWORD_ENABLE, - BRB_REG_DBG_SHIFT, BRB_REG_DBG_FORCE_VALID, - BRB_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 0 -}; - -static struct block_defs block_src_defs = { - "src", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF}, - SRC_REG_DBG_SELECT, SRC_REG_DBG_DWORD_ENABLE, - SRC_REG_DBG_SHIFT, SRC_REG_DBG_FORCE_VALID, - SRC_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 2 -}; - -static struct block_defs block_prs_defs = { - "prs", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCR}, - PRS_REG_DBG_SELECT, PRS_REG_DBG_DWORD_ENABLE, - PRS_REG_DBG_SHIFT, PRS_REG_DBG_FORCE_VALID, - PRS_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 1 -}; - -static struct block_defs block_tsdm_defs = { - "tsdm", - {true, true}, true, DBG_TSTORM_ID, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT}, - TSDM_REG_DBG_SELECT, TSDM_REG_DBG_DWORD_ENABLE, - TSDM_REG_DBG_SHIFT, TSDM_REG_DBG_FORCE_VALID, - TSDM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 3 -}; - -static struct block_defs block_msdm_defs = { - "msdm", - {true, true}, true, DBG_MSTORM_ID, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM}, - MSDM_REG_DBG_SELECT, MSDM_REG_DBG_DWORD_ENABLE, - MSDM_REG_DBG_SHIFT, MSDM_REG_DBG_FORCE_VALID, - MSDM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 6 -}; - -static struct block_defs block_usdm_defs = { - "usdm", - {true, true}, true, DBG_USTORM_ID, - {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU}, - USDM_REG_DBG_SELECT, USDM_REG_DBG_DWORD_ENABLE, - USDM_REG_DBG_SHIFT, USDM_REG_DBG_FORCE_VALID, - USDM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 7 -}; - -static struct block_defs block_xsdm_defs = { - "xsdm", - {true, true}, true, DBG_XSTORM_ID, - {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX}, - XSDM_REG_DBG_SELECT, XSDM_REG_DBG_DWORD_ENABLE, - XSDM_REG_DBG_SHIFT, XSDM_REG_DBG_FORCE_VALID, - XSDM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 20 -}; - -static struct block_defs block_ysdm_defs = { - "ysdm", - {true, true}, true, DBG_YSTORM_ID, - {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY}, - YSDM_REG_DBG_SELECT, YSDM_REG_DBG_DWORD_ENABLE, - YSDM_REG_DBG_SHIFT, YSDM_REG_DBG_FORCE_VALID, - YSDM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 8 -}; - -static struct block_defs block_psdm_defs = { - "psdm", - {true, true}, true, DBG_PSTORM_ID, - {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS}, - PSDM_REG_DBG_SELECT, PSDM_REG_DBG_DWORD_ENABLE, - PSDM_REG_DBG_SHIFT, PSDM_REG_DBG_FORCE_VALID, - PSDM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 7 -}; - -static struct block_defs block_tsem_defs = { - "tsem", - {true, true}, true, DBG_TSTORM_ID, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT}, - TSEM_REG_DBG_SELECT, TSEM_REG_DBG_DWORD_ENABLE, - TSEM_REG_DBG_SHIFT, TSEM_REG_DBG_FORCE_VALID, - TSEM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 4 -}; - -static struct block_defs block_msem_defs = { - "msem", - {true, true}, true, DBG_MSTORM_ID, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM}, - MSEM_REG_DBG_SELECT, MSEM_REG_DBG_DWORD_ENABLE, - MSEM_REG_DBG_SHIFT, MSEM_REG_DBG_FORCE_VALID, - MSEM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 9 -}; - -static struct block_defs block_usem_defs = { - "usem", - {true, true}, true, DBG_USTORM_ID, - {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU}, - USEM_REG_DBG_SELECT, USEM_REG_DBG_DWORD_ENABLE, - USEM_REG_DBG_SHIFT, USEM_REG_DBG_FORCE_VALID, - USEM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 9 -}; - -static struct block_defs block_xsem_defs = { - "xsem", - {true, true}, true, DBG_XSTORM_ID, - {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX}, - XSEM_REG_DBG_SELECT, XSEM_REG_DBG_DWORD_ENABLE, - XSEM_REG_DBG_SHIFT, XSEM_REG_DBG_FORCE_VALID, - XSEM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 21 -}; - -static struct block_defs block_ysem_defs = { - "ysem", - {true, true}, true, DBG_YSTORM_ID, - {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY}, - YSEM_REG_DBG_SELECT, YSEM_REG_DBG_DWORD_ENABLE, - YSEM_REG_DBG_SHIFT, YSEM_REG_DBG_FORCE_VALID, - YSEM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 11 -}; - -static struct block_defs block_psem_defs = { - "psem", - {true, true}, true, DBG_PSTORM_ID, - {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS}, - PSEM_REG_DBG_SELECT, PSEM_REG_DBG_DWORD_ENABLE, - PSEM_REG_DBG_SHIFT, PSEM_REG_DBG_FORCE_VALID, - PSEM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 10 -}; - -static struct block_defs block_rss_defs = { - "rss", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT}, - RSS_REG_DBG_SELECT, RSS_REG_DBG_DWORD_ENABLE, - RSS_REG_DBG_SHIFT, RSS_REG_DBG_FORCE_VALID, - RSS_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 18 -}; - -static struct block_defs block_tmld_defs = { - "tmld", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM}, - TMLD_REG_DBG_SELECT, TMLD_REG_DBG_DWORD_ENABLE, - TMLD_REG_DBG_SHIFT, TMLD_REG_DBG_FORCE_VALID, - TMLD_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 13 -}; - -static struct block_defs block_muld_defs = { - "muld", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU}, - MULD_REG_DBG_SELECT, MULD_REG_DBG_DWORD_ENABLE, - MULD_REG_DBG_SHIFT, MULD_REG_DBG_FORCE_VALID, - MULD_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 14 -}; - -static struct block_defs block_yuld_defs = { - "yuld", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU}, - YULD_REG_DBG_SELECT_BB_K2, YULD_REG_DBG_DWORD_ENABLE_BB_K2, - YULD_REG_DBG_SHIFT_BB_K2, YULD_REG_DBG_FORCE_VALID_BB_K2, - YULD_REG_DBG_FORCE_FRAME_BB_K2, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, - 15 -}; - -static struct block_defs block_xyld_defs = { - "xyld", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX}, - XYLD_REG_DBG_SELECT, XYLD_REG_DBG_DWORD_ENABLE, - XYLD_REG_DBG_SHIFT, XYLD_REG_DBG_FORCE_VALID, - XYLD_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 12 -}; - -static struct block_defs block_prm_defs = { - "prm", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM}, - PRM_REG_DBG_SELECT, PRM_REG_DBG_DWORD_ENABLE, - PRM_REG_DBG_SHIFT, PRM_REG_DBG_FORCE_VALID, - PRM_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 21 -}; - -static struct block_defs block_pbf_pb1_defs = { - "pbf_pb1", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCV}, - PBF_PB1_REG_DBG_SELECT, PBF_PB1_REG_DBG_DWORD_ENABLE, - PBF_PB1_REG_DBG_SHIFT, PBF_PB1_REG_DBG_FORCE_VALID, - PBF_PB1_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, - 11 -}; - -static struct block_defs block_pbf_pb2_defs = { - "pbf_pb2", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCV}, - PBF_PB2_REG_DBG_SELECT, PBF_PB2_REG_DBG_DWORD_ENABLE, - PBF_PB2_REG_DBG_SHIFT, PBF_PB2_REG_DBG_FORCE_VALID, - PBF_PB2_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, - 12 -}; - -static struct block_defs block_rpb_defs = { - "rpb", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM}, - RPB_REG_DBG_SELECT, RPB_REG_DBG_DWORD_ENABLE, - RPB_REG_DBG_SHIFT, RPB_REG_DBG_FORCE_VALID, - RPB_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 13 -}; - -static struct block_defs block_btb_defs = { - "btb", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCV}, - BTB_REG_DBG_SELECT, BTB_REG_DBG_DWORD_ENABLE, - BTB_REG_DBG_SHIFT, BTB_REG_DBG_FORCE_VALID, - BTB_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 10 -}; - -static struct block_defs block_pbf_defs = { - "pbf", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCV}, - PBF_REG_DBG_SELECT, PBF_REG_DBG_DWORD_ENABLE, - PBF_REG_DBG_SHIFT, PBF_REG_DBG_FORCE_VALID, - PBF_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 15 -}; - -static struct block_defs block_rdif_defs = { - "rdif", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM}, - RDIF_REG_DBG_SELECT, RDIF_REG_DBG_DWORD_ENABLE, - RDIF_REG_DBG_SHIFT, RDIF_REG_DBG_FORCE_VALID, - RDIF_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 16 -}; - -static struct block_defs block_tdif_defs = { - "tdif", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS}, - TDIF_REG_DBG_SELECT, TDIF_REG_DBG_DWORD_ENABLE, - TDIF_REG_DBG_SHIFT, TDIF_REG_DBG_FORCE_VALID, - TDIF_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 17 -}; - -static struct block_defs block_cdu_defs = { - "cdu", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF}, - CDU_REG_DBG_SELECT, CDU_REG_DBG_DWORD_ENABLE, - CDU_REG_DBG_SHIFT, CDU_REG_DBG_FORCE_VALID, - CDU_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 23 -}; - -static struct block_defs block_ccfc_defs = { - "ccfc", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF}, - CCFC_REG_DBG_SELECT, CCFC_REG_DBG_DWORD_ENABLE, - CCFC_REG_DBG_SHIFT, CCFC_REG_DBG_FORCE_VALID, - CCFC_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 24 -}; - -static struct block_defs block_tcfc_defs = { - "tcfc", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF}, - TCFC_REG_DBG_SELECT, TCFC_REG_DBG_DWORD_ENABLE, - TCFC_REG_DBG_SHIFT, TCFC_REG_DBG_FORCE_VALID, - TCFC_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 25 -}; - -static struct block_defs block_igu_defs = { - "igu", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP}, - IGU_REG_DBG_SELECT, IGU_REG_DBG_DWORD_ENABLE, - IGU_REG_DBG_SHIFT, IGU_REG_DBG_FORCE_VALID, - IGU_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 27 -}; - -static struct block_defs block_cau_defs = { - "cau", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP}, - CAU_REG_DBG_SELECT, CAU_REG_DBG_DWORD_ENABLE, - CAU_REG_DBG_SHIFT, CAU_REG_DBG_FORCE_VALID, - CAU_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 19 -}; - -static struct block_defs block_umac_defs = { - "umac", - {false, true}, false, 0, - {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCZ}, - UMAC_REG_DBG_SELECT_K2, UMAC_REG_DBG_DWORD_ENABLE_K2, - UMAC_REG_DBG_SHIFT_K2, UMAC_REG_DBG_FORCE_VALID_K2, - UMAC_REG_DBG_FORCE_FRAME_K2, - true, false, DBG_RESET_REG_MISCS_PL_HV, 6 -}; - -static struct block_defs block_xmac_defs = { - "xmac", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_dbg_defs = { - "dbg", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - true, true, DBG_RESET_REG_MISC_PL_PDA_VAUX, 3 -}; - -static struct block_defs block_nig_defs = { - "nig", - {true, true}, false, 0, - {DBG_BUS_CLIENT_RBCN, DBG_BUS_CLIENT_RBCN}, - NIG_REG_DBG_SELECT, NIG_REG_DBG_DWORD_ENABLE, - NIG_REG_DBG_SHIFT, NIG_REG_DBG_FORCE_VALID, - NIG_REG_DBG_FORCE_FRAME, - true, true, DBG_RESET_REG_MISC_PL_PDA_VAUX, 0 -}; - -static struct block_defs block_wol_defs = { - "wol", - {false, true}, false, 0, - {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCZ}, - WOL_REG_DBG_SELECT_K2, WOL_REG_DBG_DWORD_ENABLE_K2, - WOL_REG_DBG_SHIFT_K2, WOL_REG_DBG_FORCE_VALID_K2, - WOL_REG_DBG_FORCE_FRAME_K2, - true, true, DBG_RESET_REG_MISC_PL_PDA_VAUX, 7 -}; - -static struct block_defs block_bmbn_defs = { - "bmbn", - {false, true}, false, 0, - {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCB}, - BMBN_REG_DBG_SELECT_K2, BMBN_REG_DBG_DWORD_ENABLE_K2, - BMBN_REG_DBG_SHIFT_K2, BMBN_REG_DBG_FORCE_VALID_K2, - BMBN_REG_DBG_FORCE_FRAME_K2, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_ipc_defs = { - "ipc", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - true, false, DBG_RESET_REG_MISCS_PL_UA, 8 -}; - -static struct block_defs block_nwm_defs = { - "nwm", - {false, true}, false, 0, - {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCW}, - NWM_REG_DBG_SELECT_K2, NWM_REG_DBG_DWORD_ENABLE_K2, - NWM_REG_DBG_SHIFT_K2, NWM_REG_DBG_FORCE_VALID_K2, - NWM_REG_DBG_FORCE_FRAME_K2, - true, false, DBG_RESET_REG_MISCS_PL_HV_2, 0 -}; - -static struct block_defs block_nws_defs = { - "nws", - {false, true}, false, 0, - {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCW}, - NWS_REG_DBG_SELECT_K2, NWS_REG_DBG_DWORD_ENABLE_K2, - NWS_REG_DBG_SHIFT_K2, NWS_REG_DBG_FORCE_VALID_K2, - NWS_REG_DBG_FORCE_FRAME_K2, - true, false, DBG_RESET_REG_MISCS_PL_HV, 12 -}; - -static struct block_defs block_ms_defs = { - "ms", - {false, true}, false, 0, - {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCZ}, - MS_REG_DBG_SELECT_K2, MS_REG_DBG_DWORD_ENABLE_K2, - MS_REG_DBG_SHIFT_K2, MS_REG_DBG_FORCE_VALID_K2, - MS_REG_DBG_FORCE_FRAME_K2, - true, false, DBG_RESET_REG_MISCS_PL_HV, 13 -}; - -static struct block_defs block_phy_pcie_defs = { - "phy_pcie", - {false, true}, false, 0, - {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH}, - PCIE_REG_DBG_COMMON_SELECT_K2, - PCIE_REG_DBG_COMMON_DWORD_ENABLE_K2, - PCIE_REG_DBG_COMMON_SHIFT_K2, - PCIE_REG_DBG_COMMON_FORCE_VALID_K2, - PCIE_REG_DBG_COMMON_FORCE_FRAME_K2, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_led_defs = { - "led", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - true, false, DBG_RESET_REG_MISCS_PL_HV, 14 -}; - -static struct block_defs block_avs_wrap_defs = { - "avs_wrap", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - true, false, DBG_RESET_REG_MISCS_PL_UA, 11 -}; - -static struct block_defs block_rgfs_defs = { - "rgfs", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_rgsrc_defs = { - "rgsrc", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_tgfs_defs = { - "tgfs", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_tgsrc_defs = { - "tgsrc", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_ptld_defs = { - "ptld", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_ypld_defs = { - "ypld", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_misc_aeu_defs = { - "misc_aeu", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs block_bar0_map_defs = { - "bar0_map", {false, false}, false, 0, - {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS}, - 0, 0, 0, 0, 0, - false, false, MAX_DBG_RESET_REGS, 0 -}; - -static struct block_defs *s_block_defs[MAX_BLOCK_ID] = { - &block_grc_defs, - &block_miscs_defs, - &block_misc_defs, - &block_dbu_defs, - &block_pglue_b_defs, - &block_cnig_defs, - &block_cpmu_defs, - &block_ncsi_defs, - &block_opte_defs, - &block_bmb_defs, - &block_pcie_defs, - &block_mcp_defs, - &block_mcp2_defs, - &block_pswhst_defs, - &block_pswhst2_defs, - &block_pswrd_defs, - &block_pswrd2_defs, - &block_pswwr_defs, - &block_pswwr2_defs, - &block_pswrq_defs, - &block_pswrq2_defs, - &block_pglcs_defs, - &block_dmae_defs, - &block_ptu_defs, - &block_tcm_defs, - &block_mcm_defs, - &block_ucm_defs, - &block_xcm_defs, - &block_ycm_defs, - &block_pcm_defs, - &block_qm_defs, - &block_tm_defs, - &block_dorq_defs, - &block_brb_defs, - &block_src_defs, - &block_prs_defs, - &block_tsdm_defs, - &block_msdm_defs, - &block_usdm_defs, - &block_xsdm_defs, - &block_ysdm_defs, - &block_psdm_defs, - &block_tsem_defs, - &block_msem_defs, - &block_usem_defs, - &block_xsem_defs, - &block_ysem_defs, - &block_psem_defs, - &block_rss_defs, - &block_tmld_defs, - &block_muld_defs, - &block_yuld_defs, - &block_xyld_defs, - &block_ptld_defs, - &block_ypld_defs, - &block_prm_defs, - &block_pbf_pb1_defs, - &block_pbf_pb2_defs, - &block_rpb_defs, - &block_btb_defs, - &block_pbf_defs, - &block_rdif_defs, - &block_tdif_defs, - &block_cdu_defs, - &block_ccfc_defs, - &block_tcfc_defs, - &block_igu_defs, - &block_cau_defs, - &block_rgfs_defs, - &block_rgsrc_defs, - &block_tgfs_defs, - &block_tgsrc_defs, - &block_umac_defs, - &block_xmac_defs, - &block_dbg_defs, - &block_nig_defs, - &block_wol_defs, - &block_bmbn_defs, - &block_ipc_defs, - &block_nwm_defs, - &block_nws_defs, - &block_ms_defs, - &block_phy_pcie_defs, - &block_led_defs, - &block_avs_wrap_defs, - &block_misc_aeu_defs, - &block_bar0_map_defs, -}; - -static struct platform_defs s_platform_defs[] = { - {"asic", 1}, - {"reserved", 0}, - {"reserved2", 0}, - {"reserved3", 0} + {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS}, + true, + PSEM_REG_FAST_MEMORY, + PSEM_REG_DBG_FRAME_MODE, + PSEM_REG_SLOW_DBG_ACTIVE, + PSEM_REG_SLOW_DBG_MODE, + PSEM_REG_DBG_MODE1_CFG, + PSEM_REG_SYNC_DBG_EMPTY, + PSEM_REG_DBG_GPRE_VECT, + PCM_REG_CTX_RBC_ACCS, + {0, PCM_REG_SM_CON_CTX, 0, 0}, + {{0, 10, 0, 0}, {0, 10, 0, 0}} /* {bb} {k2} */ + }, +}; + +static struct hw_type_defs s_hw_type_defs[] = { + /* HW_TYPE_ASIC */ + {"asic", 1, 256, 32768}, + {"reserved", 0, 0, 0}, + {"reserved2", 0, 0, 0}, + {"reserved3", 0, 0, 0}, + {"reserved4", 0, 0, 0} }; static struct grc_param_defs s_grc_param_defs[] = { /* DBG_GRC_PARAM_DUMP_TSTORM */ - {{1, 1}, 0, 1, false, 1, 1}, + {{1, 1}, 0, 1, false, false, 1, {1, 1}}, /* DBG_GRC_PARAM_DUMP_MSTORM */ - {{1, 1}, 0, 1, false, 1, 1}, + {{1, 1}, 0, 1, false, false, 1, {1, 1}}, /* DBG_GRC_PARAM_DUMP_USTORM */ - {{1, 1}, 0, 1, false, 1, 1}, + {{1, 1}, 0, 1, false, false, 1, {1, 1}}, /* DBG_GRC_PARAM_DUMP_XSTORM */ - {{1, 1}, 0, 1, false, 1, 1}, + {{1, 1}, 0, 1, false, false, 1, {1, 1}}, /* DBG_GRC_PARAM_DUMP_YSTORM */ - {{1, 1}, 0, 1, false, 1, 1}, + {{1, 1}, 0, 1, false, false, 1, {1, 1}}, /* DBG_GRC_PARAM_DUMP_PSTORM */ - {{1, 1}, 0, 1, false, 1, 1}, + {{1, 1}, 0, 1, false, false, 1, {1, 1}}, /* DBG_GRC_PARAM_DUMP_REGS */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_RAM */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_PBUF */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_IOR */ - {{0, 0}, 0, 1, false, 0, 1}, + {{0, 0}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_VFC */ - {{0, 0}, 0, 1, false, 0, 1}, + {{0, 0}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_CM_CTX */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_ILT */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_RSS */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_CAU */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_QM */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_MCP */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, - /* DBG_GRC_PARAM_RESERVED */ - {{1, 1}, 0, 1, false, 0, 1}, + /* DBG_GRC_PARAM_DUMP_DORQ */ + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_CFC */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_IGU */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_BRB */ - {{0, 0}, 0, 1, false, 0, 1}, + {{0, 0}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_BTB */ - {{0, 0}, 0, 1, false, 0, 1}, + {{0, 0}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_BMB */ - {{0, 0}, 0, 1, false, 0, 1}, + {{0, 0}, 0, 1, false, false, 0, {0, 0}}, - /* DBG_GRC_PARAM_DUMP_NIG */ - {{1, 1}, 0, 1, false, 0, 1}, + /* DBG_GRC_PARAM_RESERVED1 */ + {{0, 0}, 0, 1, false, false, 0, {0, 0}}, /* DBG_GRC_PARAM_DUMP_MULD */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_PRS */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_DMAE */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_TM */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_SDM */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_DIF */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_STATIC */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_UNSTALL */ - {{0, 0}, 0, 1, false, 0, 0}, + {{0, 0}, 0, 1, false, false, 0, {0, 0}}, - /* DBG_GRC_PARAM_NUM_LCIDS */ - {{MAX_LCIDS, MAX_LCIDS}, 1, MAX_LCIDS, false, MAX_LCIDS, - MAX_LCIDS}, + /* DBG_GRC_PARAM_RESERVED2 */ + {{0, 0}, 0, 1, false, false, 0, {0, 0}}, - /* DBG_GRC_PARAM_NUM_LTIDS */ - {{MAX_LTIDS, MAX_LTIDS}, 1, MAX_LTIDS, false, MAX_LTIDS, - MAX_LTIDS}, + /* DBG_GRC_PARAM_MCP_TRACE_META_SIZE */ + {{0, 0}, 1, 0xffffffff, false, true, 0, {0, 0}}, /* DBG_GRC_PARAM_EXCLUDE_ALL */ - {{0, 0}, 0, 1, true, 0, 0}, + {{0, 0}, 0, 1, true, false, 0, {0, 0}}, /* DBG_GRC_PARAM_CRASH */ - {{0, 0}, 0, 1, true, 0, 0}, + {{0, 0}, 0, 1, true, false, 0, {0, 0}}, /* DBG_GRC_PARAM_PARITY_SAFE */ - {{0, 0}, 0, 1, false, 1, 0}, + {{0, 0}, 0, 1, false, false, 0, {0, 0}}, /* DBG_GRC_PARAM_DUMP_CM */ - {{1, 1}, 0, 1, false, 0, 1}, + {{1, 1}, 0, 1, false, false, 0, {1, 1}}, /* DBG_GRC_PARAM_DUMP_PHY */ - {{1, 1}, 0, 1, false, 0, 1}, + {{0, 0}, 0, 1, false, false, 0, {0, 0}}, /* DBG_GRC_PARAM_NO_MCP */ - {{0, 0}, 0, 1, false, 0, 0}, + {{0, 0}, 0, 1, false, false, 0, {0, 0}}, /* DBG_GRC_PARAM_NO_FW_VER */ - {{0, 0}, 0, 1, false, 0, 0} + {{0, 0}, 0, 1, false, false, 0, {0, 0}}, + + /* DBG_GRC_PARAM_RESERVED3 */ + {{0, 0}, 0, 1, false, false, 0, {0, 0}}, + + /* DBG_GRC_PARAM_DUMP_MCP_HW_DUMP */ + {{0, 1}, 0, 1, false, false, 0, {0, 1}}, + + /* DBG_GRC_PARAM_DUMP_ILT_CDUC */ + {{1, 1}, 0, 1, false, false, 0, {0, 0}}, + + /* DBG_GRC_PARAM_DUMP_ILT_CDUT */ + {{1, 1}, 0, 1, false, false, 0, {0, 0}}, + + /* DBG_GRC_PARAM_DUMP_CAU_EXT */ + {{0, 0}, 0, 1, false, false, 0, {1, 1}} }; static struct rss_mem_defs s_rss_mem_defs[] = { - { "rss_mem_cid", "rss_cid", 0, - {256, 320}, - {32, 32} }, + {"rss_mem_cid", "rss_cid", 0, 32, + {256, 320}}, - { "rss_mem_key_msb", "rss_key", 1024, - {128, 208}, - {256, 256} }, + {"rss_mem_key_msb", "rss_key", 1024, 256, + {128, 208}}, - { "rss_mem_key_lsb", "rss_key", 2048, - {128, 208}, - {64, 64} }, + {"rss_mem_key_lsb", "rss_key", 2048, 64, + {128, 208}}, - { "rss_mem_info", "rss_info", 3072, - {128, 208}, - {16, 16} }, + {"rss_mem_info", "rss_info", 3072, 16, + {128, 208}}, - { "rss_mem_ind", "rss_ind", 4096, - {16384, 26624}, - {16, 16} } + {"rss_mem_ind", "rss_ind", 4096, 16, + {16384, 26624}} }; static struct vfc_ram_defs s_vfc_ram_defs[] = { @@ -1648,51 +819,31 @@ static struct vfc_ram_defs s_vfc_ram_defs[] = { }; static struct big_ram_defs s_big_ram_defs[] = { - { "BRB", MEM_GROUP_BRB_MEM, MEM_GROUP_BRB_RAM, DBG_GRC_PARAM_DUMP_BRB, - BRB_REG_BIG_RAM_ADDRESS, BRB_REG_BIG_RAM_DATA, - {4800, 5632} }, + {"BRB", MEM_GROUP_BRB_MEM, MEM_GROUP_BRB_RAM, DBG_GRC_PARAM_DUMP_BRB, + BRB_REG_BIG_RAM_ADDRESS, BRB_REG_BIG_RAM_DATA, + MISC_REG_BLOCK_256B_EN, {0, 0}, + {153600, 180224}}, - { "BTB", MEM_GROUP_BTB_MEM, MEM_GROUP_BTB_RAM, DBG_GRC_PARAM_DUMP_BTB, - BTB_REG_BIG_RAM_ADDRESS, BTB_REG_BIG_RAM_DATA, - {2880, 3680} }, + {"BTB", MEM_GROUP_BTB_MEM, MEM_GROUP_BTB_RAM, DBG_GRC_PARAM_DUMP_BTB, + BTB_REG_BIG_RAM_ADDRESS, BTB_REG_BIG_RAM_DATA, + MISC_REG_BLOCK_256B_EN, {0, 1}, + {92160, 117760}}, - { "BMB", MEM_GROUP_BMB_MEM, MEM_GROUP_BMB_RAM, DBG_GRC_PARAM_DUMP_BMB, - BMB_REG_BIG_RAM_ADDRESS, BMB_REG_BIG_RAM_DATA, - {1152, 1152} } + {"BMB", MEM_GROUP_BMB_MEM, MEM_GROUP_BMB_RAM, DBG_GRC_PARAM_DUMP_BMB, + BMB_REG_BIG_RAM_ADDRESS, BMB_REG_BIG_RAM_DATA, + MISCS_REG_BLOCK_256B_EN, {0, 0}, + {36864, 36864}} }; -static struct reset_reg_defs s_reset_regs_defs[] = { - /* DBG_RESET_REG_MISCS_PL_UA */ - { MISCS_REG_RESET_PL_UA, 0x0, - {true, true} }, - - /* DBG_RESET_REG_MISCS_PL_HV */ - { MISCS_REG_RESET_PL_HV, 0x0, - {true, true} }, - - /* DBG_RESET_REG_MISCS_PL_HV_2 */ - { MISCS_REG_RESET_PL_HV_2_K2, 0x0, - {false, true} }, - - /* DBG_RESET_REG_MISC_PL_UA */ - { MISC_REG_RESET_PL_UA, 0x0, - {true, true} }, - - /* DBG_RESET_REG_MISC_PL_HV */ - { MISC_REG_RESET_PL_HV, 0x0, - {true, true} }, - - /* DBG_RESET_REG_MISC_PL_PDA_VMAIN_1 */ - { MISC_REG_RESET_PL_PDA_VMAIN_1, 0x4404040, - {true, true} }, - - /* DBG_RESET_REG_MISC_PL_PDA_VMAIN_2 */ - { MISC_REG_RESET_PL_PDA_VMAIN_2, 0x7c00007, - {true, true} }, - - /* DBG_RESET_REG_MISC_PL_PDA_VAUX */ - { MISC_REG_RESET_PL_PDA_VAUX, 0x2, - {true, true} }, +static struct rbc_reset_defs s_rbc_reset_defs[] = { + {MISCS_REG_RESET_PL_HV, + {0x0, 0x400}}, + {MISC_REG_RESET_PL_PDA_VMAIN_1, + {0x4404040, 0x4404040}}, + {MISC_REG_RESET_PL_PDA_VMAIN_2, + {0x7, 0x7c00007}}, + {MISC_REG_RESET_PL_PDA_VAUX, + {0x2, 0x2}}, }; static struct phy_defs s_phy_defs[] = { @@ -1718,8 +869,34 @@ static struct phy_defs s_phy_defs[] = { PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2}, }; +static struct split_type_defs s_split_type_defs[] = { + /* SPLIT_TYPE_NONE */ + {"eng"}, + + /* SPLIT_TYPE_PORT */ + {"port"}, + + /* SPLIT_TYPE_PF */ + {"pf"}, + + /* SPLIT_TYPE_PORT_PF */ + {"port"}, + + /* SPLIT_TYPE_VF */ + {"vf"} +}; + +/******************************** Variables **********************************/ + +/* The version of the calling app */ +static u32 s_app_ver; + /**************************** Private Functions ******************************/ +static void qed_static_asserts(void) +{ +} + /* Reads and returns a single dword from the specified unaligned buffer */ static u32 qed_read_unaligned_dword(u8 *buf) { @@ -1729,6 +906,15 @@ static u32 qed_read_unaligned_dword(u8 *buf) return dword; } +/* Sets the value of the specified GRC param */ +static void qed_grc_set_param(struct qed_hwfn *p_hwfn, + enum dbg_grc_params grc_param, u32 val) +{ + struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; + + dev_data->grc.param_val[grc_param] = val; +} + /* Returns the value of the specified GRC param */ static u32 qed_grc_get_param(struct qed_hwfn *p_hwfn, enum dbg_grc_params grc_param) @@ -1749,56 +935,132 @@ static void qed_dbg_grc_init_params(struct qed_hwfn *p_hwfn) } } +/* Sets pointer and size for the specified binary buffer type */ +static void qed_set_dbg_bin_buf(struct qed_hwfn *p_hwfn, + enum bin_dbg_buffer_type buf_type, + const u32 *ptr, u32 size) +{ + struct virt_mem_desc *buf = &p_hwfn->dbg_arrays[buf_type]; + + buf->ptr = (void *)ptr; + buf->size = size; +} + /* Initializes debug data for the specified device */ -static enum dbg_status qed_dbg_dev_init(struct qed_hwfn *p_hwfn, - struct qed_ptt *p_ptt) +static enum dbg_status qed_dbg_dev_init(struct qed_hwfn *p_hwfn) { struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; + u8 num_pfs = 0, max_pfs_per_port = 0; if (dev_data->initialized) return DBG_STATUS_OK; + if (!s_app_ver) + return DBG_STATUS_APP_VERSION_NOT_SET; + + /* Set chip */ if (QED_IS_K2(p_hwfn->cdev)) { dev_data->chip_id = CHIP_K2; dev_data->mode_enable[MODE_K2] = 1; + dev_data->num_vfs = MAX_NUM_VFS_K2; + num_pfs = MAX_NUM_PFS_K2; + max_pfs_per_port = MAX_NUM_PFS_K2 / 2; } else if (QED_IS_BB_B0(p_hwfn->cdev)) { dev_data->chip_id = CHIP_BB; dev_data->mode_enable[MODE_BB] = 1; + dev_data->num_vfs = MAX_NUM_VFS_BB; + num_pfs = MAX_NUM_PFS_BB; + max_pfs_per_port = MAX_NUM_PFS_BB; } else { return DBG_STATUS_UNKNOWN_CHIP; } - dev_data->platform_id = PLATFORM_ASIC; + /* Set HW type */ + dev_data->hw_type = HW_TYPE_ASIC; dev_data->mode_enable[MODE_ASIC] = 1; + /* Set port mode */ + switch (p_hwfn->cdev->num_ports_in_engine) { + case 1: + dev_data->mode_enable[MODE_PORTS_PER_ENG_1] = 1; + break; + case 2: + dev_data->mode_enable[MODE_PORTS_PER_ENG_2] = 1; + break; + case 4: + dev_data->mode_enable[MODE_PORTS_PER_ENG_4] = 1; + break; + } + + /* Set 100G mode */ + if (QED_IS_CMT(p_hwfn->cdev)) + dev_data->mode_enable[MODE_100G] = 1; + + /* Set number of ports */ + if (dev_data->mode_enable[MODE_PORTS_PER_ENG_1] || + dev_data->mode_enable[MODE_100G]) + dev_data->num_ports = 1; + else if (dev_data->mode_enable[MODE_PORTS_PER_ENG_2]) + dev_data->num_ports = 2; + else if (dev_data->mode_enable[MODE_PORTS_PER_ENG_4]) + dev_data->num_ports = 4; + + /* Set number of PFs per port */ + dev_data->num_pfs_per_port = min_t(u32, + num_pfs / dev_data->num_ports, + max_pfs_per_port); + /* Initializes the GRC parameters */ qed_dbg_grc_init_params(p_hwfn); - dev_data->initialized = true; + dev_data->use_dmae = true; + dev_data->initialized = 1; return DBG_STATUS_OK; } -static struct dbg_bus_block *get_dbg_bus_block_desc(struct qed_hwfn *p_hwfn, - enum block_id block_id) +static const struct dbg_block *get_dbg_block(struct qed_hwfn *p_hwfn, + enum block_id block_id) +{ + const struct dbg_block *dbg_block; + + dbg_block = p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS].ptr; + return dbg_block + block_id; +} + +static const struct dbg_block_chip *qed_get_dbg_block_per_chip(struct qed_hwfn + *p_hwfn, + enum block_id + block_id) { struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; - return (struct dbg_bus_block *)&dbg_bus_blocks[block_id * - MAX_CHIP_IDS + - dev_data->chip_id]; + return (const struct dbg_block_chip *) + p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS_CHIP_DATA].ptr + + block_id * MAX_CHIP_IDS + dev_data->chip_id; +} + +static const struct dbg_reset_reg *qed_get_dbg_reset_reg(struct qed_hwfn + *p_hwfn, + u8 reset_reg_id) +{ + struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; + + return (const struct dbg_reset_reg *) + p_hwfn->dbg_arrays[BIN_BUF_DBG_RESET_REGS].ptr + + reset_reg_id * MAX_CHIP_IDS + dev_data->chip_id; } /* Reads the FW info structure for the specified Storm from the chip, * and writes it to the specified fw_info pointer. */ -static void qed_read_fw_info(struct qed_hwfn *p_hwfn, - struct qed_ptt *p_ptt, - u8 storm_id, struct fw_info *fw_info) +static void qed_read_storm_fw_info(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + u8 storm_id, struct fw_info *fw_info) { struct storm_defs *storm = &s_storm_defs[storm_id]; struct fw_info_location fw_info_location; - u32 addr, i, *dest; + u32 addr, i, size, *dest; memset(&fw_info_location, 0, sizeof(fw_info_location)); memset(fw_info, 0, sizeof(*fw_info)); @@ -1807,23 +1069,26 @@ static void qed_read_fw_info(struct qed_hwfn *p_hwfn, * The address is located in the last line of the Storm RAM. */ addr = storm->sem_fast_mem_addr + SEM_FAST_REG_INT_RAM + - DWORDS_TO_BYTES(SEM_FAST_REG_INT_RAM_SIZE) - - sizeof(fw_info_location); + DWORDS_TO_BYTES(SEM_FAST_REG_INT_RAM_SIZE) - + sizeof(fw_info_location); + dest = (u32 *)&fw_info_location; + size = BYTES_TO_DWORDS(sizeof(fw_info_location)); - for (i = 0; i < BYTES_TO_DWORDS(sizeof(fw_info_location)); - i++, addr += BYTES_IN_DWORD) + for (i = 0; i < size; i++, addr += BYTES_IN_DWORD) dest[i] = qed_rd(p_hwfn, p_ptt, addr); /* Read FW version info from Storm RAM */ - if (fw_info_location.size > 0 && fw_info_location.size <= - sizeof(*fw_info)) { - addr = fw_info_location.grc_addr; - dest = (u32 *)fw_info; - for (i = 0; i < BYTES_TO_DWORDS(fw_info_location.size); - i++, addr += BYTES_IN_DWORD) - dest[i] = qed_rd(p_hwfn, p_ptt, addr); - } + size = le32_to_cpu(fw_info_location.size); + if (!size || size > sizeof(*fw_info)) + return; + + addr = le32_to_cpu(fw_info_location.grc_addr); + dest = (u32 *)fw_info; + size = BYTES_TO_DWORDS(size); + + for (i = 0; i < size; i++, addr += BYTES_IN_DWORD) + dest[i] = qed_rd(p_hwfn, p_ptt, addr); } /* Dumps the specified string to the specified buffer. @@ -1916,45 +1181,35 @@ static u32 qed_dump_fw_ver_param(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) { - struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; char fw_ver_str[16] = EMPTY_FW_VERSION_STR; char fw_img_str[16] = EMPTY_FW_IMAGE_STR; struct fw_info fw_info = { {0}, {0} }; u32 offset = 0; if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) { - /* Read FW image/version from PRAM in a non-reset SEMI */ - bool found = false; - u8 storm_id; - - for (storm_id = 0; storm_id < MAX_DBG_STORMS && !found; - storm_id++) { - struct storm_defs *storm = &s_storm_defs[storm_id]; - - /* Read FW version/image */ - if (dev_data->block_in_reset[storm->block_id]) - continue; - - /* Read FW info for the current Storm */ - qed_read_fw_info(p_hwfn, p_ptt, storm_id, &fw_info); - - /* Create FW version/image strings */ - if (snprintf(fw_ver_str, sizeof(fw_ver_str), - "%d_%d_%d_%d", fw_info.ver.num.major, - fw_info.ver.num.minor, fw_info.ver.num.rev, - fw_info.ver.num.eng) < 0) - DP_NOTICE(p_hwfn, - "Unexpected debug error: invalid FW version string\n"); - switch (fw_info.ver.image_id) { - case FW_IMG_MAIN: - strcpy(fw_img_str, "main"); - break; - default: - strcpy(fw_img_str, "unknown"); - break; - } - - found = true; + /* Read FW info from chip */ + qed_read_fw_info(p_hwfn, p_ptt, &fw_info); + + /* Create FW version/image strings */ + if (snprintf(fw_ver_str, sizeof(fw_ver_str), + "%d_%d_%d_%d", fw_info.ver.num.major, + fw_info.ver.num.minor, fw_info.ver.num.rev, + fw_info.ver.num.eng) < 0) + DP_NOTICE(p_hwfn, + "Unexpected debug error: invalid FW version string\n"); + switch (fw_info.ver.image_id) { + case FW_IMG_KUKU: + strcpy(fw_img_str, "kuku"); + break; + case FW_IMG_MAIN: + strcpy(fw_img_str, "main"); + break; + case FW_IMG_L2B: + strcpy(fw_img_str, "l2b"); + break; + default: + strcpy(fw_img_str, "unknown"); + break; } } @@ -1963,9 +1218,8 @@ static u32 qed_dump_fw_ver_param(struct qed_hwfn *p_hwfn, dump, "fw-version", fw_ver_str); offset += qed_dump_str_param(dump_buf + offset, dump, "fw-image", fw_img_str); - offset += qed_dump_num_param(dump_buf + offset, - dump, - "fw-timestamp", fw_info.ver.timestamp); + offset += qed_dump_num_param(dump_buf + offset, dump, "fw-timestamp", + le32_to_cpu(fw_info.ver.timestamp)); return offset; } @@ -2019,6 +1273,29 @@ static u32 qed_dump_mfw_ver_param(struct qed_hwfn *p_hwfn, return qed_dump_str_param(dump_buf, dump, "mfw-version", mfw_ver_str); } +/* Reads the chip revision from the chip and writes it as a param to the + * specified buffer. Returns the dumped size in dwords. + */ +static u32 qed_dump_chip_revision_param(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + u32 *dump_buf, bool dump) +{ + struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; + char param_str[3] = "??"; + + if (dev_data->hw_type == HW_TYPE_ASIC) { + u32 chip_rev, chip_metal; + + chip_rev = qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_REV); + chip_metal = qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_METAL); + + param_str[0] = 'a' + (u8)chip_rev; + param_str[1] = '0' + (u8)chip_metal; + } + + return qed_dump_str_param(dump_buf, dump, "chip-revision", param_str); +} + /* Writes a section header to the specified buffer. * Returns the dumped size in dwords. */ @@ -2042,7 +1319,8 @@ static u32 qed_dump_common_global_params(struct qed_hwfn *p_hwfn, u8 num_params; /* Dump global params section header */ - num_params = NUM_COMMON_GLOBAL_PARAMS + num_specific_global_params; + num_params = NUM_COMMON_GLOBAL_PARAMS + num_specific_global_params + + (dev_data->chip_id == CHIP_BB ? 1 : 0); offset += qed_dump_section_hdr(dump_buf + offset, dump, "global_params", num_params); @@ -2050,6 +1328,8 @@ static u32 qed_dump_common_global_params(struct qed_hwfn *p_hwfn, offset += qed_dump_fw_ver_param(p_hwfn, p_ptt, dump_buf + offset, dump); offset += qed_dump_mfw_ver_param(p_hwfn, p_ptt, dump_buf + offset, dump); + offset += qed_dump_chip_revision_param(p_hwfn, + p_ptt, dump_buf + offset, dump); offset += qed_dump_num_param(dump_buf + offset, dump, "tools-version", TOOLS_VERSION); offset += qed_dump_str_param(dump_buf + offset, @@ -2059,11 +1339,14 @@ static u32 qed_dump_common_global_params(struct qed_hwfn *p_hwfn, offset += qed_dump_str_param(dump_buf + offset, dump, "platform", - s_platform_defs[dev_data->platform_id]. - name); - offset += - qed_dump_num_param(dump_buf + offset, dump, "pci-func", - p_hwfn->abs_pf_id); + s_hw_type_defs[dev_data->hw_type].name); + offset += qed_dump_num_param(dump_buf + offset, + dump, "pci-func", p_hwfn->abs_pf_id); + offset += qed_dump_num_param(dump_buf + offset, + dump, "epoch", qed_get_epoch_time()); + if (dev_data->chip_id == CHIP_BB) + offset += qed_dump_num_param(dump_buf + offset, + dump, "path", QED_PATH_ID(p_hwfn)); return offset; } @@ -2071,8 +1354,7 @@ static u32 qed_dump_common_global_params(struct qed_hwfn *p_hwfn, /* Writes the "last" section (including CRC) to the specified buffer at the * given offset. Returns the dumped size in dwords. */ -static u32 qed_dump_last_section(struct qed_hwfn *p_hwfn, - u32 *dump_buf, u32 offset, bool dump) +static u32 qed_dump_last_section(u32 *dump_buf, u32 offset, bool dump) { u32 start_offset = offset; @@ -2095,24 +1377,87 @@ static void qed_update_blocks_reset_state(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) { struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; - u32 reg_val[MAX_DBG_RESET_REGS] = { 0 }; - u32 i; + u32 reg_val[NUM_DBG_RESET_REGS] = { 0 }; + u8 rst_reg_id; + u32 blk_id; /* Read reset registers */ - for (i = 0; i < MAX_DBG_RESET_REGS; i++) - if (s_reset_regs_defs[i].exists[dev_data->chip_id]) - reg_val[i] = qed_rd(p_hwfn, - p_ptt, s_reset_regs_defs[i].addr); + for (rst_reg_id = 0; rst_reg_id < NUM_DBG_RESET_REGS; rst_reg_id++) { + const struct dbg_reset_reg *rst_reg; + bool rst_reg_removed; + u32 rst_reg_addr; + + rst_reg = qed_get_dbg_reset_reg(p_hwfn, rst_reg_id); + rst_reg_removed = GET_FIELD(rst_reg->data, + DBG_RESET_REG_IS_REMOVED); + rst_reg_addr = DWORDS_TO_BYTES(GET_FIELD(rst_reg->data, + DBG_RESET_REG_ADDR)); + + if (!rst_reg_removed) + reg_val[rst_reg_id] = qed_rd(p_hwfn, p_ptt, + rst_reg_addr); + } /* Check if blocks are in reset */ - for (i = 0; i < MAX_BLOCK_ID; i++) { - struct block_defs *block = s_block_defs[i]; + for (blk_id = 0; blk_id < NUM_PHYS_BLOCKS; blk_id++) { + const struct dbg_block_chip *blk; + bool has_rst_reg; + bool is_removed; + + blk = qed_get_dbg_block_per_chip(p_hwfn, (enum block_id)blk_id); + is_removed = GET_FIELD(blk->flags, DBG_BLOCK_CHIP_IS_REMOVED); + has_rst_reg = GET_FIELD(blk->flags, + DBG_BLOCK_CHIP_HAS_RESET_REG); + + if (!is_removed && has_rst_reg) + dev_data->block_in_reset[blk_id] = + !(reg_val[blk->reset_reg_id] & + BIT(blk->reset_reg_bit_offset)); + } +} + +/* is_mode_match recursive function */ +static bool qed_is_mode_match_rec(struct qed_hwfn *p_hwfn, + u16 *modes_buf_offset, u8 rec_depth) +{ + struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; + u8 *dbg_array; + bool arg1, arg2; + u8 tree_val; - dev_data->block_in_reset[i] = block->has_reset_bit && - !(reg_val[block->reset_reg] & BIT(block->reset_bit_offset)); + if (rec_depth > MAX_RECURSION_DEPTH) { + DP_NOTICE(p_hwfn, + "Unexpected error: is_mode_match_rec exceeded the max recursion depth. This is probably due to a corrupt init/debug buffer.\n"); + return false; + } + + /* Get next element from modes tree buffer */ + dbg_array = p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr; + tree_val = dbg_array[(*modes_buf_offset)++]; + + switch (tree_val) { + case INIT_MODE_OP_NOT: + return !qed_is_mode_match_rec(p_hwfn, + modes_buf_offset, rec_depth + 1); + case INIT_MODE_OP_OR: + case INIT_MODE_OP_AND: + arg1 = qed_is_mode_match_rec(p_hwfn, + modes_buf_offset, rec_depth + 1); + arg2 = qed_is_mode_match_rec(p_hwfn, + modes_buf_offset, rec_depth + 1); + return (tree_val == INIT_MODE_OP_OR) ? (arg1 || + arg2) : (arg1 && arg2); + default: + return dev_data->mode_enable[tree_val - MAX_INIT_MODE_OPS] > 0; } } +/* Returns true if the mode (specified using modes_buf_offset) is enabled */ +static bool qed_is_mode_match(struct qed_hwfn *p_hwfn, u16 *modes_buf_offset) +{ + return qed_is_mode_match_rec(p_hwfn, modes_buf_offset, 0); +} + /* Enable / disable the Debug block */ static void qed_bus_enable_dbg_block(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, bool enable) @@ -2124,23 +1469,21 @@ static void qed_bus_enable_dbg_block(struct qed_hwfn *p_hwfn, static void qed_bus_reset_dbg_block(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) { - u32 dbg_reset_reg_addr, old_reset_reg_val, new_reset_reg_val; - struct block_defs *dbg_block = s_block_defs[BLOCK_DBG]; + u32 reset_reg_addr, old_reset_reg_val, new_reset_reg_val; + const struct dbg_reset_reg *reset_reg; + const struct dbg_block_chip *block; - dbg_reset_reg_addr = s_reset_regs_defs[dbg_block->reset_reg].addr; - old_reset_reg_val = qed_rd(p_hwfn, p_ptt, dbg_reset_reg_addr); - new_reset_reg_val = - old_reset_reg_val & ~BIT(dbg_block->reset_bit_offset); + block = qed_get_dbg_block_per_chip(p_hwfn, BLOCK_DBG); + reset_reg = qed_get_dbg_reset_reg(p_hwfn, block->reset_reg_id); + reset_reg_addr = + DWORDS_TO_BYTES(GET_FIELD(reset_reg->data, DBG_RESET_REG_ADDR)); - qed_wr(p_hwfn, p_ptt, dbg_reset_reg_addr, new_reset_reg_val); - qed_wr(p_hwfn, p_ptt, dbg_reset_reg_addr, old_reset_reg_val); -} + old_reset_reg_val = qed_rd(p_hwfn, p_ptt, reset_reg_addr); + new_reset_reg_val = + old_reset_reg_val & ~BIT(block->reset_reg_bit_offset); -static void qed_bus_set_framing_mode(struct qed_hwfn *p_hwfn, - struct qed_ptt *p_ptt, - enum dbg_bus_frame_modes mode) -{ - qed_wr(p_hwfn, p_ptt, DBG_REG_FRAMING_MODE, (u8)mode); + qed_wr(p_hwfn, p_ptt, reset_reg_addr, new_reset_reg_val); + qed_wr(p_hwfn, p_ptt, reset_reg_addr, old_reset_reg_val); } /* Enable / disable Debug Bus clients according to the specified mask @@ -2152,28 +1495,65 @@ static void qed_bus_enable_clients(struct qed_hwfn *p_hwfn, qed_wr(p_hwfn, p_ptt, DBG_REG_CLIENT_ENABLE, client_mask); } -static bool qed_is_mode_match(struct qed_hwfn *p_hwfn, u16 *modes_buf_offset) +static void qed_bus_config_dbg_line(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + enum block_id block_id, + u8 line_id, + u8 enable_mask, + u8 right_shift, + u8 force_valid_mask, u8 force_frame_mask) +{ + const struct dbg_block_chip *block = + qed_get_dbg_block_per_chip(p_hwfn, block_id); + + qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_select_reg_addr), + line_id); + qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_dword_enable_reg_addr), + enable_mask); + qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_shift_reg_addr), + right_shift); + qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_force_valid_reg_addr), + force_valid_mask); + qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_force_frame_reg_addr), + force_frame_mask); +} + +/* Disable debug bus in all blocks */ +static void qed_bus_disable_blocks(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt) { struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; - bool arg1, arg2; - const u32 *ptr; - u8 tree_val; + u32 block_id; - /* Get next element from modes tree buffer */ - ptr = s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr; - tree_val = ((u8 *)ptr)[(*modes_buf_offset)++]; + /* Disable all blocks */ + for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) { + const struct dbg_block_chip *block_per_chip = + qed_get_dbg_block_per_chip(p_hwfn, + (enum block_id)block_id); - switch (tree_val) { - case INIT_MODE_OP_NOT: - return !qed_is_mode_match(p_hwfn, modes_buf_offset); - case INIT_MODE_OP_OR: - case INIT_MODE_OP_AND: - arg1 = qed_is_mode_match(p_hwfn, modes_buf_offset); - arg2 = qed_is_mode_match(p_hwfn, modes_buf_offset); - return (tree_val == INIT_MODE_OP_OR) ? (arg1 || - arg2) : (arg1 && arg2); - default: - return dev_data->mode_enable[tree_val - MAX_INIT_MODE_OPS] > 0; + if (GET_FIELD(block_per_chip->flags, + DBG_BLOCK_CHIP_IS_REMOVED) || + dev_data->block_in_reset[block_id]) + continue; + + /* Disable debug bus */ + if (GET_FIELD(block_per_chip->flags, + DBG_BLOCK_CHIP_HAS_DBG_BUS)) { + u32 dbg_en_addr = + block_per_chip->dbg_dword_enable_reg_addr; + u16 modes_buf_offset = + GET_FIELD(block_per_chip->dbg_bus_mode.data, + DBG_MODE_HDR_MODES_BUF_OFFSET); + bool eval_mode = + GET_FIELD(block_per_chip->dbg_bus_mode.data, + DBG_MODE_HDR_EVAL_MODE) > 0; + + if (!eval_mode || + qed_is_mode_match(p_hwfn, &modes_buf_offset)) + qed_wr(p_hwfn, p_ptt, + DWORDS_TO_BYTES(dbg_en_addr), + 0); + } } } @@ -2186,6 +1566,20 @@ static bool qed_grc_is_included(struct qed_hwfn *p_hwfn, return qed_grc_get_param(p_hwfn, grc_param) > 0; } +/* Returns the storm_id that matches the specified Storm letter, + * or MAX_DBG_STORMS if invalid storm letter. + */ +static enum dbg_storms qed_get_id_from_letter(char storm_letter) +{ + u8 storm_id; + + for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) + if (s_storm_defs[storm_id].letter == storm_letter) + return (enum dbg_storms)storm_id; + + return MAX_DBG_STORMS; +} + /* Returns true of the specified Storm should be included in the dump, false * otherwise. */ @@ -2201,14 +1595,20 @@ static bool qed_grc_is_storm_included(struct qed_hwfn *p_hwfn, static bool qed_grc_is_mem_included(struct qed_hwfn *p_hwfn, enum block_id block_id, u8 mem_group_id) { - struct block_defs *block = s_block_defs[block_id]; + const struct dbg_block *block; u8 i; - /* Check Storm match */ - if (block->associated_to_storm && - !qed_grc_is_storm_included(p_hwfn, - (enum dbg_storms)block->storm_id)) - return false; + block = get_dbg_block(p_hwfn, block_id); + + /* If the block is associated with a Storm, check Storm match */ + if (block->associated_storm_letter) { + enum dbg_storms associated_storm_id = + qed_get_id_from_letter(block->associated_storm_letter); + + if (associated_storm_id == MAX_DBG_STORMS || + !qed_grc_is_storm_included(p_hwfn, associated_storm_id)) + return false; + } for (i = 0; i < NUM_BIG_RAM_TYPES; i++) { struct big_ram_defs *big_ram = &s_big_ram_defs[i]; @@ -2230,12 +1630,17 @@ static bool qed_grc_is_mem_included(struct qed_hwfn *p_hwfn, case MEM_GROUP_CAU_SB: case MEM_GROUP_CAU_PI: return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU); + case MEM_GROUP_CAU_MEM_EXT: + return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU_EXT); case MEM_GROUP_QM_MEM: return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_QM); case MEM_GROUP_CFC_MEM: case MEM_GROUP_CONN_CFC_MEM: case MEM_GROUP_TASK_CFC_MEM: - return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CFC); + return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CFC) || + qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX); + case MEM_GROUP_DORQ_MEM: + return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DORQ); case MEM_GROUP_IGU_MEM: case MEM_GROUP_IGU_MSIX: return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IGU); @@ -2274,69 +1679,111 @@ static void qed_grc_stall_storms(struct qed_hwfn *p_hwfn, continue; reg_addr = s_storm_defs[storm_id].sem_fast_mem_addr + - SEM_FAST_REG_STALL_0_BB_K2; + SEM_FAST_REG_STALL_0; qed_wr(p_hwfn, p_ptt, reg_addr, stall ? 1 : 0); } msleep(STALL_DELAY_MS); } -/* Takes all blocks out of reset */ +/* Takes all blocks out of reset. If rbc_only is true, only RBC clients are + * taken out of reset. + */ static void qed_grc_unreset_blocks(struct qed_hwfn *p_hwfn, - struct qed_ptt *p_ptt) + struct qed_ptt *p_ptt, bool rbc_only) { struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; - u32 reg_val[MAX_DBG_RESET_REGS] = { 0 }; - u32 block_id, i; + u8 chip_id = dev_data->chip_id; + u32 i; - /* Fill reset regs values */ - for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) { - struct block_defs *block = s_block_defs[block_id]; + /* Take RBCs out of reset */ + for (i = 0; i < ARRAY_SIZE(s_rbc_reset_defs); i++) + if (s_rbc_reset_defs[i].reset_val[dev_data->chip_id]) + qed_wr(p_hwfn, + p_ptt, + s_rbc_reset_defs[i].reset_reg_addr + + RESET_REG_UNRESET_OFFSET, + s_rbc_reset_defs[i].reset_val[chip_id]); - if (block->has_reset_bit && block->unreset) - reg_val[block->reset_reg] |= - BIT(block->reset_bit_offset); - } + if (!rbc_only) { + u32 reg_val[NUM_DBG_RESET_REGS] = { 0 }; + u8 reset_reg_id; + u32 block_id; - /* Write reset registers */ - for (i = 0; i < MAX_DBG_RESET_REGS; i++) { - if (!s_reset_regs_defs[i].exists[dev_data->chip_id]) - continue; + /* Fill reset regs values */ + for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) { + bool is_removed, has_reset_reg, unreset_before_dump; + const struct dbg_block_chip *block; + + block = qed_get_dbg_block_per_chip(p_hwfn, + (enum block_id) + block_id); + is_removed = + GET_FIELD(block->flags, DBG_BLOCK_CHIP_IS_REMOVED); + has_reset_reg = + GET_FIELD(block->flags, + DBG_BLOCK_CHIP_HAS_RESET_REG); + unreset_before_dump = + GET_FIELD(block->flags, + DBG_BLOCK_CHIP_UNRESET_BEFORE_DUMP); + + if (!is_removed && has_reset_reg && unreset_before_dump) + reg_val[block->reset_reg_id] |= + BIT(block->reset_reg_bit_offset); + } - reg_val[i] |= s_reset_regs_defs[i].unreset_val; + /* Write reset registers */ + for (reset_reg_id = 0; reset_reg_id < NUM_DBG_RESET_REGS; + reset_reg_id++) { + const struct dbg_reset_reg *reset_reg; + u32 reset_reg_addr; - if (reg_val[i]) - qed_wr(p_hwfn, - p_ptt, - s_reset_regs_defs[i].addr + - RESET_REG_UNRESET_OFFSET, reg_val[i]); + reset_reg = qed_get_dbg_reset_reg(p_hwfn, reset_reg_id); + + if (GET_FIELD + (reset_reg->data, DBG_RESET_REG_IS_REMOVED)) + continue; + + if (reg_val[reset_reg_id]) { + reset_reg_addr = + GET_FIELD(reset_reg->data, + DBG_RESET_REG_ADDR); + qed_wr(p_hwfn, + p_ptt, + DWORDS_TO_BYTES(reset_reg_addr) + + RESET_REG_UNRESET_OFFSET, + reg_val[reset_reg_id]); + } + } } } /* Returns the attention block data of the specified block */ static const struct dbg_attn_block_type_data * -qed_get_block_attn_data(enum block_id block_id, enum dbg_attn_type attn_type) +qed_get_block_attn_data(struct qed_hwfn *p_hwfn, + enum block_id block_id, enum dbg_attn_type attn_type) { const struct dbg_attn_block *base_attn_block_arr = - (const struct dbg_attn_block *) - s_dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr; + (const struct dbg_attn_block *) + p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr; return &base_attn_block_arr[block_id].per_type_data[attn_type]; } /* Returns the attention registers of the specified block */ static const struct dbg_attn_reg * -qed_get_block_attn_regs(enum block_id block_id, enum dbg_attn_type attn_type, +qed_get_block_attn_regs(struct qed_hwfn *p_hwfn, + enum block_id block_id, enum dbg_attn_type attn_type, u8 *num_attn_regs) { const struct dbg_attn_block_type_data *block_type_data = - qed_get_block_attn_data(block_id, attn_type); + qed_get_block_attn_data(p_hwfn, block_id, attn_type); *num_attn_regs = block_type_data->num_regs; - return &((const struct dbg_attn_reg *) - s_dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)[block_type_data-> - regs_offset]; + return (const struct dbg_attn_reg *) + p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr + + block_type_data->regs_offset; } /* For each block, clear the status of all parities */ @@ -2345,14 +1792,15 @@ static void qed_grc_clear_all_prty(struct qed_hwfn *p_hwfn, { struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; const struct dbg_attn_reg *attn_reg_arr; + u32 block_id, sts_clr_address; u8 reg_idx, num_attn_regs; - u32 block_id; - for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) { + for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) { if (dev_data->block_in_reset[block_id]) continue; - attn_reg_arr = qed_get_block_attn_regs((enum block_id)block_id, + attn_reg_arr = qed_get_block_attn_regs(p_hwfn, + (enum block_id)block_id, ATTN_TYPE_PARITY, &num_attn_regs); @@ -2369,32 +1817,122 @@ static void qed_grc_clear_all_prty(struct qed_hwfn *p_hwfn, GET_FIELD(reg_data->mode.data, DBG_MODE_HDR_MODES_BUF_OFFSET); + sts_clr_address = reg_data->sts_clr_address; /* If Mode match: clear parity status */ if (!eval_mode || qed_is_mode_match(p_hwfn, &modes_buf_offset)) qed_rd(p_hwfn, p_ptt, - DWORDS_TO_BYTES(reg_data-> - sts_clr_address)); + DWORDS_TO_BYTES(sts_clr_address)); } } } +/* Finds the meta data image in NVRAM */ +static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + u32 image_type, + u32 *nvram_offset_bytes, + u32 *nvram_size_bytes, + bool b_can_sleep) +{ + u32 ret_mcp_resp, ret_mcp_param, ret_txn_size; + struct mcp_file_att file_att; + int nvm_result; + + /* Call NVRAM get file command */ + nvm_result = qed_mcp_nvm_rd_cmd(p_hwfn, + p_ptt, + DRV_MSG_CODE_NVM_GET_FILE_ATT, + image_type, + &ret_mcp_resp, + &ret_mcp_param, + &ret_txn_size, + (u32 *)&file_att, + b_can_sleep); + + /* Check response */ + if (nvm_result || (ret_mcp_resp & FW_MSG_CODE_MASK) != + FW_MSG_CODE_NVM_OK) + return DBG_STATUS_NVRAM_GET_IMAGE_FAILED; + + /* Update return values */ + *nvram_offset_bytes = file_att.nvm_start_addr; + *nvram_size_bytes = file_att.len; + + DP_VERBOSE(p_hwfn, + QED_MSG_DEBUG, + "find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\n", + image_type, *nvram_offset_bytes, *nvram_size_bytes); + + /* Check alignment */ + if (*nvram_size_bytes & 0x3) + return DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE; + + return DBG_STATUS_OK; +} + +/* Reads data from NVRAM */ +static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + u32 nvram_offset_bytes, + u32 nvram_size_bytes, + u32 *ret_buf, + bool b_can_sleep) +{ + u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy; + s32 bytes_left = nvram_size_bytes; + u32 read_offset = 0, param = 0; + + DP_VERBOSE(p_hwfn, + QED_MSG_DEBUG, + "nvram_read: reading image of size %d bytes from NVRAM\n", + nvram_size_bytes); + + do { + bytes_to_copy = + (bytes_left > + MCP_DRV_NVM_BUF_LEN) ? MCP_DRV_NVM_BUF_LEN : bytes_left; + + /* Call NVRAM read command */ + SET_MFW_FIELD(param, + DRV_MB_PARAM_NVM_OFFSET, + nvram_offset_bytes + read_offset); + SET_MFW_FIELD(param, DRV_MB_PARAM_NVM_LEN, bytes_to_copy); + if (qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt, + DRV_MSG_CODE_NVM_READ_NVRAM, param, + &ret_mcp_resp, + &ret_mcp_param, &ret_read_size, + (u32 *)((u8 *)ret_buf + read_offset), + b_can_sleep)) + return DBG_STATUS_NVRAM_READ_FAILED; + + /* Check response */ + if ((ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK) + return DBG_STATUS_NVRAM_READ_FAILED; + + /* Update read offset */ + read_offset += ret_read_size; + bytes_left -= ret_read_size; + } while (bytes_left > 0); + + return DBG_STATUS_OK; +} + /* Dumps GRC registers section header. Returns the dumped size in dwords. - * The following parameters are dumped: - * - count: no. of dumped entries - * - split: split type - * - id: split ID (dumped only if split_id >= 0) - * - param_name: user parameter value (dumped only if param_name != NULL - * and param_val != NULL). + * the following parameters are dumped: + * - count: no. of dumped entries + * - split_type: split type + * - split_id: split ID (dumped only if split_id != SPLIT_TYPE_NONE) + * - reg_type_name: register type name (dumped only if reg_type_name != NULL) */ static u32 qed_grc_dump_regs_hdr(u32 *dump_buf, bool dump, u32 num_reg_entries, - const char *split_type, - int split_id, - const char *param_name, const char *param_val) + enum init_split_types split_type, + u8 split_id, const char *reg_type_name) { - u8 num_params = 2 + (split_id >= 0 ? 1 : 0) + (param_name ? 1 : 0); + u8 num_params = 2 + + (split_type != SPLIT_TYPE_NONE ? 1 : 0) + (reg_type_name ? 1 : 0); u32 offset = 0; offset += qed_dump_section_hdr(dump_buf + offset, @@ -2402,17 +1940,30 @@ static u32 qed_grc_dump_regs_hdr(u32 *dump_buf, offset += qed_dump_num_param(dump_buf + offset, dump, "count", num_reg_entries); offset += qed_dump_str_param(dump_buf + offset, - dump, "split", split_type); - if (split_id >= 0) + dump, "split", + s_split_type_defs[split_type].name); + if (split_type != SPLIT_TYPE_NONE) offset += qed_dump_num_param(dump_buf + offset, dump, "id", split_id); - if (param_name && param_val) + if (reg_type_name) offset += qed_dump_str_param(dump_buf + offset, - dump, param_name, param_val); + dump, "type", reg_type_name); return offset; } +/* Reads the specified registers into the specified buffer. + * The addr and len arguments are specified in dwords. + */ +void qed_read_regs(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, u32 *buf, u32 addr, u32 len) +{ + u32 i; + + for (i = 0; i < len; i++) + buf[i] = qed_rd(p_hwfn, p_ptt, DWORDS_TO_BYTES(addr + i)); +} + /* Dumps the GRC registers in the specified address range. * Returns the dumped size in dwords. * The addr and len arguments are specified in dwords. @@ -2420,17 +1971,134 @@ static u32 qed_grc_dump_regs_hdr(u32 *dump_buf, static u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *dump_buf, - bool dump, u32 addr, u32 len, bool wide_bus) + bool dump, u32 addr, u32 len, bool wide_bus, + enum init_split_types split_type, + u8 split_id) { - u32 byte_addr = DWORDS_TO_BYTES(addr), offset = 0, i; + struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; + u8 port_id = 0, pf_id = 0, vf_id = 0; + bool read_using_dmae = false; + u32 thresh; + u16 fid; if (!dump) return len; - for (i = 0; i < len; i++, byte_addr += BYTES_IN_DWORD, offset++) - *(dump_buf + offset) = qed_rd(p_hwfn, p_ptt, byte_addr); + switch (split_type) { + case SPLIT_TYPE_PORT: + port_id = split_id; + break; + case SPLIT_TYPE_PF: + pf_id = split_id; + break; + case SPLIT_TYPE_PORT_PF: + port_id = split_id / dev_data->num_pfs_per_port; + pf_id = port_id + dev_data->num_ports * + (split_id % dev_data->num_pfs_per_port); + break; + case SPLIT_TYPE_VF: + vf_id = split_id; + break; + default: + break; + } + + /* Try reading using DMAE */ + if (dev_data->use_dmae && split_type != SPLIT_TYPE_VF && + (len >= s_hw_type_defs[dev_data->hw_type].dmae_thresh || + (PROTECT_WIDE_BUS && wide_bus))) { + struct qed_dmae_params dmae_params; - return offset; + /* Set DMAE params */ + memset(&dmae_params, 0, sizeof(dmae_params)); + SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_COMPLETION_DST, 1); + switch (split_type) { + case SPLIT_TYPE_PORT: + SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_PORT_VALID, + 1); + dmae_params.port_id = port_id; + break; + case SPLIT_TYPE_PF: + SET_FIELD(dmae_params.flags, + QED_DMAE_PARAMS_SRC_PF_VALID, 1); + dmae_params.src_pfid = pf_id; + break; + case SPLIT_TYPE_PORT_PF: + SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_PORT_VALID, + 1); + SET_FIELD(dmae_params.flags, + QED_DMAE_PARAMS_SRC_PF_VALID, 1); + dmae_params.port_id = port_id; + dmae_params.src_pfid = pf_id; + break; + default: + break; + } + + /* Execute DMAE command */ + read_using_dmae = !qed_dmae_grc2host(p_hwfn, + p_ptt, + DWORDS_TO_BYTES(addr), + (u64)(uintptr_t)(dump_buf), + len, &dmae_params); + if (!read_using_dmae) { + dev_data->use_dmae = 0; + DP_VERBOSE(p_hwfn, + QED_MSG_DEBUG, + "Failed reading from chip using DMAE, using GRC instead\n"); + } + } + + if (read_using_dmae) + goto print_log; + + /* If not read using DMAE, read using GRC */ + + /* Set pretend */ + if (split_type != dev_data->pretend.split_type || + split_id != dev_data->pretend.split_id) { + switch (split_type) { + case SPLIT_TYPE_PORT: + qed_port_pretend(p_hwfn, p_ptt, port_id); + break; + case SPLIT_TYPE_PF: + fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID, + pf_id); + qed_fid_pretend(p_hwfn, p_ptt, fid); + break; + case SPLIT_TYPE_PORT_PF: + fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID, + pf_id); + qed_port_fid_pretend(p_hwfn, p_ptt, port_id, fid); + break; + case SPLIT_TYPE_VF: + fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFVALID, 1) + | FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFID, + vf_id); + qed_fid_pretend(p_hwfn, p_ptt, fid); + break; + default: + break; + } + + dev_data->pretend.split_type = (u8)split_type; + dev_data->pretend.split_id = split_id; + } + + /* Read registers using GRC */ + qed_read_regs(p_hwfn, p_ptt, dump_buf, addr, len); + +print_log: + /* Print log */ + dev_data->num_regs_read += len; + thresh = s_hw_type_defs[dev_data->hw_type].log_thresh; + if ((dev_data->num_regs_read / thresh) > + ((dev_data->num_regs_read - len) / thresh)) + DP_VERBOSE(p_hwfn, + QED_MSG_DEBUG, + "Dumped %d registers...\n", dev_data->num_regs_read); + + return len; } /* Dumps GRC registers sequence header. Returns the dumped size in dwords. @@ -2451,7 +2119,8 @@ static u32 qed_grc_dump_reg_entry_hdr(u32 *dump_buf, static u32 qed_grc_dump_reg_entry(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *dump_buf, - bool dump, u32 addr, u32 len, bool wide_bus) + bool dump, u32 addr, u32 len, bool wide_bus, + enum init_split_types split_type, u8 split_id) { u32 offset = 0; @@ -2459,7 +2128,8 @@ static u32 qed_grc_dump_reg_entry(struct qed_hwfn *p_hwfn, offset += qed_grc_dump_addr_range(p_hwfn, p_ptt, dump_buf + offset, - dump, addr, len, wide_bus); + dump, addr, len, wide_bus, + split_type, split_id); return offset; } @@ -2492,7 +2162,8 @@ static u32 qed_grc_dump_reg_entry_skip(struct qed_hwfn *p_hwfn, offset += qed_grc_dump_addr_range(p_hwfn, p_ptt, dump_buf + offset, - dump, addr, curr_len, false); + dump, addr, curr_len, false, + SPLIT_TYPE_NONE, 0); reg_offset += curr_len; addr += curr_len; @@ -2511,9 +2182,11 @@ static u32 qed_grc_dump_reg_entry_skip(struct qed_hwfn *p_hwfn, /* Dumps GRC registers entries. Returns the dumped size in dwords. */ static u32 qed_grc_dump_regs_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, - struct dbg_array input_regs_arr, + struct virt_mem_desc input_regs_arr, u32 *dump_buf, bool dump, + enum init_split_types split_type, + u8 split_id, bool block_enable[MAX_BLOCK_ID], u32 *num_dumped_reg_entries) { @@ -2522,10 +2195,10 @@ static u32 qed_grc_dump_regs_entries(struct qed_hwfn *p_hwfn, *num_dumped_reg_entries = 0; - while (input_offset < input_regs_arr.size_in_dwords) { + while (input_offset < BYTES_TO_DWORDS(input_regs_arr.size)) { const struct dbg_dump_cond_hdr *cond_hdr = (const struct dbg_dump_cond_hdr *) - &input_regs_arr.ptr[input_offset++]; + input_regs_arr.ptr + input_offset++; u16 modes_buf_offset; bool eval_mode; @@ -2548,7 +2221,7 @@ static u32 qed_grc_dump_regs_entries(struct qed_hwfn *p_hwfn, for (i = 0; i < cond_hdr->data_size; i++, input_offset++) { const struct dbg_dump_reg *reg = (const struct dbg_dump_reg *) - &input_regs_arr.ptr[input_offset]; + input_regs_arr.ptr + input_offset; u32 addr, len; bool wide_bus; @@ -2561,7 +2234,8 @@ static u32 qed_grc_dump_regs_entries(struct qed_hwfn *p_hwfn, dump, addr, len, - wide_bus); + wide_bus, + split_type, split_id); (*num_dumped_reg_entries)++; } } @@ -2572,23 +2246,30 @@ static u32 qed_grc_dump_regs_entries(struct qed_hwfn *p_hwfn, /* Dumps GRC registers entries. Returns the dumped size in dwords. */ static u32 qed_grc_dump_split_data(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, - struct dbg_array input_regs_arr, + struct virt_mem_desc input_regs_arr, u32 *dump_buf, bool dump, bool block_enable[MAX_BLOCK_ID], - const char *split_type_name, - u32 split_id, - const char *param_name, - const char *param_val) + enum init_split_types split_type, + u8 split_id, const char *reg_type_name) { + struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; + enum init_split_types hdr_split_type = split_type; u32 num_dumped_reg_entries, offset; + u8 hdr_split_id = split_id; + + /* In PORT_PF split type, print a port split header */ + if (split_type == SPLIT_TYPE_PORT_PF) { + hdr_split_type = SPLIT_TYPE_PORT; + hdr_split_id = split_id / dev_data->num_pfs_per_port; + } /* Calculate register dump header size (and skip it for now) */ offset = qed_grc_dump_regs_hdr(dump_buf, false, 0, - split_type_name, - split_id, param_name, param_val); + hdr_split_type, + hdr_split_id, reg_type_name); /* Dump registers */ offset += qed_grc_dump_regs_entries(p_hwfn, @@ -2596,6 +2277,8 @@ static u32 qed_grc_dump_split_data(struct qed_hwfn *p_hwfn, input_regs_arr, dump_buf + offset, dump, + split_type, + split_id, block_enable, &num_dumped_reg_entries); @@ -2604,8 +2287,8 @@ static u32 qed_grc_dump_split_data(struct qed_hwfn *p_hwfn, qed_grc_dump_regs_hdr(dump_buf, dump, num_dumped_reg_entries, - split_type_name, - split_id, param_name, param_val); + hdr_split_type, + hdr_split_id, reg_type_name); return num_dumped_reg_entries > 0 ? offset : 0; } @@ -2618,134 +2301,72 @@ static u32 qed_grc_dump_registers(struct qed_hwfn *p_hwfn, u32 *dump_buf, bool dump, bool block_enable[MAX_BLOCK_ID], - const char *param_name, const char *param_val) + const char *reg_type_name) { + struct virt_mem_desc *dbg_buf = + &p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG]; struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; - struct chip_platform_defs *chip_platform; u32 offset = 0, input_offset = 0; - struct chip_defs *chip; - u8 port_id, pf_id, vf_id; - u16 fid; - - chip = &s_chip_defs[dev_data->chip_id]; - chip_platform = &chip->per_platform[dev_data->platform_id]; - if (dump) - DP_VERBOSE(p_hwfn, QED_MSG_DEBUG, "Dumping registers...\n"); - - while (input_offset < - s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].size_in_dwords) { + while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) { const struct dbg_dump_split_hdr *split_hdr; - struct dbg_array curr_input_regs_arr; + struct virt_mem_desc curr_input_regs_arr; + enum init_split_types split_type; + u16 split_count = 0; u32 split_data_size; - u8 split_type_id; + u8 split_id; split_hdr = - (const struct dbg_dump_split_hdr *) - &s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr[input_offset++]; - split_type_id = - GET_FIELD(split_hdr->hdr, - DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID); - split_data_size = - GET_FIELD(split_hdr->hdr, - DBG_DUMP_SPLIT_HDR_DATA_SIZE); + (const struct dbg_dump_split_hdr *) + dbg_buf->ptr + input_offset++; + split_type = + GET_FIELD(split_hdr->hdr, + DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID); + split_data_size = GET_FIELD(split_hdr->hdr, + DBG_DUMP_SPLIT_HDR_DATA_SIZE); curr_input_regs_arr.ptr = - &s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr[input_offset]; - curr_input_regs_arr.size_in_dwords = split_data_size; + (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr + + input_offset; + curr_input_regs_arr.size = DWORDS_TO_BYTES(split_data_size); - switch (split_type_id) { + switch (split_type) { case SPLIT_TYPE_NONE: - offset += qed_grc_dump_split_data(p_hwfn, - p_ptt, - curr_input_regs_arr, - dump_buf + offset, - dump, - block_enable, - "eng", - (u32)(-1), - param_name, - param_val); + split_count = 1; break; - case SPLIT_TYPE_PORT: - for (port_id = 0; port_id < chip_platform->num_ports; - port_id++) { - if (dump) - qed_port_pretend(p_hwfn, p_ptt, - port_id); - offset += - qed_grc_dump_split_data(p_hwfn, p_ptt, - curr_input_regs_arr, - dump_buf + offset, - dump, block_enable, - "port", port_id, - param_name, - param_val); - } + split_count = dev_data->num_ports; break; - case SPLIT_TYPE_PF: case SPLIT_TYPE_PORT_PF: - for (pf_id = 0; pf_id < chip_platform->num_pfs; - pf_id++) { - u8 pfid_shift = - PXP_PRETEND_CONCRETE_FID_PFID_SHIFT; - - if (dump) { - fid = pf_id << pfid_shift; - qed_fid_pretend(p_hwfn, p_ptt, fid); - } - - offset += - qed_grc_dump_split_data(p_hwfn, - p_ptt, - curr_input_regs_arr, - dump_buf + offset, - dump, - block_enable, - "pf", - pf_id, - param_name, - param_val); - } + split_count = dev_data->num_ports * + dev_data->num_pfs_per_port; break; - case SPLIT_TYPE_VF: - for (vf_id = 0; vf_id < chip_platform->num_vfs; - vf_id++) { - u8 vfvalid_shift = - PXP_PRETEND_CONCRETE_FID_VFVALID_SHIFT; - u8 vfid_shift = - PXP_PRETEND_CONCRETE_FID_VFID_SHIFT; - - if (dump) { - fid = BIT(vfvalid_shift) | - (vf_id << vfid_shift); - qed_fid_pretend(p_hwfn, p_ptt, fid); - } - - offset += - qed_grc_dump_split_data(p_hwfn, p_ptt, - curr_input_regs_arr, - dump_buf + offset, - dump, block_enable, - "vf", vf_id, - param_name, - param_val); - } + split_count = dev_data->num_vfs; break; - default: - break; + return 0; } + for (split_id = 0; split_id < split_count; split_id++) + offset += qed_grc_dump_split_data(p_hwfn, p_ptt, + curr_input_regs_arr, + dump_buf + offset, + dump, block_enable, + split_type, + split_id, + reg_type_name); + input_offset += split_data_size; } - /* Pretend to original PF */ + /* Cancel pretends (pretend to original PF) */ if (dump) { - fid = p_hwfn->rel_pf_id << PXP_PRETEND_CONCRETE_FID_PFID_SHIFT; - qed_fid_pretend(p_hwfn, p_ptt, fid); + qed_fid_pretend(p_hwfn, p_ptt, + FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID, + p_hwfn->rel_pf_id)); + dev_data->pretend.split_type = SPLIT_TYPE_NONE; + dev_data->pretend.split_id = 0; } return offset; @@ -2756,32 +2377,40 @@ static u32 qed_grc_dump_reset_regs(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) { - struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; - u32 i, offset = 0, num_regs = 0; + u32 offset = 0, num_regs = 0; + u8 reset_reg_id; /* Calculate header size */ offset += qed_grc_dump_regs_hdr(dump_buf, - false, 0, "eng", -1, NULL, NULL); + false, + 0, SPLIT_TYPE_NONE, 0, "RESET_REGS"); /* Write reset registers */ - for (i = 0; i < MAX_DBG_RESET_REGS; i++) { - if (!s_reset_regs_defs[i].exists[dev_data->chip_id]) + for (reset_reg_id = 0; reset_reg_id < NUM_DBG_RESET_REGS; + reset_reg_id++) { + const struct dbg_reset_reg *reset_reg; + u32 reset_reg_addr; + + reset_reg = qed_get_dbg_reset_reg(p_hwfn, reset_reg_id); + + if (GET_FIELD(reset_reg->data, DBG_RESET_REG_IS_REMOVED)) continue; + reset_reg_addr = GET_FIELD(reset_reg->data, DBG_RESET_REG_ADDR); offset += qed_grc_dump_reg_entry(p_hwfn, p_ptt, dump_buf + offset, dump, - BYTES_TO_DWORDS - (s_reset_regs_defs[i].addr), 1, - false); + reset_reg_addr, + 1, false, SPLIT_TYPE_NONE, 0); num_regs++; } /* Write header */ if (dump) qed_grc_dump_regs_hdr(dump_buf, - true, num_regs, "eng", -1, NULL, NULL); + true, num_regs, SPLIT_TYPE_NONE, + 0, "RESET_REGS"); return offset; } @@ -2794,20 +2423,23 @@ static u32 qed_grc_dump_modified_regs(struct qed_hwfn *p_hwfn, u32 *dump_buf, bool dump) { struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; - u32 block_id, offset = 0, num_reg_entries = 0; + u32 block_id, offset = 0, stall_regs_offset; const struct dbg_attn_reg *attn_reg_arr; u8 storm_id, reg_idx, num_attn_regs; + u32 num_reg_entries = 0; - /* Calculate header size */ + /* Write empty header for attention registers */ offset += qed_grc_dump_regs_hdr(dump_buf, - false, 0, "eng", -1, NULL, NULL); + false, + 0, SPLIT_TYPE_NONE, 0, "ATTN_REGS"); /* Write parity registers */ - for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) { + for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) { if (dev_data->block_in_reset[block_id] && dump) continue; - attn_reg_arr = qed_get_block_attn_regs((enum block_id)block_id, + attn_reg_arr = qed_get_block_attn_regs(p_hwfn, + (enum block_id)block_id, ATTN_TYPE_PARITY, &num_attn_regs); @@ -2835,7 +2467,8 @@ static u32 qed_grc_dump_modified_regs(struct qed_hwfn *p_hwfn, dump_buf + offset, dump, addr, - 1, false); + 1, false, + SPLIT_TYPE_NONE, 0); addr = GET_FIELD(reg_data->data, DBG_ATTN_REG_STS_ADDRESS); offset += qed_grc_dump_reg_entry(p_hwfn, @@ -2843,21 +2476,35 @@ static u32 qed_grc_dump_modified_regs(struct qed_hwfn *p_hwfn, dump_buf + offset, dump, addr, - 1, false); + 1, false, + SPLIT_TYPE_NONE, 0); num_reg_entries += 2; } } + /* Overwrite header for attention registers */ + if (dump) + qed_grc_dump_regs_hdr(dump_buf, + true, + num_reg_entries, + SPLIT_TYPE_NONE, 0, "ATTN_REGS"); + + /* Write empty header for stall registers */ + stall_regs_offset = offset; + offset += qed_grc_dump_regs_hdr(dump_buf, + false, 0, SPLIT_TYPE_NONE, 0, "REGS"); + /* Write Storm stall status registers */ - for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) { + for (storm_id = 0, num_reg_entries = 0; storm_id < MAX_DBG_STORMS; + storm_id++) { struct storm_defs *storm = &s_storm_defs[storm_id]; u32 addr; - if (dev_data->block_in_reset[storm->block_id] && dump) + if (dev_data->block_in_reset[storm->sem_block_id] && dump) continue; addr = - BYTES_TO_DWORDS(s_storm_defs[storm_id].sem_fast_mem_addr + + BYTES_TO_DWORDS(storm->sem_fast_mem_addr + SEM_FAST_REG_STALLED); offset += qed_grc_dump_reg_entry(p_hwfn, p_ptt, @@ -2865,15 +2512,16 @@ static u32 qed_grc_dump_modified_regs(struct qed_hwfn *p_hwfn, dump, addr, 1, - false); + false, SPLIT_TYPE_NONE, 0); num_reg_entries++; } - /* Write header */ + /* Overwrite header for stall registers */ if (dump) - qed_grc_dump_regs_hdr(dump_buf, + qed_grc_dump_regs_hdr(dump_buf + stall_regs_offset, true, - num_reg_entries, "eng", -1, NULL, NULL); + num_reg_entries, + SPLIT_TYPE_NONE, 0, "REGS"); return offset; } @@ -2886,7 +2534,7 @@ static u32 qed_grc_dump_special_regs(struct qed_hwfn *p_hwfn, u32 offset = 0, addr; offset += qed_grc_dump_regs_hdr(dump_buf, - dump, 2, "eng", -1, NULL, NULL); + dump, 2, SPLIT_TYPE_NONE, 0, "REGS"); /* Dump R/TDIF_REG_DEBUG_ERROR_INFO_SIZE (every 8'th register should be * skipped). @@ -2934,8 +2582,7 @@ static u32 qed_grc_dump_mem_hdr(struct qed_hwfn *p_hwfn, u32 len, u32 bit_width, bool packed, - const char *mem_group, - bool is_storm, char storm_letter) + const char *mem_group, char storm_letter) { u8 num_params = 3; u32 offset = 0; @@ -2956,7 +2603,7 @@ static u32 qed_grc_dump_mem_hdr(struct qed_hwfn *p_hwfn, if (name) { /* Dump name */ - if (is_storm) { + if (storm_letter) { strcpy(buf, "?STORM_"); buf[0] = storm_letter; strcpy(buf + strlen(buf), name); @@ -2966,22 +2613,12 @@ static u32 qed_grc_dump_mem_hdr(struct qed_hwfn *p_hwfn, offset += qed_dump_str_param(dump_buf + offset, dump, "name", buf); - if (dump) - DP_VERBOSE(p_hwfn, - QED_MSG_DEBUG, - "Dumping %d registers from %s...\n", - len, buf); } else { /* Dump address */ u32 addr_in_bytes = DWORDS_TO_BYTES(addr); offset += qed_dump_num_param(dump_buf + offset, dump, "addr", addr_in_bytes); - if (dump && len > 64) - DP_VERBOSE(p_hwfn, - QED_MSG_DEBUG, - "Dumping %d registers from address 0x%x...\n", - len, addr_in_bytes); } /* Dump len */ @@ -2998,7 +2635,7 @@ static u32 qed_grc_dump_mem_hdr(struct qed_hwfn *p_hwfn, dump, "packed", 1); /* Dump reg type */ - if (is_storm) { + if (storm_letter) { strcpy(buf, "?STORM_"); buf[0] = storm_letter; strcpy(buf + strlen(buf), mem_group); @@ -3025,8 +2662,7 @@ static u32 qed_grc_dump_mem(struct qed_hwfn *p_hwfn, bool wide_bus, u32 bit_width, bool packed, - const char *mem_group, - bool is_storm, char storm_letter) + const char *mem_group, char storm_letter) { u32 offset = 0; @@ -3037,12 +2673,12 @@ static u32 qed_grc_dump_mem(struct qed_hwfn *p_hwfn, addr, len, bit_width, - packed, - mem_group, is_storm, storm_letter); + packed, mem_group, storm_letter); offset += qed_grc_dump_addr_range(p_hwfn, p_ptt, dump_buf + offset, - dump, addr, len, wide_bus); + dump, addr, len, wide_bus, + SPLIT_TYPE_NONE, 0); return offset; } @@ -3050,20 +2686,21 @@ static u32 qed_grc_dump_mem(struct qed_hwfn *p_hwfn, /* Dumps GRC memories entries. Returns the dumped size in dwords. */ static u32 qed_grc_dump_mem_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, - struct dbg_array input_mems_arr, + struct virt_mem_desc input_mems_arr, u32 *dump_buf, bool dump) { u32 i, offset = 0, input_offset = 0; bool mode_match = true; - while (input_offset < input_mems_arr.size_in_dwords) { + while (input_offset < BYTES_TO_DWORDS(input_mems_arr.size)) { const struct dbg_dump_cond_hdr *cond_hdr; u16 modes_buf_offset; u32 num_entries; bool eval_mode; - cond_hdr = (const struct dbg_dump_cond_hdr *) - &input_mems_arr.ptr[input_offset++]; + cond_hdr = + (const struct dbg_dump_cond_hdr *)input_mems_arr.ptr + + input_offset++; num_entries = cond_hdr->data_size / MEM_DUMP_ENTRY_SIZE_DWORDS; /* Check required mode */ @@ -3085,24 +2722,25 @@ static u32 qed_grc_dump_mem_entries(struct qed_hwfn *p_hwfn, for (i = 0; i < num_entries; i++, input_offset += MEM_DUMP_ENTRY_SIZE_DWORDS) { const struct dbg_dump_mem *mem = - (const struct dbg_dump_mem *) - &input_mems_arr.ptr[input_offset]; - u8 mem_group_id = GET_FIELD(mem->dword0, - DBG_DUMP_MEM_MEM_GROUP_ID); - bool is_storm = false, mem_wide_bus; - enum dbg_grc_params grc_param; - char storm_letter = 'a'; - enum block_id block_id; + (const struct dbg_dump_mem *)((u32 *) + input_mems_arr.ptr + + input_offset); + const struct dbg_block *block; + char storm_letter = 0; u32 mem_addr, mem_len; + bool mem_wide_bus; + u8 mem_group_id; + mem_group_id = GET_FIELD(mem->dword0, + DBG_DUMP_MEM_MEM_GROUP_ID); if (mem_group_id >= MEM_GROUPS_NUM) { DP_NOTICE(p_hwfn, "Invalid mem_group_id\n"); return 0; } - block_id = (enum block_id)cond_hdr->block_id; if (!qed_grc_is_mem_included(p_hwfn, - block_id, + (enum block_id) + cond_hdr->block_id, mem_group_id)) continue; @@ -3111,42 +2749,14 @@ static u32 qed_grc_dump_mem_entries(struct qed_hwfn *p_hwfn, mem_wide_bus = GET_FIELD(mem->dword1, DBG_DUMP_MEM_WIDE_BUS); - /* Update memory length for CCFC/TCFC memories - * according to number of LCIDs/LTIDs. - */ - if (mem_group_id == MEM_GROUP_CONN_CFC_MEM) { - if (mem_len % MAX_LCIDS) { - DP_NOTICE(p_hwfn, - "Invalid CCFC connection memory size\n"); - return 0; - } - - grc_param = DBG_GRC_PARAM_NUM_LCIDS; - mem_len = qed_grc_get_param(p_hwfn, grc_param) * - (mem_len / MAX_LCIDS); - } else if (mem_group_id == MEM_GROUP_TASK_CFC_MEM) { - if (mem_len % MAX_LTIDS) { - DP_NOTICE(p_hwfn, - "Invalid TCFC task memory size\n"); - return 0; - } - - grc_param = DBG_GRC_PARAM_NUM_LTIDS; - mem_len = qed_grc_get_param(p_hwfn, grc_param) * - (mem_len / MAX_LTIDS); - } + block = get_dbg_block(p_hwfn, + cond_hdr->block_id); - /* If memory is associated with Storm, update Storm - * details. + /* If memory is associated with Storm, + * update storm details */ - if (s_block_defs - [cond_hdr->block_id]->associated_to_storm) { - is_storm = true; - storm_letter = - s_storm_defs[s_block_defs - [cond_hdr->block_id]-> - storm_id].letter; - } + if (block->associated_storm_letter) + storm_letter = block->associated_storm_letter; /* Dump memory */ offset += qed_grc_dump_mem(p_hwfn, @@ -3160,7 +2770,6 @@ static u32 qed_grc_dump_mem_entries(struct qed_hwfn *p_hwfn, 0, false, s_mem_group_names[mem_group_id], - is_storm, storm_letter); } } @@ -3175,41 +2784,35 @@ static u32 qed_grc_dump_memories(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) { + struct virt_mem_desc *dbg_buf = + &p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_MEM]; u32 offset = 0, input_offset = 0; - while (input_offset < - s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].size_in_dwords) { + while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) { const struct dbg_dump_split_hdr *split_hdr; - struct dbg_array curr_input_mems_arr; + struct virt_mem_desc curr_input_mems_arr; + enum init_split_types split_type; u32 split_data_size; - u8 split_type_id; - - split_hdr = (const struct dbg_dump_split_hdr *) - &s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr[input_offset++]; - split_type_id = - GET_FIELD(split_hdr->hdr, - DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID); - split_data_size = - GET_FIELD(split_hdr->hdr, - DBG_DUMP_SPLIT_HDR_DATA_SIZE); - curr_input_mems_arr.ptr = - &s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr[input_offset]; - curr_input_mems_arr.size_in_dwords = split_data_size; - - switch (split_type_id) { - case SPLIT_TYPE_NONE: + + split_hdr = + (const struct dbg_dump_split_hdr *)dbg_buf->ptr + + input_offset++; + split_type = GET_FIELD(split_hdr->hdr, + DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID); + split_data_size = GET_FIELD(split_hdr->hdr, + DBG_DUMP_SPLIT_HDR_DATA_SIZE); + curr_input_mems_arr.ptr = (u32 *)dbg_buf->ptr + input_offset; + curr_input_mems_arr.size = DWORDS_TO_BYTES(split_data_size); + + if (split_type == SPLIT_TYPE_NONE) offset += qed_grc_dump_mem_entries(p_hwfn, p_ptt, curr_input_mems_arr, dump_buf + offset, dump); - break; - - default: + else DP_NOTICE(p_hwfn, "Dumping split memories is currently not supported\n"); - break; - } input_offset += split_data_size; } @@ -3227,17 +2830,19 @@ static u32 qed_grc_dump_ctx_data(struct qed_hwfn *p_hwfn, bool dump, const char *name, u32 num_lids, - u32 lid_size, - u32 rd_reg_addr, - u8 storm_id) + enum cm_ctx_types ctx_type, u8 storm_id) { + struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; struct storm_defs *storm = &s_storm_defs[storm_id]; - u32 i, lid, total_size, offset = 0; + u32 i, lid, lid_size, total_size; + u32 rd_reg_addr, offset = 0; + + /* Convert quad-regs to dwords */ + lid_size = storm->cm_ctx_lid_sizes[dev_data->chip_id][ctx_type] * 4; if (!lid_size) return 0; - lid_size *= BYTES_IN_DWORD; total_size = num_lids * lid_size; offset += qed_grc_dump_mem_hdr(p_hwfn, @@ -3247,19 +2852,28 @@ static u32 qed_grc_dump_ctx_data(struct qed_hwfn *p_hwfn, 0, total_size, lid_size * 32, - false, name, true, storm->letter); + false, name, storm->letter); if (!dump) return offset + total_size; + rd_reg_addr = BYTES_TO_DWORDS(storm->cm_ctx_rd_addr[ctx_type]); + /* Dump context data */ for (lid = 0; lid < num_lids; lid++) { - for (i = 0; i < lid_size; i++, offset++) { + for (i = 0; i < lid_size; i++) { qed_wr(p_hwfn, p_ptt, storm->cm_ctx_wr_addr, (i << 9) | lid); - *(dump_buf + offset) = qed_rd(p_hwfn, - p_ptt, rd_reg_addr); + offset += qed_grc_dump_addr_range(p_hwfn, + p_ptt, + dump_buf + offset, + dump, + rd_reg_addr, + 1, + false, + SPLIT_TYPE_NONE, 0); } + cond_resched(); } return offset; @@ -3269,114 +2883,126 @@ static u32 qed_grc_dump_ctx_data(struct qed_hwfn *p_hwfn, static u32 qed_grc_dump_ctx(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) { - enum dbg_grc_params grc_param; u32 offset = 0; u8 storm_id; for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) { - struct storm_defs *storm = &s_storm_defs[storm_id]; - if (!qed_grc_is_storm_included(p_hwfn, (enum dbg_storms)storm_id)) continue; /* Dump Conn AG context size */ - grc_param = DBG_GRC_PARAM_NUM_LCIDS; - offset += - qed_grc_dump_ctx_data(p_hwfn, - p_ptt, - dump_buf + offset, - dump, - "CONN_AG_CTX", - qed_grc_get_param(p_hwfn, - grc_param), - storm->cm_conn_ag_ctx_lid_size, - storm->cm_conn_ag_ctx_rd_addr, - storm_id); + offset += qed_grc_dump_ctx_data(p_hwfn, + p_ptt, + dump_buf + offset, + dump, + "CONN_AG_CTX", + NUM_OF_LCIDS, + CM_CTX_CONN_AG, storm_id); /* Dump Conn ST context size */ - grc_param = DBG_GRC_PARAM_NUM_LCIDS; - offset += - qed_grc_dump_ctx_data(p_hwfn, - p_ptt, - dump_buf + offset, - dump, - "CONN_ST_CTX", - qed_grc_get_param(p_hwfn, - grc_param), - storm->cm_conn_st_ctx_lid_size, - storm->cm_conn_st_ctx_rd_addr, - storm_id); + offset += qed_grc_dump_ctx_data(p_hwfn, + p_ptt, + dump_buf + offset, + dump, + "CONN_ST_CTX", + NUM_OF_LCIDS, + CM_CTX_CONN_ST, storm_id); /* Dump Task AG context size */ - grc_param = DBG_GRC_PARAM_NUM_LTIDS; - offset += - qed_grc_dump_ctx_data(p_hwfn, - p_ptt, - dump_buf + offset, - dump, - "TASK_AG_CTX", - qed_grc_get_param(p_hwfn, - grc_param), - storm->cm_task_ag_ctx_lid_size, - storm->cm_task_ag_ctx_rd_addr, - storm_id); + offset += qed_grc_dump_ctx_data(p_hwfn, + p_ptt, + dump_buf + offset, + dump, + "TASK_AG_CTX", + NUM_OF_LTIDS, + CM_CTX_TASK_AG, storm_id); /* Dump Task ST context size */ - grc_param = DBG_GRC_PARAM_NUM_LTIDS; - offset += - qed_grc_dump_ctx_data(p_hwfn, - p_ptt, - dump_buf + offset, - dump, - "TASK_ST_CTX", - qed_grc_get_param(p_hwfn, - grc_param), - storm->cm_task_st_ctx_lid_size, - storm->cm_task_st_ctx_rd_addr, - storm_id); + offset += qed_grc_dump_ctx_data(p_hwfn, + p_ptt, + dump_buf + offset, + dump, + "TASK_ST_CTX", + NUM_OF_LTIDS, + CM_CTX_TASK_ST, storm_id); } return offset; } -/* Dumps GRC IORs data. Returns the dumped size in dwords. */ -static u32 qed_grc_dump_iors(struct qed_hwfn *p_hwfn, - struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) -{ - char buf[10] = "IOR_SET_?"; - u32 addr, offset = 0; - u8 storm_id, set_id; +#define VFC_STATUS_RESP_READY_BIT 0 +#define VFC_STATUS_BUSY_BIT 1 +#define VFC_STATUS_SENDING_CMD_BIT 2 - for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) { - struct storm_defs *storm = &s_storm_defs[storm_id]; +#define VFC_POLLING_DELAY_MS 1 +#define VFC_POLLING_COUNT 20 - if (!qed_grc_is_storm_included(p_hwfn, - (enum dbg_storms)storm_id)) - continue; +/* Reads data from VFC. Returns the number of dwords read (0 on error). + * Sizes are specified in dwords. + */ +static u32 qed_grc_dump_read_from_vfc(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + struct storm_defs *storm, + u32 *cmd_data, + u32 cmd_size, + u32 *addr_data, + u32 addr_size, + u32 resp_size, u32 *dump_buf) +{ + struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; + u32 vfc_status, polling_ms, polling_count = 0, i; + u32 reg_addr, sem_base; + bool is_ready = false; + + sem_base = storm->sem_fast_mem_addr; + polling_ms = VFC_POLLING_DELAY_MS * + s_hw_type_defs[dev_data->hw_type].delay_factor; + + /* Write VFC command */ + ARR_REG_WR(p_hwfn, + p_ptt, + sem_base + SEM_FAST_REG_VFC_DATA_WR, + cmd_data, cmd_size); + + /* Write VFC address */ + ARR_REG_WR(p_hwfn, + p_ptt, + sem_base + SEM_FAST_REG_VFC_ADDR, + addr_data, addr_size); + + /* Read response */ + for (i = 0; i < resp_size; i++) { + /* Poll until ready */ + do { + reg_addr = sem_base + SEM_FAST_REG_VFC_STATUS; + qed_grc_dump_addr_range(p_hwfn, + p_ptt, + &vfc_status, + true, + BYTES_TO_DWORDS(reg_addr), + 1, + false, SPLIT_TYPE_NONE, 0); + is_ready = vfc_status & BIT(VFC_STATUS_RESP_READY_BIT); + + if (!is_ready) { + if (polling_count++ == VFC_POLLING_COUNT) + return 0; - for (set_id = 0; set_id < NUM_IOR_SETS; set_id++) { - addr = BYTES_TO_DWORDS(storm->sem_fast_mem_addr + - SEM_FAST_REG_STORM_REG_FILE) + - IOR_SET_OFFSET(set_id); - buf[strlen(buf) - 1] = '0' + set_id; - offset += qed_grc_dump_mem(p_hwfn, - p_ptt, - dump_buf + offset, - dump, - buf, - addr, - IORS_PER_SET, - false, - 32, - false, - "ior", - true, - storm->letter); - } + msleep(polling_ms); + } + } while (!is_ready); + + reg_addr = sem_base + SEM_FAST_REG_VFC_DATA_RD; + qed_grc_dump_addr_range(p_hwfn, + p_ptt, + dump_buf + i, + true, + BYTES_TO_DWORDS(reg_addr), + 1, false, SPLIT_TYPE_NONE, 0); } - return offset; + return resp_size; } /* Dump VFC CAM. Returns the dumped size in dwords. */ @@ -3388,7 +3014,7 @@ static u32 qed_grc_dump_vfc_cam(struct qed_hwfn *p_hwfn, struct storm_defs *storm = &s_storm_defs[storm_id]; u32 cam_addr[VFC_CAM_ADDR_DWORDS] = { 0 }; u32 cam_cmd[VFC_CAM_CMD_DWORDS] = { 0 }; - u32 row, i, offset = 0; + u32 row, offset = 0; offset += qed_grc_dump_mem_hdr(p_hwfn, dump_buf + offset, @@ -3397,7 +3023,7 @@ static u32 qed_grc_dump_vfc_cam(struct qed_hwfn *p_hwfn, 0, total_size, 256, - false, "vfc_cam", true, storm->letter); + false, "vfc_cam", storm->letter); if (!dump) return offset + total_size; @@ -3405,26 +3031,18 @@ static u32 qed_grc_dump_vfc_cam(struct qed_hwfn *p_hwfn, /* Prepare CAM address */ SET_VAR_FIELD(cam_addr, VFC_CAM_ADDR, OP, VFC_OPCODE_CAM_RD); - for (row = 0; row < VFC_CAM_NUM_ROWS; - row++, offset += VFC_CAM_RESP_DWORDS) { - /* Write VFC CAM command */ + /* Read VFC CAM data */ + for (row = 0; row < VFC_CAM_NUM_ROWS; row++) { SET_VAR_FIELD(cam_cmd, VFC_CAM_CMD, ROW, row); - ARR_REG_WR(p_hwfn, - p_ptt, - storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_DATA_WR, - cam_cmd, VFC_CAM_CMD_DWORDS); - - /* Write VFC CAM address */ - ARR_REG_WR(p_hwfn, - p_ptt, - storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_ADDR, - cam_addr, VFC_CAM_ADDR_DWORDS); - - /* Read VFC CAM read response */ - ARR_REG_RD(p_hwfn, - p_ptt, - storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_DATA_RD, - dump_buf + offset, VFC_CAM_RESP_DWORDS); + offset += qed_grc_dump_read_from_vfc(p_hwfn, + p_ptt, + storm, + cam_cmd, + VFC_CAM_CMD_DWORDS, + cam_addr, + VFC_CAM_ADDR_DWORDS, + VFC_CAM_RESP_DWORDS, + dump_buf + offset); } return offset; @@ -3441,7 +3059,7 @@ static u32 qed_grc_dump_vfc_ram(struct qed_hwfn *p_hwfn, struct storm_defs *storm = &s_storm_defs[storm_id]; u32 ram_addr[VFC_RAM_ADDR_DWORDS] = { 0 }; u32 ram_cmd[VFC_RAM_CMD_DWORDS] = { 0 }; - u32 row, i, offset = 0; + u32 row, offset = 0; offset += qed_grc_dump_mem_hdr(p_hwfn, dump_buf + offset, @@ -3452,35 +3070,27 @@ static u32 qed_grc_dump_vfc_ram(struct qed_hwfn *p_hwfn, 256, false, ram_defs->type_name, - true, storm->letter); - - /* Prepare RAM address */ - SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, OP, VFC_OPCODE_RAM_RD); + storm->letter); if (!dump) return offset + total_size; + /* Prepare RAM address */ + SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, OP, VFC_OPCODE_RAM_RD); + + /* Read VFC RAM data */ for (row = ram_defs->base_row; - row < ram_defs->base_row + ram_defs->num_rows; - row++, offset += VFC_RAM_RESP_DWORDS) { - /* Write VFC RAM command */ - ARR_REG_WR(p_hwfn, - p_ptt, - storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_DATA_WR, - ram_cmd, VFC_RAM_CMD_DWORDS); - - /* Write VFC RAM address */ + row < ram_defs->base_row + ram_defs->num_rows; row++) { SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, ROW, row); - ARR_REG_WR(p_hwfn, - p_ptt, - storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_ADDR, - ram_addr, VFC_RAM_ADDR_DWORDS); - - /* Read VFC RAM read response */ - ARR_REG_RD(p_hwfn, - p_ptt, - storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_DATA_RD, - dump_buf + offset, VFC_RAM_RESP_DWORDS); + offset += qed_grc_dump_read_from_vfc(p_hwfn, + p_ptt, + storm, + ram_cmd, + VFC_RAM_CMD_DWORDS, + ram_addr, + VFC_RAM_ADDR_DWORDS, + VFC_RAM_RESP_DWORDS, + dump_buf + offset); } return offset; @@ -3490,16 +3100,13 @@ static u32 qed_grc_dump_vfc_ram(struct qed_hwfn *p_hwfn, static u32 qed_grc_dump_vfc(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) { - struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; u8 storm_id, i; u32 offset = 0; for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) { if (!qed_grc_is_storm_included(p_hwfn, (enum dbg_storms)storm_id) || - !s_storm_defs[storm_id].has_vfc || - (storm_id == DBG_PSTORM_ID && dev_data->platform_id != - PLATFORM_ASIC)) + !s_storm_defs[storm_id].has_vfc) continue; /* Read CAM */ @@ -3530,17 +3137,16 @@ static u32 qed_grc_dump_rss(struct qed_hwfn *p_hwfn, u8 rss_mem_id; for (rss_mem_id = 0; rss_mem_id < NUM_RSS_MEM_TYPES; rss_mem_id++) { - u32 rss_addr, num_entries, entry_width, total_dwords, i; + u32 rss_addr, num_entries, total_dwords; struct rss_mem_defs *rss_defs; - u32 addr, size; + u32 addr, num_dwords_to_read; bool packed; rss_defs = &s_rss_mem_defs[rss_mem_id]; rss_addr = rss_defs->addr; num_entries = rss_defs->num_entries[dev_data->chip_id]; - entry_width = rss_defs->entry_width[dev_data->chip_id]; - total_dwords = (num_entries * entry_width) / 32; - packed = (entry_width == 16); + total_dwords = (num_entries * rss_defs->entry_width) / 32; + packed = (rss_defs->entry_width == 16); offset += qed_grc_dump_mem_hdr(p_hwfn, dump_buf + offset, @@ -3548,9 +3154,9 @@ static u32 qed_grc_dump_rss(struct qed_hwfn *p_hwfn, rss_defs->mem_name, 0, total_dwords, - entry_width, + rss_defs->entry_width, packed, - rss_defs->type_name, false, 0); + rss_defs->type_name, 0); /* Dump RSS data */ if (!dump) { @@ -3559,16 +3165,21 @@ static u32 qed_grc_dump_rss(struct qed_hwfn *p_hwfn, } addr = BYTES_TO_DWORDS(RSS_REG_RSS_RAM_DATA); - size = RSS_REG_RSS_RAM_DATA_SIZE; - for (i = 0; i < total_dwords; i += size, rss_addr++) { + while (total_dwords) { + num_dwords_to_read = min_t(u32, + RSS_REG_RSS_RAM_DATA_SIZE, + total_dwords); qed_wr(p_hwfn, p_ptt, RSS_REG_RSS_RAM_ADDR, rss_addr); offset += qed_grc_dump_addr_range(p_hwfn, p_ptt, dump_buf + offset, dump, addr, - size, - false); + num_dwords_to_read, + false, + SPLIT_TYPE_NONE, 0); + total_dwords -= num_dwords_to_read; + rss_addr++; } } @@ -3581,19 +3192,21 @@ static u32 qed_grc_dump_big_ram(struct qed_hwfn *p_hwfn, u32 *dump_buf, bool dump, u8 big_ram_id) { struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; - u32 total_blocks, ram_size, offset = 0, i; + u32 block_size, ram_size, offset = 0, reg_val, i; char mem_name[12] = "???_BIG_RAM"; char type_name[8] = "???_RAM"; struct big_ram_defs *big_ram; big_ram = &s_big_ram_defs[big_ram_id]; - total_blocks = big_ram->num_of_blocks[dev_data->chip_id]; - ram_size = total_blocks * BIG_RAM_BLOCK_SIZE_DWORDS; + ram_size = big_ram->ram_size[dev_data->chip_id]; + + reg_val = qed_rd(p_hwfn, p_ptt, big_ram->is_256b_reg_addr); + block_size = reg_val & + BIT(big_ram->is_256b_bit_offset[dev_data->chip_id]) ? 256 + : 128; - strncpy(type_name, big_ram->instance_name, - strlen(big_ram->instance_name)); - strncpy(mem_name, big_ram->instance_name, - strlen(big_ram->instance_name)); + memcpy(type_name, big_ram->instance_name, BIG_RAM_NAME_LEN); + memcpy(mem_name, big_ram->instance_name, BIG_RAM_NAME_LEN); /* Dump memory header */ offset += qed_grc_dump_mem_hdr(p_hwfn, @@ -3602,32 +3215,34 @@ static u32 qed_grc_dump_big_ram(struct qed_hwfn *p_hwfn, mem_name, 0, ram_size, - BIG_RAM_BLOCK_SIZE_BYTES * 8, - false, type_name, false, 0); + block_size * 8, + false, type_name, 0); /* Read and dump Big RAM data */ if (!dump) return offset + ram_size; /* Dump Big RAM */ - for (i = 0; i < total_blocks / 2; i++) { + for (i = 0; i < DIV_ROUND_UP(ram_size, BRB_REG_BIG_RAM_DATA_SIZE); + i++) { u32 addr, len; qed_wr(p_hwfn, p_ptt, big_ram->addr_reg_addr, i); addr = BYTES_TO_DWORDS(big_ram->data_reg_addr); - len = 2 * BIG_RAM_BLOCK_SIZE_DWORDS; + len = BRB_REG_BIG_RAM_DATA_SIZE; offset += qed_grc_dump_addr_range(p_hwfn, p_ptt, dump_buf + offset, dump, addr, len, - false); + false, SPLIT_TYPE_NONE, 0); } return offset; } +/* Dumps MCP scratchpad. Returns the dumped size in dwords. */ static u32 qed_grc_dump_mcp(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) { @@ -3650,7 +3265,7 @@ static u32 qed_grc_dump_mcp(struct qed_hwfn *p_hwfn, NULL, BYTES_TO_DWORDS(MCP_REG_SCRATCH), MCP_REG_SCRATCH_SIZE, - false, 0, false, "MCP", false, 0); + false, 0, false, "MCP", 0); /* Dump MCP cpu_reg_file */ offset += qed_grc_dump_mem(p_hwfn, @@ -3660,18 +3275,19 @@ static u32 qed_grc_dump_mcp(struct qed_hwfn *p_hwfn, NULL, BYTES_TO_DWORDS(MCP_REG_CPU_REG_FILE), MCP_REG_CPU_REG_FILE_SIZE, - false, 0, false, "MCP", false, 0); + false, 0, false, "MCP", 0); /* Dump MCP registers */ block_enable[BLOCK_MCP] = true; offset += qed_grc_dump_registers(p_hwfn, p_ptt, dump_buf + offset, - dump, block_enable, "block", "MCP"); + dump, block_enable, "MCP"); /* Dump required non-MCP registers */ offset += qed_grc_dump_regs_hdr(dump_buf + offset, - dump, 1, "eng", -1, "block", "MCP"); + dump, 1, SPLIT_TYPE_NONE, 0, + "MCP"); addr = BYTES_TO_DWORDS(MISC_REG_SHARED_MEM_ADDR); offset += qed_grc_dump_reg_entry(p_hwfn, p_ptt, @@ -3679,7 +3295,7 @@ static u32 qed_grc_dump_mcp(struct qed_hwfn *p_hwfn, dump, addr, 1, - false); + false, SPLIT_TYPE_NONE, 0); /* Release MCP */ if (halted && qed_mcp_resume(p_hwfn, p_ptt)) @@ -3688,7 +3304,9 @@ static u32 qed_grc_dump_mcp(struct qed_hwfn *p_hwfn, return offset; } -/* Dumps the tbus indirect memory for all PHYs. */ +/* Dumps the tbus indirect memory for all PHYs. + * Returns the dumped size in dwords. + */ static u32 qed_grc_dump_phy(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) { @@ -3710,7 +3328,6 @@ static u32 qed_grc_dump_phy(struct qed_hwfn *p_hwfn, phy_defs->tbus_data_lo_addr; data_hi_addr = phy_defs->base_addr + phy_defs->tbus_data_hi_addr; - bytes_buf = (u8 *)(dump_buf + offset); if (snprintf(mem_name, sizeof(mem_name), "tbus_%s", phy_defs->phy_name) < 0) @@ -3723,13 +3340,14 @@ static u32 qed_grc_dump_phy(struct qed_hwfn *p_hwfn, mem_name, 0, PHY_DUMP_SIZE_DWORDS, - 16, true, mem_name, false, 0); + 16, true, mem_name, 0); if (!dump) { offset += PHY_DUMP_SIZE_DWORDS; continue; } + bytes_buf = (u8 *)(dump_buf + offset); for (tbus_hi_offset = 0; tbus_hi_offset < (NUM_PHY_TBUS_ADDRESSES >> 8); tbus_hi_offset++) { @@ -3753,21 +3371,50 @@ static u32 qed_grc_dump_phy(struct qed_hwfn *p_hwfn, return offset; } -static void qed_config_dbg_line(struct qed_hwfn *p_hwfn, - struct qed_ptt *p_ptt, - enum block_id block_id, - u8 line_id, - u8 enable_mask, - u8 right_shift, - u8 force_valid_mask, u8 force_frame_mask) +/* Dumps the MCP HW dump from NVRAM. Returns the dumped size in dwords. */ +static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + u32 *dump_buf, bool dump) { - struct block_defs *block = s_block_defs[block_id]; + u32 hw_dump_offset_bytes = 0, hw_dump_size_bytes = 0; + u32 hw_dump_size_dwords = 0, offset = 0; + enum dbg_status status; + + /* Read HW dump image from NVRAM */ + status = qed_find_nvram_image(p_hwfn, + p_ptt, + NVM_TYPE_HW_DUMP_OUT, + &hw_dump_offset_bytes, + &hw_dump_size_bytes, + false); + if (status != DBG_STATUS_OK) + return 0; + + hw_dump_size_dwords = BYTES_TO_DWORDS(hw_dump_size_bytes); + + /* Dump HW dump image section */ + offset += qed_dump_section_hdr(dump_buf + offset, + dump, "mcp_hw_dump", 1); + offset += qed_dump_num_param(dump_buf + offset, + dump, "size", hw_dump_size_dwords); + + /* Read MCP HW dump image into dump buffer */ + if (dump && hw_dump_size_dwords) { + status = qed_nvram_read(p_hwfn, + p_ptt, + hw_dump_offset_bytes, + hw_dump_size_bytes, + dump_buf + offset, + false); + if (status != DBG_STATUS_OK) { + DP_NOTICE(p_hwfn, + "Failed to read MCP HW Dump image from NVRAM\n"); + return 0; + } + } + offset += hw_dump_size_dwords; - qed_wr(p_hwfn, p_ptt, block->dbg_select_addr, line_id); - qed_wr(p_hwfn, p_ptt, block->dbg_enable_addr, enable_mask); - qed_wr(p_hwfn, p_ptt, block->dbg_shift_addr, right_shift); - qed_wr(p_hwfn, p_ptt, block->dbg_force_valid_addr, force_valid_mask); - qed_wr(p_hwfn, p_ptt, block->dbg_force_frame_addr, force_frame_mask); + return offset; } /* Dumps Static Debug data. Returns the dumped size in dwords. */ @@ -3776,28 +3423,19 @@ static u32 qed_grc_dump_static_debug(struct qed_hwfn *p_hwfn, u32 *dump_buf, bool dump) { struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; - u32 block_id, line_id, offset = 0; + u32 block_id, line_id, offset = 0, addr, len; - /* Skip static debug if a debug bus recording is in progress */ - if (qed_rd(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON)) + /* Don't dump static debug if a debug bus recording is in progress */ + if (dump && qed_rd(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON)) return 0; if (dump) { - DP_VERBOSE(p_hwfn, - QED_MSG_DEBUG, "Dumping static debug data...\n"); - - /* Disable all blocks debug output */ - for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) { - struct block_defs *block = s_block_defs[block_id]; - - if (block->has_dbg_bus[dev_data->chip_id]) - qed_wr(p_hwfn, p_ptt, block->dbg_enable_addr, - 0); - } + /* Disable debug bus in all blocks */ + qed_bus_disable_blocks(p_hwfn, p_ptt); qed_bus_reset_dbg_block(p_hwfn, p_ptt); - qed_bus_set_framing_mode(p_hwfn, - p_ptt, DBG_BUS_FRAME_MODE_8HW_0ST); + qed_wr(p_hwfn, + p_ptt, DBG_REG_FRAMING_MODE, DBG_BUS_FRAME_MODE_8HW); qed_wr(p_hwfn, p_ptt, DBG_REG_DEBUG_TARGET, DBG_BUS_TARGET_ID_INT_BUF); qed_wr(p_hwfn, p_ptt, DBG_REG_FULL_MODE, 1); @@ -3806,28 +3444,44 @@ static u32 qed_grc_dump_static_debug(struct qed_hwfn *p_hwfn, /* Dump all static debug lines for each relevant block */ for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) { - struct block_defs *block = s_block_defs[block_id]; - struct dbg_bus_block *block_desc; - u32 block_dwords, addr, len; - u8 dbg_client_id; + const struct dbg_block_chip *block_per_chip; + const struct dbg_block *block; + bool is_removed, has_dbg_bus; + u16 modes_buf_offset; + u32 block_dwords; + + block_per_chip = + qed_get_dbg_block_per_chip(p_hwfn, (enum block_id)block_id); + is_removed = GET_FIELD(block_per_chip->flags, + DBG_BLOCK_CHIP_IS_REMOVED); + has_dbg_bus = GET_FIELD(block_per_chip->flags, + DBG_BLOCK_CHIP_HAS_DBG_BUS); + + if (!is_removed && has_dbg_bus && + GET_FIELD(block_per_chip->dbg_bus_mode.data, + DBG_MODE_HDR_EVAL_MODE) > 0) { + modes_buf_offset = + GET_FIELD(block_per_chip->dbg_bus_mode.data, + DBG_MODE_HDR_MODES_BUF_OFFSET); + if (!qed_is_mode_match(p_hwfn, &modes_buf_offset)) + has_dbg_bus = false; + } - if (!block->has_dbg_bus[dev_data->chip_id]) + if (is_removed || !has_dbg_bus) continue; - block_desc = - get_dbg_bus_block_desc(p_hwfn, - (enum block_id)block_id); - block_dwords = NUM_DBG_LINES(block_desc) * + block_dwords = NUM_DBG_LINES(block_per_chip) * STATIC_DEBUG_LINE_DWORDS; /* Dump static section params */ + block = get_dbg_block(p_hwfn, (enum block_id)block_id); offset += qed_grc_dump_mem_hdr(p_hwfn, dump_buf + offset, dump, block->name, 0, block_dwords, - 32, false, "STATIC", false, 0); + 32, false, "STATIC", 0); if (!dump) { offset += block_dwords; @@ -3843,20 +3497,19 @@ static u32 qed_grc_dump_static_debug(struct qed_hwfn *p_hwfn, } /* Enable block's client */ - dbg_client_id = block->dbg_client_id[dev_data->chip_id]; qed_bus_enable_clients(p_hwfn, p_ptt, - BIT(dbg_client_id)); + BIT(block_per_chip->dbg_client_id)); addr = BYTES_TO_DWORDS(DBG_REG_CALENDAR_OUT_DATA); len = STATIC_DEBUG_LINE_DWORDS; - for (line_id = 0; line_id < (u32)NUM_DBG_LINES(block_desc); + for (line_id = 0; line_id < (u32)NUM_DBG_LINES(block_per_chip); line_id++) { /* Configure debug line ID */ - qed_config_dbg_line(p_hwfn, - p_ptt, - (enum block_id)block_id, - (u8)line_id, 0xf, 0, 0, 0); + qed_bus_config_dbg_line(p_hwfn, + p_ptt, + (enum block_id)block_id, + (u8)line_id, 0xf, 0, 0, 0); /* Read debug line info */ offset += qed_grc_dump_addr_range(p_hwfn, @@ -3865,12 +3518,14 @@ static u32 qed_grc_dump_static_debug(struct qed_hwfn *p_hwfn, dump, addr, len, - true); + true, SPLIT_TYPE_NONE, + 0); } /* Disable block's client and debug output */ qed_bus_enable_clients(p_hwfn, p_ptt, 0); - qed_wr(p_hwfn, p_ptt, block->dbg_enable_addr, 0); + qed_bus_config_dbg_line(p_hwfn, p_ptt, + (enum block_id)block_id, 0, 0, 0, 0, 0); } if (dump) { @@ -3891,28 +3546,15 @@ static enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn, { struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; bool parities_masked = false; - u8 i, port_mode = 0; - u32 offset = 0; + u32 dwords_read, offset = 0; + u8 i; *num_dumped_dwords = 0; + dev_data->num_regs_read = 0; - if (dump) { - /* Find port mode */ - switch (qed_rd(p_hwfn, p_ptt, MISC_REG_PORT_MODE)) { - case 0: - port_mode = 1; - break; - case 1: - port_mode = 2; - break; - case 2: - port_mode = 4; - break; - } - - /* Update reset state */ + /* Update reset state */ + if (dump) qed_update_blocks_reset_state(p_hwfn, p_ptt); - } /* Dump global params */ offset += qed_dump_common_global_params(p_hwfn, @@ -3923,15 +3565,13 @@ static enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn, offset += qed_dump_num_param(dump_buf + offset, dump, "num-lcids", - qed_grc_get_param(p_hwfn, - DBG_GRC_PARAM_NUM_LCIDS)); + NUM_OF_LCIDS); offset += qed_dump_num_param(dump_buf + offset, dump, "num-ltids", - qed_grc_get_param(p_hwfn, - DBG_GRC_PARAM_NUM_LTIDS)); + NUM_OF_LTIDS); offset += qed_dump_num_param(dump_buf + offset, - dump, "num-ports", port_mode); + dump, "num-ports", dev_data->num_ports); /* Dump reset registers (dumped before taking blocks out of reset ) */ if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS)) @@ -3941,7 +3581,7 @@ static enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn, /* Take all blocks out of reset (using reset registers) */ if (dump) { - qed_grc_unreset_blocks(p_hwfn, p_ptt); + qed_grc_unreset_blocks(p_hwfn, p_ptt, false); qed_update_blocks_reset_state(p_hwfn, p_ptt); } @@ -3984,7 +3624,7 @@ static enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn, dump_buf + offset, dump, - block_enable, NULL, NULL); + block_enable, NULL); /* Dump special registers */ offset += qed_grc_dump_special_regs(p_hwfn, @@ -4018,33 +3658,39 @@ static enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn, dump_buf + offset, dump, i); - /* Dump IORs */ - if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IOR)) - offset += qed_grc_dump_iors(p_hwfn, - p_ptt, dump_buf + offset, dump); - /* Dump VFC */ - if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)) - offset += qed_grc_dump_vfc(p_hwfn, - p_ptt, dump_buf + offset, dump); + if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)) { + dwords_read = qed_grc_dump_vfc(p_hwfn, + p_ptt, dump_buf + offset, dump); + offset += dwords_read; + if (!dwords_read) + return DBG_STATUS_VFC_READ_ERROR; + } /* Dump PHY tbus */ if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PHY) && dev_data->chip_id == - CHIP_K2 && dev_data->platform_id == PLATFORM_ASIC) + CHIP_K2 && dev_data->hw_type == HW_TYPE_ASIC) offset += qed_grc_dump_phy(p_hwfn, p_ptt, dump_buf + offset, dump); - /* Dump static debug data */ + /* Dump MCP HW Dump */ + if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP_HW_DUMP) && + !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP) && 1) + offset += qed_grc_dump_mcp_hw_dump(p_hwfn, + p_ptt, + dump_buf + offset, dump); + + /* Dump static debug data (only if not during debug bus recording) */ if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_STATIC) && - dev_data->bus.state == DBG_BUS_STATE_IDLE) + (!dump || dev_data->bus.state == DBG_BUS_STATE_IDLE)) offset += qed_grc_dump_static_debug(p_hwfn, p_ptt, dump_buf + offset, dump); /* Dump last section */ - offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump); + offset += qed_dump_last_section(dump_buf, offset, dump); if (dump) { /* Unstall storms */ @@ -4069,8 +3715,7 @@ static enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn, */ static u32 qed_idle_chk_dump_failure(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, - u32 * - dump_buf, + u32 *dump_buf, bool dump, u16 rule_id, const struct dbg_idle_chk_rule *rule, @@ -4085,8 +3730,9 @@ static u32 qed_idle_chk_dump_failure(struct qed_hwfn *p_hwfn, u8 reg_id; hdr = (struct dbg_idle_chk_result_hdr *)dump_buf; - regs = &((const union dbg_idle_chk_reg *) - s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr)[rule->reg_offset]; + regs = (const union dbg_idle_chk_reg *) + p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr + + rule->reg_offset; cond_regs = ®s[0].cond_reg; info_regs = ®s[rule->num_cond_regs].info_reg; @@ -4106,8 +3752,8 @@ static u32 qed_idle_chk_dump_failure(struct qed_hwfn *p_hwfn, const struct dbg_idle_chk_cond_reg *reg = &cond_regs[reg_id]; struct dbg_idle_chk_result_reg_hdr *reg_hdr; - reg_hdr = (struct dbg_idle_chk_result_reg_hdr *) - (dump_buf + offset); + reg_hdr = + (struct dbg_idle_chk_result_reg_hdr *)(dump_buf + offset); /* Write register header */ if (!dump) { @@ -4192,7 +3838,8 @@ static u32 qed_idle_chk_dump_failure(struct qed_hwfn *p_hwfn, dump_buf + offset, dump, addr, - reg->size, wide_bus); + reg->size, wide_bus, + SPLIT_TYPE_NONE, 0); } } @@ -4223,12 +3870,13 @@ qed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, const u32 *imm_values; rule = &input_rules[i]; - regs = &((const union dbg_idle_chk_reg *) - s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr) - [rule->reg_offset]; + regs = (const union dbg_idle_chk_reg *) + p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr + + rule->reg_offset; cond_regs = ®s[0].cond_reg; - imm_values = &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr - [rule->imm_offset]; + imm_values = + (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr + + rule->imm_offset; /* Check if all condition register blocks are out of reset, and * find maximal number of entries (all condition registers that @@ -4253,30 +3901,33 @@ qed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, if (!check_rule && dump) continue; + if (!dump) { + u32 entry_dump_size = + qed_idle_chk_dump_failure(p_hwfn, + p_ptt, + dump_buf + offset, + false, + rule->rule_id, + rule, + 0, + NULL); + + offset += num_reg_entries * entry_dump_size; + (*num_failing_rules) += num_reg_entries; + continue; + } + /* Go over all register entries (number of entries is the same * for all condition registers). */ for (entry_id = 0; entry_id < num_reg_entries; entry_id++) { u32 next_reg_offset = 0; - if (!dump) { - offset += qed_idle_chk_dump_failure(p_hwfn, - p_ptt, - dump_buf + offset, - false, - rule->rule_id, - rule, - entry_id, - NULL); - (*num_failing_rules)++; - break; - } - /* Read current entry of all condition registers */ for (reg_id = 0; reg_id < rule->num_cond_regs; reg_id++) { const struct dbg_idle_chk_cond_reg *reg = - &cond_regs[reg_id]; + &cond_regs[reg_id]; u32 padded_entry_size, addr; bool wide_bus; @@ -4291,9 +3942,9 @@ qed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, if (reg->num_entries > 1 || reg->start_entry > 0) { padded_entry_size = - reg->entry_size > 1 ? - roundup_pow_of_two(reg->entry_size) - : 1; + reg->entry_size > 1 ? + roundup_pow_of_two(reg->entry_size) : + 1; addr += (reg->start_entry + entry_id) * padded_entry_size; } @@ -4312,7 +3963,8 @@ qed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, next_reg_offset, dump, addr, reg->entry_size, - wide_bus); + wide_bus, + SPLIT_TYPE_NONE, 0); } /* Call rule condition function. @@ -4329,7 +3981,6 @@ qed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, entry_id, cond_reg_values); (*num_failing_rules)++; - break; } } } @@ -4343,10 +3994,12 @@ qed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, static u32 qed_idle_chk_dump(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) { - u32 num_failing_rules_offset, offset = 0, input_offset = 0; - u32 num_failing_rules = 0; + struct virt_mem_desc *dbg_buf = + &p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES]; + u32 num_failing_rules_offset, offset = 0, + input_offset = 0, num_failing_rules = 0; - /* Dump global params */ + /* Dump global params - 1 must match below amount of params */ offset += qed_dump_common_global_params(p_hwfn, p_ptt, dump_buf + offset, dump, 1); @@ -4358,12 +4011,10 @@ static u32 qed_idle_chk_dump(struct qed_hwfn *p_hwfn, num_failing_rules_offset = offset; offset += qed_dump_num_param(dump_buf + offset, dump, "num_rules", 0); - while (input_offset < - s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].size_in_dwords) { + while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) { const struct dbg_idle_chk_cond_hdr *cond_hdr = - (const struct dbg_idle_chk_cond_hdr *) - &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr - [input_offset++]; + (const struct dbg_idle_chk_cond_hdr *)dbg_buf->ptr + + input_offset++; bool eval_mode, mode_match = true; u32 curr_failing_rules; u16 modes_buf_offset; @@ -4380,16 +4031,21 @@ static u32 qed_idle_chk_dump(struct qed_hwfn *p_hwfn, } if (mode_match) { + const struct dbg_idle_chk_rule *rule = + (const struct dbg_idle_chk_rule *)((u32 *) + dbg_buf->ptr + + input_offset); + u32 num_input_rules = + cond_hdr->data_size / IDLE_CHK_RULE_SIZE_DWORDS; offset += qed_idle_chk_dump_rule_entries(p_hwfn, - p_ptt, - dump_buf + offset, - dump, - (const struct dbg_idle_chk_rule *) - &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES]. - ptr[input_offset], - cond_hdr->data_size / IDLE_CHK_RULE_SIZE_DWORDS, - &curr_failing_rules); + p_ptt, + dump_buf + + offset, + dump, + rule, + num_input_rules, + &curr_failing_rules); num_failing_rules += curr_failing_rules; } @@ -4402,96 +4058,11 @@ static u32 qed_idle_chk_dump(struct qed_hwfn *p_hwfn, dump, "num_rules", num_failing_rules); /* Dump last section */ - offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump); + offset += qed_dump_last_section(dump_buf, offset, dump); return offset; } -/* Finds the meta data image in NVRAM */ -static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn, - struct qed_ptt *p_ptt, - u32 image_type, - u32 *nvram_offset_bytes, - u32 *nvram_size_bytes) -{ - u32 ret_mcp_resp, ret_mcp_param, ret_txn_size; - struct mcp_file_att file_att; - int nvm_result; - - /* Call NVRAM get file command */ - nvm_result = qed_mcp_nvm_rd_cmd(p_hwfn, - p_ptt, - DRV_MSG_CODE_NVM_GET_FILE_ATT, - image_type, - &ret_mcp_resp, - &ret_mcp_param, - &ret_txn_size, (u32 *)&file_att); - - /* Check response */ - if (nvm_result || - (ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK) - return DBG_STATUS_NVRAM_GET_IMAGE_FAILED; - - /* Update return values */ - *nvram_offset_bytes = file_att.nvm_start_addr; - *nvram_size_bytes = file_att.len; - - DP_VERBOSE(p_hwfn, - QED_MSG_DEBUG, - "find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\n", - image_type, *nvram_offset_bytes, *nvram_size_bytes); - - /* Check alignment */ - if (*nvram_size_bytes & 0x3) - return DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE; - - return DBG_STATUS_OK; -} - -/* Reads data from NVRAM */ -static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn, - struct qed_ptt *p_ptt, - u32 nvram_offset_bytes, - u32 nvram_size_bytes, u32 *ret_buf) -{ - u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy; - s32 bytes_left = nvram_size_bytes; - u32 read_offset = 0; - - DP_VERBOSE(p_hwfn, - QED_MSG_DEBUG, - "nvram_read: reading image of size %d bytes from NVRAM\n", - nvram_size_bytes); - - do { - bytes_to_copy = - (bytes_left > - MCP_DRV_NVM_BUF_LEN) ? MCP_DRV_NVM_BUF_LEN : bytes_left; - - /* Call NVRAM read command */ - if (qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt, - DRV_MSG_CODE_NVM_READ_NVRAM, - (nvram_offset_bytes + - read_offset) | - (bytes_to_copy << - DRV_MB_PARAM_NVM_LEN_SHIFT), - &ret_mcp_resp, &ret_mcp_param, - &ret_read_size, - (u32 *)((u8 *)ret_buf + read_offset))) - return DBG_STATUS_NVRAM_READ_FAILED; - - /* Check response */ - if ((ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK) - return DBG_STATUS_NVRAM_READ_FAILED; - - /* Update read offset */ - read_offset += ret_read_size; - bytes_left -= ret_read_size; - } while (bytes_left > 0); - - return DBG_STATUS_OK; -} - /* Get info on the MCP Trace data in the scratchpad: * - trace_data_grc_addr (OUT): trace data GRC address in bytes * - trace_data_size (OUT): trace data size in bytes (without the header) @@ -4560,7 +4131,9 @@ static enum dbg_status qed_mcp_trace_get_meta_info(struct qed_hwfn *p_hwfn, return qed_find_nvram_image(p_hwfn, p_ptt, nvram_image_type, - trace_meta_offset, trace_meta_size); + trace_meta_offset, + trace_meta_size, + true); } /* Reads the MCP Trace meta data from NVRAM into the specified buffer */ @@ -4576,7 +4149,10 @@ static enum dbg_status qed_mcp_trace_read_meta(struct qed_hwfn *p_hwfn, /* Read meta data from NVRAM */ status = qed_nvram_read(p_hwfn, p_ptt, - nvram_offset_in_bytes, size_in_bytes, buf); + nvram_offset_in_bytes, + size_in_bytes, + buf, + true); if (status != DBG_STATUS_OK) return status; @@ -4614,12 +4190,12 @@ static enum dbg_status qed_mcp_trace_dump(struct qed_hwfn *p_hwfn, u32 trace_meta_size_dwords = 0, running_bundle_id, offset = 0; u32 trace_meta_offset_bytes = 0, trace_meta_size_bytes = 0; enum dbg_status status; - bool mcp_access; int halted = 0; + bool use_mfw; *num_dumped_dwords = 0; - mcp_access = !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP); + use_mfw = !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP); /* Get trace data info */ status = qed_mcp_trace_get_data_info(p_hwfn, @@ -4640,7 +4216,7 @@ static enum dbg_status qed_mcp_trace_dump(struct qed_hwfn *p_hwfn, * consistent. if halt fails, MCP trace is taken anyway, with a small * risk that it may be corrupt. */ - if (dump && mcp_access) { + if (dump && use_mfw) { halted = !qed_mcp_halt(p_hwfn, p_ptt); if (!halted) DP_NOTICE(p_hwfn, "MCP halt failed!\n"); @@ -4663,7 +4239,8 @@ static enum dbg_status qed_mcp_trace_dump(struct qed_hwfn *p_hwfn, dump_buf + offset, dump, BYTES_TO_DWORDS(trace_data_grc_addr), - trace_data_size_dwords, false); + trace_data_size_dwords, false, + SPLIT_TYPE_NONE, 0); /* Resume MCP (only if halt succeeded) */ if (halted && qed_mcp_resume(p_hwfn, p_ptt)) @@ -4673,18 +4250,21 @@ static enum dbg_status qed_mcp_trace_dump(struct qed_hwfn *p_hwfn, offset += qed_dump_section_hdr(dump_buf + offset, dump, "mcp_trace_meta", 1); - /* Read trace meta info (trace_meta_size_bytes is dword-aligned) */ - if (mcp_access) { + /* If MCP Trace meta size parameter was set, use it. + * Otherwise, read trace meta. + * trace_meta_size_bytes is dword-aligned. + */ + trace_meta_size_bytes = + qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_MCP_TRACE_META_SIZE); + if ((!trace_meta_size_bytes || dump) && use_mfw) status = qed_mcp_trace_get_meta_info(p_hwfn, p_ptt, trace_data_size_bytes, &running_bundle_id, &trace_meta_offset_bytes, &trace_meta_size_bytes); - if (status == DBG_STATUS_OK) - trace_meta_size_dwords = - BYTES_TO_DWORDS(trace_meta_size_bytes); - } + if (status == DBG_STATUS_OK) + trace_meta_size_dwords = BYTES_TO_DWORDS(trace_meta_size_bytes); /* Dump trace meta size param */ offset += qed_dump_num_param(dump_buf + offset, @@ -4701,14 +4281,14 @@ static enum dbg_status qed_mcp_trace_dump(struct qed_hwfn *p_hwfn, offset += trace_meta_size_dwords; /* Dump last section */ - offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump); + offset += qed_dump_last_section(dump_buf, offset, dump); *num_dumped_dwords = offset; /* If no mcp access, indicate that the dump doesn't contain the meta * data from NVRAM. */ - return mcp_access ? status : DBG_STATUS_NVRAM_GET_IMAGE_FAILED; + return use_mfw ? status : DBG_STATUS_NVRAM_GET_IMAGE_FAILED; } /* Dump GRC FIFO */ @@ -4717,7 +4297,7 @@ static enum dbg_status qed_reg_fifo_dump(struct qed_hwfn *p_hwfn, u32 *dump_buf, bool dump, u32 *num_dumped_dwords) { - u32 dwords_read, size_param_offset, offset = 0; + u32 dwords_read, size_param_offset, offset = 0, addr, len; bool fifo_has_data; *num_dumped_dwords = 0; @@ -4753,14 +4333,19 @@ static enum dbg_status qed_reg_fifo_dump(struct qed_hwfn *p_hwfn, * buffer size since more entries could be added to the buffer as we are * emptying it. */ + addr = BYTES_TO_DWORDS(GRC_REG_TRACE_FIFO); + len = REG_FIFO_ELEMENT_DWORDS; for (dwords_read = 0; fifo_has_data && dwords_read < REG_FIFO_DEPTH_DWORDS; - dwords_read += REG_FIFO_ELEMENT_DWORDS, offset += - REG_FIFO_ELEMENT_DWORDS) { - if (qed_dmae_grc2host(p_hwfn, p_ptt, GRC_REG_TRACE_FIFO, - (u64)(uintptr_t)(&dump_buf[offset]), - REG_FIFO_ELEMENT_DWORDS, 0)) - return DBG_STATUS_DMAE_FAILED; + dwords_read += REG_FIFO_ELEMENT_DWORDS) { + offset += qed_grc_dump_addr_range(p_hwfn, + p_ptt, + dump_buf + offset, + true, + addr, + len, + true, SPLIT_TYPE_NONE, + 0); fifo_has_data = qed_rd(p_hwfn, p_ptt, GRC_REG_TRACE_FIFO_VALID_DATA) > 0; } @@ -4769,7 +4354,7 @@ static enum dbg_status qed_reg_fifo_dump(struct qed_hwfn *p_hwfn, dwords_read); out: /* Dump last section */ - offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump); + offset += qed_dump_last_section(dump_buf, offset, dump); *num_dumped_dwords = offset; @@ -4782,7 +4367,7 @@ static enum dbg_status qed_igu_fifo_dump(struct qed_hwfn *p_hwfn, u32 *dump_buf, bool dump, u32 *num_dumped_dwords) { - u32 dwords_read, size_param_offset, offset = 0; + u32 dwords_read, size_param_offset, offset = 0, addr, len; bool fifo_has_data; *num_dumped_dwords = 0; @@ -4818,16 +4403,20 @@ static enum dbg_status qed_igu_fifo_dump(struct qed_hwfn *p_hwfn, * buffer size since more entries could be added to the buffer as we are * emptying it. */ + addr = BYTES_TO_DWORDS(IGU_REG_ERROR_HANDLING_MEMORY); + len = IGU_FIFO_ELEMENT_DWORDS; for (dwords_read = 0; fifo_has_data && dwords_read < IGU_FIFO_DEPTH_DWORDS; - dwords_read += IGU_FIFO_ELEMENT_DWORDS, offset += - IGU_FIFO_ELEMENT_DWORDS) { - if (qed_dmae_grc2host(p_hwfn, p_ptt, - IGU_REG_ERROR_HANDLING_MEMORY, - (u64)(uintptr_t)(&dump_buf[offset]), - IGU_FIFO_ELEMENT_DWORDS, 0)) - return DBG_STATUS_DMAE_FAILED; - fifo_has_data = qed_rd(p_hwfn, p_ptt, + dwords_read += IGU_FIFO_ELEMENT_DWORDS) { + offset += qed_grc_dump_addr_range(p_hwfn, + p_ptt, + dump_buf + offset, + true, + addr, + len, + true, SPLIT_TYPE_NONE, + 0); + fifo_has_data = qed_rd(p_hwfn, p_ptt, IGU_REG_ERROR_HANDLING_DATA_VALID) > 0; } @@ -4835,7 +4424,7 @@ static enum dbg_status qed_igu_fifo_dump(struct qed_hwfn *p_hwfn, dwords_read); out: /* Dump last section */ - offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump); + offset += qed_dump_last_section(dump_buf, offset, dump); *num_dumped_dwords = offset; @@ -4849,7 +4438,7 @@ static enum dbg_status qed_protection_override_dump(struct qed_hwfn *p_hwfn, bool dump, u32 *num_dumped_dwords) { - u32 size_param_offset, override_window_dwords, offset = 0; + u32 size_param_offset, override_window_dwords, offset = 0, addr; *num_dumped_dwords = 0; @@ -4873,22 +4462,26 @@ static enum dbg_status qed_protection_override_dump(struct qed_hwfn *p_hwfn, goto out; } - /* Add override window info to buffer */ + /* Add override window info to buffer, preventing buffer overflow */ override_window_dwords = - qed_rd(p_hwfn, p_ptt, - GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW) * - PROTECTION_OVERRIDE_ELEMENT_DWORDS; - if (qed_dmae_grc2host(p_hwfn, p_ptt, - GRC_REG_PROTECTION_OVERRIDE_WINDOW, - (u64)(uintptr_t)(dump_buf + offset), - override_window_dwords, 0)) - return DBG_STATUS_DMAE_FAILED; - offset += override_window_dwords; - qed_dump_num_param(dump_buf + size_param_offset, dump, "size", - override_window_dwords); + min(qed_rd(p_hwfn, p_ptt, GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW) * + PROTECTION_OVERRIDE_ELEMENT_DWORDS, + PROTECTION_OVERRIDE_DEPTH_DWORDS); + if (override_window_dwords) { + addr = BYTES_TO_DWORDS(GRC_REG_PROTECTION_OVERRIDE_WINDOW); + offset += qed_grc_dump_addr_range(p_hwfn, + p_ptt, + dump_buf + offset, + true, + addr, + override_window_dwords, + true, SPLIT_TYPE_NONE, 0); + qed_dump_num_param(dump_buf + size_param_offset, dump, "size", + override_window_dwords); + } out: /* Dump last section */ - offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump); + offset += qed_dump_last_section(dump_buf, offset, dump); *num_dumped_dwords = offset; @@ -4921,11 +4514,11 @@ static u32 qed_fw_asserts_dump(struct qed_hwfn *p_hwfn, struct storm_defs *storm = &s_storm_defs[storm_id]; u32 last_list_idx, addr; - if (dev_data->block_in_reset[storm->block_id]) + if (dev_data->block_in_reset[storm->sem_block_id]) continue; /* Read FW info for the current Storm */ - qed_read_fw_info(p_hwfn, p_ptt, storm_id, &fw_info); + qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, &fw_info); asserts = &fw_info.fw_asserts_section; @@ -4946,15 +4539,17 @@ static u32 qed_fw_asserts_dump(struct qed_hwfn *p_hwfn, continue; } + addr = le16_to_cpu(asserts->section_ram_line_offset); fw_asserts_section_addr = storm->sem_fast_mem_addr + - SEM_FAST_REG_INT_RAM + - RAM_LINES_TO_BYTES(asserts->section_ram_line_offset); + SEM_FAST_REG_INT_RAM + + RAM_LINES_TO_BYTES(addr); + next_list_idx_addr = fw_asserts_section_addr + DWORDS_TO_BYTES(asserts->list_next_index_dword_offset); next_list_idx = qed_rd(p_hwfn, p_ptt, next_list_idx_addr); - last_list_idx = (next_list_idx > 0 - ? next_list_idx - : asserts->list_num_elements) - 1; + last_list_idx = (next_list_idx > 0 ? + next_list_idx : + asserts->list_num_elements) - 1; addr = BYTES_TO_DWORDS(fw_asserts_section_addr) + asserts->list_dword_offset + last_list_idx * asserts->list_element_dword_size; @@ -4963,28 +4558,757 @@ static u32 qed_fw_asserts_dump(struct qed_hwfn *p_hwfn, dump_buf + offset, dump, addr, asserts->list_element_dword_size, - false); + false, SPLIT_TYPE_NONE, 0); } /* Dump last section */ - offset += qed_dump_last_section(p_hwfn, dump_buf, offset, dump); + offset += qed_dump_last_section(dump_buf, offset, dump); + + return offset; +} + +/* Dumps the specified ILT pages to the specified buffer. + * Returns the dumped size in dwords. + */ +static u32 qed_ilt_dump_pages_range(u32 *dump_buf, u32 *given_offset, + bool *dump, u32 start_page_id, + u32 num_pages, + struct phys_mem_desc *ilt_pages, + bool dump_page_ids, u32 buf_size_in_dwords, + u32 *given_actual_dump_size_in_dwords) +{ + u32 actual_dump_size_in_dwords = *given_actual_dump_size_in_dwords; + u32 page_id, end_page_id, offset = *given_offset; + struct phys_mem_desc *mem_desc = NULL; + bool continue_dump = *dump; + u32 partial_page_size = 0; + + if (num_pages == 0) + return offset; + + end_page_id = start_page_id + num_pages - 1; + + for (page_id = start_page_id; page_id <= end_page_id; page_id++) { + mem_desc = &ilt_pages[page_id]; + if (!ilt_pages[page_id].virt_addr) + continue; + + if (dump_page_ids) { + /* Copy page ID to dump buffer + * (if dump is needed and buffer is not full) + */ + if ((continue_dump) && + (offset + 1 > buf_size_in_dwords)) { + continue_dump = false; + actual_dump_size_in_dwords = offset; + } + if (continue_dump) + *(dump_buf + offset) = page_id; + offset++; + } else { + /* Copy page memory to dump buffer */ + if ((continue_dump) && + (offset + BYTES_TO_DWORDS(mem_desc->size) > + buf_size_in_dwords)) { + if (offset + BYTES_TO_DWORDS(mem_desc->size) > + buf_size_in_dwords) { + partial_page_size = + buf_size_in_dwords - offset; + memcpy(dump_buf + offset, + mem_desc->virt_addr, + partial_page_size); + continue_dump = false; + actual_dump_size_in_dwords = + offset + partial_page_size; + } + } + + if (continue_dump) + memcpy(dump_buf + offset, + mem_desc->virt_addr, mem_desc->size); + offset += BYTES_TO_DWORDS(mem_desc->size); + } + } + + *dump = continue_dump; + *given_offset = offset; + *given_actual_dump_size_in_dwords = actual_dump_size_in_dwords; + + return offset; +} + +/* Dumps a section containing the dumped ILT pages. + * Returns the dumped size in dwords. + */ +static u32 qed_ilt_dump_pages_section(struct qed_hwfn *p_hwfn, + u32 *dump_buf, + u32 *given_offset, + bool *dump, + u32 valid_conn_pf_pages, + u32 valid_conn_vf_pages, + struct phys_mem_desc *ilt_pages, + bool dump_page_ids, + u32 buf_size_in_dwords, + u32 *given_actual_dump_size_in_dwords) +{ + struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients; + u32 pf_start_line, start_page_id, offset = *given_offset; + u32 cdut_pf_init_pages, cdut_vf_init_pages; + u32 cdut_pf_work_pages, cdut_vf_work_pages; + u32 base_data_offset, size_param_offset; + u32 src_pages; + u32 section_header_and_param_size; + u32 cdut_pf_pages, cdut_vf_pages; + u32 actual_dump_size_in_dwords; + bool continue_dump = *dump; + bool update_size = *dump; + const char *section_name; + u32 i; + + actual_dump_size_in_dwords = *given_actual_dump_size_in_dwords; + section_name = dump_page_ids ? "ilt_page_ids" : "ilt_page_mem"; + cdut_pf_init_pages = qed_get_cdut_num_pf_init_pages(p_hwfn); + cdut_vf_init_pages = qed_get_cdut_num_vf_init_pages(p_hwfn); + cdut_pf_work_pages = qed_get_cdut_num_pf_work_pages(p_hwfn); + cdut_vf_work_pages = qed_get_cdut_num_vf_work_pages(p_hwfn); + cdut_pf_pages = cdut_pf_init_pages + cdut_pf_work_pages; + cdut_vf_pages = cdut_vf_init_pages + cdut_vf_work_pages; + pf_start_line = p_hwfn->p_cxt_mngr->pf_start_line; + section_header_and_param_size = qed_dump_section_hdr(NULL, + false, + section_name, + 1) + + qed_dump_num_param(NULL, false, "size", 0); + + if ((continue_dump) && + (offset + section_header_and_param_size > buf_size_in_dwords)) { + continue_dump = false; + update_size = false; + actual_dump_size_in_dwords = offset; + } + + offset += qed_dump_section_hdr(dump_buf + offset, + continue_dump, section_name, 1); + + /* Dump size parameter (0 for now, overwritten with real size later) */ + size_param_offset = offset; + offset += qed_dump_num_param(dump_buf + offset, + continue_dump, "size", 0); + base_data_offset = offset; + + /* CDUC pages are ordered as follows: + * - PF pages - valid section (included in PF connection type mapping) + * - PF pages - invalid section (not dumped) + * - For each VF in the PF: + * - VF pages - valid section (included in VF connection type mapping) + * - VF pages - invalid section (not dumped) + */ + if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUC)) { + /* Dump connection PF pages */ + start_page_id = clients[ILT_CLI_CDUC].first.val - pf_start_line; + qed_ilt_dump_pages_range(dump_buf, &offset, &continue_dump, + start_page_id, valid_conn_pf_pages, + ilt_pages, dump_page_ids, + buf_size_in_dwords, + &actual_dump_size_in_dwords); + + /* Dump connection VF pages */ + start_page_id += clients[ILT_CLI_CDUC].pf_total_lines; + for (i = 0; i < p_hwfn->p_cxt_mngr->vf_count; + i++, start_page_id += clients[ILT_CLI_CDUC].vf_total_lines) + qed_ilt_dump_pages_range(dump_buf, &offset, + &continue_dump, start_page_id, + valid_conn_vf_pages, + ilt_pages, dump_page_ids, + buf_size_in_dwords, + &actual_dump_size_in_dwords); + } + + /* CDUT pages are ordered as follows: + * - PF init pages (not dumped) + * - PF work pages + * - For each VF in the PF: + * - VF init pages (not dumped) + * - VF work pages + */ + if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUT)) { + /* Dump task PF pages */ + start_page_id = clients[ILT_CLI_CDUT].first.val + + cdut_pf_init_pages - pf_start_line; + qed_ilt_dump_pages_range(dump_buf, &offset, &continue_dump, + start_page_id, cdut_pf_work_pages, + ilt_pages, dump_page_ids, + buf_size_in_dwords, + &actual_dump_size_in_dwords); + + /* Dump task VF pages */ + start_page_id = clients[ILT_CLI_CDUT].first.val + + cdut_pf_pages + cdut_vf_init_pages - pf_start_line; + for (i = 0; i < p_hwfn->p_cxt_mngr->vf_count; + i++, start_page_id += cdut_vf_pages) + qed_ilt_dump_pages_range(dump_buf, &offset, + &continue_dump, start_page_id, + cdut_vf_work_pages, ilt_pages, + dump_page_ids, + buf_size_in_dwords, + &actual_dump_size_in_dwords); + } + + /*Dump Searcher pages */ + if (clients[ILT_CLI_SRC].active) { + start_page_id = clients[ILT_CLI_SRC].first.val - pf_start_line; + src_pages = clients[ILT_CLI_SRC].last.val - + clients[ILT_CLI_SRC].first.val + 1; + qed_ilt_dump_pages_range(dump_buf, &offset, &continue_dump, + start_page_id, src_pages, ilt_pages, + dump_page_ids, buf_size_in_dwords, + &actual_dump_size_in_dwords); + } + + /* Overwrite size param */ + if (update_size) { + u32 section_size = (*dump == continue_dump) ? + offset - base_data_offset : + actual_dump_size_in_dwords - base_data_offset; + if (section_size > 0) + qed_dump_num_param(dump_buf + size_param_offset, + *dump, "size", section_size); + else if ((section_size == 0) && (*dump != continue_dump)) + actual_dump_size_in_dwords -= + section_header_and_param_size; + } + + *dump = continue_dump; + *given_offset = offset; + *given_actual_dump_size_in_dwords = actual_dump_size_in_dwords; + + return offset; +} + +/* Dumps a section containing the global parameters. + * Part of ilt dump process + * Returns the dumped size in dwords. + */ +static u32 +qed_ilt_dump_dump_common_global_params(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + u32 *dump_buf, + bool dump, + u32 cduc_page_size, + u32 conn_ctx_size, + u32 cdut_page_size, + u32 *full_dump_size_param_offset, + u32 *actual_dump_size_param_offset) +{ + struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients; + u32 offset = 0; + + offset += qed_dump_common_global_params(p_hwfn, p_ptt, + dump_buf + offset, + dump, 30); + offset += qed_dump_str_param(dump_buf + offset, + dump, + "dump-type", "ilt-dump"); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "cduc-page-size", + cduc_page_size); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "cduc-first-page-id", + clients[ILT_CLI_CDUC].first.val); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "cduc-last-page-id", + clients[ILT_CLI_CDUC].last.val); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "cduc-num-pf-pages", + clients[ILT_CLI_CDUC].pf_total_lines); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "cduc-num-vf-pages", + clients[ILT_CLI_CDUC].vf_total_lines); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "max-conn-ctx-size", + conn_ctx_size); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "cdut-page-size", + cdut_page_size); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "cdut-first-page-id", + clients[ILT_CLI_CDUT].first.val); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "cdut-last-page-id", + clients[ILT_CLI_CDUT].last.val); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "cdut-num-pf-init-pages", + qed_get_cdut_num_pf_init_pages(p_hwfn)); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "cdut-num-vf-init-pages", + qed_get_cdut_num_vf_init_pages(p_hwfn)); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "cdut-num-pf-work-pages", + qed_get_cdut_num_pf_work_pages(p_hwfn)); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "cdut-num-vf-work-pages", + qed_get_cdut_num_vf_work_pages(p_hwfn)); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "max-task-ctx-size", + p_hwfn->p_cxt_mngr->task_ctx_size); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "first-vf-id-in-pf", + p_hwfn->p_cxt_mngr->first_vf_in_pf); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "num-vfs-in-pf", + p_hwfn->p_cxt_mngr->vf_count); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "ptr-size-bytes", + sizeof(void *)); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "pf-start-line", + p_hwfn->p_cxt_mngr->pf_start_line); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "page-mem-desc-size-dwords", + PAGE_MEM_DESC_SIZE_DWORDS); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "ilt-shadow-size", + p_hwfn->p_cxt_mngr->ilt_shadow_size); + + *full_dump_size_param_offset = offset; + + offset += qed_dump_num_param(dump_buf + offset, + dump, "dump-size-full", 0); + + *actual_dump_size_param_offset = offset; + + offset += qed_dump_num_param(dump_buf + offset, + dump, + "dump-size-actual", 0); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "iscsi_task_pages", + p_hwfn->p_cxt_mngr->iscsi_task_pages); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "fcoe_task_pages", + p_hwfn->p_cxt_mngr->fcoe_task_pages); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "roce_task_pages", + p_hwfn->p_cxt_mngr->roce_task_pages); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "eth_task_pages", + p_hwfn->p_cxt_mngr->eth_task_pages); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "src-first-page-id", + clients[ILT_CLI_SRC].first.val); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "src-last-page-id", + clients[ILT_CLI_SRC].last.val); + offset += qed_dump_num_param(dump_buf + offset, + dump, + "src-is-active", + clients[ILT_CLI_SRC].active); + + /* Additional/Less parameters require matching of number in call to + * dump_common_global_params() + */ + + return offset; +} + +/* Dump section containing number of PF CIDs per connection type. + * Part of ilt dump process. + * Returns the dumped size in dwords. + */ +static u32 qed_ilt_dump_dump_num_pf_cids(struct qed_hwfn *p_hwfn, + u32 *dump_buf, + bool dump, u32 *valid_conn_pf_cids) +{ + u32 num_pf_cids = 0; + u32 offset = 0; + u8 conn_type; + + offset += qed_dump_section_hdr(dump_buf + offset, + dump, "num_pf_cids_per_conn_type", 1); + offset += qed_dump_num_param(dump_buf + offset, + dump, "size", NUM_OF_CONNECTION_TYPES); + for (conn_type = 0, *valid_conn_pf_cids = 0; + conn_type < NUM_OF_CONNECTION_TYPES; conn_type++, offset++) { + num_pf_cids = p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cid_count; + if (dump) + *(dump_buf + offset) = num_pf_cids; + *valid_conn_pf_cids += num_pf_cids; + } return offset; } +/* Dump section containing number of VF CIDs per connection type + * Part of ilt dump process. + * Returns the dumped size in dwords. + */ +static u32 qed_ilt_dump_dump_num_vf_cids(struct qed_hwfn *p_hwfn, + u32 *dump_buf, + bool dump, u32 *valid_conn_vf_cids) +{ + u32 num_vf_cids = 0; + u32 offset = 0; + u8 conn_type; + + offset += qed_dump_section_hdr(dump_buf + offset, dump, + "num_vf_cids_per_conn_type", 1); + offset += qed_dump_num_param(dump_buf + offset, + dump, "size", NUM_OF_CONNECTION_TYPES); + for (conn_type = 0, *valid_conn_vf_cids = 0; + conn_type < NUM_OF_CONNECTION_TYPES; conn_type++, offset++) { + num_vf_cids = + p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cids_per_vf; + if (dump) + *(dump_buf + offset) = num_vf_cids; + *valid_conn_vf_cids += num_vf_cids; + } + + return offset; +} + +/* Performs ILT Dump to the specified buffer. + * buf_size_in_dwords - The dumped buffer size. + * Returns the dumped size in dwords. + */ +static u32 qed_ilt_dump(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + u32 *dump_buf, u32 buf_size_in_dwords, bool dump) +{ +#if ((!defined VMWARE) && (!defined UEFI)) + struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients; +#endif + u32 valid_conn_vf_cids = 0, + valid_conn_vf_pages, offset = 0, real_dumped_size = 0; + u32 valid_conn_pf_cids = 0, valid_conn_pf_pages, num_pages; + u32 num_cids_per_page, conn_ctx_size; + u32 cduc_page_size, cdut_page_size; + u32 actual_dump_size_in_dwords = 0; + struct phys_mem_desc *ilt_pages; + u32 actul_dump_off = 0; + u32 last_section_size; + u32 full_dump_off = 0; + u32 section_size = 0; + bool continue_dump; + u32 page_id; + + last_section_size = qed_dump_last_section(NULL, 0, false); + cduc_page_size = 1 << + (clients[ILT_CLI_CDUC].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN); + cdut_page_size = 1 << + (clients[ILT_CLI_CDUT].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN); + conn_ctx_size = p_hwfn->p_cxt_mngr->conn_ctx_size; + num_cids_per_page = (int)(cduc_page_size / conn_ctx_size); + ilt_pages = p_hwfn->p_cxt_mngr->ilt_shadow; + continue_dump = dump; + + /* if need to dump then save memory for the last section + * (last section calculates CRC of dumped data) + */ + if (dump) { + if (buf_size_in_dwords >= last_section_size) { + buf_size_in_dwords -= last_section_size; + } else { + continue_dump = false; + actual_dump_size_in_dwords = offset; + } + } + + /* Dump global params */ + + /* if need to dump then first check that there is enough memory + * in dumped buffer for this section calculate the size of this + * section without dumping. if there is not enough memory - then + * stop the dumping. + */ + if (continue_dump) { + section_size = + qed_ilt_dump_dump_common_global_params(p_hwfn, + p_ptt, + NULL, + false, + cduc_page_size, + conn_ctx_size, + cdut_page_size, + &full_dump_off, + &actul_dump_off); + if (offset + section_size > buf_size_in_dwords) { + continue_dump = false; + actual_dump_size_in_dwords = offset; + } + } + + offset += qed_ilt_dump_dump_common_global_params(p_hwfn, + p_ptt, + dump_buf + offset, + continue_dump, + cduc_page_size, + conn_ctx_size, + cdut_page_size, + &full_dump_off, + &actul_dump_off); + + /* Dump section containing number of PF CIDs per connection type + * If need to dump then first check that there is enough memory in + * dumped buffer for this section. + */ + if (continue_dump) { + section_size = + qed_ilt_dump_dump_num_pf_cids(p_hwfn, + NULL, + false, + &valid_conn_pf_cids); + if (offset + section_size > buf_size_in_dwords) { + continue_dump = false; + actual_dump_size_in_dwords = offset; + } + } + + offset += qed_ilt_dump_dump_num_pf_cids(p_hwfn, + dump_buf + offset, + continue_dump, + &valid_conn_pf_cids); + + /* Dump section containing number of VF CIDs per connection type + * If need to dump then first check that there is enough memory in + * dumped buffer for this section. + */ + if (continue_dump) { + section_size = + qed_ilt_dump_dump_num_vf_cids(p_hwfn, + NULL, + false, + &valid_conn_vf_cids); + if (offset + section_size > buf_size_in_dwords) { + continue_dump = false; + actual_dump_size_in_dwords = offset; + } + } + + offset += qed_ilt_dump_dump_num_vf_cids(p_hwfn, + dump_buf + offset, + continue_dump, + &valid_conn_vf_cids); + + /* Dump section containing physical memory descriptors for each + * ILT page. + */ + num_pages = p_hwfn->p_cxt_mngr->ilt_shadow_size; + + /* If need to dump then first check that there is enough memory + * in dumped buffer for the section header. + */ + if (continue_dump) { + section_size = qed_dump_section_hdr(NULL, + false, + "ilt_page_desc", + 1) + + qed_dump_num_param(NULL, + false, + "size", + num_pages * PAGE_MEM_DESC_SIZE_DWORDS); + if (offset + section_size > buf_size_in_dwords) { + continue_dump = false; + actual_dump_size_in_dwords = offset; + } + } + + offset += qed_dump_section_hdr(dump_buf + offset, + continue_dump, "ilt_page_desc", 1); + offset += qed_dump_num_param(dump_buf + offset, + continue_dump, + "size", + num_pages * PAGE_MEM_DESC_SIZE_DWORDS); + + /* Copy memory descriptors to dump buffer + * If need to dump then dump till the dump buffer size + */ + if (continue_dump) { + for (page_id = 0; page_id < num_pages; + page_id++, offset += PAGE_MEM_DESC_SIZE_DWORDS) { + if (continue_dump && + (offset + PAGE_MEM_DESC_SIZE_DWORDS <= + buf_size_in_dwords)) { + memcpy(dump_buf + offset, + &ilt_pages[page_id], + DWORDS_TO_BYTES + (PAGE_MEM_DESC_SIZE_DWORDS)); + } else { + if (continue_dump) { + continue_dump = false; + actual_dump_size_in_dwords = offset; + } + } + } + } else { + offset += num_pages * PAGE_MEM_DESC_SIZE_DWORDS; + } + + valid_conn_pf_pages = DIV_ROUND_UP(valid_conn_pf_cids, + num_cids_per_page); + valid_conn_vf_pages = DIV_ROUND_UP(valid_conn_vf_cids, + num_cids_per_page); + + /* Dump ILT pages IDs */ + qed_ilt_dump_pages_section(p_hwfn, dump_buf, &offset, &continue_dump, + valid_conn_pf_pages, valid_conn_vf_pages, + ilt_pages, true, buf_size_in_dwords, + &actual_dump_size_in_dwords); + + /* Dump ILT pages memory */ + qed_ilt_dump_pages_section(p_hwfn, dump_buf, &offset, &continue_dump, + valid_conn_pf_pages, valid_conn_vf_pages, + ilt_pages, false, buf_size_in_dwords, + &actual_dump_size_in_dwords); + + real_dumped_size = + (continue_dump == dump) ? offset : actual_dump_size_in_dwords; + qed_dump_num_param(dump_buf + full_dump_off, dump, + "full-dump-size", offset + last_section_size); + qed_dump_num_param(dump_buf + actul_dump_off, + dump, + "actual-dump-size", + real_dumped_size + last_section_size); + + /* Dump last section */ + real_dumped_size += qed_dump_last_section(dump_buf, + real_dumped_size, dump); + + return real_dumped_size; +} + /***************************** Public Functions *******************************/ -enum dbg_status qed_dbg_set_bin_ptr(const u8 * const bin_ptr) +enum dbg_status qed_dbg_set_bin_ptr(struct qed_hwfn *p_hwfn, + const u8 * const bin_ptr) { - struct bin_buffer_hdr *buf_array = (struct bin_buffer_hdr *)bin_ptr; + struct bin_buffer_hdr *buf_hdrs = (struct bin_buffer_hdr *)bin_ptr; u8 buf_id; - /* convert binary data to debug arrays */ - for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++) { - s_dbg_arrays[buf_id].ptr = - (u32 *)(bin_ptr + buf_array[buf_id].offset); - s_dbg_arrays[buf_id].size_in_dwords = - BYTES_TO_DWORDS(buf_array[buf_id].length); + /* Convert binary data to debug arrays */ + for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++) + qed_set_dbg_bin_buf(p_hwfn, + buf_id, + (u32 *)(bin_ptr + buf_hdrs[buf_id].offset), + buf_hdrs[buf_id].length); + + return DBG_STATUS_OK; +} + +static enum dbg_status qed_dbg_set_app_ver(u32 ver) +{ + if (ver < TOOLS_VERSION) + return DBG_STATUS_UNSUPPORTED_APP_VERSION; + + s_app_ver = ver; + + return DBG_STATUS_OK; +} + +bool qed_read_fw_info(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, struct fw_info *fw_info) +{ + struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; + u8 storm_id; + + for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) { + struct storm_defs *storm = &s_storm_defs[storm_id]; + + /* Skip Storm if it's in reset */ + if (dev_data->block_in_reset[storm->sem_block_id]) + continue; + + /* Read FW info for the current Storm */ + qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, fw_info); + + return true; + } + + return false; +} + +enum dbg_status qed_dbg_grc_config(struct qed_hwfn *p_hwfn, + enum dbg_grc_params grc_param, u32 val) +{ + struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; + enum dbg_status status; + int i; + + DP_VERBOSE(p_hwfn, + QED_MSG_DEBUG, + "dbg_grc_config: paramId = %d, val = %d\n", grc_param, val); + + status = qed_dbg_dev_init(p_hwfn); + if (status != DBG_STATUS_OK) + return status; + + /* Initializes the GRC parameters (if not initialized). Needed in order + * to set the default parameter values for the first time. + */ + qed_dbg_grc_init_params(p_hwfn); + + if (grc_param >= MAX_DBG_GRC_PARAMS) + return DBG_STATUS_INVALID_ARGS; + if (val < s_grc_param_defs[grc_param].min || + val > s_grc_param_defs[grc_param].max) + return DBG_STATUS_INVALID_ARGS; + + if (s_grc_param_defs[grc_param].is_preset) { + /* Preset param */ + + /* Disabling a preset is not allowed. Call + * dbg_grc_set_params_default instead. + */ + if (!val) + return DBG_STATUS_INVALID_ARGS; + + /* Update all params with the preset values */ + for (i = 0; i < MAX_DBG_GRC_PARAMS; i++) { + struct grc_param_defs *defs = &s_grc_param_defs[i]; + u32 preset_val; + /* Skip persistent params */ + if (defs->is_persistent) + continue; + + /* Find preset value */ + if (grc_param == DBG_GRC_PARAM_EXCLUDE_ALL) + preset_val = + defs->exclude_all_preset_val; + else if (grc_param == DBG_GRC_PARAM_CRASH) + preset_val = + defs->crash_preset_val[dev_data->chip_id]; + else + return DBG_STATUS_INVALID_ARGS; + + qed_grc_set_param(p_hwfn, i, preset_val); + } + } else { + /* Regular param - set its value */ + qed_grc_set_param(p_hwfn, grc_param, val); } return DBG_STATUS_OK; @@ -4997,26 +5321,27 @@ void qed_dbg_grc_set_params_default(struct qed_hwfn *p_hwfn) u32 i; for (i = 0; i < MAX_DBG_GRC_PARAMS; i++) - dev_data->grc.param_val[i] = - s_grc_param_defs[i].default_val[dev_data->chip_id]; + if (!s_grc_param_defs[i].is_persistent) + dev_data->grc.param_val[i] = + s_grc_param_defs[i].default_val[dev_data->chip_id]; } enum dbg_status qed_dbg_grc_get_dump_buf_size(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *buf_size) { - enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt); + enum dbg_status status = qed_dbg_dev_init(p_hwfn); *buf_size = 0; if (status != DBG_STATUS_OK) return status; - if (!s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr || - !s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr || - !s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr || - !s_dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr || - !s_dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr) + if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr || + !p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr || + !p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr || + !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr || + !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr) return DBG_STATUS_DBG_ARRAY_NOT_SET; return qed_grc_dump(p_hwfn, p_ptt, NULL, false, buf_size); @@ -5042,6 +5367,9 @@ enum dbg_status qed_dbg_grc_dump(struct qed_hwfn *p_hwfn, if (buf_size_in_dwords < needed_buf_size_in_dwords) return DBG_STATUS_DUMP_BUF_TOO_SMALL; + /* Doesn't do anything, needed for compile time asserts */ + qed_static_asserts(); + /* GRC Dump */ status = qed_grc_dump(p_hwfn, p_ptt, dump_buf, true, num_dumped_dwords); @@ -5056,20 +5384,19 @@ enum dbg_status qed_dbg_idle_chk_get_dump_buf_size(struct qed_hwfn *p_hwfn, u32 *buf_size) { struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; - struct idle_chk_data *idle_chk; + struct idle_chk_data *idle_chk = &dev_data->idle_chk; enum dbg_status status; - idle_chk = &dev_data->idle_chk; *buf_size = 0; - status = qed_dbg_dev_init(p_hwfn, p_ptt); + status = qed_dbg_dev_init(p_hwfn); if (status != DBG_STATUS_OK) return status; - if (!s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr || - !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr || - !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr || - !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr) + if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr || + !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr || + !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr || + !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr) return DBG_STATUS_DBG_ARRAY_NOT_SET; if (!idle_chk->buf_size_set) { @@ -5104,6 +5431,7 @@ enum dbg_status qed_dbg_idle_chk_dump(struct qed_hwfn *p_hwfn, return DBG_STATUS_DUMP_BUF_TOO_SMALL; /* Update reset state */ + qed_grc_unreset_blocks(p_hwfn, p_ptt, true); qed_update_blocks_reset_state(p_hwfn, p_ptt); /* Idle Check Dump */ @@ -5119,7 +5447,7 @@ enum dbg_status qed_dbg_mcp_trace_get_dump_buf_size(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *buf_size) { - enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt); + enum dbg_status status = qed_dbg_dev_init(p_hwfn); *buf_size = 0; @@ -5166,7 +5494,7 @@ enum dbg_status qed_dbg_reg_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *buf_size) { - enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt); + enum dbg_status status = qed_dbg_dev_init(p_hwfn); *buf_size = 0; @@ -5212,7 +5540,7 @@ enum dbg_status qed_dbg_igu_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *buf_size) { - enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt); + enum dbg_status status = qed_dbg_dev_init(p_hwfn); *buf_size = 0; @@ -5258,7 +5586,7 @@ qed_dbg_protection_override_get_dump_buf_size(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *buf_size) { - enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt); + enum dbg_status status = qed_dbg_dev_init(p_hwfn); *buf_size = 0; @@ -5308,7 +5636,7 @@ enum dbg_status qed_dbg_fw_asserts_get_dump_buf_size(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *buf_size) { - enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt); + enum dbg_status status = qed_dbg_dev_init(p_hwfn); *buf_size = 0; @@ -5352,6 +5680,38 @@ enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn *p_hwfn, return DBG_STATUS_OK; } +static enum dbg_status qed_dbg_ilt_get_dump_buf_size(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + u32 *buf_size) +{ + enum dbg_status status = qed_dbg_dev_init(p_hwfn); + + *buf_size = 0; + + if (status != DBG_STATUS_OK) + return status; + + *buf_size = qed_ilt_dump(p_hwfn, p_ptt, NULL, 0, false); + + return DBG_STATUS_OK; +} + +static enum dbg_status qed_dbg_ilt_dump(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + u32 *dump_buf, + u32 buf_size_in_dwords, + u32 *num_dumped_dwords) +{ + *num_dumped_dwords = qed_ilt_dump(p_hwfn, + p_ptt, + dump_buf, buf_size_in_dwords, true); + + /* Reveret GRC params to their default */ + qed_dbg_grc_set_params_default(p_hwfn); + + return DBG_STATUS_OK; +} + enum dbg_status qed_dbg_read_attn(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, enum block_id block_id, @@ -5359,19 +5719,20 @@ enum dbg_status qed_dbg_read_attn(struct qed_hwfn *p_hwfn, bool clear_status, struct dbg_attn_block_result *results) { - enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt); + enum dbg_status status = qed_dbg_dev_init(p_hwfn); u8 reg_idx, num_attn_regs, num_result_regs = 0; const struct dbg_attn_reg *attn_reg_arr; if (status != DBG_STATUS_OK) return status; - if (!s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr || - !s_dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr || - !s_dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr) + if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr || + !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr || + !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr) return DBG_STATUS_DBG_ARRAY_NOT_SET; - attn_reg_arr = qed_get_block_attn_regs(block_id, + attn_reg_arr = qed_get_block_attn_regs(p_hwfn, + block_id, attn_type, &num_attn_regs); for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) { @@ -5416,7 +5777,7 @@ enum dbg_status qed_dbg_read_attn(struct qed_hwfn *p_hwfn, results->block_id = (u8)block_id; results->names_offset = - qed_get_block_attn_data(block_id, attn_type)->names_offset; + qed_get_block_attn_data(p_hwfn, block_id, attn_type)->names_offset; SET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE, attn_type); SET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_NUM_REGS, num_result_regs); @@ -5426,40 +5787,6 @@ enum dbg_status qed_dbg_read_attn(struct qed_hwfn *p_hwfn, /******************************* Data Types **********************************/ -struct block_info { - const char *name; - enum block_id id; -}; - -struct mcp_trace_format { - u32 data; -#define MCP_TRACE_FORMAT_MODULE_MASK 0x0000ffff -#define MCP_TRACE_FORMAT_MODULE_SHIFT 0 -#define MCP_TRACE_FORMAT_LEVEL_MASK 0x00030000 -#define MCP_TRACE_FORMAT_LEVEL_SHIFT 16 -#define MCP_TRACE_FORMAT_P1_SIZE_MASK 0x000c0000 -#define MCP_TRACE_FORMAT_P1_SIZE_SHIFT 18 -#define MCP_TRACE_FORMAT_P2_SIZE_MASK 0x00300000 -#define MCP_TRACE_FORMAT_P2_SIZE_SHIFT 20 -#define MCP_TRACE_FORMAT_P3_SIZE_MASK 0x00c00000 -#define MCP_TRACE_FORMAT_P3_SIZE_SHIFT 22 -#define MCP_TRACE_FORMAT_LEN_MASK 0xff000000 -#define MCP_TRACE_FORMAT_LEN_SHIFT 24 - - char *format_str; -}; - -/* Meta data structure, generated by a perl script during MFW build. therefore, - * the structs mcp_trace_meta and mcp_trace_format are duplicated in the perl - * script. - */ -struct mcp_trace_meta { - u32 modules_num; - char **modules; - u32 formats_num; - struct mcp_trace_format *formats; -}; - /* REG fifo element */ struct reg_fifo_element { u64 data; @@ -5483,6 +5810,12 @@ struct reg_fifo_element { #define REG_FIFO_ELEMENT_ERROR_MASK 0x1f }; +/* REG fifo error element */ +struct reg_fifo_err { + u32 err_code; + const char *err_msg; +}; + /* IGU fifo element */ struct igu_fifo_element { u32 dword0; @@ -5589,119 +5922,15 @@ struct igu_fifo_addr_data { #define MCP_TRACE_MAX_MODULE_LEN 8 #define MCP_TRACE_FORMAT_MAX_PARAMS 3 #define MCP_TRACE_FORMAT_PARAM_WIDTH \ - (MCP_TRACE_FORMAT_P2_SIZE_SHIFT - MCP_TRACE_FORMAT_P1_SIZE_SHIFT) + (MCP_TRACE_FORMAT_P2_SIZE_OFFSET - MCP_TRACE_FORMAT_P1_SIZE_OFFSET) #define REG_FIFO_ELEMENT_ADDR_FACTOR 4 #define REG_FIFO_ELEMENT_IS_PF_VF_VAL 127 #define PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR 4 -/********************************* Macros ************************************/ - -#define BYTES_TO_DWORDS(bytes) ((bytes) / BYTES_IN_DWORD) - /***************************** Constant Arrays *******************************/ -struct user_dbg_array { - const u32 *ptr; - u32 size_in_dwords; -}; - -/* Debug arrays */ -static struct user_dbg_array -s_user_dbg_arrays[MAX_BIN_DBG_BUFFER_TYPE] = { {NULL} }; - -/* Block names array */ -static struct block_info s_block_info_arr[] = { - {"grc", BLOCK_GRC}, - {"miscs", BLOCK_MISCS}, - {"misc", BLOCK_MISC}, - {"dbu", BLOCK_DBU}, - {"pglue_b", BLOCK_PGLUE_B}, - {"cnig", BLOCK_CNIG}, - {"cpmu", BLOCK_CPMU}, - {"ncsi", BLOCK_NCSI}, - {"opte", BLOCK_OPTE}, - {"bmb", BLOCK_BMB}, - {"pcie", BLOCK_PCIE}, - {"mcp", BLOCK_MCP}, - {"mcp2", BLOCK_MCP2}, - {"pswhst", BLOCK_PSWHST}, - {"pswhst2", BLOCK_PSWHST2}, - {"pswrd", BLOCK_PSWRD}, - {"pswrd2", BLOCK_PSWRD2}, - {"pswwr", BLOCK_PSWWR}, - {"pswwr2", BLOCK_PSWWR2}, - {"pswrq", BLOCK_PSWRQ}, - {"pswrq2", BLOCK_PSWRQ2}, - {"pglcs", BLOCK_PGLCS}, - {"ptu", BLOCK_PTU}, - {"dmae", BLOCK_DMAE}, - {"tcm", BLOCK_TCM}, - {"mcm", BLOCK_MCM}, - {"ucm", BLOCK_UCM}, - {"xcm", BLOCK_XCM}, - {"ycm", BLOCK_YCM}, - {"pcm", BLOCK_PCM}, - {"qm", BLOCK_QM}, - {"tm", BLOCK_TM}, - {"dorq", BLOCK_DORQ}, - {"brb", BLOCK_BRB}, - {"src", BLOCK_SRC}, - {"prs", BLOCK_PRS}, - {"tsdm", BLOCK_TSDM}, - {"msdm", BLOCK_MSDM}, - {"usdm", BLOCK_USDM}, - {"xsdm", BLOCK_XSDM}, - {"ysdm", BLOCK_YSDM}, - {"psdm", BLOCK_PSDM}, - {"tsem", BLOCK_TSEM}, - {"msem", BLOCK_MSEM}, - {"usem", BLOCK_USEM}, - {"xsem", BLOCK_XSEM}, - {"ysem", BLOCK_YSEM}, - {"psem", BLOCK_PSEM}, - {"rss", BLOCK_RSS}, - {"tmld", BLOCK_TMLD}, - {"muld", BLOCK_MULD}, - {"yuld", BLOCK_YULD}, - {"xyld", BLOCK_XYLD}, - {"ptld", BLOCK_PTLD}, - {"ypld", BLOCK_YPLD}, - {"prm", BLOCK_PRM}, - {"pbf_pb1", BLOCK_PBF_PB1}, - {"pbf_pb2", BLOCK_PBF_PB2}, - {"rpb", BLOCK_RPB}, - {"btb", BLOCK_BTB}, - {"pbf", BLOCK_PBF}, - {"rdif", BLOCK_RDIF}, - {"tdif", BLOCK_TDIF}, - {"cdu", BLOCK_CDU}, - {"ccfc", BLOCK_CCFC}, - {"tcfc", BLOCK_TCFC}, - {"igu", BLOCK_IGU}, - {"cau", BLOCK_CAU}, - {"rgfs", BLOCK_RGFS}, - {"rgsrc", BLOCK_RGSRC}, - {"tgfs", BLOCK_TGFS}, - {"tgsrc", BLOCK_TGSRC}, - {"umac", BLOCK_UMAC}, - {"xmac", BLOCK_XMAC}, - {"dbg", BLOCK_DBG}, - {"nig", BLOCK_NIG}, - {"wol", BLOCK_WOL}, - {"bmbn", BLOCK_BMBN}, - {"ipc", BLOCK_IPC}, - {"nwm", BLOCK_NWM}, - {"nws", BLOCK_NWS}, - {"ms", BLOCK_MS}, - {"phy_pcie", BLOCK_PHY_PCIE}, - {"led", BLOCK_LED}, - {"avs_wrap", BLOCK_AVS_WRAP}, - {"misc_aeu", BLOCK_MISC_AEU}, - {"bar0_map", BLOCK_BAR0_MAP} -}; - /* Status string array */ static const char * const s_status_str[] = { /* DBG_STATUS_OK */ @@ -5731,14 +5960,13 @@ static const char * const s_status_str[] = { /* DBG_STATUS_PCI_BUF_NOT_ALLOCATED */ "A PCI buffer wasn't allocated", - /* DBG_STATUS_TOO_MANY_INPUTS */ - "Too many inputs were enabled. Enabled less inputs, or set 'unifyInputs' to true", + /* DBG_STATUS_INVALID_FILTER_TRIGGER_DWORDS */ + "The filter/trigger constraint dword offsets are not enabled for recording", + /* DBG_STATUS_NO_MATCHING_FRAMING_MODE */ + "No matching framing mode", - /* DBG_STATUS_INPUT_OVERLAP */ - "Overlapping debug bus inputs", - - /* DBG_STATUS_HW_ONLY_RECORDING */ - "Cannot record Storm data since the entire recording cycle is used by HW", + /* DBG_STATUS_VFC_READ_ERROR */ + "Error reading from VFC", /* DBG_STATUS_STORM_ALREADY_ENABLED */ "The Storm was already enabled", @@ -5755,8 +5983,8 @@ static const char * const s_status_str[] = { /* DBG_STATUS_NO_INPUT_ENABLED */ "No input was enabled for recording", - /* DBG_STATUS_NO_FILTER_TRIGGER_64B */ - "Filters and triggers are not allowed when recording in 64b units", + /* DBG_STATUS_NO_FILTER_TRIGGER_256B */ + "Filters and triggers are not allowed in E4 256-bit mode", /* DBG_STATUS_FILTER_ALREADY_ENABLED */ "The filter was already enabled", @@ -5830,8 +6058,8 @@ static const char * const s_status_str[] = { /* DBG_STATUS_MCP_COULD_NOT_RESUME */ "Failed to resume MCP after halt", - /* DBG_STATUS_DMAE_FAILED */ - "DMAE transaction failed", + /* DBG_STATUS_RESERVED0 */ + "", /* DBG_STATUS_SEMI_FIFO_NOT_EMPTY */ "Failed to empty SEMI sync FIFO", @@ -5854,17 +6082,71 @@ static const char * const s_status_str[] = { /* DBG_STATUS_DBG_ARRAY_NOT_SET */ "Debug arrays were not set (when using binary files, dbg_set_bin_ptr must be called)", - /* DBG_STATUS_FILTER_BUG */ - "Debug Bus filtering requires the -unifyInputs option (due to a HW bug)", + /* DBG_STATUS_RESERVED1 */ + "", /* DBG_STATUS_NON_MATCHING_LINES */ - "Non-matching debug lines - all lines must be of the same type (either 128b or 256b)", + "Non-matching debug lines - in E4, all lines must be of the same type (either 128b or 256b)", - /* DBG_STATUS_INVALID_TRIGGER_DWORD_OFFSET */ - "The selected trigger dword offset wasn't enabled in the recorded HW block", + /* DBG_STATUS_INSUFFICIENT_HW_IDS */ + "Insufficient HW IDs. Try to record less Storms/blocks", /* DBG_STATUS_DBG_BUS_IN_USE */ - "The debug bus is in use" + "The debug bus is in use", + + /* DBG_STATUS_INVALID_STORM_DBG_MODE */ + "The storm debug mode is not supported in the current chip", + + /* DBG_STATUS_OTHER_ENGINE_BB_ONLY */ + "Other engine is supported only in BB", + + /* DBG_STATUS_FILTER_SINGLE_HW_ID */ + "The configured filter mode requires a single Storm/block input", + + /* DBG_STATUS_TRIGGER_SINGLE_HW_ID */ + "The configured filter mode requires that all the constraints of a single trigger state will be defined on a single Storm/block input", + + /* DBG_STATUS_MISSING_TRIGGER_STATE_STORM */ + "When triggering on Storm data, the Storm to trigger on must be specified", + + /* DBG_STATUS_MDUMP2_FAILED_TO_REQUEST_OFFSIZE */ + "Failed to request MDUMP2 Offsize", + + /* DBG_STATUS_MDUMP2_FAILED_VALIDATION_OF_DATA_CRC */ + "Expected CRC (part of the MDUMP2 data) is different than the calculated CRC over that data", + + /* DBG_STATUS_MDUMP2_INVALID_SIGNATURE */ + "Invalid Signature found at start of MDUMP2", + + /* DBG_STATUS_MDUMP2_INVALID_LOG_SIZE */ + "Invalid Log Size of MDUMP2", + + /* DBG_STATUS_MDUMP2_INVALID_LOG_HDR */ + "Invalid Log Header of MDUMP2", + + /* DBG_STATUS_MDUMP2_INVALID_LOG_DATA */ + "Invalid Log Data of MDUMP2", + + /* DBG_STATUS_MDUMP2_ERROR_EXTRACTING_NUM_PORTS */ + "Could not extract number of ports from regval buf of MDUMP2", + + /* DBG_STATUS_MDUMP2_ERROR_EXTRACTING_MFW_STATUS */ + "Could not extract MFW (link) status from regval buf of MDUMP2", + + /* DBG_STATUS_MDUMP2_ERROR_DISPLAYING_LINKDUMP */ + "Could not display linkdump of MDUMP2", + + /* DBG_STATUS_MDUMP2_ERROR_READING_PHY_CFG */ + "Could not read PHY CFG of MDUMP2", + + /* DBG_STATUS_MDUMP2_ERROR_READING_PLL_MODE */ + "Could not read PLL Mode of MDUMP2", + + /* DBG_STATUS_MDUMP2_ERROR_READING_LANE_REGS */ + "Could not read TSCF/TSCE Lane Regs of MDUMP2", + + /* DBG_STATUS_MDUMP2_ERROR_ALLOCATING_BUF */ + "Could not allocate MDUMP2 reg-val internal buffer" }; /* Idle check severity names array */ @@ -5920,7 +6202,7 @@ static const char * const s_master_strs[] = { "xsdm", "dbu", "dmae", - "???", + "jdap", "???", "???", "???", @@ -5928,12 +6210,13 @@ static const char * const s_master_strs[] = { }; /* REG FIFO error messages array */ -static const char * const s_reg_fifo_error_strs[] = { - "grc timeout", - "address doesn't belong to any block", - "reserved address in block or write to read-only address", - "privilege/protection mismatch", - "path isolation error" +static struct reg_fifo_err s_reg_fifo_errors[] = { + {1, "grc timeout"}, + {2, "address doesn't belong to any block"}, + {4, "reserved address in block or write to read-only address"}, + {8, "privilege/protection mismatch"}, + {16, "path isolation error"}, + {17, "RSL error"} }; /* IGU FIFO sources array */ @@ -5956,7 +6239,7 @@ static const char * const s_igu_fifo_error_strs[] = { "no error", "length error", "function disabled", - "VF sent command to attnetion address", + "VF sent command to attention address", "host sent prod update command", "read of during interrupt register while in MIMD mode", "access to PXP BAR reserved address", @@ -6008,16 +6291,15 @@ static const struct igu_fifo_addr_data s_igu_fifo_addr_data[] = { /******************************** Variables **********************************/ -/* MCP Trace meta data - used in case the dump doesn't contain the meta data - * (e.g. due to no NVRAM access). - */ -static struct user_dbg_array s_mcp_trace_meta = { NULL, 0 }; - /* Temporary buffer, used for print size calculations */ static char s_temp_buf[MAX_MSG_LEN]; /**************************** Private Functions ******************************/ +static void qed_user_static_asserts(void) +{ +} + static u32 qed_cyclic_add(u32 a, u32 b, u32 size) { return (a + b) % size; @@ -6041,6 +6323,9 @@ static u32 qed_read_from_cyclic_buf(void *buf, val_ptr = (u8 *)&val; + /* Assume running on a LITTLE ENDIAN and the buffer is network order + * (BIG ENDIAN), as high order bytes are placed in lower memory address. + */ for (i = 0; i < num_bytes_to_read; i++) { val_ptr[i] = bytes_buf[*offset]; *offset = qed_cyclic_add(*offset, 1, buf_size); @@ -6076,8 +6361,7 @@ static void qed_read_str_from_buf(void *buf, u32 *offset, u32 size, char *dest) { const char *source_str = &((const char *)buf)[*offset]; - strncpy(dest, source_str, size); - dest[size - 1] = '\0'; + strscpy(dest, source_str, size); *offset += size; } @@ -6109,6 +6393,7 @@ static u32 qed_read_param(u32 *dump_buf, if (*(char_buf + offset++)) { /* String param */ *param_str_val = char_buf + offset; + *param_num_val = 0; offset += strlen(*param_str_val) + 1; if (offset & 0x3) offset += (4 - (offset & 0x3)); @@ -6121,7 +6406,7 @@ static u32 qed_read_param(u32 *dump_buf, offset += 4; } - return offset / 4; + return (u32)offset / 4; } /* Reads a section header from the specified buffer. @@ -6174,6 +6459,25 @@ static u32 qed_print_section_params(u32 *dump_buf, return dump_offset; } +/* Returns the block name that matches the specified block ID, + * or NULL if not found. + */ +static const char *qed_dbg_get_block_name(struct qed_hwfn *p_hwfn, + enum block_id block_id) +{ + const struct dbg_block_user *block = + (const struct dbg_block_user *) + p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS_USER_DATA].ptr + block_id; + + return (const char *)block->name; +} + +static struct dbg_tools_user_data *qed_dbg_get_user_data(struct qed_hwfn + *p_hwfn) +{ + return (struct dbg_tools_user_data *)p_hwfn->dbg_user_info; +} + /* Parses the idle check rules and returns the number of characters printed. * In case of parsing error, returns 0. */ @@ -6206,19 +6510,18 @@ static u32 qed_parse_idle_chk_dump_rules(struct qed_hwfn *p_hwfn, hdr = (struct dbg_idle_chk_result_hdr *)dump_buf; rule_parsing_data = - (const struct dbg_idle_chk_rule_parsing_data *) - &s_user_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA]. - ptr[hdr->rule_id]; + (const struct dbg_idle_chk_rule_parsing_data *) + p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr + + hdr->rule_id; parsing_str_offset = - GET_FIELD(rule_parsing_data->data, - DBG_IDLE_CHK_RULE_PARSING_DATA_STR_OFFSET); + GET_FIELD(rule_parsing_data->data, + DBG_IDLE_CHK_RULE_PARSING_DATA_STR_OFFSET); has_fw_msg = - GET_FIELD(rule_parsing_data->data, - DBG_IDLE_CHK_RULE_PARSING_DATA_HAS_FW_MSG) > 0; - parsing_str = - &((const char *) - s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr) - [parsing_str_offset]; + GET_FIELD(rule_parsing_data->data, + DBG_IDLE_CHK_RULE_PARSING_DATA_HAS_FW_MSG) > 0; + parsing_str = (const char *) + p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr + + parsing_str_offset; lsi_msg = parsing_str; curr_reg_id = 0; @@ -6275,9 +6578,8 @@ static u32 qed_parse_idle_chk_dump_rules(struct qed_hwfn *p_hwfn, /* Skip register names until the required reg_id is * reached. */ - for (; reg_id > curr_reg_id; - curr_reg_id++, - parsing_str += strlen(parsing_str) + 1); + for (; reg_id > curr_reg_id; curr_reg_id++) + parsing_str += strlen(parsing_str) + 1; results_offset += sprintf(qed_get_buf_ptr(results_buf, @@ -6330,9 +6632,9 @@ static enum dbg_status qed_parse_idle_chk_dump(struct qed_hwfn *p_hwfn, u32 *num_errors, u32 *num_warnings) { + u32 num_section_params = 0, num_rules, num_rules_not_dumped; const char *section_name, *param_name, *param_str_val; u32 *dump_buf_end = dump_buf + num_dumped_dwords; - u32 num_section_params = 0, num_rules; /* Offset in results_buf in bytes */ u32 results_offset = 0; @@ -6341,8 +6643,8 @@ static enum dbg_status qed_parse_idle_chk_dump(struct qed_hwfn *p_hwfn, *num_errors = 0; *num_warnings = 0; - if (!s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr || - !s_user_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr) + if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr || + !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr) return DBG_STATUS_DBG_ARRAY_NOT_SET; /* Read global_params section */ @@ -6356,15 +6658,31 @@ static enum dbg_status qed_parse_idle_chk_dump(struct qed_hwfn *p_hwfn, num_section_params, results_buf, &results_offset); - /* Read idle_chk section */ + /* Read idle_chk section + * There may be 1 or 2 idle_chk section parameters: + * - 1st is "num_rules" + * - 2nd is "num_rules_not_dumped" (optional) + */ + dump_buf += qed_read_section_hdr(dump_buf, §ion_name, &num_section_params); - if (strcmp(section_name, "idle_chk") || num_section_params != 1) + if (strcmp(section_name, "idle_chk") || + (num_section_params != 2 && num_section_params != 1)) return DBG_STATUS_IDLE_CHK_PARSE_FAILED; dump_buf += qed_read_param(dump_buf, ¶m_name, ¶m_str_val, &num_rules); if (strcmp(param_name, "num_rules")) return DBG_STATUS_IDLE_CHK_PARSE_FAILED; + if (num_section_params > 1) { + dump_buf += qed_read_param(dump_buf, + ¶m_name, + ¶m_str_val, + &num_rules_not_dumped); + if (strcmp(param_name, "num_rules_not_dumped")) + return DBG_STATUS_IDLE_CHK_PARSE_FAILED; + } else { + num_rules_not_dumped = 0; + } if (num_rules) { u32 rules_print_size; @@ -6375,13 +6693,17 @@ static enum dbg_status qed_parse_idle_chk_dump(struct qed_hwfn *p_hwfn, results_offset), "FW_IDLE_CHECK:\n"); rules_print_size = - qed_parse_idle_chk_dump_rules(p_hwfn, dump_buf, - dump_buf_end, num_rules, + qed_parse_idle_chk_dump_rules(p_hwfn, + dump_buf, + dump_buf_end, + num_rules, true, results_buf ? results_buf + - results_offset : NULL, - num_errors, num_warnings); + results_offset : + NULL, + num_errors, + num_warnings); results_offset += rules_print_size; if (!rules_print_size) return DBG_STATUS_IDLE_CHK_PARSE_FAILED; @@ -6392,13 +6714,17 @@ static enum dbg_status qed_parse_idle_chk_dump(struct qed_hwfn *p_hwfn, results_offset), "\nLSI_IDLE_CHECK:\n"); rules_print_size = - qed_parse_idle_chk_dump_rules(p_hwfn, dump_buf, - dump_buf_end, num_rules, + qed_parse_idle_chk_dump_rules(p_hwfn, + dump_buf, + dump_buf_end, + num_rules, false, results_buf ? results_buf + - results_offset : NULL, - num_errors, num_warnings); + results_offset : + NULL, + num_errors, + num_warnings); results_offset += rules_print_size; if (!rules_print_size) return DBG_STATUS_IDLE_CHK_PARSE_FAILED; @@ -6423,43 +6749,39 @@ static enum dbg_status qed_parse_idle_chk_dump(struct qed_hwfn *p_hwfn, results_offset), "\nIdle Check completed successfully\n"); + if (num_rules_not_dumped) + results_offset += + sprintf(qed_get_buf_ptr(results_buf, + results_offset), + "\nIdle Check Partially dumped : num_rules_not_dumped = %d\n", + num_rules_not_dumped); + /* Add 1 for string NULL termination */ *parsed_results_bytes = results_offset + 1; return DBG_STATUS_OK; } -/* Frees the specified MCP Trace meta data */ -static void qed_mcp_trace_free_meta(struct qed_hwfn *p_hwfn, - struct mcp_trace_meta *meta) -{ - u32 i; - - /* Release modules */ - if (meta->modules) { - for (i = 0; i < meta->modules_num; i++) - kfree(meta->modules[i]); - kfree(meta->modules); - } - - /* Release formats */ - if (meta->formats) { - for (i = 0; i < meta->formats_num; i++) - kfree(meta->formats[i].format_str); - kfree(meta->formats); - } -} - /* Allocates and fills MCP Trace meta data based on the specified meta data * dump buffer. * Returns debug status code. */ -static enum dbg_status qed_mcp_trace_alloc_meta(struct qed_hwfn *p_hwfn, - const u32 *meta_buf, - struct mcp_trace_meta *meta) +static enum dbg_status +qed_mcp_trace_alloc_meta_data(struct qed_hwfn *p_hwfn, + const u32 *meta_buf) { - u8 *meta_buf_bytes = (u8 *)meta_buf; + struct dbg_tools_user_data *dev_user_data; u32 offset = 0, signature, i; + struct mcp_trace_meta *meta; + u8 *meta_buf_bytes; + + dev_user_data = qed_dbg_get_user_data(p_hwfn); + meta = &dev_user_data->mcp_trace_meta; + meta_buf_bytes = (u8 *)meta_buf; + + /* Free the previous meta before loading a new one. */ + if (meta->is_allocated) + qed_mcp_trace_free_meta_data(p_hwfn); memset(meta, 0, sizeof(*meta)); @@ -6470,7 +6792,8 @@ static enum dbg_status qed_mcp_trace_alloc_meta(struct qed_hwfn *p_hwfn, /* Read no. of modules and allocate memory for their pointers */ meta->modules_num = qed_read_byte_from_buf(meta_buf_bytes, &offset); - meta->modules = kzalloc(meta->modules_num * sizeof(char *), GFP_KERNEL); + meta->modules = kcalloc(meta->modules_num, sizeof(char *), + GFP_KERNEL); if (!meta->modules) return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; @@ -6498,7 +6821,7 @@ static enum dbg_status qed_mcp_trace_alloc_meta(struct qed_hwfn *p_hwfn, /* Read number of formats and allocate memory for all formats */ meta->formats_num = qed_read_dword_from_buf(meta_buf_bytes, &offset); - meta->formats = kzalloc(meta->formats_num * + meta->formats = kcalloc(meta->formats_num, sizeof(struct mcp_trace_format), GFP_KERNEL); if (!meta->formats) @@ -6511,9 +6834,8 @@ static enum dbg_status qed_mcp_trace_alloc_meta(struct qed_hwfn *p_hwfn, format_ptr->data = qed_read_dword_from_buf(meta_buf_bytes, &offset); - format_len = - (format_ptr->data & - MCP_TRACE_FORMAT_LEN_MASK) >> MCP_TRACE_FORMAT_LEN_SHIFT; + format_len = GET_MFW_FIELD(format_ptr->data, + MCP_TRACE_FORMAT_LEN); format_ptr->format_str = kzalloc(format_len, GFP_KERNEL); if (!format_ptr->format_str) { /* Update number of modules to be released */ @@ -6526,9 +6848,134 @@ static enum dbg_status qed_mcp_trace_alloc_meta(struct qed_hwfn *p_hwfn, format_len, format_ptr->format_str); } + meta->is_allocated = true; return DBG_STATUS_OK; } +/* Parses an MCP trace buffer. If result_buf is not NULL, the MCP Trace results + * are printed to it. The parsing status is returned. + * Arguments: + * trace_buf - MCP trace cyclic buffer + * trace_buf_size - MCP trace cyclic buffer size in bytes + * data_offset - offset in bytes of the data to parse in the MCP trace cyclic + * buffer. + * data_size - size in bytes of data to parse. + * parsed_buf - destination buffer for parsed data. + * parsed_results_bytes - size of parsed data in bytes. + */ +static enum dbg_status qed_parse_mcp_trace_buf(struct qed_hwfn *p_hwfn, + u8 *trace_buf, + u32 trace_buf_size, + u32 data_offset, + u32 data_size, + char *parsed_buf, + u32 *parsed_results_bytes) +{ + struct dbg_tools_user_data *dev_user_data; + struct mcp_trace_meta *meta; + u32 param_mask, param_shift; + enum dbg_status status; + + dev_user_data = qed_dbg_get_user_data(p_hwfn); + meta = &dev_user_data->mcp_trace_meta; + *parsed_results_bytes = 0; + + if (!meta->is_allocated) + return DBG_STATUS_MCP_TRACE_BAD_DATA; + + status = DBG_STATUS_OK; + + while (data_size) { + struct mcp_trace_format *format_ptr; + u8 format_level, format_module; + u32 params[3] = { 0, 0, 0 }; + u32 header, format_idx, i; + + if (data_size < MFW_TRACE_ENTRY_SIZE) + return DBG_STATUS_MCP_TRACE_BAD_DATA; + + header = qed_read_from_cyclic_buf(trace_buf, + &data_offset, + trace_buf_size, + MFW_TRACE_ENTRY_SIZE); + data_size -= MFW_TRACE_ENTRY_SIZE; + format_idx = header & MFW_TRACE_EVENTID_MASK; + + /* Skip message if its index doesn't exist in the meta data */ + if (format_idx >= meta->formats_num) { + u8 format_size = (u8)GET_MFW_FIELD(header, + MFW_TRACE_PRM_SIZE); + + if (data_size < format_size) + return DBG_STATUS_MCP_TRACE_BAD_DATA; + + data_offset = qed_cyclic_add(data_offset, + format_size, + trace_buf_size); + data_size -= format_size; + continue; + } + + format_ptr = &meta->formats[format_idx]; + + for (i = 0, + param_mask = MCP_TRACE_FORMAT_P1_SIZE_MASK, param_shift = + MCP_TRACE_FORMAT_P1_SIZE_OFFSET; + i < MCP_TRACE_FORMAT_MAX_PARAMS; + i++, param_mask <<= MCP_TRACE_FORMAT_PARAM_WIDTH, + param_shift += MCP_TRACE_FORMAT_PARAM_WIDTH) { + /* Extract param size (0..3) */ + u8 param_size = (u8)((format_ptr->data & param_mask) >> + param_shift); + + /* If the param size is zero, there are no other + * parameters. + */ + if (!param_size) + break; + + /* Size is encoded using 2 bits, where 3 is used to + * encode 4. + */ + if (param_size == 3) + param_size = 4; + + if (data_size < param_size) + return DBG_STATUS_MCP_TRACE_BAD_DATA; + + params[i] = qed_read_from_cyclic_buf(trace_buf, + &data_offset, + trace_buf_size, + param_size); + data_size -= param_size; + } + + format_level = (u8)GET_MFW_FIELD(format_ptr->data, + MCP_TRACE_FORMAT_LEVEL); + format_module = (u8)GET_MFW_FIELD(format_ptr->data, + MCP_TRACE_FORMAT_MODULE); + if (format_level >= ARRAY_SIZE(s_mcp_trace_level_str)) + return DBG_STATUS_MCP_TRACE_BAD_DATA; + + /* Print current message to results buffer */ + *parsed_results_bytes += + sprintf(qed_get_buf_ptr(parsed_buf, + *parsed_results_bytes), + "%s %-8s: ", + s_mcp_trace_level_str[format_level], + meta->modules[format_module]); + *parsed_results_bytes += + sprintf(qed_get_buf_ptr(parsed_buf, *parsed_results_bytes), + format_ptr->format_str, + params[0], params[1], params[2]); + } + + /* Add string NULL terminator */ + (*parsed_results_bytes)++; + + return status; +} + /* Parses an MCP Trace dump buffer. * If result_buf is not NULL, the MCP Trace results are printed to it. * In any case, the required results buffer size is assigned to @@ -6537,15 +6984,14 @@ static enum dbg_status qed_mcp_trace_alloc_meta(struct qed_hwfn *p_hwfn, */ static enum dbg_status qed_parse_mcp_trace_dump(struct qed_hwfn *p_hwfn, u32 *dump_buf, - u32 num_dumped_dwords, char *results_buf, - u32 *parsed_results_bytes) + u32 *parsed_results_bytes, + bool free_meta_data) { - u32 end_offset, bytes_left, trace_data_dwords, trace_meta_dwords; - u32 param_mask, param_shift, param_num_val, num_section_params; const char *section_name, *param_name, *param_str_val; - u32 offset, results_offset = 0; - struct mcp_trace_meta meta; + u32 data_size, trace_data_dwords, trace_meta_dwords; + u32 offset, results_offset, results_buf_bytes; + u32 param_num_val, num_section_params; struct mcp_trace *trace; enum dbg_status status; const u32 *meta_buf; @@ -6577,10 +7023,12 @@ static enum dbg_status qed_parse_mcp_trace_dump(struct qed_hwfn *p_hwfn, /* Prepare trace info */ trace = (struct mcp_trace *)dump_buf; + if (trace->signature != MFW_TRACE_SIGNATURE || !trace->size) + return DBG_STATUS_MCP_TRACE_BAD_DATA; + trace_buf = (u8 *)dump_buf + sizeof(*trace); offset = trace->trace_oldest; - end_offset = trace->trace_prod; - bytes_left = qed_cyclic_sub(end_offset, offset, trace->size); + data_size = qed_cyclic_sub(trace->trace_prod, offset, trace->size); dump_buf += trace_data_dwords; /* Read meta_data section */ @@ -6597,126 +7045,41 @@ static enum dbg_status qed_parse_mcp_trace_dump(struct qed_hwfn *p_hwfn, /* Choose meta data buffer */ if (!trace_meta_dwords) { /* Dump doesn't include meta data */ - if (!s_mcp_trace_meta.ptr) + struct dbg_tools_user_data *dev_user_data = + qed_dbg_get_user_data(p_hwfn); + + if (!dev_user_data->mcp_trace_user_meta_buf) return DBG_STATUS_MCP_TRACE_NO_META; - meta_buf = s_mcp_trace_meta.ptr; + + meta_buf = dev_user_data->mcp_trace_user_meta_buf; } else { /* Dump includes meta data */ meta_buf = dump_buf; } /* Allocate meta data memory */ - status = qed_mcp_trace_alloc_meta(p_hwfn, meta_buf, &meta); + status = qed_mcp_trace_alloc_meta_data(p_hwfn, meta_buf); if (status != DBG_STATUS_OK) - goto free_mem; - - /* Ignore the level and modules masks - just print everything that is - * already in the buffer. - */ - while (bytes_left) { - struct mcp_trace_format *format_ptr; - u8 format_level, format_module; - u32 params[3] = { 0, 0, 0 }; - u32 header, format_idx, i; - - if (bytes_left < MFW_TRACE_ENTRY_SIZE) { - status = DBG_STATUS_MCP_TRACE_BAD_DATA; - goto free_mem; - } - - header = qed_read_from_cyclic_buf(trace_buf, - &offset, - trace->size, - MFW_TRACE_ENTRY_SIZE); - bytes_left -= MFW_TRACE_ENTRY_SIZE; - format_idx = header & MFW_TRACE_EVENTID_MASK; - - /* Skip message if its index doesn't exist in the meta data */ - if (format_idx > meta.formats_num) { - u8 format_size = - (u8)((header & - MFW_TRACE_PRM_SIZE_MASK) >> - MFW_TRACE_PRM_SIZE_SHIFT); - - if (bytes_left < format_size) { - status = DBG_STATUS_MCP_TRACE_BAD_DATA; - goto free_mem; - } - - offset = qed_cyclic_add(offset, - format_size, trace->size); - bytes_left -= format_size; - continue; - } - - format_ptr = &meta.formats[format_idx]; - - for (i = 0, - param_mask = MCP_TRACE_FORMAT_P1_SIZE_MASK, param_shift = - MCP_TRACE_FORMAT_P1_SIZE_SHIFT; - i < MCP_TRACE_FORMAT_MAX_PARAMS; - i++, param_mask <<= MCP_TRACE_FORMAT_PARAM_WIDTH, - param_shift += MCP_TRACE_FORMAT_PARAM_WIDTH) { - /* Extract param size (0..3) */ - u8 param_size = - (u8)((format_ptr->data & - param_mask) >> param_shift); - - /* If the param size is zero, there are no other - * parameters. - */ - if (!param_size) - break; - - /* Size is encoded using 2 bits, where 3 is used to - * encode 4. - */ - if (param_size == 3) - param_size = 4; - - if (bytes_left < param_size) { - status = DBG_STATUS_MCP_TRACE_BAD_DATA; - goto free_mem; - } + return status; - params[i] = qed_read_from_cyclic_buf(trace_buf, - &offset, - trace->size, - param_size); + status = qed_parse_mcp_trace_buf(p_hwfn, + trace_buf, + trace->size, + offset, + data_size, + results_buf ? + results_buf + results_offset : + NULL, + &results_buf_bytes); + if (status != DBG_STATUS_OK) + return status; - bytes_left -= param_size; - } + if (free_meta_data) + qed_mcp_trace_free_meta_data(p_hwfn); - format_level = - (u8)((format_ptr->data & - MCP_TRACE_FORMAT_LEVEL_MASK) >> - MCP_TRACE_FORMAT_LEVEL_SHIFT); - format_module = - (u8)((format_ptr->data & - MCP_TRACE_FORMAT_MODULE_MASK) >> - MCP_TRACE_FORMAT_MODULE_SHIFT); - if (format_level >= ARRAY_SIZE(s_mcp_trace_level_str)) { - status = DBG_STATUS_MCP_TRACE_BAD_DATA; - goto free_mem; - } + *parsed_results_bytes = results_offset + results_buf_bytes; - /* Print current message to results buffer */ - results_offset += - sprintf(qed_get_buf_ptr(results_buf, - results_offset), "%s %-8s: ", - s_mcp_trace_level_str[format_level], - meta.modules[format_module]); - results_offset += - sprintf(qed_get_buf_ptr(results_buf, - results_offset), - format_ptr->format_str, params[0], params[1], - params[2]); - } - -free_mem: - *parsed_results_bytes = results_offset + 1; - qed_mcp_trace_free_meta(p_hwfn, &meta); - return status; + return DBG_STATUS_OK; } /* Parses a Reg FIFO dump buffer. @@ -6725,16 +7088,14 @@ free_mem: * parsed_results_bytes. * The parsing status is returned. */ -static enum dbg_status qed_parse_reg_fifo_dump(struct qed_hwfn *p_hwfn, - u32 *dump_buf, - u32 num_dumped_dwords, +static enum dbg_status qed_parse_reg_fifo_dump(u32 *dump_buf, char *results_buf, u32 *parsed_results_bytes) { const char *section_name, *param_name, *param_str_val; u32 param_num_val, num_section_params, num_elements; struct reg_fifo_element *elements; - u8 i, j, err_val, vf_val; + u8 i, j, err_code, vf_val; u32 results_offset = 0; char vf_str[4]; @@ -6765,7 +7126,7 @@ static enum dbg_status qed_parse_reg_fifo_dump(struct qed_hwfn *p_hwfn, /* Decode elements */ for (i = 0; i < num_elements; i++) { - bool err_printed = false; + const char *err_msg = NULL; /* Discover if element belongs to a VF or a PF */ vf_val = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_VF); @@ -6774,11 +7135,17 @@ static enum dbg_status qed_parse_reg_fifo_dump(struct qed_hwfn *p_hwfn, else sprintf(vf_str, "%d", vf_val); + /* Find error message */ + err_code = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_ERROR); + for (j = 0; j < ARRAY_SIZE(s_reg_fifo_errors) && !err_msg; j++) + if (err_code == s_reg_fifo_errors[j].err_code) + err_msg = s_reg_fifo_errors[j].err_msg; + /* Add parsed element to parsed buffer */ results_offset += sprintf(qed_get_buf_ptr(results_buf, results_offset), - "raw: 0x%016llx, address: 0x%07x, access: %-5s, pf: %2d, vf: %s, port: %d, privilege: %-3s, protection: %-12s, master: %-4s, errors: ", + "raw: 0x%016llx, address: 0x%07x, access: %-5s, pf: %2d, vf: %s, port: %d, privilege: %-3s, protection: %-12s, master: %-4s, error: %s\n", elements[i].data, (u32)GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_ADDRESS) * @@ -6795,30 +7162,8 @@ static enum dbg_status qed_parse_reg_fifo_dump(struct qed_hwfn *p_hwfn, s_protection_strs[GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_PROTECTION)], s_master_strs[GET_FIELD(elements[i].data, - REG_FIFO_ELEMENT_MASTER)]); - - /* Print errors */ - for (j = 0, - err_val = GET_FIELD(elements[i].data, - REG_FIFO_ELEMENT_ERROR); - j < ARRAY_SIZE(s_reg_fifo_error_strs); - j++, err_val >>= 1) { - if (err_val & 0x1) { - if (err_printed) - results_offset += - sprintf(qed_get_buf_ptr - (results_buf, - results_offset), ", "); - results_offset += - sprintf(qed_get_buf_ptr - (results_buf, results_offset), "%s", - s_reg_fifo_error_strs[j]); - err_printed = true; - } - } - - results_offset += - sprintf(qed_get_buf_ptr(results_buf, results_offset), "\n"); + REG_FIFO_ELEMENT_MASTER)], + err_msg ? err_msg : "unknown error code"); } results_offset += sprintf(qed_get_buf_ptr(results_buf, @@ -6834,8 +7179,7 @@ static enum dbg_status qed_parse_reg_fifo_dump(struct qed_hwfn *p_hwfn, static enum dbg_status qed_parse_igu_fifo_element(struct igu_fifo_element *element, char *results_buf, - u32 *results_offset, - u32 *parsed_results_bytes) + u32 *results_offset) { const struct igu_fifo_addr_data *found_addr = NULL; u8 source, err_type, i, is_cleanup; @@ -6933,9 +7277,9 @@ static enum dbg_status qed_parse_igu_fifo_element(struct igu_fifo_element "cmd_type: prod/cons update, prod/cons: 0x%x, update_flag: %s, en_dis_int_for_sb : %s, segment : %s, timer_mask = %d, ", prod_cons, update_flag ? "update" : "nop", - en_dis_int_for_sb - ? (en_dis_int_for_sb == 1 ? "disable" : "nop") - : "enable", + en_dis_int_for_sb ? + (en_dis_int_for_sb == 1 ? "disable" : "nop") : + "enable", segment ? "attn" : "regular", timer_mask); } @@ -6969,9 +7313,7 @@ out: * parsed_results_bytes. * The parsing status is returned. */ -static enum dbg_status qed_parse_igu_fifo_dump(struct qed_hwfn *p_hwfn, - u32 *dump_buf, - u32 num_dumped_dwords, +static enum dbg_status qed_parse_igu_fifo_dump(u32 *dump_buf, char *results_buf, u32 *parsed_results_bytes) { @@ -7011,8 +7353,7 @@ static enum dbg_status qed_parse_igu_fifo_dump(struct qed_hwfn *p_hwfn, for (i = 0; i < num_elements; i++) { status = qed_parse_igu_fifo_element(&elements[i], results_buf, - &results_offset, - parsed_results_bytes); + &results_offset); if (status != DBG_STATUS_OK) return status; } @@ -7028,9 +7369,7 @@ static enum dbg_status qed_parse_igu_fifo_dump(struct qed_hwfn *p_hwfn, } static enum dbg_status -qed_parse_protection_override_dump(struct qed_hwfn *p_hwfn, - u32 *dump_buf, - u32 num_dumped_dwords, +qed_parse_protection_override_dump(u32 *dump_buf, char *results_buf, u32 *parsed_results_bytes) { @@ -7105,9 +7444,7 @@ qed_parse_protection_override_dump(struct qed_hwfn *p_hwfn, * parsed_results_bytes. * The parsing status is returned. */ -static enum dbg_status qed_parse_fw_asserts_dump(struct qed_hwfn *p_hwfn, - u32 *dump_buf, - u32 num_dumped_dwords, +static enum dbg_status qed_parse_fw_asserts_dump(u32 *dump_buf, char *results_buf, u32 *parsed_results_bytes) { @@ -7180,18 +7517,29 @@ static enum dbg_status qed_parse_fw_asserts_dump(struct qed_hwfn *p_hwfn, /***************************** Public Functions *******************************/ -enum dbg_status qed_dbg_user_set_bin_ptr(const u8 * const bin_ptr) +enum dbg_status qed_dbg_user_set_bin_ptr(struct qed_hwfn *p_hwfn, + const u8 * const bin_ptr) { - struct bin_buffer_hdr *buf_array = (struct bin_buffer_hdr *)bin_ptr; + struct bin_buffer_hdr *buf_hdrs = (struct bin_buffer_hdr *)bin_ptr; u8 buf_id; /* Convert binary data to debug arrays */ - for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++) { - s_user_dbg_arrays[buf_id].ptr = - (u32 *)(bin_ptr + buf_array[buf_id].offset); - s_user_dbg_arrays[buf_id].size_in_dwords = - BYTES_TO_DWORDS(buf_array[buf_id].length); - } + for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++) + qed_set_dbg_bin_buf(p_hwfn, + (enum bin_dbg_buffer_type)buf_id, + (u32 *)(bin_ptr + buf_hdrs[buf_id].offset), + buf_hdrs[buf_id].length); + + return DBG_STATUS_OK; +} + +enum dbg_status qed_dbg_alloc_user_data(struct qed_hwfn *p_hwfn, + void **user_data_ptr) +{ + *user_data_ptr = kzalloc(sizeof(struct dbg_tools_user_data), + GFP_KERNEL); + if (!(*user_data_ptr)) + return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; return DBG_STATUS_OK; } @@ -7221,7 +7569,8 @@ enum dbg_status qed_print_idle_chk_results(struct qed_hwfn *p_hwfn, u32 *dump_buf, u32 num_dumped_dwords, char *results_buf, - u32 *num_errors, u32 *num_warnings) + u32 *num_errors, + u32 *num_warnings) { u32 parsed_buf_size; @@ -7233,10 +7582,13 @@ enum dbg_status qed_print_idle_chk_results(struct qed_hwfn *p_hwfn, num_errors, num_warnings); } -void qed_dbg_mcp_trace_set_meta_data(u32 *data, u32 size) +void qed_dbg_mcp_trace_set_meta_data(struct qed_hwfn *p_hwfn, + const u32 *meta_buf) { - s_mcp_trace_meta.ptr = data; - s_mcp_trace_meta.size_in_dwords = size; + struct dbg_tools_user_data *dev_user_data = + qed_dbg_get_user_data(p_hwfn); + + dev_user_data->mcp_trace_user_meta_buf = meta_buf; } enum dbg_status qed_get_mcp_trace_results_buf_size(struct qed_hwfn *p_hwfn, @@ -7245,9 +7597,7 @@ enum dbg_status qed_get_mcp_trace_results_buf_size(struct qed_hwfn *p_hwfn, u32 *results_buf_size) { return qed_parse_mcp_trace_dump(p_hwfn, - dump_buf, - num_dumped_dwords, - NULL, results_buf_size); + dump_buf, NULL, results_buf_size, true); } enum dbg_status qed_print_mcp_trace_results(struct qed_hwfn *p_hwfn, @@ -7257,10 +7607,41 @@ enum dbg_status qed_print_mcp_trace_results(struct qed_hwfn *p_hwfn, { u32 parsed_buf_size; + /* Doesn't do anything, needed for compile time asserts */ + qed_user_static_asserts(); + return qed_parse_mcp_trace_dump(p_hwfn, dump_buf, - num_dumped_dwords, - results_buf, &parsed_buf_size); + results_buf, &parsed_buf_size, true); +} + +/* Frees the specified MCP Trace meta data */ +void qed_mcp_trace_free_meta_data(struct qed_hwfn *p_hwfn) +{ + struct dbg_tools_user_data *dev_user_data; + struct mcp_trace_meta *meta; + u32 i; + + dev_user_data = qed_dbg_get_user_data(p_hwfn); + meta = &dev_user_data->mcp_trace_meta; + if (!meta->is_allocated) + return; + + /* Release modules */ + if (meta->modules) { + for (i = 0; i < meta->modules_num; i++) + kfree(meta->modules[i]); + kfree(meta->modules); + } + + /* Release formats */ + if (meta->formats) { + for (i = 0; i < meta->formats_num; i++) + kfree(meta->formats[i].format_str); + kfree(meta->formats); + } + + meta->is_allocated = false; } enum dbg_status qed_get_reg_fifo_results_buf_size(struct qed_hwfn *p_hwfn, @@ -7268,10 +7649,7 @@ enum dbg_status qed_get_reg_fifo_results_buf_size(struct qed_hwfn *p_hwfn, u32 num_dumped_dwords, u32 *results_buf_size) { - return qed_parse_reg_fifo_dump(p_hwfn, - dump_buf, - num_dumped_dwords, - NULL, results_buf_size); + return qed_parse_reg_fifo_dump(dump_buf, NULL, results_buf_size); } enum dbg_status qed_print_reg_fifo_results(struct qed_hwfn *p_hwfn, @@ -7281,10 +7659,7 @@ enum dbg_status qed_print_reg_fifo_results(struct qed_hwfn *p_hwfn, { u32 parsed_buf_size; - return qed_parse_reg_fifo_dump(p_hwfn, - dump_buf, - num_dumped_dwords, - results_buf, &parsed_buf_size); + return qed_parse_reg_fifo_dump(dump_buf, results_buf, &parsed_buf_size); } enum dbg_status qed_get_igu_fifo_results_buf_size(struct qed_hwfn *p_hwfn, @@ -7292,10 +7667,7 @@ enum dbg_status qed_get_igu_fifo_results_buf_size(struct qed_hwfn *p_hwfn, u32 num_dumped_dwords, u32 *results_buf_size) { - return qed_parse_igu_fifo_dump(p_hwfn, - dump_buf, - num_dumped_dwords, - NULL, results_buf_size); + return qed_parse_igu_fifo_dump(dump_buf, NULL, results_buf_size); } enum dbg_status qed_print_igu_fifo_results(struct qed_hwfn *p_hwfn, @@ -7305,10 +7677,7 @@ enum dbg_status qed_print_igu_fifo_results(struct qed_hwfn *p_hwfn, { u32 parsed_buf_size; - return qed_parse_igu_fifo_dump(p_hwfn, - dump_buf, - num_dumped_dwords, - results_buf, &parsed_buf_size); + return qed_parse_igu_fifo_dump(dump_buf, results_buf, &parsed_buf_size); } enum dbg_status @@ -7317,9 +7686,7 @@ qed_get_protection_override_results_buf_size(struct qed_hwfn *p_hwfn, u32 num_dumped_dwords, u32 *results_buf_size) { - return qed_parse_protection_override_dump(p_hwfn, - dump_buf, - num_dumped_dwords, + return qed_parse_protection_override_dump(dump_buf, NULL, results_buf_size); } @@ -7330,9 +7697,7 @@ enum dbg_status qed_print_protection_override_results(struct qed_hwfn *p_hwfn, { u32 parsed_buf_size; - return qed_parse_protection_override_dump(p_hwfn, - dump_buf, - num_dumped_dwords, + return qed_parse_protection_override_dump(dump_buf, results_buf, &parsed_buf_size); } @@ -7342,10 +7707,7 @@ enum dbg_status qed_get_fw_asserts_results_buf_size(struct qed_hwfn *p_hwfn, u32 num_dumped_dwords, u32 *results_buf_size) { - return qed_parse_fw_asserts_dump(p_hwfn, - dump_buf, - num_dumped_dwords, - NULL, results_buf_size); + return qed_parse_fw_asserts_dump(dump_buf, NULL, results_buf_size); } enum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn, @@ -7355,87 +7717,90 @@ enum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn, { u32 parsed_buf_size; - return qed_parse_fw_asserts_dump(p_hwfn, - dump_buf, - num_dumped_dwords, + return qed_parse_fw_asserts_dump(dump_buf, results_buf, &parsed_buf_size); } enum dbg_status qed_dbg_parse_attn(struct qed_hwfn *p_hwfn, struct dbg_attn_block_result *results) { - struct user_dbg_array *block_attn, *pstrings; const u32 *block_attn_name_offsets; - enum dbg_attn_type attn_type; + const char *attn_name_base; const char *block_name; + enum dbg_attn_type attn_type; u8 num_regs, i, j; num_regs = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_NUM_REGS); - attn_type = (enum dbg_attn_type) - GET_FIELD(results->data, - DBG_ATTN_BLOCK_RESULT_ATTN_TYPE); - block_name = s_block_info_arr[results->block_id].name; - - if (!s_user_dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr || - !s_user_dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr || - !s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr) + attn_type = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE); + block_name = qed_dbg_get_block_name(p_hwfn, results->block_id); + if (!block_name) + return DBG_STATUS_INVALID_ARGS; + + if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr || + !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr || + !p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr) return DBG_STATUS_DBG_ARRAY_NOT_SET; - block_attn = &s_user_dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS]; - block_attn_name_offsets = &block_attn->ptr[results->names_offset]; + block_attn_name_offsets = + (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr + + results->names_offset; + + attn_name_base = p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr; /* Go over registers with a non-zero attention status */ for (i = 0; i < num_regs; i++) { + struct dbg_attn_bit_mapping *bit_mapping; struct dbg_attn_reg_result *reg_result; - struct dbg_attn_bit_mapping *mapping; u8 num_reg_attn, bit_idx = 0; reg_result = &results->reg_results[i]; num_reg_attn = GET_FIELD(reg_result->data, DBG_ATTN_REG_RESULT_NUM_REG_ATTN); - block_attn = &s_user_dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES]; - mapping = &((struct dbg_attn_bit_mapping *) - block_attn->ptr)[reg_result->block_attn_offset]; - - pstrings = &s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS]; + bit_mapping = (struct dbg_attn_bit_mapping *) + p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr + + reg_result->block_attn_offset; /* Go over attention status bits */ for (j = 0; j < num_reg_attn; j++) { - u16 attn_idx_val = GET_FIELD(mapping[j].data, + u16 attn_idx_val = GET_FIELD(bit_mapping[j].data, DBG_ATTN_BIT_MAPPING_VAL); const char *attn_name, *attn_type_str, *masked_str; - u32 name_offset, sts_addr; + u32 attn_name_offset; + u32 sts_addr; /* Check if bit mask should be advanced (due to unused * bits). */ - if (GET_FIELD(mapping[j].data, + if (GET_FIELD(bit_mapping[j].data, DBG_ATTN_BIT_MAPPING_IS_UNUSED_BIT_CNT)) { bit_idx += (u8)attn_idx_val; continue; } /* Check current bit index */ - if (!(reg_result->sts_val & BIT(bit_idx))) { - bit_idx++; - continue; + if (reg_result->sts_val & BIT(bit_idx)) { + /* An attention bit with value=1 was found + * Find attention name + */ + attn_name_offset = + block_attn_name_offsets[attn_idx_val]; + attn_name = attn_name_base + attn_name_offset; + attn_type_str = + (attn_type == + ATTN_TYPE_INTERRUPT ? "Interrupt" : + "Parity"); + masked_str = reg_result->mask_val & + BIT(bit_idx) ? + " [masked]" : ""; + sts_addr = + GET_FIELD(reg_result->data, + DBG_ATTN_REG_RESULT_STS_ADDRESS); + DP_NOTICE(p_hwfn, + "%s (%s) : %s [address 0x%08x, bit %d]%s\n", + block_name, attn_type_str, attn_name, + sts_addr * 4, bit_idx, masked_str); } - /* Find attention name */ - name_offset = block_attn_name_offsets[attn_idx_val]; - attn_name = &((const char *) - pstrings->ptr)[name_offset]; - attn_type_str = attn_type == ATTN_TYPE_INTERRUPT ? - "Interrupt" : "Parity"; - masked_str = reg_result->mask_val & BIT(bit_idx) ? - " [masked]" : ""; - sts_addr = GET_FIELD(reg_result->data, - DBG_ATTN_REG_RESULT_STS_ADDRESS); - DP_NOTICE(p_hwfn, - "%s (%s) : %s [address 0x%08x, bit %d]%s\n", - block_name, attn_type_str, attn_name, - sts_addr, bit_idx, masked_str); - bit_idx++; } } @@ -7457,9 +7822,26 @@ qed_print_idle_chk_results_wrapper(struct qed_hwfn *p_hwfn, &num_warnnings); } +static DEFINE_MUTEX(qed_dbg_lock); + +#define MAX_PHY_RESULT_BUFFER 9000 + +/******************************** Feature Meta data section ******************/ + +#define GRC_NUM_STR_FUNCS 2 +#define IDLE_CHK_NUM_STR_FUNCS 1 +#define MCP_TRACE_NUM_STR_FUNCS 1 +#define REG_FIFO_NUM_STR_FUNCS 1 +#define IGU_FIFO_NUM_STR_FUNCS 1 +#define PROTECTION_OVERRIDE_NUM_STR_FUNCS 1 +#define FW_ASSERTS_NUM_STR_FUNCS 1 +#define ILT_NUM_STR_FUNCS 1 +#define PHY_NUM_STR_FUNCS 20 + /* Feature meta data lookup table */ static struct { char *name; + u32 num_funcs; enum dbg_status (*get_size)(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u32 *size); enum dbg_status (*perform_dump)(struct qed_hwfn *p_hwfn, @@ -7472,37 +7854,46 @@ static struct { u32 *dump_buf, u32 num_dumped_dwords, u32 *results_buf_size); + const struct qed_func_lookup *hsi_func_lookup; } qed_features_lookup[] = { { - "grc", qed_dbg_grc_get_dump_buf_size, - qed_dbg_grc_dump, NULL, NULL}, { - "idle_chk", + "grc", GRC_NUM_STR_FUNCS, qed_dbg_grc_get_dump_buf_size, + qed_dbg_grc_dump, NULL, NULL, NULL}, { + "idle_chk", IDLE_CHK_NUM_STR_FUNCS, qed_dbg_idle_chk_get_dump_buf_size, qed_dbg_idle_chk_dump, qed_print_idle_chk_results_wrapper, - qed_get_idle_chk_results_buf_size}, { - "mcp_trace", + qed_get_idle_chk_results_buf_size, + NULL}, { + "mcp_trace", MCP_TRACE_NUM_STR_FUNCS, qed_dbg_mcp_trace_get_dump_buf_size, qed_dbg_mcp_trace_dump, qed_print_mcp_trace_results, - qed_get_mcp_trace_results_buf_size}, { - "reg_fifo", + qed_get_mcp_trace_results_buf_size, + NULL}, { + "reg_fifo", REG_FIFO_NUM_STR_FUNCS, qed_dbg_reg_fifo_get_dump_buf_size, qed_dbg_reg_fifo_dump, qed_print_reg_fifo_results, - qed_get_reg_fifo_results_buf_size}, { - "igu_fifo", + qed_get_reg_fifo_results_buf_size, + NULL}, { + "igu_fifo", IGU_FIFO_NUM_STR_FUNCS, qed_dbg_igu_fifo_get_dump_buf_size, qed_dbg_igu_fifo_dump, qed_print_igu_fifo_results, - qed_get_igu_fifo_results_buf_size}, { - "protection_override", + qed_get_igu_fifo_results_buf_size, + NULL}, { + "protection_override", PROTECTION_OVERRIDE_NUM_STR_FUNCS, qed_dbg_protection_override_get_dump_buf_size, qed_dbg_protection_override_dump, qed_print_protection_override_results, - qed_get_protection_override_results_buf_size}, { - "fw_asserts", + qed_get_protection_override_results_buf_size, + NULL}, { + "fw_asserts", FW_ASSERTS_NUM_STR_FUNCS, qed_dbg_fw_asserts_get_dump_buf_size, qed_dbg_fw_asserts_dump, qed_print_fw_asserts_results, - qed_get_fw_asserts_results_buf_size},}; + qed_get_fw_asserts_results_buf_size, + NULL}, { + "ilt", ILT_NUM_STR_FUNCS, qed_dbg_ilt_get_dump_buf_size, + qed_dbg_ilt_dump, NULL, NULL, NULL},}; static void qed_dbg_print_feature(u8 *p_text_buf, u32 text_size) { @@ -7523,8 +7914,9 @@ static enum dbg_status format_feature(struct qed_hwfn *p_hwfn, enum qed_dbg_features feature_idx) { struct qed_dbg_feature *feature = - &p_hwfn->cdev->dbg_params.features[feature_idx]; - u32 text_size_bytes, null_char_pos, i; + &p_hwfn->cdev->dbg_features[feature_idx]; + u32 txt_size_bytes, null_char_pos, i; + u32 *dbuf, dwords; enum dbg_status rc; char *text_buf; @@ -7532,33 +7924,43 @@ static enum dbg_status format_feature(struct qed_hwfn *p_hwfn, if (!qed_features_lookup[feature_idx].results_buf_size) return DBG_STATUS_OK; + dbuf = (u32 *)feature->dump_buf; + dwords = feature->dumped_dwords; + /* Obtain size of formatted output */ - rc = qed_features_lookup[feature_idx]. - results_buf_size(p_hwfn, (u32 *)feature->dump_buf, - feature->dumped_dwords, &text_size_bytes); + rc = qed_features_lookup[feature_idx].results_buf_size(p_hwfn, + dbuf, + dwords, + &txt_size_bytes); if (rc != DBG_STATUS_OK) return rc; - /* Make sure that the allocated size is a multiple of dword (4 bytes) */ - null_char_pos = text_size_bytes - 1; - text_size_bytes = (text_size_bytes + 3) & ~0x3; + /* Make sure that the allocated size is a multiple of dword + * (4 bytes). + */ + null_char_pos = txt_size_bytes - 1; + txt_size_bytes = (txt_size_bytes + 3) & ~0x3; - if (text_size_bytes < QED_RESULTS_BUF_MIN_SIZE) { + if (txt_size_bytes < QED_RESULTS_BUF_MIN_SIZE) { DP_NOTICE(p_hwfn->cdev, "formatted size of feature was too small %d. Aborting\n", - text_size_bytes); + txt_size_bytes); return DBG_STATUS_INVALID_ARGS; } - /* Allocate temp text buf */ - text_buf = vzalloc(text_size_bytes); - if (!text_buf) + /* allocate temp text buf */ + text_buf = vzalloc(txt_size_bytes); + if (!text_buf) { + DP_NOTICE(p_hwfn->cdev, + "failed to allocate text buffer. Aborting\n"); return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; + } /* Decode feature opcodes to string on temp buf */ - rc = qed_features_lookup[feature_idx]. - print_results(p_hwfn, (u32 *)feature->dump_buf, - feature->dumped_dwords, text_buf); + rc = qed_features_lookup[feature_idx].print_results(p_hwfn, + dbuf, + dwords, + text_buf); if (rc != DBG_STATUS_OK) { vfree(text_buf); return rc; @@ -7568,31 +7970,40 @@ static enum dbg_status format_feature(struct qed_hwfn *p_hwfn, * The bytes that were added as a result of the dword alignment are also * padded with '\n' characters. */ - for (i = null_char_pos; i < text_size_bytes; i++) + for (i = null_char_pos; i < txt_size_bytes; i++) text_buf[i] = '\n'; /* Dump printable feature to log */ - if (p_hwfn->cdev->dbg_params.print_data) - qed_dbg_print_feature(text_buf, text_size_bytes); + if (p_hwfn->cdev->print_dbg_data) + qed_dbg_print_feature(text_buf, txt_size_bytes); - /* Free the old dump_buf and point the dump_buf to the newly allocagted + /* Dump binary data as is to the output file */ + if (p_hwfn->cdev->dbg_bin_dump) { + vfree(text_buf); + return rc; + } + + /* Free the old dump_buf and point the dump_buf to the newly allocated * and formatted text buffer. */ vfree(feature->dump_buf); feature->dump_buf = text_buf; - feature->buf_size = text_size_bytes; - feature->dumped_dwords = text_size_bytes / 4; + feature->buf_size = txt_size_bytes; + feature->dumped_dwords = txt_size_bytes / 4; + return rc; } +#define MAX_DBG_FEATURE_SIZE_DWORDS 0x3FFFFFFF + /* Generic function for performing the dump of a debug feature. */ static enum dbg_status qed_dbg_dump(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, enum qed_dbg_features feature_idx) { struct qed_dbg_feature *feature = - &p_hwfn->cdev->dbg_params.features[feature_idx]; - u32 buf_size_dwords; + &p_hwfn->cdev->dbg_features[feature_idx]; + u32 buf_size_dwords, *dbuf, *dwords; enum dbg_status rc; DP_NOTICE(p_hwfn->cdev, "Collecting a debug feature [\"%s\"]\n", @@ -7614,18 +8025,32 @@ static enum dbg_status qed_dbg_dump(struct qed_hwfn *p_hwfn, &buf_size_dwords); if (rc != DBG_STATUS_OK && rc != DBG_STATUS_NVRAM_GET_IMAGE_FAILED) return rc; + + if (buf_size_dwords > MAX_DBG_FEATURE_SIZE_DWORDS) { + feature->buf_size = 0; + DP_NOTICE(p_hwfn->cdev, + "Debug feature [\"%s\"] size (0x%x dwords) exceeds maximum size (0x%x dwords)\n", + qed_features_lookup[feature_idx].name, + buf_size_dwords, MAX_DBG_FEATURE_SIZE_DWORDS); + + return DBG_STATUS_OK; + } + feature->buf_size = buf_size_dwords * sizeof(u32); feature->dump_buf = vmalloc(feature->buf_size); if (!feature->dump_buf) return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; - rc = qed_features_lookup[feature_idx]. - perform_dump(p_hwfn, p_ptt, (u32 *)feature->dump_buf, - feature->buf_size / sizeof(u32), - &feature->dumped_dwords); + dbuf = (u32 *)feature->dump_buf; + dwords = &feature->dumped_dwords; + rc = qed_features_lookup[feature_idx].perform_dump(p_hwfn, p_ptt, + dbuf, + feature->buf_size / + sizeof(u32), + dwords); /* If mcp is stuck we get DBG_STATUS_NVRAM_GET_IMAGE_FAILED error. - * In this case the buffer holds valid binary data, but we wont able + * In this case the buffer holds valid binary data, but we won't able * to parse it (since parsing relies on data in NVRAM which is only * accessible when MFW is responsive). skip the formatting but return * success so that binary data is provided. @@ -7684,6 +8109,56 @@ int qed_dbg_igu_fifo_size(struct qed_dev *cdev) return qed_dbg_feature_size(cdev, DBG_FEATURE_IGU_FIFO); } +static int qed_dbg_nvm_image_length(struct qed_hwfn *p_hwfn, + enum qed_nvm_images image_id, u32 *length) +{ + struct qed_nvm_image_att image_att; + int rc; + + *length = 0; + rc = qed_mcp_get_nvm_image_att(p_hwfn, image_id, &image_att); + if (rc) + return rc; + + *length = image_att.length; + + return rc; +} + +static int qed_dbg_nvm_image(struct qed_dev *cdev, void *buffer, + u32 *num_dumped_bytes, + enum qed_nvm_images image_id) +{ + struct qed_hwfn *p_hwfn = + &cdev->hwfns[cdev->engine_for_debug]; + u32 len_rounded; + int rc; + + *num_dumped_bytes = 0; + rc = qed_dbg_nvm_image_length(p_hwfn, image_id, &len_rounded); + if (rc) + return rc; + + DP_NOTICE(p_hwfn->cdev, + "Collecting a debug feature [\"nvram image %d\"]\n", + image_id); + + len_rounded = roundup(len_rounded, sizeof(u32)); + rc = qed_mcp_get_nvm_image(p_hwfn, image_id, buffer, len_rounded); + if (rc) + return rc; + + /* QED_NVM_IMAGE_NVM_META image is not swapped like other images */ + if (image_id != QED_NVM_IMAGE_NVM_META) + cpu_to_be32_array((__force __be32 *)buffer, + (const u32 *)buffer, + len_rounded / sizeof(u32)); + + *num_dumped_bytes = len_rounded; + + return rc; +} + int qed_dbg_protection_override(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes) { @@ -7708,6 +8183,16 @@ int qed_dbg_fw_asserts_size(struct qed_dev *cdev) return qed_dbg_feature_size(cdev, DBG_FEATURE_FW_ASSERTS); } +int qed_dbg_ilt(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes) +{ + return qed_dbg_feature(cdev, buffer, DBG_FEATURE_ILT, num_dumped_bytes); +} + +int qed_dbg_ilt_size(struct qed_dev *cdev) +{ + return qed_dbg_feature_size(cdev, DBG_FEATURE_ILT); +} + int qed_dbg_mcp_trace(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes) { @@ -7724,9 +8209,19 @@ int qed_dbg_mcp_trace_size(struct qed_dev *cdev) * feature buffer. */ #define REGDUMP_HEADER_SIZE sizeof(u32) +#define REGDUMP_HEADER_SIZE_SHIFT 0 +#define REGDUMP_HEADER_SIZE_MASK 0xffffff #define REGDUMP_HEADER_FEATURE_SHIFT 24 -#define REGDUMP_HEADER_ENGINE_SHIFT 31 +#define REGDUMP_HEADER_FEATURE_MASK 0x1f +#define REGDUMP_HEADER_BIN_DUMP_SHIFT 29 +#define REGDUMP_HEADER_BIN_DUMP_MASK 0x1 #define REGDUMP_HEADER_OMIT_ENGINE_SHIFT 30 +#define REGDUMP_HEADER_OMIT_ENGINE_MASK 0x1 +#define REGDUMP_HEADER_ENGINE_SHIFT 31 +#define REGDUMP_HEADER_ENGINE_MASK 0x1 +#define REGDUMP_MAX_SIZE 0x1000000 +#define ILT_DUMP_MAX_SIZE (1024 * 1024 * 15) + enum debug_print_features { OLD_MODE = 0, IDLE_CHK = 1, @@ -7737,28 +8232,51 @@ enum debug_print_features { IGU_FIFO = 6, PHY = 7, FW_ASSERTS = 8, + NVM_CFG1 = 9, + DEFAULT_CFG = 10, + NVM_META = 11, + MDUMP = 12, + ILT_DUMP = 13, }; -static u32 qed_calc_regdump_header(enum debug_print_features feature, - int engine, u32 feature_size, u8 omit_engine) +static u32 qed_calc_regdump_header(struct qed_dev *cdev, + enum debug_print_features feature, + int engine, u32 feature_size, + u8 omit_engine, u8 dbg_bin_dump) { - /* Insert the engine, feature and mode inside the header and combine it - * with feature size. - */ - return feature_size | (feature << REGDUMP_HEADER_FEATURE_SHIFT) | - (omit_engine << REGDUMP_HEADER_OMIT_ENGINE_SHIFT) | - (engine << REGDUMP_HEADER_ENGINE_SHIFT); + u32 res = 0; + + SET_FIELD(res, REGDUMP_HEADER_SIZE, feature_size); + if (res != feature_size) + DP_NOTICE(cdev, + "Feature %d is too large (size 0x%x) and will corrupt the dump\n", + feature, feature_size); + + SET_FIELD(res, REGDUMP_HEADER_FEATURE, feature); + SET_FIELD(res, REGDUMP_HEADER_BIN_DUMP, dbg_bin_dump); + SET_FIELD(res, REGDUMP_HEADER_OMIT_ENGINE, omit_engine); + SET_FIELD(res, REGDUMP_HEADER_ENGINE, engine); + + return res; } int qed_dbg_all_data(struct qed_dev *cdev, void *buffer) { u8 cur_engine, omit_engine = 0, org_engine; + struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug]; + struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; + int grc_params[MAX_DBG_GRC_PARAMS], rc, i; u32 offset = 0, feature_size; - int rc; - if (cdev->num_hwfns == 1) + for (i = 0; i < MAX_DBG_GRC_PARAMS; i++) + grc_params[i] = dev_data->grc.param_val[i]; + + if (!QED_IS_CMT(cdev)) omit_engine = 1; + cdev->dbg_bin_dump = 1; + mutex_lock(&qed_dbg_lock); + org_engine = qed_get_debug_engine(cdev); for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) { /* Collect idle_chks and grcDump for each hw function */ @@ -7771,8 +8289,11 @@ int qed_dbg_all_data(struct qed_dev *cdev, void *buffer) REGDUMP_HEADER_SIZE, &feature_size); if (!rc) { *(u32 *)((u8 *)buffer + offset) = - qed_calc_regdump_header(IDLE_CHK, cur_engine, - feature_size, omit_engine); + qed_calc_regdump_header(cdev, IDLE_CHK, + cur_engine, + feature_size, + omit_engine, + cdev->dbg_bin_dump); offset += (feature_size + REGDUMP_HEADER_SIZE); } else { DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc); @@ -7783,8 +8304,11 @@ int qed_dbg_all_data(struct qed_dev *cdev, void *buffer) REGDUMP_HEADER_SIZE, &feature_size); if (!rc) { *(u32 *)((u8 *)buffer + offset) = - qed_calc_regdump_header(IDLE_CHK, cur_engine, - feature_size, omit_engine); + qed_calc_regdump_header(cdev, IDLE_CHK, + cur_engine, + feature_size, + omit_engine, + cdev->dbg_bin_dump); offset += (feature_size + REGDUMP_HEADER_SIZE); } else { DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc); @@ -7795,8 +8319,11 @@ int qed_dbg_all_data(struct qed_dev *cdev, void *buffer) REGDUMP_HEADER_SIZE, &feature_size); if (!rc) { *(u32 *)((u8 *)buffer + offset) = - qed_calc_regdump_header(REG_FIFO, cur_engine, - feature_size, omit_engine); + qed_calc_regdump_header(cdev, REG_FIFO, + cur_engine, + feature_size, + omit_engine, + cdev->dbg_bin_dump); offset += (feature_size + REGDUMP_HEADER_SIZE); } else { DP_ERR(cdev, "qed_dbg_reg_fifo failed. rc = %d\n", rc); @@ -7807,8 +8334,11 @@ int qed_dbg_all_data(struct qed_dev *cdev, void *buffer) REGDUMP_HEADER_SIZE, &feature_size); if (!rc) { *(u32 *)((u8 *)buffer + offset) = - qed_calc_regdump_header(IGU_FIFO, cur_engine, - feature_size, omit_engine); + qed_calc_regdump_header(cdev, IGU_FIFO, + cur_engine, + feature_size, + omit_engine, + cdev->dbg_bin_dump); offset += (feature_size + REGDUMP_HEADER_SIZE); } else { DP_ERR(cdev, "qed_dbg_igu_fifo failed. rc = %d", rc); @@ -7820,9 +8350,12 @@ int qed_dbg_all_data(struct qed_dev *cdev, void *buffer) &feature_size); if (!rc) { *(u32 *)((u8 *)buffer + offset) = - qed_calc_regdump_header(PROTECTION_OVERRIDE, + qed_calc_regdump_header(cdev, + PROTECTION_OVERRIDE, cur_engine, - feature_size, omit_engine); + feature_size, + omit_engine, + cdev->dbg_bin_dump); offset += (feature_size + REGDUMP_HEADER_SIZE); } else { DP_ERR(cdev, @@ -7835,51 +8368,156 @@ int qed_dbg_all_data(struct qed_dev *cdev, void *buffer) REGDUMP_HEADER_SIZE, &feature_size); if (!rc) { *(u32 *)((u8 *)buffer + offset) = - qed_calc_regdump_header(FW_ASSERTS, cur_engine, - feature_size, omit_engine); + qed_calc_regdump_header(cdev, FW_ASSERTS, + cur_engine, + feature_size, + omit_engine, + cdev->dbg_bin_dump); offset += (feature_size + REGDUMP_HEADER_SIZE); } else { DP_ERR(cdev, "qed_dbg_fw_asserts failed. rc = %d\n", rc); } - /* GRC dump - must be last because when mcp stuck it will + feature_size = qed_dbg_ilt_size(cdev); + if (!cdev->disable_ilt_dump && feature_size < + ILT_DUMP_MAX_SIZE) { + rc = qed_dbg_ilt(cdev, (u8 *)buffer + offset + + REGDUMP_HEADER_SIZE, &feature_size); + if (!rc) { + *(u32 *)((u8 *)buffer + offset) = + qed_calc_regdump_header(cdev, ILT_DUMP, + cur_engine, + feature_size, + omit_engine, + cdev->dbg_bin_dump); + offset += (feature_size + REGDUMP_HEADER_SIZE); + } else { + DP_ERR(cdev, "qed_dbg_ilt failed. rc = %d\n", + rc); + } + } + + /* Grc dump - must be last because when mcp stuck it will * clutter idle_chk, reg_fifo, ... */ + for (i = 0; i < MAX_DBG_GRC_PARAMS; i++) + dev_data->grc.param_val[i] = grc_params[i]; + rc = qed_dbg_grc(cdev, (u8 *)buffer + offset + REGDUMP_HEADER_SIZE, &feature_size); if (!rc) { *(u32 *)((u8 *)buffer + offset) = - qed_calc_regdump_header(GRC_DUMP, cur_engine, - feature_size, omit_engine); + qed_calc_regdump_header(cdev, GRC_DUMP, + cur_engine, + feature_size, + omit_engine, + cdev->dbg_bin_dump); offset += (feature_size + REGDUMP_HEADER_SIZE); } else { DP_ERR(cdev, "qed_dbg_grc failed. rc = %d", rc); } } + qed_set_debug_engine(cdev, org_engine); + /* mcp_trace */ rc = qed_dbg_mcp_trace(cdev, (u8 *)buffer + offset + REGDUMP_HEADER_SIZE, &feature_size); if (!rc) { *(u32 *)((u8 *)buffer + offset) = - qed_calc_regdump_header(MCP_TRACE, cur_engine, - feature_size, omit_engine); + qed_calc_regdump_header(cdev, MCP_TRACE, cur_engine, + feature_size, omit_engine, + cdev->dbg_bin_dump); offset += (feature_size + REGDUMP_HEADER_SIZE); } else { DP_ERR(cdev, "qed_dbg_mcp_trace failed. rc = %d\n", rc); } - qed_set_debug_engine(cdev, org_engine); + /* nvm cfg1 */ + rc = qed_dbg_nvm_image(cdev, + (u8 *)buffer + offset + + REGDUMP_HEADER_SIZE, &feature_size, + QED_NVM_IMAGE_NVM_CFG1); + if (!rc) { + *(u32 *)((u8 *)buffer + offset) = + qed_calc_regdump_header(cdev, NVM_CFG1, cur_engine, + feature_size, omit_engine, + cdev->dbg_bin_dump); + offset += (feature_size + REGDUMP_HEADER_SIZE); + } else if (rc != -ENOENT) { + DP_ERR(cdev, + "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n", + QED_NVM_IMAGE_NVM_CFG1, "QED_NVM_IMAGE_NVM_CFG1", + rc); + } + + /* nvm default */ + rc = qed_dbg_nvm_image(cdev, + (u8 *)buffer + offset + + REGDUMP_HEADER_SIZE, &feature_size, + QED_NVM_IMAGE_DEFAULT_CFG); + if (!rc) { + *(u32 *)((u8 *)buffer + offset) = + qed_calc_regdump_header(cdev, DEFAULT_CFG, + cur_engine, feature_size, + omit_engine, + cdev->dbg_bin_dump); + offset += (feature_size + REGDUMP_HEADER_SIZE); + } else if (rc != -ENOENT) { + DP_ERR(cdev, + "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n", + QED_NVM_IMAGE_DEFAULT_CFG, + "QED_NVM_IMAGE_DEFAULT_CFG", rc); + } + + /* nvm meta */ + rc = qed_dbg_nvm_image(cdev, + (u8 *)buffer + offset + + REGDUMP_HEADER_SIZE, &feature_size, + QED_NVM_IMAGE_NVM_META); + if (!rc) { + *(u32 *)((u8 *)buffer + offset) = + qed_calc_regdump_header(cdev, NVM_META, cur_engine, + feature_size, omit_engine, + cdev->dbg_bin_dump); + offset += (feature_size + REGDUMP_HEADER_SIZE); + } else if (rc != -ENOENT) { + DP_ERR(cdev, + "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n", + QED_NVM_IMAGE_NVM_META, "QED_NVM_IMAGE_NVM_META", + rc); + } + + /* nvm mdump */ + rc = qed_dbg_nvm_image(cdev, (u8 *)buffer + offset + + REGDUMP_HEADER_SIZE, &feature_size, + QED_NVM_IMAGE_MDUMP); + if (!rc) { + *(u32 *)((u8 *)buffer + offset) = + qed_calc_regdump_header(cdev, MDUMP, cur_engine, + feature_size, omit_engine, + cdev->dbg_bin_dump); + offset += (feature_size + REGDUMP_HEADER_SIZE); + } else if (rc != -ENOENT) { + DP_ERR(cdev, + "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n", + QED_NVM_IMAGE_MDUMP, "QED_NVM_IMAGE_MDUMP", rc); + } + + mutex_unlock(&qed_dbg_lock); + cdev->dbg_bin_dump = 0; return 0; } int qed_dbg_all_data_size(struct qed_dev *cdev) { + u32 regs_len = 0, image_len = 0, ilt_len = 0, total_ilt_len = 0; + struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug]; u8 cur_engine, org_engine; - u32 regs_len = 0; + cdev->disable_ilt_dump = false; org_engine = qed_get_debug_engine(cdev); for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) { /* Engine specific */ @@ -7887,29 +8525,54 @@ int qed_dbg_all_data_size(struct qed_dev *cdev) "calculating idle_chk and grcdump register length for current engine\n"); qed_set_debug_engine(cdev, cur_engine); regs_len += REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) + - REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) + - REGDUMP_HEADER_SIZE + qed_dbg_grc_size(cdev) + - REGDUMP_HEADER_SIZE + qed_dbg_reg_fifo_size(cdev) + - REGDUMP_HEADER_SIZE + qed_dbg_igu_fifo_size(cdev) + - REGDUMP_HEADER_SIZE + - qed_dbg_protection_override_size(cdev) + - REGDUMP_HEADER_SIZE + qed_dbg_fw_asserts_size(cdev); + REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) + + REGDUMP_HEADER_SIZE + qed_dbg_grc_size(cdev) + + REGDUMP_HEADER_SIZE + qed_dbg_reg_fifo_size(cdev) + + REGDUMP_HEADER_SIZE + qed_dbg_igu_fifo_size(cdev) + + REGDUMP_HEADER_SIZE + + qed_dbg_protection_override_size(cdev) + + REGDUMP_HEADER_SIZE + qed_dbg_fw_asserts_size(cdev); + ilt_len = REGDUMP_HEADER_SIZE + qed_dbg_ilt_size(cdev); + if (ilt_len < ILT_DUMP_MAX_SIZE) { + total_ilt_len += ilt_len; + regs_len += ilt_len; + } } - /* Engine common */ - regs_len += REGDUMP_HEADER_SIZE + qed_dbg_mcp_trace_size(cdev); qed_set_debug_engine(cdev, org_engine); + /* Engine common */ + regs_len += REGDUMP_HEADER_SIZE + qed_dbg_mcp_trace_size(cdev) + + REGDUMP_HEADER_SIZE + qed_dbg_phy_size(cdev); + qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_CFG1, &image_len); + if (image_len) + regs_len += REGDUMP_HEADER_SIZE + image_len; + qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_DEFAULT_CFG, &image_len); + if (image_len) + regs_len += REGDUMP_HEADER_SIZE + image_len; + qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_META, &image_len); + if (image_len) + regs_len += REGDUMP_HEADER_SIZE + image_len; + qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_MDUMP, &image_len); + if (image_len) + regs_len += REGDUMP_HEADER_SIZE + image_len; + + if (regs_len > REGDUMP_MAX_SIZE) { + DP_VERBOSE(cdev, QED_MSG_DEBUG, + "Dump exceeds max size 0x%x, disable ILT dump\n", + REGDUMP_MAX_SIZE); + cdev->disable_ilt_dump = true; + regs_len -= total_ilt_len; + } + return regs_len; } int qed_dbg_feature(struct qed_dev *cdev, void *buffer, enum qed_dbg_features feature, u32 *num_dumped_bytes) { - struct qed_hwfn *p_hwfn = - &cdev->hwfns[cdev->dbg_params.engine_for_debug]; - struct qed_dbg_feature *qed_feature = - &cdev->dbg_params.features[feature]; + struct qed_dbg_feature *qed_feature = &cdev->dbg_features[feature]; + struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug]; enum dbg_status dbg_rc; struct qed_ptt *p_ptt; int rc = 0; @@ -7932,7 +8595,7 @@ int qed_dbg_feature(struct qed_dev *cdev, void *buffer, DP_VERBOSE(cdev, QED_MSG_DEBUG, "copying debugfs feature to external buffer\n"); memcpy(buffer, qed_feature->dump_buf, qed_feature->buf_size); - *num_dumped_bytes = cdev->dbg_params.features[feature].dumped_dwords * + *num_dumped_bytes = cdev->dbg_features[feature].dumped_dwords * 4; out: @@ -7942,11 +8605,9 @@ out: int qed_dbg_feature_size(struct qed_dev *cdev, enum qed_dbg_features feature) { - struct qed_hwfn *p_hwfn = - &cdev->hwfns[cdev->dbg_params.engine_for_debug]; + struct qed_dbg_feature *qed_feature = &cdev->dbg_features[feature]; + struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug]; struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn); - struct qed_dbg_feature *qed_feature = - &cdev->dbg_params.features[feature]; u32 buf_size_dwords; enum dbg_status rc; @@ -7958,33 +8619,55 @@ int qed_dbg_feature_size(struct qed_dev *cdev, enum qed_dbg_features feature) if (rc != DBG_STATUS_OK) buf_size_dwords = 0; + /* Feature will not be dumped if it exceeds maximum size */ + if (buf_size_dwords > MAX_DBG_FEATURE_SIZE_DWORDS) + buf_size_dwords = 0; + qed_ptt_release(p_hwfn, p_ptt); qed_feature->buf_size = buf_size_dwords * sizeof(u32); return qed_feature->buf_size; } +int qed_dbg_phy_size(struct qed_dev *cdev) +{ + /* return max size of phy info and + * phy mac_stat multiplied by the number of ports + */ + return MAX_PHY_RESULT_BUFFER * (1 + qed_device_num_ports(cdev)); +} + u8 qed_get_debug_engine(struct qed_dev *cdev) { - return cdev->dbg_params.engine_for_debug; + return cdev->engine_for_debug; } void qed_set_debug_engine(struct qed_dev *cdev, int engine_number) { DP_VERBOSE(cdev, QED_MSG_DEBUG, "set debug engine to %d\n", engine_number); - cdev->dbg_params.engine_for_debug = engine_number; + cdev->engine_for_debug = engine_number; } void qed_dbg_pf_init(struct qed_dev *cdev) { - const u8 *dbg_values; + const u8 *dbg_values = NULL; + int i; + + /* Sync ver with debugbus qed code */ + qed_dbg_set_app_ver(TOOLS_VERSION); /* Debug values are after init values. * The offset is the first dword of the file. */ dbg_values = cdev->firmware->data + *(u32 *)cdev->firmware->data; - qed_dbg_set_bin_ptr((u8 *)dbg_values); - qed_dbg_user_set_bin_ptr((u8 *)dbg_values); + + for_each_hwfn(cdev, i) { + qed_dbg_set_bin_ptr(&cdev->hwfns[i], dbg_values); + qed_dbg_user_set_bin_ptr(&cdev->hwfns[i], dbg_values); + } + + /* Set the hwfn to be 0 as default */ + cdev->engine_for_debug = 0; } void qed_dbg_pf_exit(struct qed_dev *cdev) @@ -7992,11 +8675,11 @@ void qed_dbg_pf_exit(struct qed_dev *cdev) struct qed_dbg_feature *feature = NULL; enum qed_dbg_features feature_idx; - /* Debug features' buffers may be allocated if debug feature was used - * but dump wasn't called. + /* debug features' buffers may be allocated if debug feature was used + * but dump wasn't called */ for (feature_idx = 0; feature_idx < DBG_FEATURE_NUM; feature_idx++) { - feature = &cdev->dbg_params.features[feature_idx]; + feature = &cdev->dbg_features[feature_idx]; if (feature->dump_buf) { vfree(feature->dump_buf); feature->dump_buf = NULL; |
