18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 28c2ecf20Sopenharmony_ci/* QLogic qed NIC Driver 38c2ecf20Sopenharmony_ci * Copyright (c) 2015 QLogic Corporation 48c2ecf20Sopenharmony_ci * Copyright (c) 2019-2020 Marvell International Ltd. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/module.h> 88c2ecf20Sopenharmony_ci#include <linux/vmalloc.h> 98c2ecf20Sopenharmony_ci#include <linux/crc32.h> 108c2ecf20Sopenharmony_ci#include "qed.h" 118c2ecf20Sopenharmony_ci#include "qed_cxt.h" 128c2ecf20Sopenharmony_ci#include "qed_hsi.h" 138c2ecf20Sopenharmony_ci#include "qed_hw.h" 148c2ecf20Sopenharmony_ci#include "qed_mcp.h" 158c2ecf20Sopenharmony_ci#include "qed_reg_addr.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* Memory groups enum */ 188c2ecf20Sopenharmony_cienum mem_groups { 198c2ecf20Sopenharmony_ci MEM_GROUP_PXP_MEM, 208c2ecf20Sopenharmony_ci MEM_GROUP_DMAE_MEM, 218c2ecf20Sopenharmony_ci MEM_GROUP_CM_MEM, 228c2ecf20Sopenharmony_ci MEM_GROUP_QM_MEM, 238c2ecf20Sopenharmony_ci MEM_GROUP_DORQ_MEM, 248c2ecf20Sopenharmony_ci MEM_GROUP_BRB_RAM, 258c2ecf20Sopenharmony_ci MEM_GROUP_BRB_MEM, 268c2ecf20Sopenharmony_ci MEM_GROUP_PRS_MEM, 278c2ecf20Sopenharmony_ci MEM_GROUP_SDM_MEM, 288c2ecf20Sopenharmony_ci MEM_GROUP_PBUF, 298c2ecf20Sopenharmony_ci MEM_GROUP_IOR, 308c2ecf20Sopenharmony_ci MEM_GROUP_RAM, 318c2ecf20Sopenharmony_ci MEM_GROUP_BTB_RAM, 328c2ecf20Sopenharmony_ci MEM_GROUP_RDIF_CTX, 338c2ecf20Sopenharmony_ci MEM_GROUP_TDIF_CTX, 348c2ecf20Sopenharmony_ci MEM_GROUP_CFC_MEM, 358c2ecf20Sopenharmony_ci MEM_GROUP_CONN_CFC_MEM, 368c2ecf20Sopenharmony_ci MEM_GROUP_CAU_PI, 378c2ecf20Sopenharmony_ci MEM_GROUP_CAU_MEM, 388c2ecf20Sopenharmony_ci MEM_GROUP_CAU_MEM_EXT, 398c2ecf20Sopenharmony_ci MEM_GROUP_PXP_ILT, 408c2ecf20Sopenharmony_ci MEM_GROUP_MULD_MEM, 418c2ecf20Sopenharmony_ci MEM_GROUP_BTB_MEM, 428c2ecf20Sopenharmony_ci MEM_GROUP_IGU_MEM, 438c2ecf20Sopenharmony_ci MEM_GROUP_IGU_MSIX, 448c2ecf20Sopenharmony_ci MEM_GROUP_CAU_SB, 458c2ecf20Sopenharmony_ci MEM_GROUP_BMB_RAM, 468c2ecf20Sopenharmony_ci MEM_GROUP_BMB_MEM, 478c2ecf20Sopenharmony_ci MEM_GROUP_TM_MEM, 488c2ecf20Sopenharmony_ci MEM_GROUP_TASK_CFC_MEM, 498c2ecf20Sopenharmony_ci MEM_GROUPS_NUM 508c2ecf20Sopenharmony_ci}; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci/* Memory groups names */ 538c2ecf20Sopenharmony_cistatic const char * const s_mem_group_names[] = { 548c2ecf20Sopenharmony_ci "PXP_MEM", 558c2ecf20Sopenharmony_ci "DMAE_MEM", 568c2ecf20Sopenharmony_ci "CM_MEM", 578c2ecf20Sopenharmony_ci "QM_MEM", 588c2ecf20Sopenharmony_ci "DORQ_MEM", 598c2ecf20Sopenharmony_ci "BRB_RAM", 608c2ecf20Sopenharmony_ci "BRB_MEM", 618c2ecf20Sopenharmony_ci "PRS_MEM", 628c2ecf20Sopenharmony_ci "SDM_MEM", 638c2ecf20Sopenharmony_ci "PBUF", 648c2ecf20Sopenharmony_ci "IOR", 658c2ecf20Sopenharmony_ci "RAM", 668c2ecf20Sopenharmony_ci "BTB_RAM", 678c2ecf20Sopenharmony_ci "RDIF_CTX", 688c2ecf20Sopenharmony_ci "TDIF_CTX", 698c2ecf20Sopenharmony_ci "CFC_MEM", 708c2ecf20Sopenharmony_ci "CONN_CFC_MEM", 718c2ecf20Sopenharmony_ci "CAU_PI", 728c2ecf20Sopenharmony_ci "CAU_MEM", 738c2ecf20Sopenharmony_ci "CAU_MEM_EXT", 748c2ecf20Sopenharmony_ci "PXP_ILT", 758c2ecf20Sopenharmony_ci "MULD_MEM", 768c2ecf20Sopenharmony_ci "BTB_MEM", 778c2ecf20Sopenharmony_ci "IGU_MEM", 788c2ecf20Sopenharmony_ci "IGU_MSIX", 798c2ecf20Sopenharmony_ci "CAU_SB", 808c2ecf20Sopenharmony_ci "BMB_RAM", 818c2ecf20Sopenharmony_ci "BMB_MEM", 828c2ecf20Sopenharmony_ci "TM_MEM", 838c2ecf20Sopenharmony_ci "TASK_CFC_MEM", 848c2ecf20Sopenharmony_ci}; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci/* Idle check conditions */ 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic u32 cond5(const u32 *r, const u32 *imm) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci return ((r[0] & imm[0]) != imm[1]) && ((r[1] & imm[2]) != imm[3]); 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic u32 cond7(const u32 *r, const u32 *imm) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci return ((r[0] >> imm[0]) & imm[1]) != imm[2]; 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic u32 cond6(const u32 *r, const u32 *imm) 998c2ecf20Sopenharmony_ci{ 1008c2ecf20Sopenharmony_ci return (r[0] & imm[0]) != imm[1]; 1018c2ecf20Sopenharmony_ci} 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistatic u32 cond9(const u32 *r, const u32 *imm) 1048c2ecf20Sopenharmony_ci{ 1058c2ecf20Sopenharmony_ci return ((r[0] & imm[0]) >> imm[1]) != 1068c2ecf20Sopenharmony_ci (((r[0] & imm[2]) >> imm[3]) | ((r[1] & imm[4]) << imm[5])); 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic u32 cond10(const u32 *r, const u32 *imm) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci return ((r[0] & imm[0]) >> imm[1]) != (r[0] & imm[2]); 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistatic u32 cond4(const u32 *r, const u32 *imm) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci return (r[0] & ~imm[0]) != imm[1]; 1178c2ecf20Sopenharmony_ci} 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cistatic u32 cond0(const u32 *r, const u32 *imm) 1208c2ecf20Sopenharmony_ci{ 1218c2ecf20Sopenharmony_ci return (r[0] & ~r[1]) != imm[0]; 1228c2ecf20Sopenharmony_ci} 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistatic u32 cond1(const u32 *r, const u32 *imm) 1258c2ecf20Sopenharmony_ci{ 1268c2ecf20Sopenharmony_ci return r[0] != imm[0]; 1278c2ecf20Sopenharmony_ci} 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_cistatic u32 cond11(const u32 *r, const u32 *imm) 1308c2ecf20Sopenharmony_ci{ 1318c2ecf20Sopenharmony_ci return r[0] != r[1] && r[2] == imm[0]; 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic u32 cond12(const u32 *r, const u32 *imm) 1358c2ecf20Sopenharmony_ci{ 1368c2ecf20Sopenharmony_ci return r[0] != r[1] && r[2] > imm[0]; 1378c2ecf20Sopenharmony_ci} 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cistatic u32 cond3(const u32 *r, const u32 *imm) 1408c2ecf20Sopenharmony_ci{ 1418c2ecf20Sopenharmony_ci return r[0] != r[1]; 1428c2ecf20Sopenharmony_ci} 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_cistatic u32 cond13(const u32 *r, const u32 *imm) 1458c2ecf20Sopenharmony_ci{ 1468c2ecf20Sopenharmony_ci return r[0] & imm[0]; 1478c2ecf20Sopenharmony_ci} 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_cistatic u32 cond8(const u32 *r, const u32 *imm) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci return r[0] < (r[1] - imm[0]); 1528c2ecf20Sopenharmony_ci} 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic u32 cond2(const u32 *r, const u32 *imm) 1558c2ecf20Sopenharmony_ci{ 1568c2ecf20Sopenharmony_ci return r[0] > imm[0]; 1578c2ecf20Sopenharmony_ci} 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci/* Array of Idle Check conditions */ 1608c2ecf20Sopenharmony_cistatic u32(*cond_arr[]) (const u32 *r, const u32 *imm) = { 1618c2ecf20Sopenharmony_ci cond0, 1628c2ecf20Sopenharmony_ci cond1, 1638c2ecf20Sopenharmony_ci cond2, 1648c2ecf20Sopenharmony_ci cond3, 1658c2ecf20Sopenharmony_ci cond4, 1668c2ecf20Sopenharmony_ci cond5, 1678c2ecf20Sopenharmony_ci cond6, 1688c2ecf20Sopenharmony_ci cond7, 1698c2ecf20Sopenharmony_ci cond8, 1708c2ecf20Sopenharmony_ci cond9, 1718c2ecf20Sopenharmony_ci cond10, 1728c2ecf20Sopenharmony_ci cond11, 1738c2ecf20Sopenharmony_ci cond12, 1748c2ecf20Sopenharmony_ci cond13, 1758c2ecf20Sopenharmony_ci}; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci#define NUM_PHYS_BLOCKS 84 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci#define NUM_DBG_RESET_REGS 8 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci/******************************* Data Types **********************************/ 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cienum hw_types { 1848c2ecf20Sopenharmony_ci HW_TYPE_ASIC, 1858c2ecf20Sopenharmony_ci PLATFORM_RESERVED, 1868c2ecf20Sopenharmony_ci PLATFORM_RESERVED2, 1878c2ecf20Sopenharmony_ci PLATFORM_RESERVED3, 1888c2ecf20Sopenharmony_ci PLATFORM_RESERVED4, 1898c2ecf20Sopenharmony_ci MAX_HW_TYPES 1908c2ecf20Sopenharmony_ci}; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci/* CM context types */ 1938c2ecf20Sopenharmony_cienum cm_ctx_types { 1948c2ecf20Sopenharmony_ci CM_CTX_CONN_AG, 1958c2ecf20Sopenharmony_ci CM_CTX_CONN_ST, 1968c2ecf20Sopenharmony_ci CM_CTX_TASK_AG, 1978c2ecf20Sopenharmony_ci CM_CTX_TASK_ST, 1988c2ecf20Sopenharmony_ci NUM_CM_CTX_TYPES 1998c2ecf20Sopenharmony_ci}; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci/* Debug bus frame modes */ 2028c2ecf20Sopenharmony_cienum dbg_bus_frame_modes { 2038c2ecf20Sopenharmony_ci DBG_BUS_FRAME_MODE_4ST = 0, /* 4 Storm dwords (no HW) */ 2048c2ecf20Sopenharmony_ci DBG_BUS_FRAME_MODE_2ST_2HW = 1, /* 2 Storm dwords, 2 HW dwords */ 2058c2ecf20Sopenharmony_ci DBG_BUS_FRAME_MODE_1ST_3HW = 2, /* 1 Storm dwords, 3 HW dwords */ 2068c2ecf20Sopenharmony_ci DBG_BUS_FRAME_MODE_4HW = 3, /* 4 HW dwords (no Storms) */ 2078c2ecf20Sopenharmony_ci DBG_BUS_FRAME_MODE_8HW = 4, /* 8 HW dwords (no Storms) */ 2088c2ecf20Sopenharmony_ci DBG_BUS_NUM_FRAME_MODES 2098c2ecf20Sopenharmony_ci}; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci/* Chip constant definitions */ 2128c2ecf20Sopenharmony_cistruct chip_defs { 2138c2ecf20Sopenharmony_ci const char *name; 2148c2ecf20Sopenharmony_ci u32 num_ilt_pages; 2158c2ecf20Sopenharmony_ci}; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci/* HW type constant definitions */ 2188c2ecf20Sopenharmony_cistruct hw_type_defs { 2198c2ecf20Sopenharmony_ci const char *name; 2208c2ecf20Sopenharmony_ci u32 delay_factor; 2218c2ecf20Sopenharmony_ci u32 dmae_thresh; 2228c2ecf20Sopenharmony_ci u32 log_thresh; 2238c2ecf20Sopenharmony_ci}; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci/* RBC reset definitions */ 2268c2ecf20Sopenharmony_cistruct rbc_reset_defs { 2278c2ecf20Sopenharmony_ci u32 reset_reg_addr; 2288c2ecf20Sopenharmony_ci u32 reset_val[MAX_CHIP_IDS]; 2298c2ecf20Sopenharmony_ci}; 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci/* Storm constant definitions. 2328c2ecf20Sopenharmony_ci * Addresses are in bytes, sizes are in quad-regs. 2338c2ecf20Sopenharmony_ci */ 2348c2ecf20Sopenharmony_cistruct storm_defs { 2358c2ecf20Sopenharmony_ci char letter; 2368c2ecf20Sopenharmony_ci enum block_id sem_block_id; 2378c2ecf20Sopenharmony_ci enum dbg_bus_clients dbg_client_id[MAX_CHIP_IDS]; 2388c2ecf20Sopenharmony_ci bool has_vfc; 2398c2ecf20Sopenharmony_ci u32 sem_fast_mem_addr; 2408c2ecf20Sopenharmony_ci u32 sem_frame_mode_addr; 2418c2ecf20Sopenharmony_ci u32 sem_slow_enable_addr; 2428c2ecf20Sopenharmony_ci u32 sem_slow_mode_addr; 2438c2ecf20Sopenharmony_ci u32 sem_slow_mode1_conf_addr; 2448c2ecf20Sopenharmony_ci u32 sem_sync_dbg_empty_addr; 2458c2ecf20Sopenharmony_ci u32 sem_gpre_vect_addr; 2468c2ecf20Sopenharmony_ci u32 cm_ctx_wr_addr; 2478c2ecf20Sopenharmony_ci u32 cm_ctx_rd_addr[NUM_CM_CTX_TYPES]; 2488c2ecf20Sopenharmony_ci u32 cm_ctx_lid_sizes[MAX_CHIP_IDS][NUM_CM_CTX_TYPES]; 2498c2ecf20Sopenharmony_ci}; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci/* Debug Bus Constraint operation constant definitions */ 2528c2ecf20Sopenharmony_cistruct dbg_bus_constraint_op_defs { 2538c2ecf20Sopenharmony_ci u8 hw_op_val; 2548c2ecf20Sopenharmony_ci bool is_cyclic; 2558c2ecf20Sopenharmony_ci}; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci/* Storm Mode definitions */ 2588c2ecf20Sopenharmony_cistruct storm_mode_defs { 2598c2ecf20Sopenharmony_ci const char *name; 2608c2ecf20Sopenharmony_ci bool is_fast_dbg; 2618c2ecf20Sopenharmony_ci u8 id_in_hw; 2628c2ecf20Sopenharmony_ci u32 src_disable_reg_addr; 2638c2ecf20Sopenharmony_ci u32 src_enable_val; 2648c2ecf20Sopenharmony_ci bool exists[MAX_CHIP_IDS]; 2658c2ecf20Sopenharmony_ci}; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_cistruct grc_param_defs { 2688c2ecf20Sopenharmony_ci u32 default_val[MAX_CHIP_IDS]; 2698c2ecf20Sopenharmony_ci u32 min; 2708c2ecf20Sopenharmony_ci u32 max; 2718c2ecf20Sopenharmony_ci bool is_preset; 2728c2ecf20Sopenharmony_ci bool is_persistent; 2738c2ecf20Sopenharmony_ci u32 exclude_all_preset_val; 2748c2ecf20Sopenharmony_ci u32 crash_preset_val[MAX_CHIP_IDS]; 2758c2ecf20Sopenharmony_ci}; 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci/* Address is in 128b units. Width is in bits. */ 2788c2ecf20Sopenharmony_cistruct rss_mem_defs { 2798c2ecf20Sopenharmony_ci const char *mem_name; 2808c2ecf20Sopenharmony_ci const char *type_name; 2818c2ecf20Sopenharmony_ci u32 addr; 2828c2ecf20Sopenharmony_ci u32 entry_width; 2838c2ecf20Sopenharmony_ci u32 num_entries[MAX_CHIP_IDS]; 2848c2ecf20Sopenharmony_ci}; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_cistruct vfc_ram_defs { 2878c2ecf20Sopenharmony_ci const char *mem_name; 2888c2ecf20Sopenharmony_ci const char *type_name; 2898c2ecf20Sopenharmony_ci u32 base_row; 2908c2ecf20Sopenharmony_ci u32 num_rows; 2918c2ecf20Sopenharmony_ci}; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_cistruct big_ram_defs { 2948c2ecf20Sopenharmony_ci const char *instance_name; 2958c2ecf20Sopenharmony_ci enum mem_groups mem_group_id; 2968c2ecf20Sopenharmony_ci enum mem_groups ram_mem_group_id; 2978c2ecf20Sopenharmony_ci enum dbg_grc_params grc_param; 2988c2ecf20Sopenharmony_ci u32 addr_reg_addr; 2998c2ecf20Sopenharmony_ci u32 data_reg_addr; 3008c2ecf20Sopenharmony_ci u32 is_256b_reg_addr; 3018c2ecf20Sopenharmony_ci u32 is_256b_bit_offset[MAX_CHIP_IDS]; 3028c2ecf20Sopenharmony_ci u32 ram_size[MAX_CHIP_IDS]; /* In dwords */ 3038c2ecf20Sopenharmony_ci}; 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_cistruct phy_defs { 3068c2ecf20Sopenharmony_ci const char *phy_name; 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci /* PHY base GRC address */ 3098c2ecf20Sopenharmony_ci u32 base_addr; 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci /* Relative address of indirect TBUS address register (bits 0..7) */ 3128c2ecf20Sopenharmony_ci u32 tbus_addr_lo_addr; 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci /* Relative address of indirect TBUS address register (bits 8..10) */ 3158c2ecf20Sopenharmony_ci u32 tbus_addr_hi_addr; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci /* Relative address of indirect TBUS data register (bits 0..7) */ 3188c2ecf20Sopenharmony_ci u32 tbus_data_lo_addr; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci /* Relative address of indirect TBUS data register (bits 8..11) */ 3218c2ecf20Sopenharmony_ci u32 tbus_data_hi_addr; 3228c2ecf20Sopenharmony_ci}; 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci/* Split type definitions */ 3258c2ecf20Sopenharmony_cistruct split_type_defs { 3268c2ecf20Sopenharmony_ci const char *name; 3278c2ecf20Sopenharmony_ci}; 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci/******************************** Constants **********************************/ 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci#define BYTES_IN_DWORD sizeof(u32) 3328c2ecf20Sopenharmony_ci/* In the macros below, size and offset are specified in bits */ 3338c2ecf20Sopenharmony_ci#define CEIL_DWORDS(size) DIV_ROUND_UP(size, 32) 3348c2ecf20Sopenharmony_ci#define FIELD_BIT_OFFSET(type, field) type ## _ ## field ## _ ## OFFSET 3358c2ecf20Sopenharmony_ci#define FIELD_BIT_SIZE(type, field) type ## _ ## field ## _ ## SIZE 3368c2ecf20Sopenharmony_ci#define FIELD_DWORD_OFFSET(type, field) \ 3378c2ecf20Sopenharmony_ci (int)(FIELD_BIT_OFFSET(type, field) / 32) 3388c2ecf20Sopenharmony_ci#define FIELD_DWORD_SHIFT(type, field) (FIELD_BIT_OFFSET(type, field) % 32) 3398c2ecf20Sopenharmony_ci#define FIELD_BIT_MASK(type, field) \ 3408c2ecf20Sopenharmony_ci (((1 << FIELD_BIT_SIZE(type, field)) - 1) << \ 3418c2ecf20Sopenharmony_ci FIELD_DWORD_SHIFT(type, field)) 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci#define SET_VAR_FIELD(var, type, field, val) \ 3448c2ecf20Sopenharmony_ci do { \ 3458c2ecf20Sopenharmony_ci var[FIELD_DWORD_OFFSET(type, field)] &= \ 3468c2ecf20Sopenharmony_ci (~FIELD_BIT_MASK(type, field)); \ 3478c2ecf20Sopenharmony_ci var[FIELD_DWORD_OFFSET(type, field)] |= \ 3488c2ecf20Sopenharmony_ci (val) << FIELD_DWORD_SHIFT(type, field); \ 3498c2ecf20Sopenharmony_ci } while (0) 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci#define ARR_REG_WR(dev, ptt, addr, arr, arr_size) \ 3528c2ecf20Sopenharmony_ci do { \ 3538c2ecf20Sopenharmony_ci for (i = 0; i < (arr_size); i++) \ 3548c2ecf20Sopenharmony_ci qed_wr(dev, ptt, addr, (arr)[i]); \ 3558c2ecf20Sopenharmony_ci } while (0) 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci#define DWORDS_TO_BYTES(dwords) ((dwords) * BYTES_IN_DWORD) 3588c2ecf20Sopenharmony_ci#define BYTES_TO_DWORDS(bytes) ((bytes) / BYTES_IN_DWORD) 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci/* extra lines include a signature line + optional latency events line */ 3618c2ecf20Sopenharmony_ci#define NUM_EXTRA_DBG_LINES(block) \ 3628c2ecf20Sopenharmony_ci (GET_FIELD((block)->flags, DBG_BLOCK_CHIP_HAS_LATENCY_EVENTS) ? 2 : 1) 3638c2ecf20Sopenharmony_ci#define NUM_DBG_LINES(block) \ 3648c2ecf20Sopenharmony_ci ((block)->num_of_dbg_bus_lines + NUM_EXTRA_DBG_LINES(block)) 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci#define USE_DMAE true 3678c2ecf20Sopenharmony_ci#define PROTECT_WIDE_BUS true 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci#define RAM_LINES_TO_DWORDS(lines) ((lines) * 2) 3708c2ecf20Sopenharmony_ci#define RAM_LINES_TO_BYTES(lines) \ 3718c2ecf20Sopenharmony_ci DWORDS_TO_BYTES(RAM_LINES_TO_DWORDS(lines)) 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci#define REG_DUMP_LEN_SHIFT 24 3748c2ecf20Sopenharmony_ci#define MEM_DUMP_ENTRY_SIZE_DWORDS \ 3758c2ecf20Sopenharmony_ci BYTES_TO_DWORDS(sizeof(struct dbg_dump_mem)) 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci#define IDLE_CHK_RULE_SIZE_DWORDS \ 3788c2ecf20Sopenharmony_ci BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_rule)) 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci#define IDLE_CHK_RESULT_HDR_DWORDS \ 3818c2ecf20Sopenharmony_ci BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_hdr)) 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci#define IDLE_CHK_RESULT_REG_HDR_DWORDS \ 3848c2ecf20Sopenharmony_ci BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_reg_hdr)) 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci#define PAGE_MEM_DESC_SIZE_DWORDS \ 3878c2ecf20Sopenharmony_ci BYTES_TO_DWORDS(sizeof(struct phys_mem_desc)) 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci#define IDLE_CHK_MAX_ENTRIES_SIZE 32 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci/* The sizes and offsets below are specified in bits */ 3928c2ecf20Sopenharmony_ci#define VFC_CAM_CMD_STRUCT_SIZE 64 3938c2ecf20Sopenharmony_ci#define VFC_CAM_CMD_ROW_OFFSET 48 3948c2ecf20Sopenharmony_ci#define VFC_CAM_CMD_ROW_SIZE 9 3958c2ecf20Sopenharmony_ci#define VFC_CAM_ADDR_STRUCT_SIZE 16 3968c2ecf20Sopenharmony_ci#define VFC_CAM_ADDR_OP_OFFSET 0 3978c2ecf20Sopenharmony_ci#define VFC_CAM_ADDR_OP_SIZE 4 3988c2ecf20Sopenharmony_ci#define VFC_CAM_RESP_STRUCT_SIZE 256 3998c2ecf20Sopenharmony_ci#define VFC_RAM_ADDR_STRUCT_SIZE 16 4008c2ecf20Sopenharmony_ci#define VFC_RAM_ADDR_OP_OFFSET 0 4018c2ecf20Sopenharmony_ci#define VFC_RAM_ADDR_OP_SIZE 2 4028c2ecf20Sopenharmony_ci#define VFC_RAM_ADDR_ROW_OFFSET 2 4038c2ecf20Sopenharmony_ci#define VFC_RAM_ADDR_ROW_SIZE 10 4048c2ecf20Sopenharmony_ci#define VFC_RAM_RESP_STRUCT_SIZE 256 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci#define VFC_CAM_CMD_DWORDS CEIL_DWORDS(VFC_CAM_CMD_STRUCT_SIZE) 4078c2ecf20Sopenharmony_ci#define VFC_CAM_ADDR_DWORDS CEIL_DWORDS(VFC_CAM_ADDR_STRUCT_SIZE) 4088c2ecf20Sopenharmony_ci#define VFC_CAM_RESP_DWORDS CEIL_DWORDS(VFC_CAM_RESP_STRUCT_SIZE) 4098c2ecf20Sopenharmony_ci#define VFC_RAM_CMD_DWORDS VFC_CAM_CMD_DWORDS 4108c2ecf20Sopenharmony_ci#define VFC_RAM_ADDR_DWORDS CEIL_DWORDS(VFC_RAM_ADDR_STRUCT_SIZE) 4118c2ecf20Sopenharmony_ci#define VFC_RAM_RESP_DWORDS CEIL_DWORDS(VFC_RAM_RESP_STRUCT_SIZE) 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci#define NUM_VFC_RAM_TYPES 4 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci#define VFC_CAM_NUM_ROWS 512 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci#define VFC_OPCODE_CAM_RD 14 4188c2ecf20Sopenharmony_ci#define VFC_OPCODE_RAM_RD 0 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci#define NUM_RSS_MEM_TYPES 5 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci#define NUM_BIG_RAM_TYPES 3 4238c2ecf20Sopenharmony_ci#define BIG_RAM_NAME_LEN 3 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci#define NUM_PHY_TBUS_ADDRESSES 2048 4268c2ecf20Sopenharmony_ci#define PHY_DUMP_SIZE_DWORDS (NUM_PHY_TBUS_ADDRESSES / 2) 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci#define RESET_REG_UNRESET_OFFSET 4 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci#define STALL_DELAY_MS 500 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ci#define STATIC_DEBUG_LINE_DWORDS 9 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci#define NUM_COMMON_GLOBAL_PARAMS 9 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci#define MAX_RECURSION_DEPTH 10 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci#define FW_IMG_MAIN 1 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_DWORDS 2 4418c2ecf20Sopenharmony_ci#define REG_FIFO_DEPTH_ELEMENTS 32 4428c2ecf20Sopenharmony_ci#define REG_FIFO_DEPTH_DWORDS \ 4438c2ecf20Sopenharmony_ci (REG_FIFO_ELEMENT_DWORDS * REG_FIFO_DEPTH_ELEMENTS) 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORDS 4 4468c2ecf20Sopenharmony_ci#define IGU_FIFO_DEPTH_ELEMENTS 64 4478c2ecf20Sopenharmony_ci#define IGU_FIFO_DEPTH_DWORDS \ 4488c2ecf20Sopenharmony_ci (IGU_FIFO_ELEMENT_DWORDS * IGU_FIFO_DEPTH_ELEMENTS) 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_DWORDS 2 4518c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_DEPTH_ELEMENTS 20 4528c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_DEPTH_DWORDS \ 4538c2ecf20Sopenharmony_ci (PROTECTION_OVERRIDE_DEPTH_ELEMENTS * \ 4548c2ecf20Sopenharmony_ci PROTECTION_OVERRIDE_ELEMENT_DWORDS) 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci#define MCP_SPAD_TRACE_OFFSIZE_ADDR \ 4578c2ecf20Sopenharmony_ci (MCP_REG_SCRATCH + \ 4588c2ecf20Sopenharmony_ci offsetof(struct static_init, sections[SPAD_SECTION_TRACE])) 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci#define MAX_SW_PLTAFORM_STR_SIZE 64 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_ci#define EMPTY_FW_VERSION_STR "???_???_???_???" 4638c2ecf20Sopenharmony_ci#define EMPTY_FW_IMAGE_STR "???????????????" 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci/***************************** Constant Arrays *******************************/ 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci/* Chip constant definitions array */ 4688c2ecf20Sopenharmony_cistatic struct chip_defs s_chip_defs[MAX_CHIP_IDS] = { 4698c2ecf20Sopenharmony_ci {"bb", PSWRQ2_REG_ILT_MEMORY_SIZE_BB / 2}, 4708c2ecf20Sopenharmony_ci {"ah", PSWRQ2_REG_ILT_MEMORY_SIZE_K2 / 2} 4718c2ecf20Sopenharmony_ci}; 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci/* Storm constant definitions array */ 4748c2ecf20Sopenharmony_cistatic struct storm_defs s_storm_defs[] = { 4758c2ecf20Sopenharmony_ci /* Tstorm */ 4768c2ecf20Sopenharmony_ci {'T', BLOCK_TSEM, 4778c2ecf20Sopenharmony_ci {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT}, 4788c2ecf20Sopenharmony_ci true, 4798c2ecf20Sopenharmony_ci TSEM_REG_FAST_MEMORY, 4808c2ecf20Sopenharmony_ci TSEM_REG_DBG_FRAME_MODE_BB_K2, TSEM_REG_SLOW_DBG_ACTIVE_BB_K2, 4818c2ecf20Sopenharmony_ci TSEM_REG_SLOW_DBG_MODE_BB_K2, TSEM_REG_DBG_MODE1_CFG_BB_K2, 4828c2ecf20Sopenharmony_ci TSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_DBG_GPRE_VECT, 4838c2ecf20Sopenharmony_ci TCM_REG_CTX_RBC_ACCS, 4848c2ecf20Sopenharmony_ci {TCM_REG_AGG_CON_CTX, TCM_REG_SM_CON_CTX, TCM_REG_AGG_TASK_CTX, 4858c2ecf20Sopenharmony_ci TCM_REG_SM_TASK_CTX}, 4868c2ecf20Sopenharmony_ci {{4, 16, 2, 4}, {4, 16, 2, 4}} /* {bb} {k2} */ 4878c2ecf20Sopenharmony_ci }, 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci /* Mstorm */ 4908c2ecf20Sopenharmony_ci {'M', BLOCK_MSEM, 4918c2ecf20Sopenharmony_ci {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM}, 4928c2ecf20Sopenharmony_ci false, 4938c2ecf20Sopenharmony_ci MSEM_REG_FAST_MEMORY, 4948c2ecf20Sopenharmony_ci MSEM_REG_DBG_FRAME_MODE_BB_K2, 4958c2ecf20Sopenharmony_ci MSEM_REG_SLOW_DBG_ACTIVE_BB_K2, 4968c2ecf20Sopenharmony_ci MSEM_REG_SLOW_DBG_MODE_BB_K2, 4978c2ecf20Sopenharmony_ci MSEM_REG_DBG_MODE1_CFG_BB_K2, 4988c2ecf20Sopenharmony_ci MSEM_REG_SYNC_DBG_EMPTY, 4998c2ecf20Sopenharmony_ci MSEM_REG_DBG_GPRE_VECT, 5008c2ecf20Sopenharmony_ci MCM_REG_CTX_RBC_ACCS, 5018c2ecf20Sopenharmony_ci {MCM_REG_AGG_CON_CTX, MCM_REG_SM_CON_CTX, MCM_REG_AGG_TASK_CTX, 5028c2ecf20Sopenharmony_ci MCM_REG_SM_TASK_CTX }, 5038c2ecf20Sopenharmony_ci {{1, 10, 2, 7}, {1, 10, 2, 7}} /* {bb} {k2}*/ 5048c2ecf20Sopenharmony_ci }, 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci /* Ustorm */ 5078c2ecf20Sopenharmony_ci {'U', BLOCK_USEM, 5088c2ecf20Sopenharmony_ci {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU}, 5098c2ecf20Sopenharmony_ci false, 5108c2ecf20Sopenharmony_ci USEM_REG_FAST_MEMORY, 5118c2ecf20Sopenharmony_ci USEM_REG_DBG_FRAME_MODE_BB_K2, 5128c2ecf20Sopenharmony_ci USEM_REG_SLOW_DBG_ACTIVE_BB_K2, 5138c2ecf20Sopenharmony_ci USEM_REG_SLOW_DBG_MODE_BB_K2, 5148c2ecf20Sopenharmony_ci USEM_REG_DBG_MODE1_CFG_BB_K2, 5158c2ecf20Sopenharmony_ci USEM_REG_SYNC_DBG_EMPTY, 5168c2ecf20Sopenharmony_ci USEM_REG_DBG_GPRE_VECT, 5178c2ecf20Sopenharmony_ci UCM_REG_CTX_RBC_ACCS, 5188c2ecf20Sopenharmony_ci {UCM_REG_AGG_CON_CTX, UCM_REG_SM_CON_CTX, UCM_REG_AGG_TASK_CTX, 5198c2ecf20Sopenharmony_ci UCM_REG_SM_TASK_CTX}, 5208c2ecf20Sopenharmony_ci {{2, 13, 3, 3}, {2, 13, 3, 3}} /* {bb} {k2} */ 5218c2ecf20Sopenharmony_ci }, 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci /* Xstorm */ 5248c2ecf20Sopenharmony_ci {'X', BLOCK_XSEM, 5258c2ecf20Sopenharmony_ci {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX}, 5268c2ecf20Sopenharmony_ci false, 5278c2ecf20Sopenharmony_ci XSEM_REG_FAST_MEMORY, 5288c2ecf20Sopenharmony_ci XSEM_REG_DBG_FRAME_MODE_BB_K2, 5298c2ecf20Sopenharmony_ci XSEM_REG_SLOW_DBG_ACTIVE_BB_K2, 5308c2ecf20Sopenharmony_ci XSEM_REG_SLOW_DBG_MODE_BB_K2, 5318c2ecf20Sopenharmony_ci XSEM_REG_DBG_MODE1_CFG_BB_K2, 5328c2ecf20Sopenharmony_ci XSEM_REG_SYNC_DBG_EMPTY, 5338c2ecf20Sopenharmony_ci XSEM_REG_DBG_GPRE_VECT, 5348c2ecf20Sopenharmony_ci XCM_REG_CTX_RBC_ACCS, 5358c2ecf20Sopenharmony_ci {XCM_REG_AGG_CON_CTX, XCM_REG_SM_CON_CTX, 0, 0}, 5368c2ecf20Sopenharmony_ci {{9, 15, 0, 0}, {9, 15, 0, 0}} /* {bb} {k2} */ 5378c2ecf20Sopenharmony_ci }, 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_ci /* Ystorm */ 5408c2ecf20Sopenharmony_ci {'Y', BLOCK_YSEM, 5418c2ecf20Sopenharmony_ci {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY}, 5428c2ecf20Sopenharmony_ci false, 5438c2ecf20Sopenharmony_ci YSEM_REG_FAST_MEMORY, 5448c2ecf20Sopenharmony_ci YSEM_REG_DBG_FRAME_MODE_BB_K2, 5458c2ecf20Sopenharmony_ci YSEM_REG_SLOW_DBG_ACTIVE_BB_K2, 5468c2ecf20Sopenharmony_ci YSEM_REG_SLOW_DBG_MODE_BB_K2, 5478c2ecf20Sopenharmony_ci YSEM_REG_DBG_MODE1_CFG_BB_K2, 5488c2ecf20Sopenharmony_ci YSEM_REG_SYNC_DBG_EMPTY, 5498c2ecf20Sopenharmony_ci YSEM_REG_DBG_GPRE_VECT, 5508c2ecf20Sopenharmony_ci YCM_REG_CTX_RBC_ACCS, 5518c2ecf20Sopenharmony_ci {YCM_REG_AGG_CON_CTX, YCM_REG_SM_CON_CTX, YCM_REG_AGG_TASK_CTX, 5528c2ecf20Sopenharmony_ci YCM_REG_SM_TASK_CTX}, 5538c2ecf20Sopenharmony_ci {{2, 3, 2, 12}, {2, 3, 2, 12}} /* {bb} {k2} */ 5548c2ecf20Sopenharmony_ci }, 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_ci /* Pstorm */ 5578c2ecf20Sopenharmony_ci {'P', BLOCK_PSEM, 5588c2ecf20Sopenharmony_ci {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS}, 5598c2ecf20Sopenharmony_ci true, 5608c2ecf20Sopenharmony_ci PSEM_REG_FAST_MEMORY, 5618c2ecf20Sopenharmony_ci PSEM_REG_DBG_FRAME_MODE_BB_K2, 5628c2ecf20Sopenharmony_ci PSEM_REG_SLOW_DBG_ACTIVE_BB_K2, 5638c2ecf20Sopenharmony_ci PSEM_REG_SLOW_DBG_MODE_BB_K2, 5648c2ecf20Sopenharmony_ci PSEM_REG_DBG_MODE1_CFG_BB_K2, 5658c2ecf20Sopenharmony_ci PSEM_REG_SYNC_DBG_EMPTY, 5668c2ecf20Sopenharmony_ci PSEM_REG_DBG_GPRE_VECT, 5678c2ecf20Sopenharmony_ci PCM_REG_CTX_RBC_ACCS, 5688c2ecf20Sopenharmony_ci {0, PCM_REG_SM_CON_CTX, 0, 0}, 5698c2ecf20Sopenharmony_ci {{0, 10, 0, 0}, {0, 10, 0, 0}} /* {bb} {k2} */ 5708c2ecf20Sopenharmony_ci }, 5718c2ecf20Sopenharmony_ci}; 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_cistatic struct hw_type_defs s_hw_type_defs[] = { 5748c2ecf20Sopenharmony_ci /* HW_TYPE_ASIC */ 5758c2ecf20Sopenharmony_ci {"asic", 1, 256, 32768}, 5768c2ecf20Sopenharmony_ci {"reserved", 0, 0, 0}, 5778c2ecf20Sopenharmony_ci {"reserved2", 0, 0, 0}, 5788c2ecf20Sopenharmony_ci {"reserved3", 0, 0, 0} 5798c2ecf20Sopenharmony_ci}; 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_cistatic struct grc_param_defs s_grc_param_defs[] = { 5828c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_TSTORM */ 5838c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 1, {1, 1}}, 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_MSTORM */ 5868c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 1, {1, 1}}, 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_USTORM */ 5898c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 1, {1, 1}}, 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_XSTORM */ 5928c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 1, {1, 1}}, 5938c2ecf20Sopenharmony_ci 5948c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_YSTORM */ 5958c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 1, {1, 1}}, 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_PSTORM */ 5988c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 1, {1, 1}}, 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_REGS */ 6018c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_RAM */ 6048c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_PBUF */ 6078c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_IOR */ 6108c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {1, 1}}, 6118c2ecf20Sopenharmony_ci 6128c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_VFC */ 6138c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {1, 1}}, 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_CM_CTX */ 6168c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_ILT */ 6198c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_RSS */ 6228c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_CAU */ 6258c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_QM */ 6288c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_MCP */ 6318c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_DORQ */ 6348c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6358c2ecf20Sopenharmony_ci 6368c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_CFC */ 6378c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_IGU */ 6408c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_BRB */ 6438c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {1, 1}}, 6448c2ecf20Sopenharmony_ci 6458c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_BTB */ 6468c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {1, 1}}, 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_BMB */ 6498c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {0, 0}}, 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_RESERVED1 */ 6528c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {0, 0}}, 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_MULD */ 6558c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_PRS */ 6588c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_DMAE */ 6618c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6628c2ecf20Sopenharmony_ci 6638c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_TM */ 6648c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_SDM */ 6678c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_DIF */ 6708c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_STATIC */ 6738c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_UNSTALL */ 6768c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {0, 0}}, 6778c2ecf20Sopenharmony_ci 6788c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_RESERVED2 */ 6798c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {0, 0}}, 6808c2ecf20Sopenharmony_ci 6818c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_MCP_TRACE_META_SIZE */ 6828c2ecf20Sopenharmony_ci {{0, 0}, 1, 0xffffffff, false, true, 0, {0, 0}}, 6838c2ecf20Sopenharmony_ci 6848c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_EXCLUDE_ALL */ 6858c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, true, false, 0, {0, 0}}, 6868c2ecf20Sopenharmony_ci 6878c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_CRASH */ 6888c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, true, false, 0, {0, 0}}, 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_PARITY_SAFE */ 6918c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {0, 0}}, 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_CM */ 6948c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {1, 1}}, 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_PHY */ 6978c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {0, 0}}, 6988c2ecf20Sopenharmony_ci 6998c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_NO_MCP */ 7008c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {0, 0}}, 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_NO_FW_VER */ 7038c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {0, 0}}, 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_RESERVED3 */ 7068c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {0, 0}}, 7078c2ecf20Sopenharmony_ci 7088c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_MCP_HW_DUMP */ 7098c2ecf20Sopenharmony_ci {{0, 1}, 0, 1, false, false, 0, {0, 1}}, 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_ILT_CDUC */ 7128c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {0, 0}}, 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_ILT_CDUT */ 7158c2ecf20Sopenharmony_ci {{1, 1}, 0, 1, false, false, 0, {0, 0}}, 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci /* DBG_GRC_PARAM_DUMP_CAU_EXT */ 7188c2ecf20Sopenharmony_ci {{0, 0}, 0, 1, false, false, 0, {1, 1}} 7198c2ecf20Sopenharmony_ci}; 7208c2ecf20Sopenharmony_ci 7218c2ecf20Sopenharmony_cistatic struct rss_mem_defs s_rss_mem_defs[] = { 7228c2ecf20Sopenharmony_ci {"rss_mem_cid", "rss_cid", 0, 32, 7238c2ecf20Sopenharmony_ci {256, 320}}, 7248c2ecf20Sopenharmony_ci 7258c2ecf20Sopenharmony_ci {"rss_mem_key_msb", "rss_key", 1024, 256, 7268c2ecf20Sopenharmony_ci {128, 208}}, 7278c2ecf20Sopenharmony_ci 7288c2ecf20Sopenharmony_ci {"rss_mem_key_lsb", "rss_key", 2048, 64, 7298c2ecf20Sopenharmony_ci {128, 208}}, 7308c2ecf20Sopenharmony_ci 7318c2ecf20Sopenharmony_ci {"rss_mem_info", "rss_info", 3072, 16, 7328c2ecf20Sopenharmony_ci {128, 208}}, 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_ci {"rss_mem_ind", "rss_ind", 4096, 16, 7358c2ecf20Sopenharmony_ci {16384, 26624}} 7368c2ecf20Sopenharmony_ci}; 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_cistatic struct vfc_ram_defs s_vfc_ram_defs[] = { 7398c2ecf20Sopenharmony_ci {"vfc_ram_tt1", "vfc_ram", 0, 512}, 7408c2ecf20Sopenharmony_ci {"vfc_ram_mtt2", "vfc_ram", 512, 128}, 7418c2ecf20Sopenharmony_ci {"vfc_ram_stt2", "vfc_ram", 640, 32}, 7428c2ecf20Sopenharmony_ci {"vfc_ram_ro_vect", "vfc_ram", 672, 32} 7438c2ecf20Sopenharmony_ci}; 7448c2ecf20Sopenharmony_ci 7458c2ecf20Sopenharmony_cistatic struct big_ram_defs s_big_ram_defs[] = { 7468c2ecf20Sopenharmony_ci {"BRB", MEM_GROUP_BRB_MEM, MEM_GROUP_BRB_RAM, DBG_GRC_PARAM_DUMP_BRB, 7478c2ecf20Sopenharmony_ci BRB_REG_BIG_RAM_ADDRESS, BRB_REG_BIG_RAM_DATA, 7488c2ecf20Sopenharmony_ci MISC_REG_BLOCK_256B_EN, {0, 0}, 7498c2ecf20Sopenharmony_ci {153600, 180224}}, 7508c2ecf20Sopenharmony_ci 7518c2ecf20Sopenharmony_ci {"BTB", MEM_GROUP_BTB_MEM, MEM_GROUP_BTB_RAM, DBG_GRC_PARAM_DUMP_BTB, 7528c2ecf20Sopenharmony_ci BTB_REG_BIG_RAM_ADDRESS, BTB_REG_BIG_RAM_DATA, 7538c2ecf20Sopenharmony_ci MISC_REG_BLOCK_256B_EN, {0, 1}, 7548c2ecf20Sopenharmony_ci {92160, 117760}}, 7558c2ecf20Sopenharmony_ci 7568c2ecf20Sopenharmony_ci {"BMB", MEM_GROUP_BMB_MEM, MEM_GROUP_BMB_RAM, DBG_GRC_PARAM_DUMP_BMB, 7578c2ecf20Sopenharmony_ci BMB_REG_BIG_RAM_ADDRESS, BMB_REG_BIG_RAM_DATA, 7588c2ecf20Sopenharmony_ci MISCS_REG_BLOCK_256B_EN, {0, 0}, 7598c2ecf20Sopenharmony_ci {36864, 36864}} 7608c2ecf20Sopenharmony_ci}; 7618c2ecf20Sopenharmony_ci 7628c2ecf20Sopenharmony_cistatic struct rbc_reset_defs s_rbc_reset_defs[] = { 7638c2ecf20Sopenharmony_ci {MISCS_REG_RESET_PL_HV, 7648c2ecf20Sopenharmony_ci {0x0, 0x400}}, 7658c2ecf20Sopenharmony_ci {MISC_REG_RESET_PL_PDA_VMAIN_1, 7668c2ecf20Sopenharmony_ci {0x4404040, 0x4404040}}, 7678c2ecf20Sopenharmony_ci {MISC_REG_RESET_PL_PDA_VMAIN_2, 7688c2ecf20Sopenharmony_ci {0x7, 0x7c00007}}, 7698c2ecf20Sopenharmony_ci {MISC_REG_RESET_PL_PDA_VAUX, 7708c2ecf20Sopenharmony_ci {0x2, 0x2}}, 7718c2ecf20Sopenharmony_ci}; 7728c2ecf20Sopenharmony_ci 7738c2ecf20Sopenharmony_cistatic struct phy_defs s_phy_defs[] = { 7748c2ecf20Sopenharmony_ci {"nw_phy", NWS_REG_NWS_CMU_K2, 7758c2ecf20Sopenharmony_ci PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_7_0_K2_E5, 7768c2ecf20Sopenharmony_ci PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_15_8_K2_E5, 7778c2ecf20Sopenharmony_ci PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_7_0_K2_E5, 7788c2ecf20Sopenharmony_ci PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_11_8_K2_E5}, 7798c2ecf20Sopenharmony_ci {"sgmii_phy", MS_REG_MS_CMU_K2_E5, 7808c2ecf20Sopenharmony_ci PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X132_K2_E5, 7818c2ecf20Sopenharmony_ci PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X133_K2_E5, 7828c2ecf20Sopenharmony_ci PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X130_K2_E5, 7838c2ecf20Sopenharmony_ci PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X131_K2_E5}, 7848c2ecf20Sopenharmony_ci {"pcie_phy0", PHY_PCIE_REG_PHY0_K2_E5, 7858c2ecf20Sopenharmony_ci PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2_E5, 7868c2ecf20Sopenharmony_ci PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2_E5, 7878c2ecf20Sopenharmony_ci PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2_E5, 7888c2ecf20Sopenharmony_ci PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2_E5}, 7898c2ecf20Sopenharmony_ci {"pcie_phy1", PHY_PCIE_REG_PHY1_K2_E5, 7908c2ecf20Sopenharmony_ci PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2_E5, 7918c2ecf20Sopenharmony_ci PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2_E5, 7928c2ecf20Sopenharmony_ci PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2_E5, 7938c2ecf20Sopenharmony_ci PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2_E5}, 7948c2ecf20Sopenharmony_ci}; 7958c2ecf20Sopenharmony_ci 7968c2ecf20Sopenharmony_cistatic struct split_type_defs s_split_type_defs[] = { 7978c2ecf20Sopenharmony_ci /* SPLIT_TYPE_NONE */ 7988c2ecf20Sopenharmony_ci {"eng"}, 7998c2ecf20Sopenharmony_ci 8008c2ecf20Sopenharmony_ci /* SPLIT_TYPE_PORT */ 8018c2ecf20Sopenharmony_ci {"port"}, 8028c2ecf20Sopenharmony_ci 8038c2ecf20Sopenharmony_ci /* SPLIT_TYPE_PF */ 8048c2ecf20Sopenharmony_ci {"pf"}, 8058c2ecf20Sopenharmony_ci 8068c2ecf20Sopenharmony_ci /* SPLIT_TYPE_PORT_PF */ 8078c2ecf20Sopenharmony_ci {"port"}, 8088c2ecf20Sopenharmony_ci 8098c2ecf20Sopenharmony_ci /* SPLIT_TYPE_VF */ 8108c2ecf20Sopenharmony_ci {"vf"} 8118c2ecf20Sopenharmony_ci}; 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ci/**************************** Private Functions ******************************/ 8148c2ecf20Sopenharmony_ci 8158c2ecf20Sopenharmony_ci/* Reads and returns a single dword from the specified unaligned buffer */ 8168c2ecf20Sopenharmony_cistatic u32 qed_read_unaligned_dword(u8 *buf) 8178c2ecf20Sopenharmony_ci{ 8188c2ecf20Sopenharmony_ci u32 dword; 8198c2ecf20Sopenharmony_ci 8208c2ecf20Sopenharmony_ci memcpy((u8 *)&dword, buf, sizeof(dword)); 8218c2ecf20Sopenharmony_ci return dword; 8228c2ecf20Sopenharmony_ci} 8238c2ecf20Sopenharmony_ci 8248c2ecf20Sopenharmony_ci/* Sets the value of the specified GRC param */ 8258c2ecf20Sopenharmony_cistatic void qed_grc_set_param(struct qed_hwfn *p_hwfn, 8268c2ecf20Sopenharmony_ci enum dbg_grc_params grc_param, u32 val) 8278c2ecf20Sopenharmony_ci{ 8288c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 8298c2ecf20Sopenharmony_ci 8308c2ecf20Sopenharmony_ci dev_data->grc.param_val[grc_param] = val; 8318c2ecf20Sopenharmony_ci} 8328c2ecf20Sopenharmony_ci 8338c2ecf20Sopenharmony_ci/* Returns the value of the specified GRC param */ 8348c2ecf20Sopenharmony_cistatic u32 qed_grc_get_param(struct qed_hwfn *p_hwfn, 8358c2ecf20Sopenharmony_ci enum dbg_grc_params grc_param) 8368c2ecf20Sopenharmony_ci{ 8378c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 8388c2ecf20Sopenharmony_ci 8398c2ecf20Sopenharmony_ci return dev_data->grc.param_val[grc_param]; 8408c2ecf20Sopenharmony_ci} 8418c2ecf20Sopenharmony_ci 8428c2ecf20Sopenharmony_ci/* Initializes the GRC parameters */ 8438c2ecf20Sopenharmony_cistatic void qed_dbg_grc_init_params(struct qed_hwfn *p_hwfn) 8448c2ecf20Sopenharmony_ci{ 8458c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 8468c2ecf20Sopenharmony_ci 8478c2ecf20Sopenharmony_ci if (!dev_data->grc.params_initialized) { 8488c2ecf20Sopenharmony_ci qed_dbg_grc_set_params_default(p_hwfn); 8498c2ecf20Sopenharmony_ci dev_data->grc.params_initialized = 1; 8508c2ecf20Sopenharmony_ci } 8518c2ecf20Sopenharmony_ci} 8528c2ecf20Sopenharmony_ci 8538c2ecf20Sopenharmony_ci/* Sets pointer and size for the specified binary buffer type */ 8548c2ecf20Sopenharmony_cistatic void qed_set_dbg_bin_buf(struct qed_hwfn *p_hwfn, 8558c2ecf20Sopenharmony_ci enum bin_dbg_buffer_type buf_type, 8568c2ecf20Sopenharmony_ci const u32 *ptr, u32 size) 8578c2ecf20Sopenharmony_ci{ 8588c2ecf20Sopenharmony_ci struct virt_mem_desc *buf = &p_hwfn->dbg_arrays[buf_type]; 8598c2ecf20Sopenharmony_ci 8608c2ecf20Sopenharmony_ci buf->ptr = (void *)ptr; 8618c2ecf20Sopenharmony_ci buf->size = size; 8628c2ecf20Sopenharmony_ci} 8638c2ecf20Sopenharmony_ci 8648c2ecf20Sopenharmony_ci/* Initializes debug data for the specified device */ 8658c2ecf20Sopenharmony_cistatic enum dbg_status qed_dbg_dev_init(struct qed_hwfn *p_hwfn) 8668c2ecf20Sopenharmony_ci{ 8678c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 8688c2ecf20Sopenharmony_ci u8 num_pfs = 0, max_pfs_per_port = 0; 8698c2ecf20Sopenharmony_ci 8708c2ecf20Sopenharmony_ci if (dev_data->initialized) 8718c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 8728c2ecf20Sopenharmony_ci 8738c2ecf20Sopenharmony_ci /* Set chip */ 8748c2ecf20Sopenharmony_ci if (QED_IS_K2(p_hwfn->cdev)) { 8758c2ecf20Sopenharmony_ci dev_data->chip_id = CHIP_K2; 8768c2ecf20Sopenharmony_ci dev_data->mode_enable[MODE_K2] = 1; 8778c2ecf20Sopenharmony_ci dev_data->num_vfs = MAX_NUM_VFS_K2; 8788c2ecf20Sopenharmony_ci num_pfs = MAX_NUM_PFS_K2; 8798c2ecf20Sopenharmony_ci max_pfs_per_port = MAX_NUM_PFS_K2 / 2; 8808c2ecf20Sopenharmony_ci } else if (QED_IS_BB_B0(p_hwfn->cdev)) { 8818c2ecf20Sopenharmony_ci dev_data->chip_id = CHIP_BB; 8828c2ecf20Sopenharmony_ci dev_data->mode_enable[MODE_BB] = 1; 8838c2ecf20Sopenharmony_ci dev_data->num_vfs = MAX_NUM_VFS_BB; 8848c2ecf20Sopenharmony_ci num_pfs = MAX_NUM_PFS_BB; 8858c2ecf20Sopenharmony_ci max_pfs_per_port = MAX_NUM_PFS_BB; 8868c2ecf20Sopenharmony_ci } else { 8878c2ecf20Sopenharmony_ci return DBG_STATUS_UNKNOWN_CHIP; 8888c2ecf20Sopenharmony_ci } 8898c2ecf20Sopenharmony_ci 8908c2ecf20Sopenharmony_ci /* Set HW type */ 8918c2ecf20Sopenharmony_ci dev_data->hw_type = HW_TYPE_ASIC; 8928c2ecf20Sopenharmony_ci dev_data->mode_enable[MODE_ASIC] = 1; 8938c2ecf20Sopenharmony_ci 8948c2ecf20Sopenharmony_ci /* Set port mode */ 8958c2ecf20Sopenharmony_ci switch (p_hwfn->cdev->num_ports_in_engine) { 8968c2ecf20Sopenharmony_ci case 1: 8978c2ecf20Sopenharmony_ci dev_data->mode_enable[MODE_PORTS_PER_ENG_1] = 1; 8988c2ecf20Sopenharmony_ci break; 8998c2ecf20Sopenharmony_ci case 2: 9008c2ecf20Sopenharmony_ci dev_data->mode_enable[MODE_PORTS_PER_ENG_2] = 1; 9018c2ecf20Sopenharmony_ci break; 9028c2ecf20Sopenharmony_ci case 4: 9038c2ecf20Sopenharmony_ci dev_data->mode_enable[MODE_PORTS_PER_ENG_4] = 1; 9048c2ecf20Sopenharmony_ci break; 9058c2ecf20Sopenharmony_ci } 9068c2ecf20Sopenharmony_ci 9078c2ecf20Sopenharmony_ci /* Set 100G mode */ 9088c2ecf20Sopenharmony_ci if (QED_IS_CMT(p_hwfn->cdev)) 9098c2ecf20Sopenharmony_ci dev_data->mode_enable[MODE_100G] = 1; 9108c2ecf20Sopenharmony_ci 9118c2ecf20Sopenharmony_ci /* Set number of ports */ 9128c2ecf20Sopenharmony_ci if (dev_data->mode_enable[MODE_PORTS_PER_ENG_1] || 9138c2ecf20Sopenharmony_ci dev_data->mode_enable[MODE_100G]) 9148c2ecf20Sopenharmony_ci dev_data->num_ports = 1; 9158c2ecf20Sopenharmony_ci else if (dev_data->mode_enable[MODE_PORTS_PER_ENG_2]) 9168c2ecf20Sopenharmony_ci dev_data->num_ports = 2; 9178c2ecf20Sopenharmony_ci else if (dev_data->mode_enable[MODE_PORTS_PER_ENG_4]) 9188c2ecf20Sopenharmony_ci dev_data->num_ports = 4; 9198c2ecf20Sopenharmony_ci 9208c2ecf20Sopenharmony_ci /* Set number of PFs per port */ 9218c2ecf20Sopenharmony_ci dev_data->num_pfs_per_port = min_t(u32, 9228c2ecf20Sopenharmony_ci num_pfs / dev_data->num_ports, 9238c2ecf20Sopenharmony_ci max_pfs_per_port); 9248c2ecf20Sopenharmony_ci 9258c2ecf20Sopenharmony_ci /* Initializes the GRC parameters */ 9268c2ecf20Sopenharmony_ci qed_dbg_grc_init_params(p_hwfn); 9278c2ecf20Sopenharmony_ci 9288c2ecf20Sopenharmony_ci dev_data->use_dmae = true; 9298c2ecf20Sopenharmony_ci dev_data->initialized = 1; 9308c2ecf20Sopenharmony_ci 9318c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 9328c2ecf20Sopenharmony_ci} 9338c2ecf20Sopenharmony_ci 9348c2ecf20Sopenharmony_cistatic const struct dbg_block *get_dbg_block(struct qed_hwfn *p_hwfn, 9358c2ecf20Sopenharmony_ci enum block_id block_id) 9368c2ecf20Sopenharmony_ci{ 9378c2ecf20Sopenharmony_ci const struct dbg_block *dbg_block; 9388c2ecf20Sopenharmony_ci 9398c2ecf20Sopenharmony_ci dbg_block = p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS].ptr; 9408c2ecf20Sopenharmony_ci return dbg_block + block_id; 9418c2ecf20Sopenharmony_ci} 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_cistatic const struct dbg_block_chip *qed_get_dbg_block_per_chip(struct qed_hwfn 9448c2ecf20Sopenharmony_ci *p_hwfn, 9458c2ecf20Sopenharmony_ci enum block_id 9468c2ecf20Sopenharmony_ci block_id) 9478c2ecf20Sopenharmony_ci{ 9488c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 9498c2ecf20Sopenharmony_ci 9508c2ecf20Sopenharmony_ci return (const struct dbg_block_chip *) 9518c2ecf20Sopenharmony_ci p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS_CHIP_DATA].ptr + 9528c2ecf20Sopenharmony_ci block_id * MAX_CHIP_IDS + dev_data->chip_id; 9538c2ecf20Sopenharmony_ci} 9548c2ecf20Sopenharmony_ci 9558c2ecf20Sopenharmony_cistatic const struct dbg_reset_reg *qed_get_dbg_reset_reg(struct qed_hwfn 9568c2ecf20Sopenharmony_ci *p_hwfn, 9578c2ecf20Sopenharmony_ci u8 reset_reg_id) 9588c2ecf20Sopenharmony_ci{ 9598c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 9608c2ecf20Sopenharmony_ci 9618c2ecf20Sopenharmony_ci return (const struct dbg_reset_reg *) 9628c2ecf20Sopenharmony_ci p_hwfn->dbg_arrays[BIN_BUF_DBG_RESET_REGS].ptr + 9638c2ecf20Sopenharmony_ci reset_reg_id * MAX_CHIP_IDS + dev_data->chip_id; 9648c2ecf20Sopenharmony_ci} 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_ci/* Reads the FW info structure for the specified Storm from the chip, 9678c2ecf20Sopenharmony_ci * and writes it to the specified fw_info pointer. 9688c2ecf20Sopenharmony_ci */ 9698c2ecf20Sopenharmony_cistatic void qed_read_storm_fw_info(struct qed_hwfn *p_hwfn, 9708c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 9718c2ecf20Sopenharmony_ci u8 storm_id, struct fw_info *fw_info) 9728c2ecf20Sopenharmony_ci{ 9738c2ecf20Sopenharmony_ci struct storm_defs *storm = &s_storm_defs[storm_id]; 9748c2ecf20Sopenharmony_ci struct fw_info_location fw_info_location; 9758c2ecf20Sopenharmony_ci u32 addr, i, size, *dest; 9768c2ecf20Sopenharmony_ci 9778c2ecf20Sopenharmony_ci memset(&fw_info_location, 0, sizeof(fw_info_location)); 9788c2ecf20Sopenharmony_ci memset(fw_info, 0, sizeof(*fw_info)); 9798c2ecf20Sopenharmony_ci 9808c2ecf20Sopenharmony_ci /* Read first the address that points to fw_info location. 9818c2ecf20Sopenharmony_ci * The address is located in the last line of the Storm RAM. 9828c2ecf20Sopenharmony_ci */ 9838c2ecf20Sopenharmony_ci addr = storm->sem_fast_mem_addr + SEM_FAST_REG_INT_RAM + 9848c2ecf20Sopenharmony_ci DWORDS_TO_BYTES(SEM_FAST_REG_INT_RAM_SIZE) - 9858c2ecf20Sopenharmony_ci sizeof(fw_info_location); 9868c2ecf20Sopenharmony_ci 9878c2ecf20Sopenharmony_ci dest = (u32 *)&fw_info_location; 9888c2ecf20Sopenharmony_ci size = BYTES_TO_DWORDS(sizeof(fw_info_location)); 9898c2ecf20Sopenharmony_ci 9908c2ecf20Sopenharmony_ci for (i = 0; i < size; i++, addr += BYTES_IN_DWORD) 9918c2ecf20Sopenharmony_ci dest[i] = qed_rd(p_hwfn, p_ptt, addr); 9928c2ecf20Sopenharmony_ci 9938c2ecf20Sopenharmony_ci /* qed_rq() fetches data in CPU byteorder. Swap it back to 9948c2ecf20Sopenharmony_ci * the device's to get right structure layout. 9958c2ecf20Sopenharmony_ci */ 9968c2ecf20Sopenharmony_ci cpu_to_le32_array(dest, size); 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_ci /* Read FW version info from Storm RAM */ 9998c2ecf20Sopenharmony_ci size = le32_to_cpu(fw_info_location.size); 10008c2ecf20Sopenharmony_ci if (!size || size > sizeof(*fw_info)) 10018c2ecf20Sopenharmony_ci return; 10028c2ecf20Sopenharmony_ci 10038c2ecf20Sopenharmony_ci addr = le32_to_cpu(fw_info_location.grc_addr); 10048c2ecf20Sopenharmony_ci dest = (u32 *)fw_info; 10058c2ecf20Sopenharmony_ci size = BYTES_TO_DWORDS(size); 10068c2ecf20Sopenharmony_ci 10078c2ecf20Sopenharmony_ci for (i = 0; i < size; i++, addr += BYTES_IN_DWORD) 10088c2ecf20Sopenharmony_ci dest[i] = qed_rd(p_hwfn, p_ptt, addr); 10098c2ecf20Sopenharmony_ci 10108c2ecf20Sopenharmony_ci cpu_to_le32_array(dest, size); 10118c2ecf20Sopenharmony_ci} 10128c2ecf20Sopenharmony_ci 10138c2ecf20Sopenharmony_ci/* Dumps the specified string to the specified buffer. 10148c2ecf20Sopenharmony_ci * Returns the dumped size in bytes. 10158c2ecf20Sopenharmony_ci */ 10168c2ecf20Sopenharmony_cistatic u32 qed_dump_str(char *dump_buf, bool dump, const char *str) 10178c2ecf20Sopenharmony_ci{ 10188c2ecf20Sopenharmony_ci if (dump) 10198c2ecf20Sopenharmony_ci strcpy(dump_buf, str); 10208c2ecf20Sopenharmony_ci 10218c2ecf20Sopenharmony_ci return (u32)strlen(str) + 1; 10228c2ecf20Sopenharmony_ci} 10238c2ecf20Sopenharmony_ci 10248c2ecf20Sopenharmony_ci/* Dumps zeros to align the specified buffer to dwords. 10258c2ecf20Sopenharmony_ci * Returns the dumped size in bytes. 10268c2ecf20Sopenharmony_ci */ 10278c2ecf20Sopenharmony_cistatic u32 qed_dump_align(char *dump_buf, bool dump, u32 byte_offset) 10288c2ecf20Sopenharmony_ci{ 10298c2ecf20Sopenharmony_ci u8 offset_in_dword, align_size; 10308c2ecf20Sopenharmony_ci 10318c2ecf20Sopenharmony_ci offset_in_dword = (u8)(byte_offset & 0x3); 10328c2ecf20Sopenharmony_ci align_size = offset_in_dword ? BYTES_IN_DWORD - offset_in_dword : 0; 10338c2ecf20Sopenharmony_ci 10348c2ecf20Sopenharmony_ci if (dump && align_size) 10358c2ecf20Sopenharmony_ci memset(dump_buf, 0, align_size); 10368c2ecf20Sopenharmony_ci 10378c2ecf20Sopenharmony_ci return align_size; 10388c2ecf20Sopenharmony_ci} 10398c2ecf20Sopenharmony_ci 10408c2ecf20Sopenharmony_ci/* Writes the specified string param to the specified buffer. 10418c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 10428c2ecf20Sopenharmony_ci */ 10438c2ecf20Sopenharmony_cistatic u32 qed_dump_str_param(u32 *dump_buf, 10448c2ecf20Sopenharmony_ci bool dump, 10458c2ecf20Sopenharmony_ci const char *param_name, const char *param_val) 10468c2ecf20Sopenharmony_ci{ 10478c2ecf20Sopenharmony_ci char *char_buf = (char *)dump_buf; 10488c2ecf20Sopenharmony_ci u32 offset = 0; 10498c2ecf20Sopenharmony_ci 10508c2ecf20Sopenharmony_ci /* Dump param name */ 10518c2ecf20Sopenharmony_ci offset += qed_dump_str(char_buf + offset, dump, param_name); 10528c2ecf20Sopenharmony_ci 10538c2ecf20Sopenharmony_ci /* Indicate a string param value */ 10548c2ecf20Sopenharmony_ci if (dump) 10558c2ecf20Sopenharmony_ci *(char_buf + offset) = 1; 10568c2ecf20Sopenharmony_ci offset++; 10578c2ecf20Sopenharmony_ci 10588c2ecf20Sopenharmony_ci /* Dump param value */ 10598c2ecf20Sopenharmony_ci offset += qed_dump_str(char_buf + offset, dump, param_val); 10608c2ecf20Sopenharmony_ci 10618c2ecf20Sopenharmony_ci /* Align buffer to next dword */ 10628c2ecf20Sopenharmony_ci offset += qed_dump_align(char_buf + offset, dump, offset); 10638c2ecf20Sopenharmony_ci 10648c2ecf20Sopenharmony_ci return BYTES_TO_DWORDS(offset); 10658c2ecf20Sopenharmony_ci} 10668c2ecf20Sopenharmony_ci 10678c2ecf20Sopenharmony_ci/* Writes the specified numeric param to the specified buffer. 10688c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 10698c2ecf20Sopenharmony_ci */ 10708c2ecf20Sopenharmony_cistatic u32 qed_dump_num_param(u32 *dump_buf, 10718c2ecf20Sopenharmony_ci bool dump, const char *param_name, u32 param_val) 10728c2ecf20Sopenharmony_ci{ 10738c2ecf20Sopenharmony_ci char *char_buf = (char *)dump_buf; 10748c2ecf20Sopenharmony_ci u32 offset = 0; 10758c2ecf20Sopenharmony_ci 10768c2ecf20Sopenharmony_ci /* Dump param name */ 10778c2ecf20Sopenharmony_ci offset += qed_dump_str(char_buf + offset, dump, param_name); 10788c2ecf20Sopenharmony_ci 10798c2ecf20Sopenharmony_ci /* Indicate a numeric param value */ 10808c2ecf20Sopenharmony_ci if (dump) 10818c2ecf20Sopenharmony_ci *(char_buf + offset) = 0; 10828c2ecf20Sopenharmony_ci offset++; 10838c2ecf20Sopenharmony_ci 10848c2ecf20Sopenharmony_ci /* Align buffer to next dword */ 10858c2ecf20Sopenharmony_ci offset += qed_dump_align(char_buf + offset, dump, offset); 10868c2ecf20Sopenharmony_ci 10878c2ecf20Sopenharmony_ci /* Dump param value (and change offset from bytes to dwords) */ 10888c2ecf20Sopenharmony_ci offset = BYTES_TO_DWORDS(offset); 10898c2ecf20Sopenharmony_ci if (dump) 10908c2ecf20Sopenharmony_ci *(dump_buf + offset) = param_val; 10918c2ecf20Sopenharmony_ci offset++; 10928c2ecf20Sopenharmony_ci 10938c2ecf20Sopenharmony_ci return offset; 10948c2ecf20Sopenharmony_ci} 10958c2ecf20Sopenharmony_ci 10968c2ecf20Sopenharmony_ci/* Reads the FW version and writes it as a param to the specified buffer. 10978c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 10988c2ecf20Sopenharmony_ci */ 10998c2ecf20Sopenharmony_cistatic u32 qed_dump_fw_ver_param(struct qed_hwfn *p_hwfn, 11008c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 11018c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump) 11028c2ecf20Sopenharmony_ci{ 11038c2ecf20Sopenharmony_ci char fw_ver_str[16] = EMPTY_FW_VERSION_STR; 11048c2ecf20Sopenharmony_ci char fw_img_str[16] = EMPTY_FW_IMAGE_STR; 11058c2ecf20Sopenharmony_ci struct fw_info fw_info = { {0}, {0} }; 11068c2ecf20Sopenharmony_ci u32 offset = 0; 11078c2ecf20Sopenharmony_ci 11088c2ecf20Sopenharmony_ci if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) { 11098c2ecf20Sopenharmony_ci /* Read FW info from chip */ 11108c2ecf20Sopenharmony_ci qed_read_fw_info(p_hwfn, p_ptt, &fw_info); 11118c2ecf20Sopenharmony_ci 11128c2ecf20Sopenharmony_ci /* Create FW version/image strings */ 11138c2ecf20Sopenharmony_ci if (snprintf(fw_ver_str, sizeof(fw_ver_str), 11148c2ecf20Sopenharmony_ci "%d_%d_%d_%d", fw_info.ver.num.major, 11158c2ecf20Sopenharmony_ci fw_info.ver.num.minor, fw_info.ver.num.rev, 11168c2ecf20Sopenharmony_ci fw_info.ver.num.eng) < 0) 11178c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, 11188c2ecf20Sopenharmony_ci "Unexpected debug error: invalid FW version string\n"); 11198c2ecf20Sopenharmony_ci switch (fw_info.ver.image_id) { 11208c2ecf20Sopenharmony_ci case FW_IMG_MAIN: 11218c2ecf20Sopenharmony_ci strcpy(fw_img_str, "main"); 11228c2ecf20Sopenharmony_ci break; 11238c2ecf20Sopenharmony_ci default: 11248c2ecf20Sopenharmony_ci strcpy(fw_img_str, "unknown"); 11258c2ecf20Sopenharmony_ci break; 11268c2ecf20Sopenharmony_ci } 11278c2ecf20Sopenharmony_ci } 11288c2ecf20Sopenharmony_ci 11298c2ecf20Sopenharmony_ci /* Dump FW version, image and timestamp */ 11308c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 11318c2ecf20Sopenharmony_ci dump, "fw-version", fw_ver_str); 11328c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 11338c2ecf20Sopenharmony_ci dump, "fw-image", fw_img_str); 11348c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, dump, "fw-timestamp", 11358c2ecf20Sopenharmony_ci le32_to_cpu(fw_info.ver.timestamp)); 11368c2ecf20Sopenharmony_ci 11378c2ecf20Sopenharmony_ci return offset; 11388c2ecf20Sopenharmony_ci} 11398c2ecf20Sopenharmony_ci 11408c2ecf20Sopenharmony_ci/* Reads the MFW version and writes it as a param to the specified buffer. 11418c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 11428c2ecf20Sopenharmony_ci */ 11438c2ecf20Sopenharmony_cistatic u32 qed_dump_mfw_ver_param(struct qed_hwfn *p_hwfn, 11448c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 11458c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump) 11468c2ecf20Sopenharmony_ci{ 11478c2ecf20Sopenharmony_ci char mfw_ver_str[16] = EMPTY_FW_VERSION_STR; 11488c2ecf20Sopenharmony_ci 11498c2ecf20Sopenharmony_ci if (dump && 11508c2ecf20Sopenharmony_ci !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) { 11518c2ecf20Sopenharmony_ci u32 global_section_offsize, global_section_addr, mfw_ver; 11528c2ecf20Sopenharmony_ci u32 public_data_addr, global_section_offsize_addr; 11538c2ecf20Sopenharmony_ci 11548c2ecf20Sopenharmony_ci /* Find MCP public data GRC address. Needs to be ORed with 11558c2ecf20Sopenharmony_ci * MCP_REG_SCRATCH due to a HW bug. 11568c2ecf20Sopenharmony_ci */ 11578c2ecf20Sopenharmony_ci public_data_addr = qed_rd(p_hwfn, 11588c2ecf20Sopenharmony_ci p_ptt, 11598c2ecf20Sopenharmony_ci MISC_REG_SHARED_MEM_ADDR) | 11608c2ecf20Sopenharmony_ci MCP_REG_SCRATCH; 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci /* Find MCP public global section offset */ 11638c2ecf20Sopenharmony_ci global_section_offsize_addr = public_data_addr + 11648c2ecf20Sopenharmony_ci offsetof(struct mcp_public_data, 11658c2ecf20Sopenharmony_ci sections) + 11668c2ecf20Sopenharmony_ci sizeof(offsize_t) * PUBLIC_GLOBAL; 11678c2ecf20Sopenharmony_ci global_section_offsize = qed_rd(p_hwfn, p_ptt, 11688c2ecf20Sopenharmony_ci global_section_offsize_addr); 11698c2ecf20Sopenharmony_ci global_section_addr = 11708c2ecf20Sopenharmony_ci MCP_REG_SCRATCH + 11718c2ecf20Sopenharmony_ci (global_section_offsize & OFFSIZE_OFFSET_MASK) * 4; 11728c2ecf20Sopenharmony_ci 11738c2ecf20Sopenharmony_ci /* Read MFW version from MCP public global section */ 11748c2ecf20Sopenharmony_ci mfw_ver = qed_rd(p_hwfn, p_ptt, 11758c2ecf20Sopenharmony_ci global_section_addr + 11768c2ecf20Sopenharmony_ci offsetof(struct public_global, mfw_ver)); 11778c2ecf20Sopenharmony_ci 11788c2ecf20Sopenharmony_ci /* Dump MFW version param */ 11798c2ecf20Sopenharmony_ci if (snprintf(mfw_ver_str, sizeof(mfw_ver_str), "%d_%d_%d_%d", 11808c2ecf20Sopenharmony_ci (u8)(mfw_ver >> 24), (u8)(mfw_ver >> 16), 11818c2ecf20Sopenharmony_ci (u8)(mfw_ver >> 8), (u8)mfw_ver) < 0) 11828c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, 11838c2ecf20Sopenharmony_ci "Unexpected debug error: invalid MFW version string\n"); 11848c2ecf20Sopenharmony_ci } 11858c2ecf20Sopenharmony_ci 11868c2ecf20Sopenharmony_ci return qed_dump_str_param(dump_buf, dump, "mfw-version", mfw_ver_str); 11878c2ecf20Sopenharmony_ci} 11888c2ecf20Sopenharmony_ci 11898c2ecf20Sopenharmony_ci/* Reads the chip revision from the chip and writes it as a param to the 11908c2ecf20Sopenharmony_ci * specified buffer. Returns the dumped size in dwords. 11918c2ecf20Sopenharmony_ci */ 11928c2ecf20Sopenharmony_cistatic u32 qed_dump_chip_revision_param(struct qed_hwfn *p_hwfn, 11938c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 11948c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump) 11958c2ecf20Sopenharmony_ci{ 11968c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 11978c2ecf20Sopenharmony_ci char param_str[3] = "??"; 11988c2ecf20Sopenharmony_ci 11998c2ecf20Sopenharmony_ci if (dev_data->hw_type == HW_TYPE_ASIC) { 12008c2ecf20Sopenharmony_ci u32 chip_rev, chip_metal; 12018c2ecf20Sopenharmony_ci 12028c2ecf20Sopenharmony_ci chip_rev = qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_REV); 12038c2ecf20Sopenharmony_ci chip_metal = qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_METAL); 12048c2ecf20Sopenharmony_ci 12058c2ecf20Sopenharmony_ci param_str[0] = 'a' + (u8)chip_rev; 12068c2ecf20Sopenharmony_ci param_str[1] = '0' + (u8)chip_metal; 12078c2ecf20Sopenharmony_ci } 12088c2ecf20Sopenharmony_ci 12098c2ecf20Sopenharmony_ci return qed_dump_str_param(dump_buf, dump, "chip-revision", param_str); 12108c2ecf20Sopenharmony_ci} 12118c2ecf20Sopenharmony_ci 12128c2ecf20Sopenharmony_ci/* Writes a section header to the specified buffer. 12138c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 12148c2ecf20Sopenharmony_ci */ 12158c2ecf20Sopenharmony_cistatic u32 qed_dump_section_hdr(u32 *dump_buf, 12168c2ecf20Sopenharmony_ci bool dump, const char *name, u32 num_params) 12178c2ecf20Sopenharmony_ci{ 12188c2ecf20Sopenharmony_ci return qed_dump_num_param(dump_buf, dump, name, num_params); 12198c2ecf20Sopenharmony_ci} 12208c2ecf20Sopenharmony_ci 12218c2ecf20Sopenharmony_ci/* Writes the common global params to the specified buffer. 12228c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 12238c2ecf20Sopenharmony_ci */ 12248c2ecf20Sopenharmony_cistatic u32 qed_dump_common_global_params(struct qed_hwfn *p_hwfn, 12258c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 12268c2ecf20Sopenharmony_ci u32 *dump_buf, 12278c2ecf20Sopenharmony_ci bool dump, 12288c2ecf20Sopenharmony_ci u8 num_specific_global_params) 12298c2ecf20Sopenharmony_ci{ 12308c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 12318c2ecf20Sopenharmony_ci u32 offset = 0; 12328c2ecf20Sopenharmony_ci u8 num_params; 12338c2ecf20Sopenharmony_ci 12348c2ecf20Sopenharmony_ci /* Dump global params section header */ 12358c2ecf20Sopenharmony_ci num_params = NUM_COMMON_GLOBAL_PARAMS + num_specific_global_params + 12368c2ecf20Sopenharmony_ci (dev_data->chip_id == CHIP_BB ? 1 : 0); 12378c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 12388c2ecf20Sopenharmony_ci dump, "global_params", num_params); 12398c2ecf20Sopenharmony_ci 12408c2ecf20Sopenharmony_ci /* Store params */ 12418c2ecf20Sopenharmony_ci offset += qed_dump_fw_ver_param(p_hwfn, p_ptt, dump_buf + offset, dump); 12428c2ecf20Sopenharmony_ci offset += qed_dump_mfw_ver_param(p_hwfn, 12438c2ecf20Sopenharmony_ci p_ptt, dump_buf + offset, dump); 12448c2ecf20Sopenharmony_ci offset += qed_dump_chip_revision_param(p_hwfn, 12458c2ecf20Sopenharmony_ci p_ptt, dump_buf + offset, dump); 12468c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 12478c2ecf20Sopenharmony_ci dump, "tools-version", TOOLS_VERSION); 12488c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 12498c2ecf20Sopenharmony_ci dump, 12508c2ecf20Sopenharmony_ci "chip", 12518c2ecf20Sopenharmony_ci s_chip_defs[dev_data->chip_id].name); 12528c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 12538c2ecf20Sopenharmony_ci dump, 12548c2ecf20Sopenharmony_ci "platform", 12558c2ecf20Sopenharmony_ci s_hw_type_defs[dev_data->hw_type].name); 12568c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 12578c2ecf20Sopenharmony_ci dump, "pci-func", p_hwfn->abs_pf_id); 12588c2ecf20Sopenharmony_ci if (dev_data->chip_id == CHIP_BB) 12598c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 12608c2ecf20Sopenharmony_ci dump, "path", QED_PATH_ID(p_hwfn)); 12618c2ecf20Sopenharmony_ci 12628c2ecf20Sopenharmony_ci return offset; 12638c2ecf20Sopenharmony_ci} 12648c2ecf20Sopenharmony_ci 12658c2ecf20Sopenharmony_ci/* Writes the "last" section (including CRC) to the specified buffer at the 12668c2ecf20Sopenharmony_ci * given offset. Returns the dumped size in dwords. 12678c2ecf20Sopenharmony_ci */ 12688c2ecf20Sopenharmony_cistatic u32 qed_dump_last_section(u32 *dump_buf, u32 offset, bool dump) 12698c2ecf20Sopenharmony_ci{ 12708c2ecf20Sopenharmony_ci u32 start_offset = offset; 12718c2ecf20Sopenharmony_ci 12728c2ecf20Sopenharmony_ci /* Dump CRC section header */ 12738c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, dump, "last", 0); 12748c2ecf20Sopenharmony_ci 12758c2ecf20Sopenharmony_ci /* Calculate CRC32 and add it to the dword after the "last" section */ 12768c2ecf20Sopenharmony_ci if (dump) 12778c2ecf20Sopenharmony_ci *(dump_buf + offset) = ~crc32(0xffffffff, 12788c2ecf20Sopenharmony_ci (u8 *)dump_buf, 12798c2ecf20Sopenharmony_ci DWORDS_TO_BYTES(offset)); 12808c2ecf20Sopenharmony_ci 12818c2ecf20Sopenharmony_ci offset++; 12828c2ecf20Sopenharmony_ci 12838c2ecf20Sopenharmony_ci return offset - start_offset; 12848c2ecf20Sopenharmony_ci} 12858c2ecf20Sopenharmony_ci 12868c2ecf20Sopenharmony_ci/* Update blocks reset state */ 12878c2ecf20Sopenharmony_cistatic void qed_update_blocks_reset_state(struct qed_hwfn *p_hwfn, 12888c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt) 12898c2ecf20Sopenharmony_ci{ 12908c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 12918c2ecf20Sopenharmony_ci u32 reg_val[NUM_DBG_RESET_REGS] = { 0 }; 12928c2ecf20Sopenharmony_ci u8 rst_reg_id; 12938c2ecf20Sopenharmony_ci u32 blk_id; 12948c2ecf20Sopenharmony_ci 12958c2ecf20Sopenharmony_ci /* Read reset registers */ 12968c2ecf20Sopenharmony_ci for (rst_reg_id = 0; rst_reg_id < NUM_DBG_RESET_REGS; rst_reg_id++) { 12978c2ecf20Sopenharmony_ci const struct dbg_reset_reg *rst_reg; 12988c2ecf20Sopenharmony_ci bool rst_reg_removed; 12998c2ecf20Sopenharmony_ci u32 rst_reg_addr; 13008c2ecf20Sopenharmony_ci 13018c2ecf20Sopenharmony_ci rst_reg = qed_get_dbg_reset_reg(p_hwfn, rst_reg_id); 13028c2ecf20Sopenharmony_ci rst_reg_removed = GET_FIELD(rst_reg->data, 13038c2ecf20Sopenharmony_ci DBG_RESET_REG_IS_REMOVED); 13048c2ecf20Sopenharmony_ci rst_reg_addr = DWORDS_TO_BYTES(GET_FIELD(rst_reg->data, 13058c2ecf20Sopenharmony_ci DBG_RESET_REG_ADDR)); 13068c2ecf20Sopenharmony_ci 13078c2ecf20Sopenharmony_ci if (!rst_reg_removed) 13088c2ecf20Sopenharmony_ci reg_val[rst_reg_id] = qed_rd(p_hwfn, p_ptt, 13098c2ecf20Sopenharmony_ci rst_reg_addr); 13108c2ecf20Sopenharmony_ci } 13118c2ecf20Sopenharmony_ci 13128c2ecf20Sopenharmony_ci /* Check if blocks are in reset */ 13138c2ecf20Sopenharmony_ci for (blk_id = 0; blk_id < NUM_PHYS_BLOCKS; blk_id++) { 13148c2ecf20Sopenharmony_ci const struct dbg_block_chip *blk; 13158c2ecf20Sopenharmony_ci bool has_rst_reg; 13168c2ecf20Sopenharmony_ci bool is_removed; 13178c2ecf20Sopenharmony_ci 13188c2ecf20Sopenharmony_ci blk = qed_get_dbg_block_per_chip(p_hwfn, (enum block_id)blk_id); 13198c2ecf20Sopenharmony_ci is_removed = GET_FIELD(blk->flags, DBG_BLOCK_CHIP_IS_REMOVED); 13208c2ecf20Sopenharmony_ci has_rst_reg = GET_FIELD(blk->flags, 13218c2ecf20Sopenharmony_ci DBG_BLOCK_CHIP_HAS_RESET_REG); 13228c2ecf20Sopenharmony_ci 13238c2ecf20Sopenharmony_ci if (!is_removed && has_rst_reg) 13248c2ecf20Sopenharmony_ci dev_data->block_in_reset[blk_id] = 13258c2ecf20Sopenharmony_ci !(reg_val[blk->reset_reg_id] & 13268c2ecf20Sopenharmony_ci BIT(blk->reset_reg_bit_offset)); 13278c2ecf20Sopenharmony_ci } 13288c2ecf20Sopenharmony_ci} 13298c2ecf20Sopenharmony_ci 13308c2ecf20Sopenharmony_ci/* is_mode_match recursive function */ 13318c2ecf20Sopenharmony_cistatic bool qed_is_mode_match_rec(struct qed_hwfn *p_hwfn, 13328c2ecf20Sopenharmony_ci u16 *modes_buf_offset, u8 rec_depth) 13338c2ecf20Sopenharmony_ci{ 13348c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 13358c2ecf20Sopenharmony_ci u8 *dbg_array; 13368c2ecf20Sopenharmony_ci bool arg1, arg2; 13378c2ecf20Sopenharmony_ci u8 tree_val; 13388c2ecf20Sopenharmony_ci 13398c2ecf20Sopenharmony_ci if (rec_depth > MAX_RECURSION_DEPTH) { 13408c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, 13418c2ecf20Sopenharmony_ci "Unexpected error: is_mode_match_rec exceeded the max recursion depth. This is probably due to a corrupt init/debug buffer.\n"); 13428c2ecf20Sopenharmony_ci return false; 13438c2ecf20Sopenharmony_ci } 13448c2ecf20Sopenharmony_ci 13458c2ecf20Sopenharmony_ci /* Get next element from modes tree buffer */ 13468c2ecf20Sopenharmony_ci dbg_array = p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr; 13478c2ecf20Sopenharmony_ci tree_val = dbg_array[(*modes_buf_offset)++]; 13488c2ecf20Sopenharmony_ci 13498c2ecf20Sopenharmony_ci switch (tree_val) { 13508c2ecf20Sopenharmony_ci case INIT_MODE_OP_NOT: 13518c2ecf20Sopenharmony_ci return !qed_is_mode_match_rec(p_hwfn, 13528c2ecf20Sopenharmony_ci modes_buf_offset, rec_depth + 1); 13538c2ecf20Sopenharmony_ci case INIT_MODE_OP_OR: 13548c2ecf20Sopenharmony_ci case INIT_MODE_OP_AND: 13558c2ecf20Sopenharmony_ci arg1 = qed_is_mode_match_rec(p_hwfn, 13568c2ecf20Sopenharmony_ci modes_buf_offset, rec_depth + 1); 13578c2ecf20Sopenharmony_ci arg2 = qed_is_mode_match_rec(p_hwfn, 13588c2ecf20Sopenharmony_ci modes_buf_offset, rec_depth + 1); 13598c2ecf20Sopenharmony_ci return (tree_val == INIT_MODE_OP_OR) ? (arg1 || 13608c2ecf20Sopenharmony_ci arg2) : (arg1 && arg2); 13618c2ecf20Sopenharmony_ci default: 13628c2ecf20Sopenharmony_ci return dev_data->mode_enable[tree_val - MAX_INIT_MODE_OPS] > 0; 13638c2ecf20Sopenharmony_ci } 13648c2ecf20Sopenharmony_ci} 13658c2ecf20Sopenharmony_ci 13668c2ecf20Sopenharmony_ci/* Returns true if the mode (specified using modes_buf_offset) is enabled */ 13678c2ecf20Sopenharmony_cistatic bool qed_is_mode_match(struct qed_hwfn *p_hwfn, u16 *modes_buf_offset) 13688c2ecf20Sopenharmony_ci{ 13698c2ecf20Sopenharmony_ci return qed_is_mode_match_rec(p_hwfn, modes_buf_offset, 0); 13708c2ecf20Sopenharmony_ci} 13718c2ecf20Sopenharmony_ci 13728c2ecf20Sopenharmony_ci/* Enable / disable the Debug block */ 13738c2ecf20Sopenharmony_cistatic void qed_bus_enable_dbg_block(struct qed_hwfn *p_hwfn, 13748c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, bool enable) 13758c2ecf20Sopenharmony_ci{ 13768c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON, enable ? 1 : 0); 13778c2ecf20Sopenharmony_ci} 13788c2ecf20Sopenharmony_ci 13798c2ecf20Sopenharmony_ci/* Resets the Debug block */ 13808c2ecf20Sopenharmony_cistatic void qed_bus_reset_dbg_block(struct qed_hwfn *p_hwfn, 13818c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt) 13828c2ecf20Sopenharmony_ci{ 13838c2ecf20Sopenharmony_ci u32 reset_reg_addr, old_reset_reg_val, new_reset_reg_val; 13848c2ecf20Sopenharmony_ci const struct dbg_reset_reg *reset_reg; 13858c2ecf20Sopenharmony_ci const struct dbg_block_chip *block; 13868c2ecf20Sopenharmony_ci 13878c2ecf20Sopenharmony_ci block = qed_get_dbg_block_per_chip(p_hwfn, BLOCK_DBG); 13888c2ecf20Sopenharmony_ci reset_reg = qed_get_dbg_reset_reg(p_hwfn, block->reset_reg_id); 13898c2ecf20Sopenharmony_ci reset_reg_addr = 13908c2ecf20Sopenharmony_ci DWORDS_TO_BYTES(GET_FIELD(reset_reg->data, DBG_RESET_REG_ADDR)); 13918c2ecf20Sopenharmony_ci 13928c2ecf20Sopenharmony_ci old_reset_reg_val = qed_rd(p_hwfn, p_ptt, reset_reg_addr); 13938c2ecf20Sopenharmony_ci new_reset_reg_val = 13948c2ecf20Sopenharmony_ci old_reset_reg_val & ~BIT(block->reset_reg_bit_offset); 13958c2ecf20Sopenharmony_ci 13968c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, reset_reg_addr, new_reset_reg_val); 13978c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, reset_reg_addr, old_reset_reg_val); 13988c2ecf20Sopenharmony_ci} 13998c2ecf20Sopenharmony_ci 14008c2ecf20Sopenharmony_ci/* Enable / disable Debug Bus clients according to the specified mask 14018c2ecf20Sopenharmony_ci * (1 = enable, 0 = disable). 14028c2ecf20Sopenharmony_ci */ 14038c2ecf20Sopenharmony_cistatic void qed_bus_enable_clients(struct qed_hwfn *p_hwfn, 14048c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, u32 client_mask) 14058c2ecf20Sopenharmony_ci{ 14068c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, DBG_REG_CLIENT_ENABLE, client_mask); 14078c2ecf20Sopenharmony_ci} 14088c2ecf20Sopenharmony_ci 14098c2ecf20Sopenharmony_cistatic void qed_bus_config_dbg_line(struct qed_hwfn *p_hwfn, 14108c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 14118c2ecf20Sopenharmony_ci enum block_id block_id, 14128c2ecf20Sopenharmony_ci u8 line_id, 14138c2ecf20Sopenharmony_ci u8 enable_mask, 14148c2ecf20Sopenharmony_ci u8 right_shift, 14158c2ecf20Sopenharmony_ci u8 force_valid_mask, u8 force_frame_mask) 14168c2ecf20Sopenharmony_ci{ 14178c2ecf20Sopenharmony_ci const struct dbg_block_chip *block = 14188c2ecf20Sopenharmony_ci qed_get_dbg_block_per_chip(p_hwfn, block_id); 14198c2ecf20Sopenharmony_ci 14208c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_select_reg_addr), 14218c2ecf20Sopenharmony_ci line_id); 14228c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_dword_enable_reg_addr), 14238c2ecf20Sopenharmony_ci enable_mask); 14248c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_shift_reg_addr), 14258c2ecf20Sopenharmony_ci right_shift); 14268c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_force_valid_reg_addr), 14278c2ecf20Sopenharmony_ci force_valid_mask); 14288c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_force_frame_reg_addr), 14298c2ecf20Sopenharmony_ci force_frame_mask); 14308c2ecf20Sopenharmony_ci} 14318c2ecf20Sopenharmony_ci 14328c2ecf20Sopenharmony_ci/* Disable debug bus in all blocks */ 14338c2ecf20Sopenharmony_cistatic void qed_bus_disable_blocks(struct qed_hwfn *p_hwfn, 14348c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt) 14358c2ecf20Sopenharmony_ci{ 14368c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 14378c2ecf20Sopenharmony_ci u32 block_id; 14388c2ecf20Sopenharmony_ci 14398c2ecf20Sopenharmony_ci /* Disable all blocks */ 14408c2ecf20Sopenharmony_ci for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) { 14418c2ecf20Sopenharmony_ci const struct dbg_block_chip *block_per_chip = 14428c2ecf20Sopenharmony_ci qed_get_dbg_block_per_chip(p_hwfn, 14438c2ecf20Sopenharmony_ci (enum block_id)block_id); 14448c2ecf20Sopenharmony_ci 14458c2ecf20Sopenharmony_ci if (GET_FIELD(block_per_chip->flags, 14468c2ecf20Sopenharmony_ci DBG_BLOCK_CHIP_IS_REMOVED) || 14478c2ecf20Sopenharmony_ci dev_data->block_in_reset[block_id]) 14488c2ecf20Sopenharmony_ci continue; 14498c2ecf20Sopenharmony_ci 14508c2ecf20Sopenharmony_ci /* Disable debug bus */ 14518c2ecf20Sopenharmony_ci if (GET_FIELD(block_per_chip->flags, 14528c2ecf20Sopenharmony_ci DBG_BLOCK_CHIP_HAS_DBG_BUS)) { 14538c2ecf20Sopenharmony_ci u32 dbg_en_addr = 14548c2ecf20Sopenharmony_ci block_per_chip->dbg_dword_enable_reg_addr; 14558c2ecf20Sopenharmony_ci u16 modes_buf_offset = 14568c2ecf20Sopenharmony_ci GET_FIELD(block_per_chip->dbg_bus_mode.data, 14578c2ecf20Sopenharmony_ci DBG_MODE_HDR_MODES_BUF_OFFSET); 14588c2ecf20Sopenharmony_ci bool eval_mode = 14598c2ecf20Sopenharmony_ci GET_FIELD(block_per_chip->dbg_bus_mode.data, 14608c2ecf20Sopenharmony_ci DBG_MODE_HDR_EVAL_MODE) > 0; 14618c2ecf20Sopenharmony_ci 14628c2ecf20Sopenharmony_ci if (!eval_mode || 14638c2ecf20Sopenharmony_ci qed_is_mode_match(p_hwfn, &modes_buf_offset)) 14648c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, 14658c2ecf20Sopenharmony_ci DWORDS_TO_BYTES(dbg_en_addr), 14668c2ecf20Sopenharmony_ci 0); 14678c2ecf20Sopenharmony_ci } 14688c2ecf20Sopenharmony_ci } 14698c2ecf20Sopenharmony_ci} 14708c2ecf20Sopenharmony_ci 14718c2ecf20Sopenharmony_ci/* Returns true if the specified entity (indicated by GRC param) should be 14728c2ecf20Sopenharmony_ci * included in the dump, false otherwise. 14738c2ecf20Sopenharmony_ci */ 14748c2ecf20Sopenharmony_cistatic bool qed_grc_is_included(struct qed_hwfn *p_hwfn, 14758c2ecf20Sopenharmony_ci enum dbg_grc_params grc_param) 14768c2ecf20Sopenharmony_ci{ 14778c2ecf20Sopenharmony_ci return qed_grc_get_param(p_hwfn, grc_param) > 0; 14788c2ecf20Sopenharmony_ci} 14798c2ecf20Sopenharmony_ci 14808c2ecf20Sopenharmony_ci/* Returns the storm_id that matches the specified Storm letter, 14818c2ecf20Sopenharmony_ci * or MAX_DBG_STORMS if invalid storm letter. 14828c2ecf20Sopenharmony_ci */ 14838c2ecf20Sopenharmony_cistatic enum dbg_storms qed_get_id_from_letter(char storm_letter) 14848c2ecf20Sopenharmony_ci{ 14858c2ecf20Sopenharmony_ci u8 storm_id; 14868c2ecf20Sopenharmony_ci 14878c2ecf20Sopenharmony_ci for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) 14888c2ecf20Sopenharmony_ci if (s_storm_defs[storm_id].letter == storm_letter) 14898c2ecf20Sopenharmony_ci return (enum dbg_storms)storm_id; 14908c2ecf20Sopenharmony_ci 14918c2ecf20Sopenharmony_ci return MAX_DBG_STORMS; 14928c2ecf20Sopenharmony_ci} 14938c2ecf20Sopenharmony_ci 14948c2ecf20Sopenharmony_ci/* Returns true of the specified Storm should be included in the dump, false 14958c2ecf20Sopenharmony_ci * otherwise. 14968c2ecf20Sopenharmony_ci */ 14978c2ecf20Sopenharmony_cistatic bool qed_grc_is_storm_included(struct qed_hwfn *p_hwfn, 14988c2ecf20Sopenharmony_ci enum dbg_storms storm) 14998c2ecf20Sopenharmony_ci{ 15008c2ecf20Sopenharmony_ci return qed_grc_get_param(p_hwfn, (enum dbg_grc_params)storm) > 0; 15018c2ecf20Sopenharmony_ci} 15028c2ecf20Sopenharmony_ci 15038c2ecf20Sopenharmony_ci/* Returns true if the specified memory should be included in the dump, false 15048c2ecf20Sopenharmony_ci * otherwise. 15058c2ecf20Sopenharmony_ci */ 15068c2ecf20Sopenharmony_cistatic bool qed_grc_is_mem_included(struct qed_hwfn *p_hwfn, 15078c2ecf20Sopenharmony_ci enum block_id block_id, u8 mem_group_id) 15088c2ecf20Sopenharmony_ci{ 15098c2ecf20Sopenharmony_ci const struct dbg_block *block; 15108c2ecf20Sopenharmony_ci u8 i; 15118c2ecf20Sopenharmony_ci 15128c2ecf20Sopenharmony_ci block = get_dbg_block(p_hwfn, block_id); 15138c2ecf20Sopenharmony_ci 15148c2ecf20Sopenharmony_ci /* If the block is associated with a Storm, check Storm match */ 15158c2ecf20Sopenharmony_ci if (block->associated_storm_letter) { 15168c2ecf20Sopenharmony_ci enum dbg_storms associated_storm_id = 15178c2ecf20Sopenharmony_ci qed_get_id_from_letter(block->associated_storm_letter); 15188c2ecf20Sopenharmony_ci 15198c2ecf20Sopenharmony_ci if (associated_storm_id == MAX_DBG_STORMS || 15208c2ecf20Sopenharmony_ci !qed_grc_is_storm_included(p_hwfn, associated_storm_id)) 15218c2ecf20Sopenharmony_ci return false; 15228c2ecf20Sopenharmony_ci } 15238c2ecf20Sopenharmony_ci 15248c2ecf20Sopenharmony_ci for (i = 0; i < NUM_BIG_RAM_TYPES; i++) { 15258c2ecf20Sopenharmony_ci struct big_ram_defs *big_ram = &s_big_ram_defs[i]; 15268c2ecf20Sopenharmony_ci 15278c2ecf20Sopenharmony_ci if (mem_group_id == big_ram->mem_group_id || 15288c2ecf20Sopenharmony_ci mem_group_id == big_ram->ram_mem_group_id) 15298c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, big_ram->grc_param); 15308c2ecf20Sopenharmony_ci } 15318c2ecf20Sopenharmony_ci 15328c2ecf20Sopenharmony_ci switch (mem_group_id) { 15338c2ecf20Sopenharmony_ci case MEM_GROUP_PXP_ILT: 15348c2ecf20Sopenharmony_ci case MEM_GROUP_PXP_MEM: 15358c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PXP); 15368c2ecf20Sopenharmony_ci case MEM_GROUP_RAM: 15378c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RAM); 15388c2ecf20Sopenharmony_ci case MEM_GROUP_PBUF: 15398c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PBUF); 15408c2ecf20Sopenharmony_ci case MEM_GROUP_CAU_MEM: 15418c2ecf20Sopenharmony_ci case MEM_GROUP_CAU_SB: 15428c2ecf20Sopenharmony_ci case MEM_GROUP_CAU_PI: 15438c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU); 15448c2ecf20Sopenharmony_ci case MEM_GROUP_CAU_MEM_EXT: 15458c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU_EXT); 15468c2ecf20Sopenharmony_ci case MEM_GROUP_QM_MEM: 15478c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_QM); 15488c2ecf20Sopenharmony_ci case MEM_GROUP_CFC_MEM: 15498c2ecf20Sopenharmony_ci case MEM_GROUP_CONN_CFC_MEM: 15508c2ecf20Sopenharmony_ci case MEM_GROUP_TASK_CFC_MEM: 15518c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CFC) || 15528c2ecf20Sopenharmony_ci qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX); 15538c2ecf20Sopenharmony_ci case MEM_GROUP_DORQ_MEM: 15548c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DORQ); 15558c2ecf20Sopenharmony_ci case MEM_GROUP_IGU_MEM: 15568c2ecf20Sopenharmony_ci case MEM_GROUP_IGU_MSIX: 15578c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IGU); 15588c2ecf20Sopenharmony_ci case MEM_GROUP_MULD_MEM: 15598c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MULD); 15608c2ecf20Sopenharmony_ci case MEM_GROUP_PRS_MEM: 15618c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PRS); 15628c2ecf20Sopenharmony_ci case MEM_GROUP_DMAE_MEM: 15638c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DMAE); 15648c2ecf20Sopenharmony_ci case MEM_GROUP_TM_MEM: 15658c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_TM); 15668c2ecf20Sopenharmony_ci case MEM_GROUP_SDM_MEM: 15678c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_SDM); 15688c2ecf20Sopenharmony_ci case MEM_GROUP_TDIF_CTX: 15698c2ecf20Sopenharmony_ci case MEM_GROUP_RDIF_CTX: 15708c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DIF); 15718c2ecf20Sopenharmony_ci case MEM_GROUP_CM_MEM: 15728c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM); 15738c2ecf20Sopenharmony_ci case MEM_GROUP_IOR: 15748c2ecf20Sopenharmony_ci return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IOR); 15758c2ecf20Sopenharmony_ci default: 15768c2ecf20Sopenharmony_ci return true; 15778c2ecf20Sopenharmony_ci } 15788c2ecf20Sopenharmony_ci} 15798c2ecf20Sopenharmony_ci 15808c2ecf20Sopenharmony_ci/* Stalls all Storms */ 15818c2ecf20Sopenharmony_cistatic void qed_grc_stall_storms(struct qed_hwfn *p_hwfn, 15828c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, bool stall) 15838c2ecf20Sopenharmony_ci{ 15848c2ecf20Sopenharmony_ci u32 reg_addr; 15858c2ecf20Sopenharmony_ci u8 storm_id; 15868c2ecf20Sopenharmony_ci 15878c2ecf20Sopenharmony_ci for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) { 15888c2ecf20Sopenharmony_ci if (!qed_grc_is_storm_included(p_hwfn, 15898c2ecf20Sopenharmony_ci (enum dbg_storms)storm_id)) 15908c2ecf20Sopenharmony_ci continue; 15918c2ecf20Sopenharmony_ci 15928c2ecf20Sopenharmony_ci reg_addr = s_storm_defs[storm_id].sem_fast_mem_addr + 15938c2ecf20Sopenharmony_ci SEM_FAST_REG_STALL_0_BB_K2; 15948c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, reg_addr, stall ? 1 : 0); 15958c2ecf20Sopenharmony_ci } 15968c2ecf20Sopenharmony_ci 15978c2ecf20Sopenharmony_ci msleep(STALL_DELAY_MS); 15988c2ecf20Sopenharmony_ci} 15998c2ecf20Sopenharmony_ci 16008c2ecf20Sopenharmony_ci/* Takes all blocks out of reset. If rbc_only is true, only RBC clients are 16018c2ecf20Sopenharmony_ci * taken out of reset. 16028c2ecf20Sopenharmony_ci */ 16038c2ecf20Sopenharmony_cistatic void qed_grc_unreset_blocks(struct qed_hwfn *p_hwfn, 16048c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, bool rbc_only) 16058c2ecf20Sopenharmony_ci{ 16068c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 16078c2ecf20Sopenharmony_ci u8 chip_id = dev_data->chip_id; 16088c2ecf20Sopenharmony_ci u32 i; 16098c2ecf20Sopenharmony_ci 16108c2ecf20Sopenharmony_ci /* Take RBCs out of reset */ 16118c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(s_rbc_reset_defs); i++) 16128c2ecf20Sopenharmony_ci if (s_rbc_reset_defs[i].reset_val[dev_data->chip_id]) 16138c2ecf20Sopenharmony_ci qed_wr(p_hwfn, 16148c2ecf20Sopenharmony_ci p_ptt, 16158c2ecf20Sopenharmony_ci s_rbc_reset_defs[i].reset_reg_addr + 16168c2ecf20Sopenharmony_ci RESET_REG_UNRESET_OFFSET, 16178c2ecf20Sopenharmony_ci s_rbc_reset_defs[i].reset_val[chip_id]); 16188c2ecf20Sopenharmony_ci 16198c2ecf20Sopenharmony_ci if (!rbc_only) { 16208c2ecf20Sopenharmony_ci u32 reg_val[NUM_DBG_RESET_REGS] = { 0 }; 16218c2ecf20Sopenharmony_ci u8 reset_reg_id; 16228c2ecf20Sopenharmony_ci u32 block_id; 16238c2ecf20Sopenharmony_ci 16248c2ecf20Sopenharmony_ci /* Fill reset regs values */ 16258c2ecf20Sopenharmony_ci for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) { 16268c2ecf20Sopenharmony_ci bool is_removed, has_reset_reg, unreset_before_dump; 16278c2ecf20Sopenharmony_ci const struct dbg_block_chip *block; 16288c2ecf20Sopenharmony_ci 16298c2ecf20Sopenharmony_ci block = qed_get_dbg_block_per_chip(p_hwfn, 16308c2ecf20Sopenharmony_ci (enum block_id) 16318c2ecf20Sopenharmony_ci block_id); 16328c2ecf20Sopenharmony_ci is_removed = 16338c2ecf20Sopenharmony_ci GET_FIELD(block->flags, DBG_BLOCK_CHIP_IS_REMOVED); 16348c2ecf20Sopenharmony_ci has_reset_reg = 16358c2ecf20Sopenharmony_ci GET_FIELD(block->flags, 16368c2ecf20Sopenharmony_ci DBG_BLOCK_CHIP_HAS_RESET_REG); 16378c2ecf20Sopenharmony_ci unreset_before_dump = 16388c2ecf20Sopenharmony_ci GET_FIELD(block->flags, 16398c2ecf20Sopenharmony_ci DBG_BLOCK_CHIP_UNRESET_BEFORE_DUMP); 16408c2ecf20Sopenharmony_ci 16418c2ecf20Sopenharmony_ci if (!is_removed && has_reset_reg && unreset_before_dump) 16428c2ecf20Sopenharmony_ci reg_val[block->reset_reg_id] |= 16438c2ecf20Sopenharmony_ci BIT(block->reset_reg_bit_offset); 16448c2ecf20Sopenharmony_ci } 16458c2ecf20Sopenharmony_ci 16468c2ecf20Sopenharmony_ci /* Write reset registers */ 16478c2ecf20Sopenharmony_ci for (reset_reg_id = 0; reset_reg_id < NUM_DBG_RESET_REGS; 16488c2ecf20Sopenharmony_ci reset_reg_id++) { 16498c2ecf20Sopenharmony_ci const struct dbg_reset_reg *reset_reg; 16508c2ecf20Sopenharmony_ci u32 reset_reg_addr; 16518c2ecf20Sopenharmony_ci 16528c2ecf20Sopenharmony_ci reset_reg = qed_get_dbg_reset_reg(p_hwfn, reset_reg_id); 16538c2ecf20Sopenharmony_ci 16548c2ecf20Sopenharmony_ci if (GET_FIELD 16558c2ecf20Sopenharmony_ci (reset_reg->data, DBG_RESET_REG_IS_REMOVED)) 16568c2ecf20Sopenharmony_ci continue; 16578c2ecf20Sopenharmony_ci 16588c2ecf20Sopenharmony_ci if (reg_val[reset_reg_id]) { 16598c2ecf20Sopenharmony_ci reset_reg_addr = 16608c2ecf20Sopenharmony_ci GET_FIELD(reset_reg->data, 16618c2ecf20Sopenharmony_ci DBG_RESET_REG_ADDR); 16628c2ecf20Sopenharmony_ci qed_wr(p_hwfn, 16638c2ecf20Sopenharmony_ci p_ptt, 16648c2ecf20Sopenharmony_ci DWORDS_TO_BYTES(reset_reg_addr) + 16658c2ecf20Sopenharmony_ci RESET_REG_UNRESET_OFFSET, 16668c2ecf20Sopenharmony_ci reg_val[reset_reg_id]); 16678c2ecf20Sopenharmony_ci } 16688c2ecf20Sopenharmony_ci } 16698c2ecf20Sopenharmony_ci } 16708c2ecf20Sopenharmony_ci} 16718c2ecf20Sopenharmony_ci 16728c2ecf20Sopenharmony_ci/* Returns the attention block data of the specified block */ 16738c2ecf20Sopenharmony_cistatic const struct dbg_attn_block_type_data * 16748c2ecf20Sopenharmony_ciqed_get_block_attn_data(struct qed_hwfn *p_hwfn, 16758c2ecf20Sopenharmony_ci enum block_id block_id, enum dbg_attn_type attn_type) 16768c2ecf20Sopenharmony_ci{ 16778c2ecf20Sopenharmony_ci const struct dbg_attn_block *base_attn_block_arr = 16788c2ecf20Sopenharmony_ci (const struct dbg_attn_block *) 16798c2ecf20Sopenharmony_ci p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr; 16808c2ecf20Sopenharmony_ci 16818c2ecf20Sopenharmony_ci return &base_attn_block_arr[block_id].per_type_data[attn_type]; 16828c2ecf20Sopenharmony_ci} 16838c2ecf20Sopenharmony_ci 16848c2ecf20Sopenharmony_ci/* Returns the attention registers of the specified block */ 16858c2ecf20Sopenharmony_cistatic const struct dbg_attn_reg * 16868c2ecf20Sopenharmony_ciqed_get_block_attn_regs(struct qed_hwfn *p_hwfn, 16878c2ecf20Sopenharmony_ci enum block_id block_id, enum dbg_attn_type attn_type, 16888c2ecf20Sopenharmony_ci u8 *num_attn_regs) 16898c2ecf20Sopenharmony_ci{ 16908c2ecf20Sopenharmony_ci const struct dbg_attn_block_type_data *block_type_data = 16918c2ecf20Sopenharmony_ci qed_get_block_attn_data(p_hwfn, block_id, attn_type); 16928c2ecf20Sopenharmony_ci 16938c2ecf20Sopenharmony_ci *num_attn_regs = block_type_data->num_regs; 16948c2ecf20Sopenharmony_ci 16958c2ecf20Sopenharmony_ci return (const struct dbg_attn_reg *) 16968c2ecf20Sopenharmony_ci p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr + 16978c2ecf20Sopenharmony_ci block_type_data->regs_offset; 16988c2ecf20Sopenharmony_ci} 16998c2ecf20Sopenharmony_ci 17008c2ecf20Sopenharmony_ci/* For each block, clear the status of all parities */ 17018c2ecf20Sopenharmony_cistatic void qed_grc_clear_all_prty(struct qed_hwfn *p_hwfn, 17028c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt) 17038c2ecf20Sopenharmony_ci{ 17048c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 17058c2ecf20Sopenharmony_ci const struct dbg_attn_reg *attn_reg_arr; 17068c2ecf20Sopenharmony_ci u8 reg_idx, num_attn_regs; 17078c2ecf20Sopenharmony_ci u32 block_id; 17088c2ecf20Sopenharmony_ci 17098c2ecf20Sopenharmony_ci for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) { 17108c2ecf20Sopenharmony_ci if (dev_data->block_in_reset[block_id]) 17118c2ecf20Sopenharmony_ci continue; 17128c2ecf20Sopenharmony_ci 17138c2ecf20Sopenharmony_ci attn_reg_arr = qed_get_block_attn_regs(p_hwfn, 17148c2ecf20Sopenharmony_ci (enum block_id)block_id, 17158c2ecf20Sopenharmony_ci ATTN_TYPE_PARITY, 17168c2ecf20Sopenharmony_ci &num_attn_regs); 17178c2ecf20Sopenharmony_ci 17188c2ecf20Sopenharmony_ci for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) { 17198c2ecf20Sopenharmony_ci const struct dbg_attn_reg *reg_data = 17208c2ecf20Sopenharmony_ci &attn_reg_arr[reg_idx]; 17218c2ecf20Sopenharmony_ci u16 modes_buf_offset; 17228c2ecf20Sopenharmony_ci bool eval_mode; 17238c2ecf20Sopenharmony_ci 17248c2ecf20Sopenharmony_ci /* Check mode */ 17258c2ecf20Sopenharmony_ci eval_mode = GET_FIELD(reg_data->mode.data, 17268c2ecf20Sopenharmony_ci DBG_MODE_HDR_EVAL_MODE) > 0; 17278c2ecf20Sopenharmony_ci modes_buf_offset = 17288c2ecf20Sopenharmony_ci GET_FIELD(reg_data->mode.data, 17298c2ecf20Sopenharmony_ci DBG_MODE_HDR_MODES_BUF_OFFSET); 17308c2ecf20Sopenharmony_ci 17318c2ecf20Sopenharmony_ci /* If Mode match: clear parity status */ 17328c2ecf20Sopenharmony_ci if (!eval_mode || 17338c2ecf20Sopenharmony_ci qed_is_mode_match(p_hwfn, &modes_buf_offset)) 17348c2ecf20Sopenharmony_ci qed_rd(p_hwfn, p_ptt, 17358c2ecf20Sopenharmony_ci DWORDS_TO_BYTES(reg_data-> 17368c2ecf20Sopenharmony_ci sts_clr_address)); 17378c2ecf20Sopenharmony_ci } 17388c2ecf20Sopenharmony_ci } 17398c2ecf20Sopenharmony_ci} 17408c2ecf20Sopenharmony_ci 17418c2ecf20Sopenharmony_ci/* Dumps GRC registers section header. Returns the dumped size in dwords. 17428c2ecf20Sopenharmony_ci * the following parameters are dumped: 17438c2ecf20Sopenharmony_ci * - count: no. of dumped entries 17448c2ecf20Sopenharmony_ci * - split_type: split type 17458c2ecf20Sopenharmony_ci * - split_id: split ID (dumped only if split_id != SPLIT_TYPE_NONE) 17468c2ecf20Sopenharmony_ci * - reg_type_name: register type name (dumped only if reg_type_name != NULL) 17478c2ecf20Sopenharmony_ci */ 17488c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_regs_hdr(u32 *dump_buf, 17498c2ecf20Sopenharmony_ci bool dump, 17508c2ecf20Sopenharmony_ci u32 num_reg_entries, 17518c2ecf20Sopenharmony_ci enum init_split_types split_type, 17528c2ecf20Sopenharmony_ci u8 split_id, const char *reg_type_name) 17538c2ecf20Sopenharmony_ci{ 17548c2ecf20Sopenharmony_ci u8 num_params = 2 + 17558c2ecf20Sopenharmony_ci (split_type != SPLIT_TYPE_NONE ? 1 : 0) + (reg_type_name ? 1 : 0); 17568c2ecf20Sopenharmony_ci u32 offset = 0; 17578c2ecf20Sopenharmony_ci 17588c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 17598c2ecf20Sopenharmony_ci dump, "grc_regs", num_params); 17608c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 17618c2ecf20Sopenharmony_ci dump, "count", num_reg_entries); 17628c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 17638c2ecf20Sopenharmony_ci dump, "split", 17648c2ecf20Sopenharmony_ci s_split_type_defs[split_type].name); 17658c2ecf20Sopenharmony_ci if (split_type != SPLIT_TYPE_NONE) 17668c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 17678c2ecf20Sopenharmony_ci dump, "id", split_id); 17688c2ecf20Sopenharmony_ci if (reg_type_name) 17698c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 17708c2ecf20Sopenharmony_ci dump, "type", reg_type_name); 17718c2ecf20Sopenharmony_ci 17728c2ecf20Sopenharmony_ci return offset; 17738c2ecf20Sopenharmony_ci} 17748c2ecf20Sopenharmony_ci 17758c2ecf20Sopenharmony_ci/* Reads the specified registers into the specified buffer. 17768c2ecf20Sopenharmony_ci * The addr and len arguments are specified in dwords. 17778c2ecf20Sopenharmony_ci */ 17788c2ecf20Sopenharmony_civoid qed_read_regs(struct qed_hwfn *p_hwfn, 17798c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, u32 *buf, u32 addr, u32 len) 17808c2ecf20Sopenharmony_ci{ 17818c2ecf20Sopenharmony_ci u32 i; 17828c2ecf20Sopenharmony_ci 17838c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) 17848c2ecf20Sopenharmony_ci buf[i] = qed_rd(p_hwfn, p_ptt, DWORDS_TO_BYTES(addr + i)); 17858c2ecf20Sopenharmony_ci} 17868c2ecf20Sopenharmony_ci 17878c2ecf20Sopenharmony_ci/* Dumps the GRC registers in the specified address range. 17888c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 17898c2ecf20Sopenharmony_ci * The addr and len arguments are specified in dwords. 17908c2ecf20Sopenharmony_ci */ 17918c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn, 17928c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 17938c2ecf20Sopenharmony_ci u32 *dump_buf, 17948c2ecf20Sopenharmony_ci bool dump, u32 addr, u32 len, bool wide_bus, 17958c2ecf20Sopenharmony_ci enum init_split_types split_type, 17968c2ecf20Sopenharmony_ci u8 split_id) 17978c2ecf20Sopenharmony_ci{ 17988c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 17998c2ecf20Sopenharmony_ci u8 port_id = 0, pf_id = 0, vf_id = 0; 18008c2ecf20Sopenharmony_ci bool read_using_dmae = false; 18018c2ecf20Sopenharmony_ci u32 thresh; 18028c2ecf20Sopenharmony_ci u16 fid; 18038c2ecf20Sopenharmony_ci 18048c2ecf20Sopenharmony_ci if (!dump) 18058c2ecf20Sopenharmony_ci return len; 18068c2ecf20Sopenharmony_ci 18078c2ecf20Sopenharmony_ci switch (split_type) { 18088c2ecf20Sopenharmony_ci case SPLIT_TYPE_PORT: 18098c2ecf20Sopenharmony_ci port_id = split_id; 18108c2ecf20Sopenharmony_ci break; 18118c2ecf20Sopenharmony_ci case SPLIT_TYPE_PF: 18128c2ecf20Sopenharmony_ci pf_id = split_id; 18138c2ecf20Sopenharmony_ci break; 18148c2ecf20Sopenharmony_ci case SPLIT_TYPE_PORT_PF: 18158c2ecf20Sopenharmony_ci port_id = split_id / dev_data->num_pfs_per_port; 18168c2ecf20Sopenharmony_ci pf_id = port_id + dev_data->num_ports * 18178c2ecf20Sopenharmony_ci (split_id % dev_data->num_pfs_per_port); 18188c2ecf20Sopenharmony_ci break; 18198c2ecf20Sopenharmony_ci case SPLIT_TYPE_VF: 18208c2ecf20Sopenharmony_ci vf_id = split_id; 18218c2ecf20Sopenharmony_ci break; 18228c2ecf20Sopenharmony_ci default: 18238c2ecf20Sopenharmony_ci break; 18248c2ecf20Sopenharmony_ci } 18258c2ecf20Sopenharmony_ci 18268c2ecf20Sopenharmony_ci /* Try reading using DMAE */ 18278c2ecf20Sopenharmony_ci if (dev_data->use_dmae && split_type != SPLIT_TYPE_VF && 18288c2ecf20Sopenharmony_ci (len >= s_hw_type_defs[dev_data->hw_type].dmae_thresh || 18298c2ecf20Sopenharmony_ci (PROTECT_WIDE_BUS && wide_bus))) { 18308c2ecf20Sopenharmony_ci struct qed_dmae_params dmae_params; 18318c2ecf20Sopenharmony_ci 18328c2ecf20Sopenharmony_ci /* Set DMAE params */ 18338c2ecf20Sopenharmony_ci memset(&dmae_params, 0, sizeof(dmae_params)); 18348c2ecf20Sopenharmony_ci SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_COMPLETION_DST, 1); 18358c2ecf20Sopenharmony_ci switch (split_type) { 18368c2ecf20Sopenharmony_ci case SPLIT_TYPE_PORT: 18378c2ecf20Sopenharmony_ci SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_PORT_VALID, 18388c2ecf20Sopenharmony_ci 1); 18398c2ecf20Sopenharmony_ci dmae_params.port_id = port_id; 18408c2ecf20Sopenharmony_ci break; 18418c2ecf20Sopenharmony_ci case SPLIT_TYPE_PF: 18428c2ecf20Sopenharmony_ci SET_FIELD(dmae_params.flags, 18438c2ecf20Sopenharmony_ci QED_DMAE_PARAMS_SRC_PF_VALID, 1); 18448c2ecf20Sopenharmony_ci dmae_params.src_pfid = pf_id; 18458c2ecf20Sopenharmony_ci break; 18468c2ecf20Sopenharmony_ci case SPLIT_TYPE_PORT_PF: 18478c2ecf20Sopenharmony_ci SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_PORT_VALID, 18488c2ecf20Sopenharmony_ci 1); 18498c2ecf20Sopenharmony_ci SET_FIELD(dmae_params.flags, 18508c2ecf20Sopenharmony_ci QED_DMAE_PARAMS_SRC_PF_VALID, 1); 18518c2ecf20Sopenharmony_ci dmae_params.port_id = port_id; 18528c2ecf20Sopenharmony_ci dmae_params.src_pfid = pf_id; 18538c2ecf20Sopenharmony_ci break; 18548c2ecf20Sopenharmony_ci default: 18558c2ecf20Sopenharmony_ci break; 18568c2ecf20Sopenharmony_ci } 18578c2ecf20Sopenharmony_ci 18588c2ecf20Sopenharmony_ci /* Execute DMAE command */ 18598c2ecf20Sopenharmony_ci read_using_dmae = !qed_dmae_grc2host(p_hwfn, 18608c2ecf20Sopenharmony_ci p_ptt, 18618c2ecf20Sopenharmony_ci DWORDS_TO_BYTES(addr), 18628c2ecf20Sopenharmony_ci (u64)(uintptr_t)(dump_buf), 18638c2ecf20Sopenharmony_ci len, &dmae_params); 18648c2ecf20Sopenharmony_ci if (!read_using_dmae) { 18658c2ecf20Sopenharmony_ci dev_data->use_dmae = 0; 18668c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, 18678c2ecf20Sopenharmony_ci QED_MSG_DEBUG, 18688c2ecf20Sopenharmony_ci "Failed reading from chip using DMAE, using GRC instead\n"); 18698c2ecf20Sopenharmony_ci } 18708c2ecf20Sopenharmony_ci } 18718c2ecf20Sopenharmony_ci 18728c2ecf20Sopenharmony_ci if (read_using_dmae) 18738c2ecf20Sopenharmony_ci goto print_log; 18748c2ecf20Sopenharmony_ci 18758c2ecf20Sopenharmony_ci /* If not read using DMAE, read using GRC */ 18768c2ecf20Sopenharmony_ci 18778c2ecf20Sopenharmony_ci /* Set pretend */ 18788c2ecf20Sopenharmony_ci if (split_type != dev_data->pretend.split_type || 18798c2ecf20Sopenharmony_ci split_id != dev_data->pretend.split_id) { 18808c2ecf20Sopenharmony_ci switch (split_type) { 18818c2ecf20Sopenharmony_ci case SPLIT_TYPE_PORT: 18828c2ecf20Sopenharmony_ci qed_port_pretend(p_hwfn, p_ptt, port_id); 18838c2ecf20Sopenharmony_ci break; 18848c2ecf20Sopenharmony_ci case SPLIT_TYPE_PF: 18858c2ecf20Sopenharmony_ci fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID, 18868c2ecf20Sopenharmony_ci pf_id); 18878c2ecf20Sopenharmony_ci qed_fid_pretend(p_hwfn, p_ptt, fid); 18888c2ecf20Sopenharmony_ci break; 18898c2ecf20Sopenharmony_ci case SPLIT_TYPE_PORT_PF: 18908c2ecf20Sopenharmony_ci fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID, 18918c2ecf20Sopenharmony_ci pf_id); 18928c2ecf20Sopenharmony_ci qed_port_fid_pretend(p_hwfn, p_ptt, port_id, fid); 18938c2ecf20Sopenharmony_ci break; 18948c2ecf20Sopenharmony_ci case SPLIT_TYPE_VF: 18958c2ecf20Sopenharmony_ci fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFVALID, 1) 18968c2ecf20Sopenharmony_ci | FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFID, 18978c2ecf20Sopenharmony_ci vf_id); 18988c2ecf20Sopenharmony_ci qed_fid_pretend(p_hwfn, p_ptt, fid); 18998c2ecf20Sopenharmony_ci break; 19008c2ecf20Sopenharmony_ci default: 19018c2ecf20Sopenharmony_ci break; 19028c2ecf20Sopenharmony_ci } 19038c2ecf20Sopenharmony_ci 19048c2ecf20Sopenharmony_ci dev_data->pretend.split_type = (u8)split_type; 19058c2ecf20Sopenharmony_ci dev_data->pretend.split_id = split_id; 19068c2ecf20Sopenharmony_ci } 19078c2ecf20Sopenharmony_ci 19088c2ecf20Sopenharmony_ci /* Read registers using GRC */ 19098c2ecf20Sopenharmony_ci qed_read_regs(p_hwfn, p_ptt, dump_buf, addr, len); 19108c2ecf20Sopenharmony_ci 19118c2ecf20Sopenharmony_ciprint_log: 19128c2ecf20Sopenharmony_ci /* Print log */ 19138c2ecf20Sopenharmony_ci dev_data->num_regs_read += len; 19148c2ecf20Sopenharmony_ci thresh = s_hw_type_defs[dev_data->hw_type].log_thresh; 19158c2ecf20Sopenharmony_ci if ((dev_data->num_regs_read / thresh) > 19168c2ecf20Sopenharmony_ci ((dev_data->num_regs_read - len) / thresh)) 19178c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, 19188c2ecf20Sopenharmony_ci QED_MSG_DEBUG, 19198c2ecf20Sopenharmony_ci "Dumped %d registers...\n", dev_data->num_regs_read); 19208c2ecf20Sopenharmony_ci 19218c2ecf20Sopenharmony_ci return len; 19228c2ecf20Sopenharmony_ci} 19238c2ecf20Sopenharmony_ci 19248c2ecf20Sopenharmony_ci/* Dumps GRC registers sequence header. Returns the dumped size in dwords. 19258c2ecf20Sopenharmony_ci * The addr and len arguments are specified in dwords. 19268c2ecf20Sopenharmony_ci */ 19278c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_reg_entry_hdr(u32 *dump_buf, 19288c2ecf20Sopenharmony_ci bool dump, u32 addr, u32 len) 19298c2ecf20Sopenharmony_ci{ 19308c2ecf20Sopenharmony_ci if (dump) 19318c2ecf20Sopenharmony_ci *dump_buf = addr | (len << REG_DUMP_LEN_SHIFT); 19328c2ecf20Sopenharmony_ci 19338c2ecf20Sopenharmony_ci return 1; 19348c2ecf20Sopenharmony_ci} 19358c2ecf20Sopenharmony_ci 19368c2ecf20Sopenharmony_ci/* Dumps GRC registers sequence. Returns the dumped size in dwords. 19378c2ecf20Sopenharmony_ci * The addr and len arguments are specified in dwords. 19388c2ecf20Sopenharmony_ci */ 19398c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_reg_entry(struct qed_hwfn *p_hwfn, 19408c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 19418c2ecf20Sopenharmony_ci u32 *dump_buf, 19428c2ecf20Sopenharmony_ci bool dump, u32 addr, u32 len, bool wide_bus, 19438c2ecf20Sopenharmony_ci enum init_split_types split_type, u8 split_id) 19448c2ecf20Sopenharmony_ci{ 19458c2ecf20Sopenharmony_ci u32 offset = 0; 19468c2ecf20Sopenharmony_ci 19478c2ecf20Sopenharmony_ci offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, len); 19488c2ecf20Sopenharmony_ci offset += qed_grc_dump_addr_range(p_hwfn, 19498c2ecf20Sopenharmony_ci p_ptt, 19508c2ecf20Sopenharmony_ci dump_buf + offset, 19518c2ecf20Sopenharmony_ci dump, addr, len, wide_bus, 19528c2ecf20Sopenharmony_ci split_type, split_id); 19538c2ecf20Sopenharmony_ci 19548c2ecf20Sopenharmony_ci return offset; 19558c2ecf20Sopenharmony_ci} 19568c2ecf20Sopenharmony_ci 19578c2ecf20Sopenharmony_ci/* Dumps GRC registers sequence with skip cycle. 19588c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 19598c2ecf20Sopenharmony_ci * - addr: start GRC address in dwords 19608c2ecf20Sopenharmony_ci * - total_len: total no. of dwords to dump 19618c2ecf20Sopenharmony_ci * - read_len: no. consecutive dwords to read 19628c2ecf20Sopenharmony_ci * - skip_len: no. of dwords to skip (and fill with zeros) 19638c2ecf20Sopenharmony_ci */ 19648c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_reg_entry_skip(struct qed_hwfn *p_hwfn, 19658c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 19668c2ecf20Sopenharmony_ci u32 *dump_buf, 19678c2ecf20Sopenharmony_ci bool dump, 19688c2ecf20Sopenharmony_ci u32 addr, 19698c2ecf20Sopenharmony_ci u32 total_len, 19708c2ecf20Sopenharmony_ci u32 read_len, u32 skip_len) 19718c2ecf20Sopenharmony_ci{ 19728c2ecf20Sopenharmony_ci u32 offset = 0, reg_offset = 0; 19738c2ecf20Sopenharmony_ci 19748c2ecf20Sopenharmony_ci offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, total_len); 19758c2ecf20Sopenharmony_ci 19768c2ecf20Sopenharmony_ci if (!dump) 19778c2ecf20Sopenharmony_ci return offset + total_len; 19788c2ecf20Sopenharmony_ci 19798c2ecf20Sopenharmony_ci while (reg_offset < total_len) { 19808c2ecf20Sopenharmony_ci u32 curr_len = min_t(u32, read_len, total_len - reg_offset); 19818c2ecf20Sopenharmony_ci 19828c2ecf20Sopenharmony_ci offset += qed_grc_dump_addr_range(p_hwfn, 19838c2ecf20Sopenharmony_ci p_ptt, 19848c2ecf20Sopenharmony_ci dump_buf + offset, 19858c2ecf20Sopenharmony_ci dump, addr, curr_len, false, 19868c2ecf20Sopenharmony_ci SPLIT_TYPE_NONE, 0); 19878c2ecf20Sopenharmony_ci reg_offset += curr_len; 19888c2ecf20Sopenharmony_ci addr += curr_len; 19898c2ecf20Sopenharmony_ci 19908c2ecf20Sopenharmony_ci if (reg_offset < total_len) { 19918c2ecf20Sopenharmony_ci curr_len = min_t(u32, skip_len, total_len - skip_len); 19928c2ecf20Sopenharmony_ci memset(dump_buf + offset, 0, DWORDS_TO_BYTES(curr_len)); 19938c2ecf20Sopenharmony_ci offset += curr_len; 19948c2ecf20Sopenharmony_ci reg_offset += curr_len; 19958c2ecf20Sopenharmony_ci addr += curr_len; 19968c2ecf20Sopenharmony_ci } 19978c2ecf20Sopenharmony_ci } 19988c2ecf20Sopenharmony_ci 19998c2ecf20Sopenharmony_ci return offset; 20008c2ecf20Sopenharmony_ci} 20018c2ecf20Sopenharmony_ci 20028c2ecf20Sopenharmony_ci/* Dumps GRC registers entries. Returns the dumped size in dwords. */ 20038c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_regs_entries(struct qed_hwfn *p_hwfn, 20048c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 20058c2ecf20Sopenharmony_ci struct virt_mem_desc input_regs_arr, 20068c2ecf20Sopenharmony_ci u32 *dump_buf, 20078c2ecf20Sopenharmony_ci bool dump, 20088c2ecf20Sopenharmony_ci enum init_split_types split_type, 20098c2ecf20Sopenharmony_ci u8 split_id, 20108c2ecf20Sopenharmony_ci bool block_enable[MAX_BLOCK_ID], 20118c2ecf20Sopenharmony_ci u32 *num_dumped_reg_entries) 20128c2ecf20Sopenharmony_ci{ 20138c2ecf20Sopenharmony_ci u32 i, offset = 0, input_offset = 0; 20148c2ecf20Sopenharmony_ci bool mode_match = true; 20158c2ecf20Sopenharmony_ci 20168c2ecf20Sopenharmony_ci *num_dumped_reg_entries = 0; 20178c2ecf20Sopenharmony_ci 20188c2ecf20Sopenharmony_ci while (input_offset < BYTES_TO_DWORDS(input_regs_arr.size)) { 20198c2ecf20Sopenharmony_ci const struct dbg_dump_cond_hdr *cond_hdr = 20208c2ecf20Sopenharmony_ci (const struct dbg_dump_cond_hdr *) 20218c2ecf20Sopenharmony_ci input_regs_arr.ptr + input_offset++; 20228c2ecf20Sopenharmony_ci u16 modes_buf_offset; 20238c2ecf20Sopenharmony_ci bool eval_mode; 20248c2ecf20Sopenharmony_ci 20258c2ecf20Sopenharmony_ci /* Check mode/block */ 20268c2ecf20Sopenharmony_ci eval_mode = GET_FIELD(cond_hdr->mode.data, 20278c2ecf20Sopenharmony_ci DBG_MODE_HDR_EVAL_MODE) > 0; 20288c2ecf20Sopenharmony_ci if (eval_mode) { 20298c2ecf20Sopenharmony_ci modes_buf_offset = 20308c2ecf20Sopenharmony_ci GET_FIELD(cond_hdr->mode.data, 20318c2ecf20Sopenharmony_ci DBG_MODE_HDR_MODES_BUF_OFFSET); 20328c2ecf20Sopenharmony_ci mode_match = qed_is_mode_match(p_hwfn, 20338c2ecf20Sopenharmony_ci &modes_buf_offset); 20348c2ecf20Sopenharmony_ci } 20358c2ecf20Sopenharmony_ci 20368c2ecf20Sopenharmony_ci if (!mode_match || !block_enable[cond_hdr->block_id]) { 20378c2ecf20Sopenharmony_ci input_offset += cond_hdr->data_size; 20388c2ecf20Sopenharmony_ci continue; 20398c2ecf20Sopenharmony_ci } 20408c2ecf20Sopenharmony_ci 20418c2ecf20Sopenharmony_ci for (i = 0; i < cond_hdr->data_size; i++, input_offset++) { 20428c2ecf20Sopenharmony_ci const struct dbg_dump_reg *reg = 20438c2ecf20Sopenharmony_ci (const struct dbg_dump_reg *) 20448c2ecf20Sopenharmony_ci input_regs_arr.ptr + input_offset; 20458c2ecf20Sopenharmony_ci u32 addr, len; 20468c2ecf20Sopenharmony_ci bool wide_bus; 20478c2ecf20Sopenharmony_ci 20488c2ecf20Sopenharmony_ci addr = GET_FIELD(reg->data, DBG_DUMP_REG_ADDRESS); 20498c2ecf20Sopenharmony_ci len = GET_FIELD(reg->data, DBG_DUMP_REG_LENGTH); 20508c2ecf20Sopenharmony_ci wide_bus = GET_FIELD(reg->data, DBG_DUMP_REG_WIDE_BUS); 20518c2ecf20Sopenharmony_ci offset += qed_grc_dump_reg_entry(p_hwfn, 20528c2ecf20Sopenharmony_ci p_ptt, 20538c2ecf20Sopenharmony_ci dump_buf + offset, 20548c2ecf20Sopenharmony_ci dump, 20558c2ecf20Sopenharmony_ci addr, 20568c2ecf20Sopenharmony_ci len, 20578c2ecf20Sopenharmony_ci wide_bus, 20588c2ecf20Sopenharmony_ci split_type, split_id); 20598c2ecf20Sopenharmony_ci (*num_dumped_reg_entries)++; 20608c2ecf20Sopenharmony_ci } 20618c2ecf20Sopenharmony_ci } 20628c2ecf20Sopenharmony_ci 20638c2ecf20Sopenharmony_ci return offset; 20648c2ecf20Sopenharmony_ci} 20658c2ecf20Sopenharmony_ci 20668c2ecf20Sopenharmony_ci/* Dumps GRC registers entries. Returns the dumped size in dwords. */ 20678c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_split_data(struct qed_hwfn *p_hwfn, 20688c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 20698c2ecf20Sopenharmony_ci struct virt_mem_desc input_regs_arr, 20708c2ecf20Sopenharmony_ci u32 *dump_buf, 20718c2ecf20Sopenharmony_ci bool dump, 20728c2ecf20Sopenharmony_ci bool block_enable[MAX_BLOCK_ID], 20738c2ecf20Sopenharmony_ci enum init_split_types split_type, 20748c2ecf20Sopenharmony_ci u8 split_id, const char *reg_type_name) 20758c2ecf20Sopenharmony_ci{ 20768c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 20778c2ecf20Sopenharmony_ci enum init_split_types hdr_split_type = split_type; 20788c2ecf20Sopenharmony_ci u32 num_dumped_reg_entries, offset; 20798c2ecf20Sopenharmony_ci u8 hdr_split_id = split_id; 20808c2ecf20Sopenharmony_ci 20818c2ecf20Sopenharmony_ci /* In PORT_PF split type, print a port split header */ 20828c2ecf20Sopenharmony_ci if (split_type == SPLIT_TYPE_PORT_PF) { 20838c2ecf20Sopenharmony_ci hdr_split_type = SPLIT_TYPE_PORT; 20848c2ecf20Sopenharmony_ci hdr_split_id = split_id / dev_data->num_pfs_per_port; 20858c2ecf20Sopenharmony_ci } 20868c2ecf20Sopenharmony_ci 20878c2ecf20Sopenharmony_ci /* Calculate register dump header size (and skip it for now) */ 20888c2ecf20Sopenharmony_ci offset = qed_grc_dump_regs_hdr(dump_buf, 20898c2ecf20Sopenharmony_ci false, 20908c2ecf20Sopenharmony_ci 0, 20918c2ecf20Sopenharmony_ci hdr_split_type, 20928c2ecf20Sopenharmony_ci hdr_split_id, reg_type_name); 20938c2ecf20Sopenharmony_ci 20948c2ecf20Sopenharmony_ci /* Dump registers */ 20958c2ecf20Sopenharmony_ci offset += qed_grc_dump_regs_entries(p_hwfn, 20968c2ecf20Sopenharmony_ci p_ptt, 20978c2ecf20Sopenharmony_ci input_regs_arr, 20988c2ecf20Sopenharmony_ci dump_buf + offset, 20998c2ecf20Sopenharmony_ci dump, 21008c2ecf20Sopenharmony_ci split_type, 21018c2ecf20Sopenharmony_ci split_id, 21028c2ecf20Sopenharmony_ci block_enable, 21038c2ecf20Sopenharmony_ci &num_dumped_reg_entries); 21048c2ecf20Sopenharmony_ci 21058c2ecf20Sopenharmony_ci /* Write register dump header */ 21068c2ecf20Sopenharmony_ci if (dump && num_dumped_reg_entries > 0) 21078c2ecf20Sopenharmony_ci qed_grc_dump_regs_hdr(dump_buf, 21088c2ecf20Sopenharmony_ci dump, 21098c2ecf20Sopenharmony_ci num_dumped_reg_entries, 21108c2ecf20Sopenharmony_ci hdr_split_type, 21118c2ecf20Sopenharmony_ci hdr_split_id, reg_type_name); 21128c2ecf20Sopenharmony_ci 21138c2ecf20Sopenharmony_ci return num_dumped_reg_entries > 0 ? offset : 0; 21148c2ecf20Sopenharmony_ci} 21158c2ecf20Sopenharmony_ci 21168c2ecf20Sopenharmony_ci/* Dumps registers according to the input registers array. Returns the dumped 21178c2ecf20Sopenharmony_ci * size in dwords. 21188c2ecf20Sopenharmony_ci */ 21198c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_registers(struct qed_hwfn *p_hwfn, 21208c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 21218c2ecf20Sopenharmony_ci u32 *dump_buf, 21228c2ecf20Sopenharmony_ci bool dump, 21238c2ecf20Sopenharmony_ci bool block_enable[MAX_BLOCK_ID], 21248c2ecf20Sopenharmony_ci const char *reg_type_name) 21258c2ecf20Sopenharmony_ci{ 21268c2ecf20Sopenharmony_ci struct virt_mem_desc *dbg_buf = 21278c2ecf20Sopenharmony_ci &p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG]; 21288c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 21298c2ecf20Sopenharmony_ci u32 offset = 0, input_offset = 0; 21308c2ecf20Sopenharmony_ci 21318c2ecf20Sopenharmony_ci while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) { 21328c2ecf20Sopenharmony_ci const struct dbg_dump_split_hdr *split_hdr; 21338c2ecf20Sopenharmony_ci struct virt_mem_desc curr_input_regs_arr; 21348c2ecf20Sopenharmony_ci enum init_split_types split_type; 21358c2ecf20Sopenharmony_ci u16 split_count = 0; 21368c2ecf20Sopenharmony_ci u32 split_data_size; 21378c2ecf20Sopenharmony_ci u8 split_id; 21388c2ecf20Sopenharmony_ci 21398c2ecf20Sopenharmony_ci split_hdr = 21408c2ecf20Sopenharmony_ci (const struct dbg_dump_split_hdr *) 21418c2ecf20Sopenharmony_ci dbg_buf->ptr + input_offset++; 21428c2ecf20Sopenharmony_ci split_type = 21438c2ecf20Sopenharmony_ci GET_FIELD(split_hdr->hdr, 21448c2ecf20Sopenharmony_ci DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID); 21458c2ecf20Sopenharmony_ci split_data_size = GET_FIELD(split_hdr->hdr, 21468c2ecf20Sopenharmony_ci DBG_DUMP_SPLIT_HDR_DATA_SIZE); 21478c2ecf20Sopenharmony_ci curr_input_regs_arr.ptr = 21488c2ecf20Sopenharmony_ci (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr + 21498c2ecf20Sopenharmony_ci input_offset; 21508c2ecf20Sopenharmony_ci curr_input_regs_arr.size = DWORDS_TO_BYTES(split_data_size); 21518c2ecf20Sopenharmony_ci 21528c2ecf20Sopenharmony_ci switch (split_type) { 21538c2ecf20Sopenharmony_ci case SPLIT_TYPE_NONE: 21548c2ecf20Sopenharmony_ci split_count = 1; 21558c2ecf20Sopenharmony_ci break; 21568c2ecf20Sopenharmony_ci case SPLIT_TYPE_PORT: 21578c2ecf20Sopenharmony_ci split_count = dev_data->num_ports; 21588c2ecf20Sopenharmony_ci break; 21598c2ecf20Sopenharmony_ci case SPLIT_TYPE_PF: 21608c2ecf20Sopenharmony_ci case SPLIT_TYPE_PORT_PF: 21618c2ecf20Sopenharmony_ci split_count = dev_data->num_ports * 21628c2ecf20Sopenharmony_ci dev_data->num_pfs_per_port; 21638c2ecf20Sopenharmony_ci break; 21648c2ecf20Sopenharmony_ci case SPLIT_TYPE_VF: 21658c2ecf20Sopenharmony_ci split_count = dev_data->num_vfs; 21668c2ecf20Sopenharmony_ci break; 21678c2ecf20Sopenharmony_ci default: 21688c2ecf20Sopenharmony_ci return 0; 21698c2ecf20Sopenharmony_ci } 21708c2ecf20Sopenharmony_ci 21718c2ecf20Sopenharmony_ci for (split_id = 0; split_id < split_count; split_id++) 21728c2ecf20Sopenharmony_ci offset += qed_grc_dump_split_data(p_hwfn, p_ptt, 21738c2ecf20Sopenharmony_ci curr_input_regs_arr, 21748c2ecf20Sopenharmony_ci dump_buf + offset, 21758c2ecf20Sopenharmony_ci dump, block_enable, 21768c2ecf20Sopenharmony_ci split_type, 21778c2ecf20Sopenharmony_ci split_id, 21788c2ecf20Sopenharmony_ci reg_type_name); 21798c2ecf20Sopenharmony_ci 21808c2ecf20Sopenharmony_ci input_offset += split_data_size; 21818c2ecf20Sopenharmony_ci } 21828c2ecf20Sopenharmony_ci 21838c2ecf20Sopenharmony_ci /* Cancel pretends (pretend to original PF) */ 21848c2ecf20Sopenharmony_ci if (dump) { 21858c2ecf20Sopenharmony_ci qed_fid_pretend(p_hwfn, p_ptt, 21868c2ecf20Sopenharmony_ci FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID, 21878c2ecf20Sopenharmony_ci p_hwfn->rel_pf_id)); 21888c2ecf20Sopenharmony_ci dev_data->pretend.split_type = SPLIT_TYPE_NONE; 21898c2ecf20Sopenharmony_ci dev_data->pretend.split_id = 0; 21908c2ecf20Sopenharmony_ci } 21918c2ecf20Sopenharmony_ci 21928c2ecf20Sopenharmony_ci return offset; 21938c2ecf20Sopenharmony_ci} 21948c2ecf20Sopenharmony_ci 21958c2ecf20Sopenharmony_ci/* Dump reset registers. Returns the dumped size in dwords. */ 21968c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_reset_regs(struct qed_hwfn *p_hwfn, 21978c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 21988c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump) 21998c2ecf20Sopenharmony_ci{ 22008c2ecf20Sopenharmony_ci u32 offset = 0, num_regs = 0; 22018c2ecf20Sopenharmony_ci u8 reset_reg_id; 22028c2ecf20Sopenharmony_ci 22038c2ecf20Sopenharmony_ci /* Calculate header size */ 22048c2ecf20Sopenharmony_ci offset += qed_grc_dump_regs_hdr(dump_buf, 22058c2ecf20Sopenharmony_ci false, 22068c2ecf20Sopenharmony_ci 0, SPLIT_TYPE_NONE, 0, "RESET_REGS"); 22078c2ecf20Sopenharmony_ci 22088c2ecf20Sopenharmony_ci /* Write reset registers */ 22098c2ecf20Sopenharmony_ci for (reset_reg_id = 0; reset_reg_id < NUM_DBG_RESET_REGS; 22108c2ecf20Sopenharmony_ci reset_reg_id++) { 22118c2ecf20Sopenharmony_ci const struct dbg_reset_reg *reset_reg; 22128c2ecf20Sopenharmony_ci u32 reset_reg_addr; 22138c2ecf20Sopenharmony_ci 22148c2ecf20Sopenharmony_ci reset_reg = qed_get_dbg_reset_reg(p_hwfn, reset_reg_id); 22158c2ecf20Sopenharmony_ci 22168c2ecf20Sopenharmony_ci if (GET_FIELD(reset_reg->data, DBG_RESET_REG_IS_REMOVED)) 22178c2ecf20Sopenharmony_ci continue; 22188c2ecf20Sopenharmony_ci 22198c2ecf20Sopenharmony_ci reset_reg_addr = GET_FIELD(reset_reg->data, DBG_RESET_REG_ADDR); 22208c2ecf20Sopenharmony_ci offset += qed_grc_dump_reg_entry(p_hwfn, 22218c2ecf20Sopenharmony_ci p_ptt, 22228c2ecf20Sopenharmony_ci dump_buf + offset, 22238c2ecf20Sopenharmony_ci dump, 22248c2ecf20Sopenharmony_ci reset_reg_addr, 22258c2ecf20Sopenharmony_ci 1, false, SPLIT_TYPE_NONE, 0); 22268c2ecf20Sopenharmony_ci num_regs++; 22278c2ecf20Sopenharmony_ci } 22288c2ecf20Sopenharmony_ci 22298c2ecf20Sopenharmony_ci /* Write header */ 22308c2ecf20Sopenharmony_ci if (dump) 22318c2ecf20Sopenharmony_ci qed_grc_dump_regs_hdr(dump_buf, 22328c2ecf20Sopenharmony_ci true, num_regs, SPLIT_TYPE_NONE, 22338c2ecf20Sopenharmony_ci 0, "RESET_REGS"); 22348c2ecf20Sopenharmony_ci 22358c2ecf20Sopenharmony_ci return offset; 22368c2ecf20Sopenharmony_ci} 22378c2ecf20Sopenharmony_ci 22388c2ecf20Sopenharmony_ci/* Dump registers that are modified during GRC Dump and therefore must be 22398c2ecf20Sopenharmony_ci * dumped first. Returns the dumped size in dwords. 22408c2ecf20Sopenharmony_ci */ 22418c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_modified_regs(struct qed_hwfn *p_hwfn, 22428c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 22438c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump) 22448c2ecf20Sopenharmony_ci{ 22458c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 22468c2ecf20Sopenharmony_ci u32 block_id, offset = 0, stall_regs_offset; 22478c2ecf20Sopenharmony_ci const struct dbg_attn_reg *attn_reg_arr; 22488c2ecf20Sopenharmony_ci u8 storm_id, reg_idx, num_attn_regs; 22498c2ecf20Sopenharmony_ci u32 num_reg_entries = 0; 22508c2ecf20Sopenharmony_ci 22518c2ecf20Sopenharmony_ci /* Write empty header for attention registers */ 22528c2ecf20Sopenharmony_ci offset += qed_grc_dump_regs_hdr(dump_buf, 22538c2ecf20Sopenharmony_ci false, 22548c2ecf20Sopenharmony_ci 0, SPLIT_TYPE_NONE, 0, "ATTN_REGS"); 22558c2ecf20Sopenharmony_ci 22568c2ecf20Sopenharmony_ci /* Write parity registers */ 22578c2ecf20Sopenharmony_ci for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) { 22588c2ecf20Sopenharmony_ci if (dev_data->block_in_reset[block_id] && dump) 22598c2ecf20Sopenharmony_ci continue; 22608c2ecf20Sopenharmony_ci 22618c2ecf20Sopenharmony_ci attn_reg_arr = qed_get_block_attn_regs(p_hwfn, 22628c2ecf20Sopenharmony_ci (enum block_id)block_id, 22638c2ecf20Sopenharmony_ci ATTN_TYPE_PARITY, 22648c2ecf20Sopenharmony_ci &num_attn_regs); 22658c2ecf20Sopenharmony_ci 22668c2ecf20Sopenharmony_ci for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) { 22678c2ecf20Sopenharmony_ci const struct dbg_attn_reg *reg_data = 22688c2ecf20Sopenharmony_ci &attn_reg_arr[reg_idx]; 22698c2ecf20Sopenharmony_ci u16 modes_buf_offset; 22708c2ecf20Sopenharmony_ci bool eval_mode; 22718c2ecf20Sopenharmony_ci u32 addr; 22728c2ecf20Sopenharmony_ci 22738c2ecf20Sopenharmony_ci /* Check mode */ 22748c2ecf20Sopenharmony_ci eval_mode = GET_FIELD(reg_data->mode.data, 22758c2ecf20Sopenharmony_ci DBG_MODE_HDR_EVAL_MODE) > 0; 22768c2ecf20Sopenharmony_ci modes_buf_offset = 22778c2ecf20Sopenharmony_ci GET_FIELD(reg_data->mode.data, 22788c2ecf20Sopenharmony_ci DBG_MODE_HDR_MODES_BUF_OFFSET); 22798c2ecf20Sopenharmony_ci if (eval_mode && 22808c2ecf20Sopenharmony_ci !qed_is_mode_match(p_hwfn, &modes_buf_offset)) 22818c2ecf20Sopenharmony_ci continue; 22828c2ecf20Sopenharmony_ci 22838c2ecf20Sopenharmony_ci /* Mode match: read & dump registers */ 22848c2ecf20Sopenharmony_ci addr = reg_data->mask_address; 22858c2ecf20Sopenharmony_ci offset += qed_grc_dump_reg_entry(p_hwfn, 22868c2ecf20Sopenharmony_ci p_ptt, 22878c2ecf20Sopenharmony_ci dump_buf + offset, 22888c2ecf20Sopenharmony_ci dump, 22898c2ecf20Sopenharmony_ci addr, 22908c2ecf20Sopenharmony_ci 1, false, 22918c2ecf20Sopenharmony_ci SPLIT_TYPE_NONE, 0); 22928c2ecf20Sopenharmony_ci addr = GET_FIELD(reg_data->data, 22938c2ecf20Sopenharmony_ci DBG_ATTN_REG_STS_ADDRESS); 22948c2ecf20Sopenharmony_ci offset += qed_grc_dump_reg_entry(p_hwfn, 22958c2ecf20Sopenharmony_ci p_ptt, 22968c2ecf20Sopenharmony_ci dump_buf + offset, 22978c2ecf20Sopenharmony_ci dump, 22988c2ecf20Sopenharmony_ci addr, 22998c2ecf20Sopenharmony_ci 1, false, 23008c2ecf20Sopenharmony_ci SPLIT_TYPE_NONE, 0); 23018c2ecf20Sopenharmony_ci num_reg_entries += 2; 23028c2ecf20Sopenharmony_ci } 23038c2ecf20Sopenharmony_ci } 23048c2ecf20Sopenharmony_ci 23058c2ecf20Sopenharmony_ci /* Overwrite header for attention registers */ 23068c2ecf20Sopenharmony_ci if (dump) 23078c2ecf20Sopenharmony_ci qed_grc_dump_regs_hdr(dump_buf, 23088c2ecf20Sopenharmony_ci true, 23098c2ecf20Sopenharmony_ci num_reg_entries, 23108c2ecf20Sopenharmony_ci SPLIT_TYPE_NONE, 0, "ATTN_REGS"); 23118c2ecf20Sopenharmony_ci 23128c2ecf20Sopenharmony_ci /* Write empty header for stall registers */ 23138c2ecf20Sopenharmony_ci stall_regs_offset = offset; 23148c2ecf20Sopenharmony_ci offset += qed_grc_dump_regs_hdr(dump_buf, 23158c2ecf20Sopenharmony_ci false, 0, SPLIT_TYPE_NONE, 0, "REGS"); 23168c2ecf20Sopenharmony_ci 23178c2ecf20Sopenharmony_ci /* Write Storm stall status registers */ 23188c2ecf20Sopenharmony_ci for (storm_id = 0, num_reg_entries = 0; storm_id < MAX_DBG_STORMS; 23198c2ecf20Sopenharmony_ci storm_id++) { 23208c2ecf20Sopenharmony_ci struct storm_defs *storm = &s_storm_defs[storm_id]; 23218c2ecf20Sopenharmony_ci u32 addr; 23228c2ecf20Sopenharmony_ci 23238c2ecf20Sopenharmony_ci if (dev_data->block_in_reset[storm->sem_block_id] && dump) 23248c2ecf20Sopenharmony_ci continue; 23258c2ecf20Sopenharmony_ci 23268c2ecf20Sopenharmony_ci addr = 23278c2ecf20Sopenharmony_ci BYTES_TO_DWORDS(storm->sem_fast_mem_addr + 23288c2ecf20Sopenharmony_ci SEM_FAST_REG_STALLED); 23298c2ecf20Sopenharmony_ci offset += qed_grc_dump_reg_entry(p_hwfn, 23308c2ecf20Sopenharmony_ci p_ptt, 23318c2ecf20Sopenharmony_ci dump_buf + offset, 23328c2ecf20Sopenharmony_ci dump, 23338c2ecf20Sopenharmony_ci addr, 23348c2ecf20Sopenharmony_ci 1, 23358c2ecf20Sopenharmony_ci false, SPLIT_TYPE_NONE, 0); 23368c2ecf20Sopenharmony_ci num_reg_entries++; 23378c2ecf20Sopenharmony_ci } 23388c2ecf20Sopenharmony_ci 23398c2ecf20Sopenharmony_ci /* Overwrite header for stall registers */ 23408c2ecf20Sopenharmony_ci if (dump) 23418c2ecf20Sopenharmony_ci qed_grc_dump_regs_hdr(dump_buf + stall_regs_offset, 23428c2ecf20Sopenharmony_ci true, 23438c2ecf20Sopenharmony_ci num_reg_entries, 23448c2ecf20Sopenharmony_ci SPLIT_TYPE_NONE, 0, "REGS"); 23458c2ecf20Sopenharmony_ci 23468c2ecf20Sopenharmony_ci return offset; 23478c2ecf20Sopenharmony_ci} 23488c2ecf20Sopenharmony_ci 23498c2ecf20Sopenharmony_ci/* Dumps registers that can't be represented in the debug arrays */ 23508c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_special_regs(struct qed_hwfn *p_hwfn, 23518c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 23528c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump) 23538c2ecf20Sopenharmony_ci{ 23548c2ecf20Sopenharmony_ci u32 offset = 0, addr; 23558c2ecf20Sopenharmony_ci 23568c2ecf20Sopenharmony_ci offset += qed_grc_dump_regs_hdr(dump_buf, 23578c2ecf20Sopenharmony_ci dump, 2, SPLIT_TYPE_NONE, 0, "REGS"); 23588c2ecf20Sopenharmony_ci 23598c2ecf20Sopenharmony_ci /* Dump R/TDIF_REG_DEBUG_ERROR_INFO_SIZE (every 8'th register should be 23608c2ecf20Sopenharmony_ci * skipped). 23618c2ecf20Sopenharmony_ci */ 23628c2ecf20Sopenharmony_ci addr = BYTES_TO_DWORDS(RDIF_REG_DEBUG_ERROR_INFO); 23638c2ecf20Sopenharmony_ci offset += qed_grc_dump_reg_entry_skip(p_hwfn, 23648c2ecf20Sopenharmony_ci p_ptt, 23658c2ecf20Sopenharmony_ci dump_buf + offset, 23668c2ecf20Sopenharmony_ci dump, 23678c2ecf20Sopenharmony_ci addr, 23688c2ecf20Sopenharmony_ci RDIF_REG_DEBUG_ERROR_INFO_SIZE, 23698c2ecf20Sopenharmony_ci 7, 23708c2ecf20Sopenharmony_ci 1); 23718c2ecf20Sopenharmony_ci addr = BYTES_TO_DWORDS(TDIF_REG_DEBUG_ERROR_INFO); 23728c2ecf20Sopenharmony_ci offset += 23738c2ecf20Sopenharmony_ci qed_grc_dump_reg_entry_skip(p_hwfn, 23748c2ecf20Sopenharmony_ci p_ptt, 23758c2ecf20Sopenharmony_ci dump_buf + offset, 23768c2ecf20Sopenharmony_ci dump, 23778c2ecf20Sopenharmony_ci addr, 23788c2ecf20Sopenharmony_ci TDIF_REG_DEBUG_ERROR_INFO_SIZE, 23798c2ecf20Sopenharmony_ci 7, 23808c2ecf20Sopenharmony_ci 1); 23818c2ecf20Sopenharmony_ci 23828c2ecf20Sopenharmony_ci return offset; 23838c2ecf20Sopenharmony_ci} 23848c2ecf20Sopenharmony_ci 23858c2ecf20Sopenharmony_ci/* Dumps a GRC memory header (section and params). Returns the dumped size in 23868c2ecf20Sopenharmony_ci * dwords. The following parameters are dumped: 23878c2ecf20Sopenharmony_ci * - name: dumped only if it's not NULL. 23888c2ecf20Sopenharmony_ci * - addr: in dwords, dumped only if name is NULL. 23898c2ecf20Sopenharmony_ci * - len: in dwords, always dumped. 23908c2ecf20Sopenharmony_ci * - width: dumped if it's not zero. 23918c2ecf20Sopenharmony_ci * - packed: dumped only if it's not false. 23928c2ecf20Sopenharmony_ci * - mem_group: always dumped. 23938c2ecf20Sopenharmony_ci * - is_storm: true only if the memory is related to a Storm. 23948c2ecf20Sopenharmony_ci * - storm_letter: valid only if is_storm is true. 23958c2ecf20Sopenharmony_ci * 23968c2ecf20Sopenharmony_ci */ 23978c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_mem_hdr(struct qed_hwfn *p_hwfn, 23988c2ecf20Sopenharmony_ci u32 *dump_buf, 23998c2ecf20Sopenharmony_ci bool dump, 24008c2ecf20Sopenharmony_ci const char *name, 24018c2ecf20Sopenharmony_ci u32 addr, 24028c2ecf20Sopenharmony_ci u32 len, 24038c2ecf20Sopenharmony_ci u32 bit_width, 24048c2ecf20Sopenharmony_ci bool packed, 24058c2ecf20Sopenharmony_ci const char *mem_group, char storm_letter) 24068c2ecf20Sopenharmony_ci{ 24078c2ecf20Sopenharmony_ci u8 num_params = 3; 24088c2ecf20Sopenharmony_ci u32 offset = 0; 24098c2ecf20Sopenharmony_ci char buf[64]; 24108c2ecf20Sopenharmony_ci 24118c2ecf20Sopenharmony_ci if (!len) 24128c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, 24138c2ecf20Sopenharmony_ci "Unexpected GRC Dump error: dumped memory size must be non-zero\n"); 24148c2ecf20Sopenharmony_ci 24158c2ecf20Sopenharmony_ci if (bit_width) 24168c2ecf20Sopenharmony_ci num_params++; 24178c2ecf20Sopenharmony_ci if (packed) 24188c2ecf20Sopenharmony_ci num_params++; 24198c2ecf20Sopenharmony_ci 24208c2ecf20Sopenharmony_ci /* Dump section header */ 24218c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 24228c2ecf20Sopenharmony_ci dump, "grc_mem", num_params); 24238c2ecf20Sopenharmony_ci 24248c2ecf20Sopenharmony_ci if (name) { 24258c2ecf20Sopenharmony_ci /* Dump name */ 24268c2ecf20Sopenharmony_ci if (storm_letter) { 24278c2ecf20Sopenharmony_ci strcpy(buf, "?STORM_"); 24288c2ecf20Sopenharmony_ci buf[0] = storm_letter; 24298c2ecf20Sopenharmony_ci strcpy(buf + strlen(buf), name); 24308c2ecf20Sopenharmony_ci } else { 24318c2ecf20Sopenharmony_ci strcpy(buf, name); 24328c2ecf20Sopenharmony_ci } 24338c2ecf20Sopenharmony_ci 24348c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 24358c2ecf20Sopenharmony_ci dump, "name", buf); 24368c2ecf20Sopenharmony_ci } else { 24378c2ecf20Sopenharmony_ci /* Dump address */ 24388c2ecf20Sopenharmony_ci u32 addr_in_bytes = DWORDS_TO_BYTES(addr); 24398c2ecf20Sopenharmony_ci 24408c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 24418c2ecf20Sopenharmony_ci dump, "addr", addr_in_bytes); 24428c2ecf20Sopenharmony_ci } 24438c2ecf20Sopenharmony_ci 24448c2ecf20Sopenharmony_ci /* Dump len */ 24458c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, dump, "len", len); 24468c2ecf20Sopenharmony_ci 24478c2ecf20Sopenharmony_ci /* Dump bit width */ 24488c2ecf20Sopenharmony_ci if (bit_width) 24498c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 24508c2ecf20Sopenharmony_ci dump, "width", bit_width); 24518c2ecf20Sopenharmony_ci 24528c2ecf20Sopenharmony_ci /* Dump packed */ 24538c2ecf20Sopenharmony_ci if (packed) 24548c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 24558c2ecf20Sopenharmony_ci dump, "packed", 1); 24568c2ecf20Sopenharmony_ci 24578c2ecf20Sopenharmony_ci /* Dump reg type */ 24588c2ecf20Sopenharmony_ci if (storm_letter) { 24598c2ecf20Sopenharmony_ci strcpy(buf, "?STORM_"); 24608c2ecf20Sopenharmony_ci buf[0] = storm_letter; 24618c2ecf20Sopenharmony_ci strcpy(buf + strlen(buf), mem_group); 24628c2ecf20Sopenharmony_ci } else { 24638c2ecf20Sopenharmony_ci strcpy(buf, mem_group); 24648c2ecf20Sopenharmony_ci } 24658c2ecf20Sopenharmony_ci 24668c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, dump, "type", buf); 24678c2ecf20Sopenharmony_ci 24688c2ecf20Sopenharmony_ci return offset; 24698c2ecf20Sopenharmony_ci} 24708c2ecf20Sopenharmony_ci 24718c2ecf20Sopenharmony_ci/* Dumps a single GRC memory. If name is NULL, the memory is stored by address. 24728c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 24738c2ecf20Sopenharmony_ci * The addr and len arguments are specified in dwords. 24748c2ecf20Sopenharmony_ci */ 24758c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_mem(struct qed_hwfn *p_hwfn, 24768c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 24778c2ecf20Sopenharmony_ci u32 *dump_buf, 24788c2ecf20Sopenharmony_ci bool dump, 24798c2ecf20Sopenharmony_ci const char *name, 24808c2ecf20Sopenharmony_ci u32 addr, 24818c2ecf20Sopenharmony_ci u32 len, 24828c2ecf20Sopenharmony_ci bool wide_bus, 24838c2ecf20Sopenharmony_ci u32 bit_width, 24848c2ecf20Sopenharmony_ci bool packed, 24858c2ecf20Sopenharmony_ci const char *mem_group, char storm_letter) 24868c2ecf20Sopenharmony_ci{ 24878c2ecf20Sopenharmony_ci u32 offset = 0; 24888c2ecf20Sopenharmony_ci 24898c2ecf20Sopenharmony_ci offset += qed_grc_dump_mem_hdr(p_hwfn, 24908c2ecf20Sopenharmony_ci dump_buf + offset, 24918c2ecf20Sopenharmony_ci dump, 24928c2ecf20Sopenharmony_ci name, 24938c2ecf20Sopenharmony_ci addr, 24948c2ecf20Sopenharmony_ci len, 24958c2ecf20Sopenharmony_ci bit_width, 24968c2ecf20Sopenharmony_ci packed, mem_group, storm_letter); 24978c2ecf20Sopenharmony_ci offset += qed_grc_dump_addr_range(p_hwfn, 24988c2ecf20Sopenharmony_ci p_ptt, 24998c2ecf20Sopenharmony_ci dump_buf + offset, 25008c2ecf20Sopenharmony_ci dump, addr, len, wide_bus, 25018c2ecf20Sopenharmony_ci SPLIT_TYPE_NONE, 0); 25028c2ecf20Sopenharmony_ci 25038c2ecf20Sopenharmony_ci return offset; 25048c2ecf20Sopenharmony_ci} 25058c2ecf20Sopenharmony_ci 25068c2ecf20Sopenharmony_ci/* Dumps GRC memories entries. Returns the dumped size in dwords. */ 25078c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_mem_entries(struct qed_hwfn *p_hwfn, 25088c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 25098c2ecf20Sopenharmony_ci struct virt_mem_desc input_mems_arr, 25108c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump) 25118c2ecf20Sopenharmony_ci{ 25128c2ecf20Sopenharmony_ci u32 i, offset = 0, input_offset = 0; 25138c2ecf20Sopenharmony_ci bool mode_match = true; 25148c2ecf20Sopenharmony_ci 25158c2ecf20Sopenharmony_ci while (input_offset < BYTES_TO_DWORDS(input_mems_arr.size)) { 25168c2ecf20Sopenharmony_ci const struct dbg_dump_cond_hdr *cond_hdr; 25178c2ecf20Sopenharmony_ci u16 modes_buf_offset; 25188c2ecf20Sopenharmony_ci u32 num_entries; 25198c2ecf20Sopenharmony_ci bool eval_mode; 25208c2ecf20Sopenharmony_ci 25218c2ecf20Sopenharmony_ci cond_hdr = 25228c2ecf20Sopenharmony_ci (const struct dbg_dump_cond_hdr *)input_mems_arr.ptr + 25238c2ecf20Sopenharmony_ci input_offset++; 25248c2ecf20Sopenharmony_ci num_entries = cond_hdr->data_size / MEM_DUMP_ENTRY_SIZE_DWORDS; 25258c2ecf20Sopenharmony_ci 25268c2ecf20Sopenharmony_ci /* Check required mode */ 25278c2ecf20Sopenharmony_ci eval_mode = GET_FIELD(cond_hdr->mode.data, 25288c2ecf20Sopenharmony_ci DBG_MODE_HDR_EVAL_MODE) > 0; 25298c2ecf20Sopenharmony_ci if (eval_mode) { 25308c2ecf20Sopenharmony_ci modes_buf_offset = 25318c2ecf20Sopenharmony_ci GET_FIELD(cond_hdr->mode.data, 25328c2ecf20Sopenharmony_ci DBG_MODE_HDR_MODES_BUF_OFFSET); 25338c2ecf20Sopenharmony_ci mode_match = qed_is_mode_match(p_hwfn, 25348c2ecf20Sopenharmony_ci &modes_buf_offset); 25358c2ecf20Sopenharmony_ci } 25368c2ecf20Sopenharmony_ci 25378c2ecf20Sopenharmony_ci if (!mode_match) { 25388c2ecf20Sopenharmony_ci input_offset += cond_hdr->data_size; 25398c2ecf20Sopenharmony_ci continue; 25408c2ecf20Sopenharmony_ci } 25418c2ecf20Sopenharmony_ci 25428c2ecf20Sopenharmony_ci for (i = 0; i < num_entries; 25438c2ecf20Sopenharmony_ci i++, input_offset += MEM_DUMP_ENTRY_SIZE_DWORDS) { 25448c2ecf20Sopenharmony_ci const struct dbg_dump_mem *mem = 25458c2ecf20Sopenharmony_ci (const struct dbg_dump_mem *)((u32 *) 25468c2ecf20Sopenharmony_ci input_mems_arr.ptr 25478c2ecf20Sopenharmony_ci + input_offset); 25488c2ecf20Sopenharmony_ci const struct dbg_block *block; 25498c2ecf20Sopenharmony_ci char storm_letter = 0; 25508c2ecf20Sopenharmony_ci u32 mem_addr, mem_len; 25518c2ecf20Sopenharmony_ci bool mem_wide_bus; 25528c2ecf20Sopenharmony_ci u8 mem_group_id; 25538c2ecf20Sopenharmony_ci 25548c2ecf20Sopenharmony_ci mem_group_id = GET_FIELD(mem->dword0, 25558c2ecf20Sopenharmony_ci DBG_DUMP_MEM_MEM_GROUP_ID); 25568c2ecf20Sopenharmony_ci if (mem_group_id >= MEM_GROUPS_NUM) { 25578c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, "Invalid mem_group_id\n"); 25588c2ecf20Sopenharmony_ci return 0; 25598c2ecf20Sopenharmony_ci } 25608c2ecf20Sopenharmony_ci 25618c2ecf20Sopenharmony_ci if (!qed_grc_is_mem_included(p_hwfn, 25628c2ecf20Sopenharmony_ci (enum block_id) 25638c2ecf20Sopenharmony_ci cond_hdr->block_id, 25648c2ecf20Sopenharmony_ci mem_group_id)) 25658c2ecf20Sopenharmony_ci continue; 25668c2ecf20Sopenharmony_ci 25678c2ecf20Sopenharmony_ci mem_addr = GET_FIELD(mem->dword0, DBG_DUMP_MEM_ADDRESS); 25688c2ecf20Sopenharmony_ci mem_len = GET_FIELD(mem->dword1, DBG_DUMP_MEM_LENGTH); 25698c2ecf20Sopenharmony_ci mem_wide_bus = GET_FIELD(mem->dword1, 25708c2ecf20Sopenharmony_ci DBG_DUMP_MEM_WIDE_BUS); 25718c2ecf20Sopenharmony_ci 25728c2ecf20Sopenharmony_ci block = get_dbg_block(p_hwfn, 25738c2ecf20Sopenharmony_ci cond_hdr->block_id); 25748c2ecf20Sopenharmony_ci 25758c2ecf20Sopenharmony_ci /* If memory is associated with Storm, 25768c2ecf20Sopenharmony_ci * update storm details 25778c2ecf20Sopenharmony_ci */ 25788c2ecf20Sopenharmony_ci if (block->associated_storm_letter) 25798c2ecf20Sopenharmony_ci storm_letter = block->associated_storm_letter; 25808c2ecf20Sopenharmony_ci 25818c2ecf20Sopenharmony_ci /* Dump memory */ 25828c2ecf20Sopenharmony_ci offset += qed_grc_dump_mem(p_hwfn, 25838c2ecf20Sopenharmony_ci p_ptt, 25848c2ecf20Sopenharmony_ci dump_buf + offset, 25858c2ecf20Sopenharmony_ci dump, 25868c2ecf20Sopenharmony_ci NULL, 25878c2ecf20Sopenharmony_ci mem_addr, 25888c2ecf20Sopenharmony_ci mem_len, 25898c2ecf20Sopenharmony_ci mem_wide_bus, 25908c2ecf20Sopenharmony_ci 0, 25918c2ecf20Sopenharmony_ci false, 25928c2ecf20Sopenharmony_ci s_mem_group_names[mem_group_id], 25938c2ecf20Sopenharmony_ci storm_letter); 25948c2ecf20Sopenharmony_ci } 25958c2ecf20Sopenharmony_ci } 25968c2ecf20Sopenharmony_ci 25978c2ecf20Sopenharmony_ci return offset; 25988c2ecf20Sopenharmony_ci} 25998c2ecf20Sopenharmony_ci 26008c2ecf20Sopenharmony_ci/* Dumps GRC memories according to the input array dump_mem. 26018c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 26028c2ecf20Sopenharmony_ci */ 26038c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_memories(struct qed_hwfn *p_hwfn, 26048c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 26058c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump) 26068c2ecf20Sopenharmony_ci{ 26078c2ecf20Sopenharmony_ci struct virt_mem_desc *dbg_buf = 26088c2ecf20Sopenharmony_ci &p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_MEM]; 26098c2ecf20Sopenharmony_ci u32 offset = 0, input_offset = 0; 26108c2ecf20Sopenharmony_ci 26118c2ecf20Sopenharmony_ci while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) { 26128c2ecf20Sopenharmony_ci const struct dbg_dump_split_hdr *split_hdr; 26138c2ecf20Sopenharmony_ci struct virt_mem_desc curr_input_mems_arr; 26148c2ecf20Sopenharmony_ci enum init_split_types split_type; 26158c2ecf20Sopenharmony_ci u32 split_data_size; 26168c2ecf20Sopenharmony_ci 26178c2ecf20Sopenharmony_ci split_hdr = 26188c2ecf20Sopenharmony_ci (const struct dbg_dump_split_hdr *)dbg_buf->ptr + 26198c2ecf20Sopenharmony_ci input_offset++; 26208c2ecf20Sopenharmony_ci split_type = GET_FIELD(split_hdr->hdr, 26218c2ecf20Sopenharmony_ci DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID); 26228c2ecf20Sopenharmony_ci split_data_size = GET_FIELD(split_hdr->hdr, 26238c2ecf20Sopenharmony_ci DBG_DUMP_SPLIT_HDR_DATA_SIZE); 26248c2ecf20Sopenharmony_ci curr_input_mems_arr.ptr = (u32 *)dbg_buf->ptr + input_offset; 26258c2ecf20Sopenharmony_ci curr_input_mems_arr.size = DWORDS_TO_BYTES(split_data_size); 26268c2ecf20Sopenharmony_ci 26278c2ecf20Sopenharmony_ci if (split_type == SPLIT_TYPE_NONE) 26288c2ecf20Sopenharmony_ci offset += qed_grc_dump_mem_entries(p_hwfn, 26298c2ecf20Sopenharmony_ci p_ptt, 26308c2ecf20Sopenharmony_ci curr_input_mems_arr, 26318c2ecf20Sopenharmony_ci dump_buf + offset, 26328c2ecf20Sopenharmony_ci dump); 26338c2ecf20Sopenharmony_ci else 26348c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, 26358c2ecf20Sopenharmony_ci "Dumping split memories is currently not supported\n"); 26368c2ecf20Sopenharmony_ci 26378c2ecf20Sopenharmony_ci input_offset += split_data_size; 26388c2ecf20Sopenharmony_ci } 26398c2ecf20Sopenharmony_ci 26408c2ecf20Sopenharmony_ci return offset; 26418c2ecf20Sopenharmony_ci} 26428c2ecf20Sopenharmony_ci 26438c2ecf20Sopenharmony_ci/* Dumps GRC context data for the specified Storm. 26448c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 26458c2ecf20Sopenharmony_ci * The lid_size argument is specified in quad-regs. 26468c2ecf20Sopenharmony_ci */ 26478c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_ctx_data(struct qed_hwfn *p_hwfn, 26488c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 26498c2ecf20Sopenharmony_ci u32 *dump_buf, 26508c2ecf20Sopenharmony_ci bool dump, 26518c2ecf20Sopenharmony_ci const char *name, 26528c2ecf20Sopenharmony_ci u32 num_lids, 26538c2ecf20Sopenharmony_ci enum cm_ctx_types ctx_type, u8 storm_id) 26548c2ecf20Sopenharmony_ci{ 26558c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 26568c2ecf20Sopenharmony_ci struct storm_defs *storm = &s_storm_defs[storm_id]; 26578c2ecf20Sopenharmony_ci u32 i, lid, lid_size, total_size; 26588c2ecf20Sopenharmony_ci u32 rd_reg_addr, offset = 0; 26598c2ecf20Sopenharmony_ci 26608c2ecf20Sopenharmony_ci /* Convert quad-regs to dwords */ 26618c2ecf20Sopenharmony_ci lid_size = storm->cm_ctx_lid_sizes[dev_data->chip_id][ctx_type] * 4; 26628c2ecf20Sopenharmony_ci 26638c2ecf20Sopenharmony_ci if (!lid_size) 26648c2ecf20Sopenharmony_ci return 0; 26658c2ecf20Sopenharmony_ci 26668c2ecf20Sopenharmony_ci total_size = num_lids * lid_size; 26678c2ecf20Sopenharmony_ci 26688c2ecf20Sopenharmony_ci offset += qed_grc_dump_mem_hdr(p_hwfn, 26698c2ecf20Sopenharmony_ci dump_buf + offset, 26708c2ecf20Sopenharmony_ci dump, 26718c2ecf20Sopenharmony_ci name, 26728c2ecf20Sopenharmony_ci 0, 26738c2ecf20Sopenharmony_ci total_size, 26748c2ecf20Sopenharmony_ci lid_size * 32, 26758c2ecf20Sopenharmony_ci false, name, storm->letter); 26768c2ecf20Sopenharmony_ci 26778c2ecf20Sopenharmony_ci if (!dump) 26788c2ecf20Sopenharmony_ci return offset + total_size; 26798c2ecf20Sopenharmony_ci 26808c2ecf20Sopenharmony_ci rd_reg_addr = BYTES_TO_DWORDS(storm->cm_ctx_rd_addr[ctx_type]); 26818c2ecf20Sopenharmony_ci 26828c2ecf20Sopenharmony_ci /* Dump context data */ 26838c2ecf20Sopenharmony_ci for (lid = 0; lid < num_lids; lid++) { 26848c2ecf20Sopenharmony_ci for (i = 0; i < lid_size; i++) { 26858c2ecf20Sopenharmony_ci qed_wr(p_hwfn, 26868c2ecf20Sopenharmony_ci p_ptt, storm->cm_ctx_wr_addr, (i << 9) | lid); 26878c2ecf20Sopenharmony_ci offset += qed_grc_dump_addr_range(p_hwfn, 26888c2ecf20Sopenharmony_ci p_ptt, 26898c2ecf20Sopenharmony_ci dump_buf + offset, 26908c2ecf20Sopenharmony_ci dump, 26918c2ecf20Sopenharmony_ci rd_reg_addr, 26928c2ecf20Sopenharmony_ci 1, 26938c2ecf20Sopenharmony_ci false, 26948c2ecf20Sopenharmony_ci SPLIT_TYPE_NONE, 0); 26958c2ecf20Sopenharmony_ci } 26968c2ecf20Sopenharmony_ci } 26978c2ecf20Sopenharmony_ci 26988c2ecf20Sopenharmony_ci return offset; 26998c2ecf20Sopenharmony_ci} 27008c2ecf20Sopenharmony_ci 27018c2ecf20Sopenharmony_ci/* Dumps GRC contexts. Returns the dumped size in dwords. */ 27028c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_ctx(struct qed_hwfn *p_hwfn, 27038c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) 27048c2ecf20Sopenharmony_ci{ 27058c2ecf20Sopenharmony_ci u32 offset = 0; 27068c2ecf20Sopenharmony_ci u8 storm_id; 27078c2ecf20Sopenharmony_ci 27088c2ecf20Sopenharmony_ci for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) { 27098c2ecf20Sopenharmony_ci if (!qed_grc_is_storm_included(p_hwfn, 27108c2ecf20Sopenharmony_ci (enum dbg_storms)storm_id)) 27118c2ecf20Sopenharmony_ci continue; 27128c2ecf20Sopenharmony_ci 27138c2ecf20Sopenharmony_ci /* Dump Conn AG context size */ 27148c2ecf20Sopenharmony_ci offset += qed_grc_dump_ctx_data(p_hwfn, 27158c2ecf20Sopenharmony_ci p_ptt, 27168c2ecf20Sopenharmony_ci dump_buf + offset, 27178c2ecf20Sopenharmony_ci dump, 27188c2ecf20Sopenharmony_ci "CONN_AG_CTX", 27198c2ecf20Sopenharmony_ci NUM_OF_LCIDS, 27208c2ecf20Sopenharmony_ci CM_CTX_CONN_AG, storm_id); 27218c2ecf20Sopenharmony_ci 27228c2ecf20Sopenharmony_ci /* Dump Conn ST context size */ 27238c2ecf20Sopenharmony_ci offset += qed_grc_dump_ctx_data(p_hwfn, 27248c2ecf20Sopenharmony_ci p_ptt, 27258c2ecf20Sopenharmony_ci dump_buf + offset, 27268c2ecf20Sopenharmony_ci dump, 27278c2ecf20Sopenharmony_ci "CONN_ST_CTX", 27288c2ecf20Sopenharmony_ci NUM_OF_LCIDS, 27298c2ecf20Sopenharmony_ci CM_CTX_CONN_ST, storm_id); 27308c2ecf20Sopenharmony_ci 27318c2ecf20Sopenharmony_ci /* Dump Task AG context size */ 27328c2ecf20Sopenharmony_ci offset += qed_grc_dump_ctx_data(p_hwfn, 27338c2ecf20Sopenharmony_ci p_ptt, 27348c2ecf20Sopenharmony_ci dump_buf + offset, 27358c2ecf20Sopenharmony_ci dump, 27368c2ecf20Sopenharmony_ci "TASK_AG_CTX", 27378c2ecf20Sopenharmony_ci NUM_OF_LTIDS, 27388c2ecf20Sopenharmony_ci CM_CTX_TASK_AG, storm_id); 27398c2ecf20Sopenharmony_ci 27408c2ecf20Sopenharmony_ci /* Dump Task ST context size */ 27418c2ecf20Sopenharmony_ci offset += qed_grc_dump_ctx_data(p_hwfn, 27428c2ecf20Sopenharmony_ci p_ptt, 27438c2ecf20Sopenharmony_ci dump_buf + offset, 27448c2ecf20Sopenharmony_ci dump, 27458c2ecf20Sopenharmony_ci "TASK_ST_CTX", 27468c2ecf20Sopenharmony_ci NUM_OF_LTIDS, 27478c2ecf20Sopenharmony_ci CM_CTX_TASK_ST, storm_id); 27488c2ecf20Sopenharmony_ci } 27498c2ecf20Sopenharmony_ci 27508c2ecf20Sopenharmony_ci return offset; 27518c2ecf20Sopenharmony_ci} 27528c2ecf20Sopenharmony_ci 27538c2ecf20Sopenharmony_ci#define VFC_STATUS_RESP_READY_BIT 0 27548c2ecf20Sopenharmony_ci#define VFC_STATUS_BUSY_BIT 1 27558c2ecf20Sopenharmony_ci#define VFC_STATUS_SENDING_CMD_BIT 2 27568c2ecf20Sopenharmony_ci 27578c2ecf20Sopenharmony_ci#define VFC_POLLING_DELAY_MS 1 27588c2ecf20Sopenharmony_ci#define VFC_POLLING_COUNT 20 27598c2ecf20Sopenharmony_ci 27608c2ecf20Sopenharmony_ci/* Reads data from VFC. Returns the number of dwords read (0 on error). 27618c2ecf20Sopenharmony_ci * Sizes are specified in dwords. 27628c2ecf20Sopenharmony_ci */ 27638c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_read_from_vfc(struct qed_hwfn *p_hwfn, 27648c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 27658c2ecf20Sopenharmony_ci struct storm_defs *storm, 27668c2ecf20Sopenharmony_ci u32 *cmd_data, 27678c2ecf20Sopenharmony_ci u32 cmd_size, 27688c2ecf20Sopenharmony_ci u32 *addr_data, 27698c2ecf20Sopenharmony_ci u32 addr_size, 27708c2ecf20Sopenharmony_ci u32 resp_size, u32 *dump_buf) 27718c2ecf20Sopenharmony_ci{ 27728c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 27738c2ecf20Sopenharmony_ci u32 vfc_status, polling_ms, polling_count = 0, i; 27748c2ecf20Sopenharmony_ci u32 reg_addr, sem_base; 27758c2ecf20Sopenharmony_ci bool is_ready = false; 27768c2ecf20Sopenharmony_ci 27778c2ecf20Sopenharmony_ci sem_base = storm->sem_fast_mem_addr; 27788c2ecf20Sopenharmony_ci polling_ms = VFC_POLLING_DELAY_MS * 27798c2ecf20Sopenharmony_ci s_hw_type_defs[dev_data->hw_type].delay_factor; 27808c2ecf20Sopenharmony_ci 27818c2ecf20Sopenharmony_ci /* Write VFC command */ 27828c2ecf20Sopenharmony_ci ARR_REG_WR(p_hwfn, 27838c2ecf20Sopenharmony_ci p_ptt, 27848c2ecf20Sopenharmony_ci sem_base + SEM_FAST_REG_VFC_DATA_WR, 27858c2ecf20Sopenharmony_ci cmd_data, cmd_size); 27868c2ecf20Sopenharmony_ci 27878c2ecf20Sopenharmony_ci /* Write VFC address */ 27888c2ecf20Sopenharmony_ci ARR_REG_WR(p_hwfn, 27898c2ecf20Sopenharmony_ci p_ptt, 27908c2ecf20Sopenharmony_ci sem_base + SEM_FAST_REG_VFC_ADDR, 27918c2ecf20Sopenharmony_ci addr_data, addr_size); 27928c2ecf20Sopenharmony_ci 27938c2ecf20Sopenharmony_ci /* Read response */ 27948c2ecf20Sopenharmony_ci for (i = 0; i < resp_size; i++) { 27958c2ecf20Sopenharmony_ci /* Poll until ready */ 27968c2ecf20Sopenharmony_ci do { 27978c2ecf20Sopenharmony_ci reg_addr = sem_base + SEM_FAST_REG_VFC_STATUS; 27988c2ecf20Sopenharmony_ci qed_grc_dump_addr_range(p_hwfn, 27998c2ecf20Sopenharmony_ci p_ptt, 28008c2ecf20Sopenharmony_ci &vfc_status, 28018c2ecf20Sopenharmony_ci true, 28028c2ecf20Sopenharmony_ci BYTES_TO_DWORDS(reg_addr), 28038c2ecf20Sopenharmony_ci 1, 28048c2ecf20Sopenharmony_ci false, SPLIT_TYPE_NONE, 0); 28058c2ecf20Sopenharmony_ci is_ready = vfc_status & BIT(VFC_STATUS_RESP_READY_BIT); 28068c2ecf20Sopenharmony_ci 28078c2ecf20Sopenharmony_ci if (!is_ready) { 28088c2ecf20Sopenharmony_ci if (polling_count++ == VFC_POLLING_COUNT) 28098c2ecf20Sopenharmony_ci return 0; 28108c2ecf20Sopenharmony_ci 28118c2ecf20Sopenharmony_ci msleep(polling_ms); 28128c2ecf20Sopenharmony_ci } 28138c2ecf20Sopenharmony_ci } while (!is_ready); 28148c2ecf20Sopenharmony_ci 28158c2ecf20Sopenharmony_ci reg_addr = sem_base + SEM_FAST_REG_VFC_DATA_RD; 28168c2ecf20Sopenharmony_ci qed_grc_dump_addr_range(p_hwfn, 28178c2ecf20Sopenharmony_ci p_ptt, 28188c2ecf20Sopenharmony_ci dump_buf + i, 28198c2ecf20Sopenharmony_ci true, 28208c2ecf20Sopenharmony_ci BYTES_TO_DWORDS(reg_addr), 28218c2ecf20Sopenharmony_ci 1, false, SPLIT_TYPE_NONE, 0); 28228c2ecf20Sopenharmony_ci } 28238c2ecf20Sopenharmony_ci 28248c2ecf20Sopenharmony_ci return resp_size; 28258c2ecf20Sopenharmony_ci} 28268c2ecf20Sopenharmony_ci 28278c2ecf20Sopenharmony_ci/* Dump VFC CAM. Returns the dumped size in dwords. */ 28288c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_vfc_cam(struct qed_hwfn *p_hwfn, 28298c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 28308c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump, u8 storm_id) 28318c2ecf20Sopenharmony_ci{ 28328c2ecf20Sopenharmony_ci u32 total_size = VFC_CAM_NUM_ROWS * VFC_CAM_RESP_DWORDS; 28338c2ecf20Sopenharmony_ci struct storm_defs *storm = &s_storm_defs[storm_id]; 28348c2ecf20Sopenharmony_ci u32 cam_addr[VFC_CAM_ADDR_DWORDS] = { 0 }; 28358c2ecf20Sopenharmony_ci u32 cam_cmd[VFC_CAM_CMD_DWORDS] = { 0 }; 28368c2ecf20Sopenharmony_ci u32 row, offset = 0; 28378c2ecf20Sopenharmony_ci 28388c2ecf20Sopenharmony_ci offset += qed_grc_dump_mem_hdr(p_hwfn, 28398c2ecf20Sopenharmony_ci dump_buf + offset, 28408c2ecf20Sopenharmony_ci dump, 28418c2ecf20Sopenharmony_ci "vfc_cam", 28428c2ecf20Sopenharmony_ci 0, 28438c2ecf20Sopenharmony_ci total_size, 28448c2ecf20Sopenharmony_ci 256, 28458c2ecf20Sopenharmony_ci false, "vfc_cam", storm->letter); 28468c2ecf20Sopenharmony_ci 28478c2ecf20Sopenharmony_ci if (!dump) 28488c2ecf20Sopenharmony_ci return offset + total_size; 28498c2ecf20Sopenharmony_ci 28508c2ecf20Sopenharmony_ci /* Prepare CAM address */ 28518c2ecf20Sopenharmony_ci SET_VAR_FIELD(cam_addr, VFC_CAM_ADDR, OP, VFC_OPCODE_CAM_RD); 28528c2ecf20Sopenharmony_ci 28538c2ecf20Sopenharmony_ci /* Read VFC CAM data */ 28548c2ecf20Sopenharmony_ci for (row = 0; row < VFC_CAM_NUM_ROWS; row++) { 28558c2ecf20Sopenharmony_ci SET_VAR_FIELD(cam_cmd, VFC_CAM_CMD, ROW, row); 28568c2ecf20Sopenharmony_ci offset += qed_grc_dump_read_from_vfc(p_hwfn, 28578c2ecf20Sopenharmony_ci p_ptt, 28588c2ecf20Sopenharmony_ci storm, 28598c2ecf20Sopenharmony_ci cam_cmd, 28608c2ecf20Sopenharmony_ci VFC_CAM_CMD_DWORDS, 28618c2ecf20Sopenharmony_ci cam_addr, 28628c2ecf20Sopenharmony_ci VFC_CAM_ADDR_DWORDS, 28638c2ecf20Sopenharmony_ci VFC_CAM_RESP_DWORDS, 28648c2ecf20Sopenharmony_ci dump_buf + offset); 28658c2ecf20Sopenharmony_ci } 28668c2ecf20Sopenharmony_ci 28678c2ecf20Sopenharmony_ci return offset; 28688c2ecf20Sopenharmony_ci} 28698c2ecf20Sopenharmony_ci 28708c2ecf20Sopenharmony_ci/* Dump VFC RAM. Returns the dumped size in dwords. */ 28718c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_vfc_ram(struct qed_hwfn *p_hwfn, 28728c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 28738c2ecf20Sopenharmony_ci u32 *dump_buf, 28748c2ecf20Sopenharmony_ci bool dump, 28758c2ecf20Sopenharmony_ci u8 storm_id, struct vfc_ram_defs *ram_defs) 28768c2ecf20Sopenharmony_ci{ 28778c2ecf20Sopenharmony_ci u32 total_size = ram_defs->num_rows * VFC_RAM_RESP_DWORDS; 28788c2ecf20Sopenharmony_ci struct storm_defs *storm = &s_storm_defs[storm_id]; 28798c2ecf20Sopenharmony_ci u32 ram_addr[VFC_RAM_ADDR_DWORDS] = { 0 }; 28808c2ecf20Sopenharmony_ci u32 ram_cmd[VFC_RAM_CMD_DWORDS] = { 0 }; 28818c2ecf20Sopenharmony_ci u32 row, offset = 0; 28828c2ecf20Sopenharmony_ci 28838c2ecf20Sopenharmony_ci offset += qed_grc_dump_mem_hdr(p_hwfn, 28848c2ecf20Sopenharmony_ci dump_buf + offset, 28858c2ecf20Sopenharmony_ci dump, 28868c2ecf20Sopenharmony_ci ram_defs->mem_name, 28878c2ecf20Sopenharmony_ci 0, 28888c2ecf20Sopenharmony_ci total_size, 28898c2ecf20Sopenharmony_ci 256, 28908c2ecf20Sopenharmony_ci false, 28918c2ecf20Sopenharmony_ci ram_defs->type_name, 28928c2ecf20Sopenharmony_ci storm->letter); 28938c2ecf20Sopenharmony_ci 28948c2ecf20Sopenharmony_ci if (!dump) 28958c2ecf20Sopenharmony_ci return offset + total_size; 28968c2ecf20Sopenharmony_ci 28978c2ecf20Sopenharmony_ci /* Prepare RAM address */ 28988c2ecf20Sopenharmony_ci SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, OP, VFC_OPCODE_RAM_RD); 28998c2ecf20Sopenharmony_ci 29008c2ecf20Sopenharmony_ci /* Read VFC RAM data */ 29018c2ecf20Sopenharmony_ci for (row = ram_defs->base_row; 29028c2ecf20Sopenharmony_ci row < ram_defs->base_row + ram_defs->num_rows; row++) { 29038c2ecf20Sopenharmony_ci SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, ROW, row); 29048c2ecf20Sopenharmony_ci offset += qed_grc_dump_read_from_vfc(p_hwfn, 29058c2ecf20Sopenharmony_ci p_ptt, 29068c2ecf20Sopenharmony_ci storm, 29078c2ecf20Sopenharmony_ci ram_cmd, 29088c2ecf20Sopenharmony_ci VFC_RAM_CMD_DWORDS, 29098c2ecf20Sopenharmony_ci ram_addr, 29108c2ecf20Sopenharmony_ci VFC_RAM_ADDR_DWORDS, 29118c2ecf20Sopenharmony_ci VFC_RAM_RESP_DWORDS, 29128c2ecf20Sopenharmony_ci dump_buf + offset); 29138c2ecf20Sopenharmony_ci } 29148c2ecf20Sopenharmony_ci 29158c2ecf20Sopenharmony_ci return offset; 29168c2ecf20Sopenharmony_ci} 29178c2ecf20Sopenharmony_ci 29188c2ecf20Sopenharmony_ci/* Dumps GRC VFC data. Returns the dumped size in dwords. */ 29198c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_vfc(struct qed_hwfn *p_hwfn, 29208c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) 29218c2ecf20Sopenharmony_ci{ 29228c2ecf20Sopenharmony_ci u8 storm_id, i; 29238c2ecf20Sopenharmony_ci u32 offset = 0; 29248c2ecf20Sopenharmony_ci 29258c2ecf20Sopenharmony_ci for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) { 29268c2ecf20Sopenharmony_ci if (!qed_grc_is_storm_included(p_hwfn, 29278c2ecf20Sopenharmony_ci (enum dbg_storms)storm_id) || 29288c2ecf20Sopenharmony_ci !s_storm_defs[storm_id].has_vfc) 29298c2ecf20Sopenharmony_ci continue; 29308c2ecf20Sopenharmony_ci 29318c2ecf20Sopenharmony_ci /* Read CAM */ 29328c2ecf20Sopenharmony_ci offset += qed_grc_dump_vfc_cam(p_hwfn, 29338c2ecf20Sopenharmony_ci p_ptt, 29348c2ecf20Sopenharmony_ci dump_buf + offset, 29358c2ecf20Sopenharmony_ci dump, storm_id); 29368c2ecf20Sopenharmony_ci 29378c2ecf20Sopenharmony_ci /* Read RAM */ 29388c2ecf20Sopenharmony_ci for (i = 0; i < NUM_VFC_RAM_TYPES; i++) 29398c2ecf20Sopenharmony_ci offset += qed_grc_dump_vfc_ram(p_hwfn, 29408c2ecf20Sopenharmony_ci p_ptt, 29418c2ecf20Sopenharmony_ci dump_buf + offset, 29428c2ecf20Sopenharmony_ci dump, 29438c2ecf20Sopenharmony_ci storm_id, 29448c2ecf20Sopenharmony_ci &s_vfc_ram_defs[i]); 29458c2ecf20Sopenharmony_ci } 29468c2ecf20Sopenharmony_ci 29478c2ecf20Sopenharmony_ci return offset; 29488c2ecf20Sopenharmony_ci} 29498c2ecf20Sopenharmony_ci 29508c2ecf20Sopenharmony_ci/* Dumps GRC RSS data. Returns the dumped size in dwords. */ 29518c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_rss(struct qed_hwfn *p_hwfn, 29528c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) 29538c2ecf20Sopenharmony_ci{ 29548c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 29558c2ecf20Sopenharmony_ci u32 offset = 0; 29568c2ecf20Sopenharmony_ci u8 rss_mem_id; 29578c2ecf20Sopenharmony_ci 29588c2ecf20Sopenharmony_ci for (rss_mem_id = 0; rss_mem_id < NUM_RSS_MEM_TYPES; rss_mem_id++) { 29598c2ecf20Sopenharmony_ci u32 rss_addr, num_entries, total_dwords; 29608c2ecf20Sopenharmony_ci struct rss_mem_defs *rss_defs; 29618c2ecf20Sopenharmony_ci u32 addr, num_dwords_to_read; 29628c2ecf20Sopenharmony_ci bool packed; 29638c2ecf20Sopenharmony_ci 29648c2ecf20Sopenharmony_ci rss_defs = &s_rss_mem_defs[rss_mem_id]; 29658c2ecf20Sopenharmony_ci rss_addr = rss_defs->addr; 29668c2ecf20Sopenharmony_ci num_entries = rss_defs->num_entries[dev_data->chip_id]; 29678c2ecf20Sopenharmony_ci total_dwords = (num_entries * rss_defs->entry_width) / 32; 29688c2ecf20Sopenharmony_ci packed = (rss_defs->entry_width == 16); 29698c2ecf20Sopenharmony_ci 29708c2ecf20Sopenharmony_ci offset += qed_grc_dump_mem_hdr(p_hwfn, 29718c2ecf20Sopenharmony_ci dump_buf + offset, 29728c2ecf20Sopenharmony_ci dump, 29738c2ecf20Sopenharmony_ci rss_defs->mem_name, 29748c2ecf20Sopenharmony_ci 0, 29758c2ecf20Sopenharmony_ci total_dwords, 29768c2ecf20Sopenharmony_ci rss_defs->entry_width, 29778c2ecf20Sopenharmony_ci packed, 29788c2ecf20Sopenharmony_ci rss_defs->type_name, 0); 29798c2ecf20Sopenharmony_ci 29808c2ecf20Sopenharmony_ci /* Dump RSS data */ 29818c2ecf20Sopenharmony_ci if (!dump) { 29828c2ecf20Sopenharmony_ci offset += total_dwords; 29838c2ecf20Sopenharmony_ci continue; 29848c2ecf20Sopenharmony_ci } 29858c2ecf20Sopenharmony_ci 29868c2ecf20Sopenharmony_ci addr = BYTES_TO_DWORDS(RSS_REG_RSS_RAM_DATA); 29878c2ecf20Sopenharmony_ci while (total_dwords) { 29888c2ecf20Sopenharmony_ci num_dwords_to_read = min_t(u32, 29898c2ecf20Sopenharmony_ci RSS_REG_RSS_RAM_DATA_SIZE, 29908c2ecf20Sopenharmony_ci total_dwords); 29918c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, RSS_REG_RSS_RAM_ADDR, rss_addr); 29928c2ecf20Sopenharmony_ci offset += qed_grc_dump_addr_range(p_hwfn, 29938c2ecf20Sopenharmony_ci p_ptt, 29948c2ecf20Sopenharmony_ci dump_buf + offset, 29958c2ecf20Sopenharmony_ci dump, 29968c2ecf20Sopenharmony_ci addr, 29978c2ecf20Sopenharmony_ci num_dwords_to_read, 29988c2ecf20Sopenharmony_ci false, 29998c2ecf20Sopenharmony_ci SPLIT_TYPE_NONE, 0); 30008c2ecf20Sopenharmony_ci total_dwords -= num_dwords_to_read; 30018c2ecf20Sopenharmony_ci rss_addr++; 30028c2ecf20Sopenharmony_ci } 30038c2ecf20Sopenharmony_ci } 30048c2ecf20Sopenharmony_ci 30058c2ecf20Sopenharmony_ci return offset; 30068c2ecf20Sopenharmony_ci} 30078c2ecf20Sopenharmony_ci 30088c2ecf20Sopenharmony_ci/* Dumps GRC Big RAM. Returns the dumped size in dwords. */ 30098c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_big_ram(struct qed_hwfn *p_hwfn, 30108c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 30118c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump, u8 big_ram_id) 30128c2ecf20Sopenharmony_ci{ 30138c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 30148c2ecf20Sopenharmony_ci u32 block_size, ram_size, offset = 0, reg_val, i; 30158c2ecf20Sopenharmony_ci char mem_name[12] = "???_BIG_RAM"; 30168c2ecf20Sopenharmony_ci char type_name[8] = "???_RAM"; 30178c2ecf20Sopenharmony_ci struct big_ram_defs *big_ram; 30188c2ecf20Sopenharmony_ci 30198c2ecf20Sopenharmony_ci big_ram = &s_big_ram_defs[big_ram_id]; 30208c2ecf20Sopenharmony_ci ram_size = big_ram->ram_size[dev_data->chip_id]; 30218c2ecf20Sopenharmony_ci 30228c2ecf20Sopenharmony_ci reg_val = qed_rd(p_hwfn, p_ptt, big_ram->is_256b_reg_addr); 30238c2ecf20Sopenharmony_ci block_size = reg_val & 30248c2ecf20Sopenharmony_ci BIT(big_ram->is_256b_bit_offset[dev_data->chip_id]) ? 256 30258c2ecf20Sopenharmony_ci : 128; 30268c2ecf20Sopenharmony_ci 30278c2ecf20Sopenharmony_ci strncpy(type_name, big_ram->instance_name, BIG_RAM_NAME_LEN); 30288c2ecf20Sopenharmony_ci strncpy(mem_name, big_ram->instance_name, BIG_RAM_NAME_LEN); 30298c2ecf20Sopenharmony_ci 30308c2ecf20Sopenharmony_ci /* Dump memory header */ 30318c2ecf20Sopenharmony_ci offset += qed_grc_dump_mem_hdr(p_hwfn, 30328c2ecf20Sopenharmony_ci dump_buf + offset, 30338c2ecf20Sopenharmony_ci dump, 30348c2ecf20Sopenharmony_ci mem_name, 30358c2ecf20Sopenharmony_ci 0, 30368c2ecf20Sopenharmony_ci ram_size, 30378c2ecf20Sopenharmony_ci block_size * 8, 30388c2ecf20Sopenharmony_ci false, type_name, 0); 30398c2ecf20Sopenharmony_ci 30408c2ecf20Sopenharmony_ci /* Read and dump Big RAM data */ 30418c2ecf20Sopenharmony_ci if (!dump) 30428c2ecf20Sopenharmony_ci return offset + ram_size; 30438c2ecf20Sopenharmony_ci 30448c2ecf20Sopenharmony_ci /* Dump Big RAM */ 30458c2ecf20Sopenharmony_ci for (i = 0; i < DIV_ROUND_UP(ram_size, BRB_REG_BIG_RAM_DATA_SIZE); 30468c2ecf20Sopenharmony_ci i++) { 30478c2ecf20Sopenharmony_ci u32 addr, len; 30488c2ecf20Sopenharmony_ci 30498c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, big_ram->addr_reg_addr, i); 30508c2ecf20Sopenharmony_ci addr = BYTES_TO_DWORDS(big_ram->data_reg_addr); 30518c2ecf20Sopenharmony_ci len = BRB_REG_BIG_RAM_DATA_SIZE; 30528c2ecf20Sopenharmony_ci offset += qed_grc_dump_addr_range(p_hwfn, 30538c2ecf20Sopenharmony_ci p_ptt, 30548c2ecf20Sopenharmony_ci dump_buf + offset, 30558c2ecf20Sopenharmony_ci dump, 30568c2ecf20Sopenharmony_ci addr, 30578c2ecf20Sopenharmony_ci len, 30588c2ecf20Sopenharmony_ci false, SPLIT_TYPE_NONE, 0); 30598c2ecf20Sopenharmony_ci } 30608c2ecf20Sopenharmony_ci 30618c2ecf20Sopenharmony_ci return offset; 30628c2ecf20Sopenharmony_ci} 30638c2ecf20Sopenharmony_ci 30648c2ecf20Sopenharmony_ci/* Dumps MCP scratchpad. Returns the dumped size in dwords. */ 30658c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_mcp(struct qed_hwfn *p_hwfn, 30668c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) 30678c2ecf20Sopenharmony_ci{ 30688c2ecf20Sopenharmony_ci bool block_enable[MAX_BLOCK_ID] = { 0 }; 30698c2ecf20Sopenharmony_ci u32 offset = 0, addr; 30708c2ecf20Sopenharmony_ci bool halted = false; 30718c2ecf20Sopenharmony_ci 30728c2ecf20Sopenharmony_ci /* Halt MCP */ 30738c2ecf20Sopenharmony_ci if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) { 30748c2ecf20Sopenharmony_ci halted = !qed_mcp_halt(p_hwfn, p_ptt); 30758c2ecf20Sopenharmony_ci if (!halted) 30768c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, "MCP halt failed!\n"); 30778c2ecf20Sopenharmony_ci } 30788c2ecf20Sopenharmony_ci 30798c2ecf20Sopenharmony_ci /* Dump MCP scratchpad */ 30808c2ecf20Sopenharmony_ci offset += qed_grc_dump_mem(p_hwfn, 30818c2ecf20Sopenharmony_ci p_ptt, 30828c2ecf20Sopenharmony_ci dump_buf + offset, 30838c2ecf20Sopenharmony_ci dump, 30848c2ecf20Sopenharmony_ci NULL, 30858c2ecf20Sopenharmony_ci BYTES_TO_DWORDS(MCP_REG_SCRATCH), 30868c2ecf20Sopenharmony_ci MCP_REG_SCRATCH_SIZE, 30878c2ecf20Sopenharmony_ci false, 0, false, "MCP", 0); 30888c2ecf20Sopenharmony_ci 30898c2ecf20Sopenharmony_ci /* Dump MCP cpu_reg_file */ 30908c2ecf20Sopenharmony_ci offset += qed_grc_dump_mem(p_hwfn, 30918c2ecf20Sopenharmony_ci p_ptt, 30928c2ecf20Sopenharmony_ci dump_buf + offset, 30938c2ecf20Sopenharmony_ci dump, 30948c2ecf20Sopenharmony_ci NULL, 30958c2ecf20Sopenharmony_ci BYTES_TO_DWORDS(MCP_REG_CPU_REG_FILE), 30968c2ecf20Sopenharmony_ci MCP_REG_CPU_REG_FILE_SIZE, 30978c2ecf20Sopenharmony_ci false, 0, false, "MCP", 0); 30988c2ecf20Sopenharmony_ci 30998c2ecf20Sopenharmony_ci /* Dump MCP registers */ 31008c2ecf20Sopenharmony_ci block_enable[BLOCK_MCP] = true; 31018c2ecf20Sopenharmony_ci offset += qed_grc_dump_registers(p_hwfn, 31028c2ecf20Sopenharmony_ci p_ptt, 31038c2ecf20Sopenharmony_ci dump_buf + offset, 31048c2ecf20Sopenharmony_ci dump, block_enable, "MCP"); 31058c2ecf20Sopenharmony_ci 31068c2ecf20Sopenharmony_ci /* Dump required non-MCP registers */ 31078c2ecf20Sopenharmony_ci offset += qed_grc_dump_regs_hdr(dump_buf + offset, 31088c2ecf20Sopenharmony_ci dump, 1, SPLIT_TYPE_NONE, 0, 31098c2ecf20Sopenharmony_ci "MCP"); 31108c2ecf20Sopenharmony_ci addr = BYTES_TO_DWORDS(MISC_REG_SHARED_MEM_ADDR); 31118c2ecf20Sopenharmony_ci offset += qed_grc_dump_reg_entry(p_hwfn, 31128c2ecf20Sopenharmony_ci p_ptt, 31138c2ecf20Sopenharmony_ci dump_buf + offset, 31148c2ecf20Sopenharmony_ci dump, 31158c2ecf20Sopenharmony_ci addr, 31168c2ecf20Sopenharmony_ci 1, 31178c2ecf20Sopenharmony_ci false, SPLIT_TYPE_NONE, 0); 31188c2ecf20Sopenharmony_ci 31198c2ecf20Sopenharmony_ci /* Release MCP */ 31208c2ecf20Sopenharmony_ci if (halted && qed_mcp_resume(p_hwfn, p_ptt)) 31218c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n"); 31228c2ecf20Sopenharmony_ci 31238c2ecf20Sopenharmony_ci return offset; 31248c2ecf20Sopenharmony_ci} 31258c2ecf20Sopenharmony_ci 31268c2ecf20Sopenharmony_ci/* Dumps the tbus indirect memory for all PHYs. 31278c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 31288c2ecf20Sopenharmony_ci */ 31298c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_phy(struct qed_hwfn *p_hwfn, 31308c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) 31318c2ecf20Sopenharmony_ci{ 31328c2ecf20Sopenharmony_ci u32 offset = 0, tbus_lo_offset, tbus_hi_offset; 31338c2ecf20Sopenharmony_ci char mem_name[32]; 31348c2ecf20Sopenharmony_ci u8 phy_id; 31358c2ecf20Sopenharmony_ci 31368c2ecf20Sopenharmony_ci for (phy_id = 0; phy_id < ARRAY_SIZE(s_phy_defs); phy_id++) { 31378c2ecf20Sopenharmony_ci u32 addr_lo_addr, addr_hi_addr, data_lo_addr, data_hi_addr; 31388c2ecf20Sopenharmony_ci struct phy_defs *phy_defs; 31398c2ecf20Sopenharmony_ci u8 *bytes_buf; 31408c2ecf20Sopenharmony_ci 31418c2ecf20Sopenharmony_ci phy_defs = &s_phy_defs[phy_id]; 31428c2ecf20Sopenharmony_ci addr_lo_addr = phy_defs->base_addr + 31438c2ecf20Sopenharmony_ci phy_defs->tbus_addr_lo_addr; 31448c2ecf20Sopenharmony_ci addr_hi_addr = phy_defs->base_addr + 31458c2ecf20Sopenharmony_ci phy_defs->tbus_addr_hi_addr; 31468c2ecf20Sopenharmony_ci data_lo_addr = phy_defs->base_addr + 31478c2ecf20Sopenharmony_ci phy_defs->tbus_data_lo_addr; 31488c2ecf20Sopenharmony_ci data_hi_addr = phy_defs->base_addr + 31498c2ecf20Sopenharmony_ci phy_defs->tbus_data_hi_addr; 31508c2ecf20Sopenharmony_ci 31518c2ecf20Sopenharmony_ci if (snprintf(mem_name, sizeof(mem_name), "tbus_%s", 31528c2ecf20Sopenharmony_ci phy_defs->phy_name) < 0) 31538c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, 31548c2ecf20Sopenharmony_ci "Unexpected debug error: invalid PHY memory name\n"); 31558c2ecf20Sopenharmony_ci 31568c2ecf20Sopenharmony_ci offset += qed_grc_dump_mem_hdr(p_hwfn, 31578c2ecf20Sopenharmony_ci dump_buf + offset, 31588c2ecf20Sopenharmony_ci dump, 31598c2ecf20Sopenharmony_ci mem_name, 31608c2ecf20Sopenharmony_ci 0, 31618c2ecf20Sopenharmony_ci PHY_DUMP_SIZE_DWORDS, 31628c2ecf20Sopenharmony_ci 16, true, mem_name, 0); 31638c2ecf20Sopenharmony_ci 31648c2ecf20Sopenharmony_ci if (!dump) { 31658c2ecf20Sopenharmony_ci offset += PHY_DUMP_SIZE_DWORDS; 31668c2ecf20Sopenharmony_ci continue; 31678c2ecf20Sopenharmony_ci } 31688c2ecf20Sopenharmony_ci 31698c2ecf20Sopenharmony_ci bytes_buf = (u8 *)(dump_buf + offset); 31708c2ecf20Sopenharmony_ci for (tbus_hi_offset = 0; 31718c2ecf20Sopenharmony_ci tbus_hi_offset < (NUM_PHY_TBUS_ADDRESSES >> 8); 31728c2ecf20Sopenharmony_ci tbus_hi_offset++) { 31738c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, addr_hi_addr, tbus_hi_offset); 31748c2ecf20Sopenharmony_ci for (tbus_lo_offset = 0; tbus_lo_offset < 256; 31758c2ecf20Sopenharmony_ci tbus_lo_offset++) { 31768c2ecf20Sopenharmony_ci qed_wr(p_hwfn, 31778c2ecf20Sopenharmony_ci p_ptt, addr_lo_addr, tbus_lo_offset); 31788c2ecf20Sopenharmony_ci *(bytes_buf++) = (u8)qed_rd(p_hwfn, 31798c2ecf20Sopenharmony_ci p_ptt, 31808c2ecf20Sopenharmony_ci data_lo_addr); 31818c2ecf20Sopenharmony_ci *(bytes_buf++) = (u8)qed_rd(p_hwfn, 31828c2ecf20Sopenharmony_ci p_ptt, 31838c2ecf20Sopenharmony_ci data_hi_addr); 31848c2ecf20Sopenharmony_ci } 31858c2ecf20Sopenharmony_ci } 31868c2ecf20Sopenharmony_ci 31878c2ecf20Sopenharmony_ci offset += PHY_DUMP_SIZE_DWORDS; 31888c2ecf20Sopenharmony_ci } 31898c2ecf20Sopenharmony_ci 31908c2ecf20Sopenharmony_ci return offset; 31918c2ecf20Sopenharmony_ci} 31928c2ecf20Sopenharmony_ci 31938c2ecf20Sopenharmony_cistatic enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn, 31948c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 31958c2ecf20Sopenharmony_ci u32 image_type, 31968c2ecf20Sopenharmony_ci u32 *nvram_offset_bytes, 31978c2ecf20Sopenharmony_ci u32 *nvram_size_bytes); 31988c2ecf20Sopenharmony_ci 31998c2ecf20Sopenharmony_cistatic enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn, 32008c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 32018c2ecf20Sopenharmony_ci u32 nvram_offset_bytes, 32028c2ecf20Sopenharmony_ci u32 nvram_size_bytes, u32 *ret_buf); 32038c2ecf20Sopenharmony_ci 32048c2ecf20Sopenharmony_ci/* Dumps the MCP HW dump from NVRAM. Returns the dumped size in dwords. */ 32058c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn, 32068c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 32078c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump) 32088c2ecf20Sopenharmony_ci{ 32098c2ecf20Sopenharmony_ci u32 hw_dump_offset_bytes = 0, hw_dump_size_bytes = 0; 32108c2ecf20Sopenharmony_ci u32 hw_dump_size_dwords = 0, offset = 0; 32118c2ecf20Sopenharmony_ci enum dbg_status status; 32128c2ecf20Sopenharmony_ci 32138c2ecf20Sopenharmony_ci /* Read HW dump image from NVRAM */ 32148c2ecf20Sopenharmony_ci status = qed_find_nvram_image(p_hwfn, 32158c2ecf20Sopenharmony_ci p_ptt, 32168c2ecf20Sopenharmony_ci NVM_TYPE_HW_DUMP_OUT, 32178c2ecf20Sopenharmony_ci &hw_dump_offset_bytes, 32188c2ecf20Sopenharmony_ci &hw_dump_size_bytes); 32198c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 32208c2ecf20Sopenharmony_ci return 0; 32218c2ecf20Sopenharmony_ci 32228c2ecf20Sopenharmony_ci hw_dump_size_dwords = BYTES_TO_DWORDS(hw_dump_size_bytes); 32238c2ecf20Sopenharmony_ci 32248c2ecf20Sopenharmony_ci /* Dump HW dump image section */ 32258c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 32268c2ecf20Sopenharmony_ci dump, "mcp_hw_dump", 1); 32278c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 32288c2ecf20Sopenharmony_ci dump, "size", hw_dump_size_dwords); 32298c2ecf20Sopenharmony_ci 32308c2ecf20Sopenharmony_ci /* Read MCP HW dump image into dump buffer */ 32318c2ecf20Sopenharmony_ci if (dump && hw_dump_size_dwords) { 32328c2ecf20Sopenharmony_ci status = qed_nvram_read(p_hwfn, 32338c2ecf20Sopenharmony_ci p_ptt, 32348c2ecf20Sopenharmony_ci hw_dump_offset_bytes, 32358c2ecf20Sopenharmony_ci hw_dump_size_bytes, dump_buf + offset); 32368c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) { 32378c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, 32388c2ecf20Sopenharmony_ci "Failed to read MCP HW Dump image from NVRAM\n"); 32398c2ecf20Sopenharmony_ci return 0; 32408c2ecf20Sopenharmony_ci } 32418c2ecf20Sopenharmony_ci } 32428c2ecf20Sopenharmony_ci offset += hw_dump_size_dwords; 32438c2ecf20Sopenharmony_ci 32448c2ecf20Sopenharmony_ci return offset; 32458c2ecf20Sopenharmony_ci} 32468c2ecf20Sopenharmony_ci 32478c2ecf20Sopenharmony_ci/* Dumps Static Debug data. Returns the dumped size in dwords. */ 32488c2ecf20Sopenharmony_cistatic u32 qed_grc_dump_static_debug(struct qed_hwfn *p_hwfn, 32498c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 32508c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump) 32518c2ecf20Sopenharmony_ci{ 32528c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 32538c2ecf20Sopenharmony_ci u32 block_id, line_id, offset = 0, addr, len; 32548c2ecf20Sopenharmony_ci 32558c2ecf20Sopenharmony_ci /* Don't dump static debug if a debug bus recording is in progress */ 32568c2ecf20Sopenharmony_ci if (dump && qed_rd(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON)) 32578c2ecf20Sopenharmony_ci return 0; 32588c2ecf20Sopenharmony_ci 32598c2ecf20Sopenharmony_ci if (dump) { 32608c2ecf20Sopenharmony_ci /* Disable debug bus in all blocks */ 32618c2ecf20Sopenharmony_ci qed_bus_disable_blocks(p_hwfn, p_ptt); 32628c2ecf20Sopenharmony_ci 32638c2ecf20Sopenharmony_ci qed_bus_reset_dbg_block(p_hwfn, p_ptt); 32648c2ecf20Sopenharmony_ci qed_wr(p_hwfn, 32658c2ecf20Sopenharmony_ci p_ptt, DBG_REG_FRAMING_MODE, DBG_BUS_FRAME_MODE_8HW); 32668c2ecf20Sopenharmony_ci qed_wr(p_hwfn, 32678c2ecf20Sopenharmony_ci p_ptt, DBG_REG_DEBUG_TARGET, DBG_BUS_TARGET_ID_INT_BUF); 32688c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, DBG_REG_FULL_MODE, 1); 32698c2ecf20Sopenharmony_ci qed_bus_enable_dbg_block(p_hwfn, p_ptt, true); 32708c2ecf20Sopenharmony_ci } 32718c2ecf20Sopenharmony_ci 32728c2ecf20Sopenharmony_ci /* Dump all static debug lines for each relevant block */ 32738c2ecf20Sopenharmony_ci for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) { 32748c2ecf20Sopenharmony_ci const struct dbg_block_chip *block_per_chip; 32758c2ecf20Sopenharmony_ci const struct dbg_block *block; 32768c2ecf20Sopenharmony_ci bool is_removed, has_dbg_bus; 32778c2ecf20Sopenharmony_ci u16 modes_buf_offset; 32788c2ecf20Sopenharmony_ci u32 block_dwords; 32798c2ecf20Sopenharmony_ci 32808c2ecf20Sopenharmony_ci block_per_chip = 32818c2ecf20Sopenharmony_ci qed_get_dbg_block_per_chip(p_hwfn, (enum block_id)block_id); 32828c2ecf20Sopenharmony_ci is_removed = GET_FIELD(block_per_chip->flags, 32838c2ecf20Sopenharmony_ci DBG_BLOCK_CHIP_IS_REMOVED); 32848c2ecf20Sopenharmony_ci has_dbg_bus = GET_FIELD(block_per_chip->flags, 32858c2ecf20Sopenharmony_ci DBG_BLOCK_CHIP_HAS_DBG_BUS); 32868c2ecf20Sopenharmony_ci 32878c2ecf20Sopenharmony_ci /* read+clear for NWS parity is not working, skip NWS block */ 32888c2ecf20Sopenharmony_ci if (block_id == BLOCK_NWS) 32898c2ecf20Sopenharmony_ci continue; 32908c2ecf20Sopenharmony_ci 32918c2ecf20Sopenharmony_ci if (!is_removed && has_dbg_bus && 32928c2ecf20Sopenharmony_ci GET_FIELD(block_per_chip->dbg_bus_mode.data, 32938c2ecf20Sopenharmony_ci DBG_MODE_HDR_EVAL_MODE) > 0) { 32948c2ecf20Sopenharmony_ci modes_buf_offset = 32958c2ecf20Sopenharmony_ci GET_FIELD(block_per_chip->dbg_bus_mode.data, 32968c2ecf20Sopenharmony_ci DBG_MODE_HDR_MODES_BUF_OFFSET); 32978c2ecf20Sopenharmony_ci if (!qed_is_mode_match(p_hwfn, &modes_buf_offset)) 32988c2ecf20Sopenharmony_ci has_dbg_bus = false; 32998c2ecf20Sopenharmony_ci } 33008c2ecf20Sopenharmony_ci 33018c2ecf20Sopenharmony_ci if (is_removed || !has_dbg_bus) 33028c2ecf20Sopenharmony_ci continue; 33038c2ecf20Sopenharmony_ci 33048c2ecf20Sopenharmony_ci block_dwords = NUM_DBG_LINES(block_per_chip) * 33058c2ecf20Sopenharmony_ci STATIC_DEBUG_LINE_DWORDS; 33068c2ecf20Sopenharmony_ci 33078c2ecf20Sopenharmony_ci /* Dump static section params */ 33088c2ecf20Sopenharmony_ci block = get_dbg_block(p_hwfn, (enum block_id)block_id); 33098c2ecf20Sopenharmony_ci offset += qed_grc_dump_mem_hdr(p_hwfn, 33108c2ecf20Sopenharmony_ci dump_buf + offset, 33118c2ecf20Sopenharmony_ci dump, 33128c2ecf20Sopenharmony_ci block->name, 33138c2ecf20Sopenharmony_ci 0, 33148c2ecf20Sopenharmony_ci block_dwords, 33158c2ecf20Sopenharmony_ci 32, false, "STATIC", 0); 33168c2ecf20Sopenharmony_ci 33178c2ecf20Sopenharmony_ci if (!dump) { 33188c2ecf20Sopenharmony_ci offset += block_dwords; 33198c2ecf20Sopenharmony_ci continue; 33208c2ecf20Sopenharmony_ci } 33218c2ecf20Sopenharmony_ci 33228c2ecf20Sopenharmony_ci /* If all lines are invalid - dump zeros */ 33238c2ecf20Sopenharmony_ci if (dev_data->block_in_reset[block_id]) { 33248c2ecf20Sopenharmony_ci memset(dump_buf + offset, 0, 33258c2ecf20Sopenharmony_ci DWORDS_TO_BYTES(block_dwords)); 33268c2ecf20Sopenharmony_ci offset += block_dwords; 33278c2ecf20Sopenharmony_ci continue; 33288c2ecf20Sopenharmony_ci } 33298c2ecf20Sopenharmony_ci 33308c2ecf20Sopenharmony_ci /* Enable block's client */ 33318c2ecf20Sopenharmony_ci qed_bus_enable_clients(p_hwfn, 33328c2ecf20Sopenharmony_ci p_ptt, 33338c2ecf20Sopenharmony_ci BIT(block_per_chip->dbg_client_id)); 33348c2ecf20Sopenharmony_ci 33358c2ecf20Sopenharmony_ci addr = BYTES_TO_DWORDS(DBG_REG_CALENDAR_OUT_DATA); 33368c2ecf20Sopenharmony_ci len = STATIC_DEBUG_LINE_DWORDS; 33378c2ecf20Sopenharmony_ci for (line_id = 0; line_id < (u32)NUM_DBG_LINES(block_per_chip); 33388c2ecf20Sopenharmony_ci line_id++) { 33398c2ecf20Sopenharmony_ci /* Configure debug line ID */ 33408c2ecf20Sopenharmony_ci qed_bus_config_dbg_line(p_hwfn, 33418c2ecf20Sopenharmony_ci p_ptt, 33428c2ecf20Sopenharmony_ci (enum block_id)block_id, 33438c2ecf20Sopenharmony_ci (u8)line_id, 0xf, 0, 0, 0); 33448c2ecf20Sopenharmony_ci 33458c2ecf20Sopenharmony_ci /* Read debug line info */ 33468c2ecf20Sopenharmony_ci offset += qed_grc_dump_addr_range(p_hwfn, 33478c2ecf20Sopenharmony_ci p_ptt, 33488c2ecf20Sopenharmony_ci dump_buf + offset, 33498c2ecf20Sopenharmony_ci dump, 33508c2ecf20Sopenharmony_ci addr, 33518c2ecf20Sopenharmony_ci len, 33528c2ecf20Sopenharmony_ci true, SPLIT_TYPE_NONE, 33538c2ecf20Sopenharmony_ci 0); 33548c2ecf20Sopenharmony_ci } 33558c2ecf20Sopenharmony_ci 33568c2ecf20Sopenharmony_ci /* Disable block's client and debug output */ 33578c2ecf20Sopenharmony_ci qed_bus_enable_clients(p_hwfn, p_ptt, 0); 33588c2ecf20Sopenharmony_ci qed_bus_config_dbg_line(p_hwfn, p_ptt, 33598c2ecf20Sopenharmony_ci (enum block_id)block_id, 0, 0, 0, 0, 0); 33608c2ecf20Sopenharmony_ci } 33618c2ecf20Sopenharmony_ci 33628c2ecf20Sopenharmony_ci if (dump) { 33638c2ecf20Sopenharmony_ci qed_bus_enable_dbg_block(p_hwfn, p_ptt, false); 33648c2ecf20Sopenharmony_ci qed_bus_enable_clients(p_hwfn, p_ptt, 0); 33658c2ecf20Sopenharmony_ci } 33668c2ecf20Sopenharmony_ci 33678c2ecf20Sopenharmony_ci return offset; 33688c2ecf20Sopenharmony_ci} 33698c2ecf20Sopenharmony_ci 33708c2ecf20Sopenharmony_ci/* Performs GRC Dump to the specified buffer. 33718c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 33728c2ecf20Sopenharmony_ci */ 33738c2ecf20Sopenharmony_cistatic enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn, 33748c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 33758c2ecf20Sopenharmony_ci u32 *dump_buf, 33768c2ecf20Sopenharmony_ci bool dump, u32 *num_dumped_dwords) 33778c2ecf20Sopenharmony_ci{ 33788c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 33798c2ecf20Sopenharmony_ci u32 dwords_read, offset = 0; 33808c2ecf20Sopenharmony_ci bool parities_masked = false; 33818c2ecf20Sopenharmony_ci u8 i; 33828c2ecf20Sopenharmony_ci 33838c2ecf20Sopenharmony_ci *num_dumped_dwords = 0; 33848c2ecf20Sopenharmony_ci dev_data->num_regs_read = 0; 33858c2ecf20Sopenharmony_ci 33868c2ecf20Sopenharmony_ci /* Update reset state */ 33878c2ecf20Sopenharmony_ci if (dump) 33888c2ecf20Sopenharmony_ci qed_update_blocks_reset_state(p_hwfn, p_ptt); 33898c2ecf20Sopenharmony_ci 33908c2ecf20Sopenharmony_ci /* Dump global params */ 33918c2ecf20Sopenharmony_ci offset += qed_dump_common_global_params(p_hwfn, 33928c2ecf20Sopenharmony_ci p_ptt, 33938c2ecf20Sopenharmony_ci dump_buf + offset, dump, 4); 33948c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 33958c2ecf20Sopenharmony_ci dump, "dump-type", "grc-dump"); 33968c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 33978c2ecf20Sopenharmony_ci dump, 33988c2ecf20Sopenharmony_ci "num-lcids", 33998c2ecf20Sopenharmony_ci NUM_OF_LCIDS); 34008c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 34018c2ecf20Sopenharmony_ci dump, 34028c2ecf20Sopenharmony_ci "num-ltids", 34038c2ecf20Sopenharmony_ci NUM_OF_LTIDS); 34048c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 34058c2ecf20Sopenharmony_ci dump, "num-ports", dev_data->num_ports); 34068c2ecf20Sopenharmony_ci 34078c2ecf20Sopenharmony_ci /* Dump reset registers (dumped before taking blocks out of reset ) */ 34088c2ecf20Sopenharmony_ci if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS)) 34098c2ecf20Sopenharmony_ci offset += qed_grc_dump_reset_regs(p_hwfn, 34108c2ecf20Sopenharmony_ci p_ptt, 34118c2ecf20Sopenharmony_ci dump_buf + offset, dump); 34128c2ecf20Sopenharmony_ci 34138c2ecf20Sopenharmony_ci /* Take all blocks out of reset (using reset registers) */ 34148c2ecf20Sopenharmony_ci if (dump) { 34158c2ecf20Sopenharmony_ci qed_grc_unreset_blocks(p_hwfn, p_ptt, false); 34168c2ecf20Sopenharmony_ci qed_update_blocks_reset_state(p_hwfn, p_ptt); 34178c2ecf20Sopenharmony_ci } 34188c2ecf20Sopenharmony_ci 34198c2ecf20Sopenharmony_ci /* Disable all parities using MFW command */ 34208c2ecf20Sopenharmony_ci if (dump && 34218c2ecf20Sopenharmony_ci !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) { 34228c2ecf20Sopenharmony_ci parities_masked = !qed_mcp_mask_parities(p_hwfn, p_ptt, 1); 34238c2ecf20Sopenharmony_ci if (!parities_masked) { 34248c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, 34258c2ecf20Sopenharmony_ci "Failed to mask parities using MFW\n"); 34268c2ecf20Sopenharmony_ci if (qed_grc_get_param 34278c2ecf20Sopenharmony_ci (p_hwfn, DBG_GRC_PARAM_PARITY_SAFE)) 34288c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_COULD_NOT_MASK_PRTY; 34298c2ecf20Sopenharmony_ci } 34308c2ecf20Sopenharmony_ci } 34318c2ecf20Sopenharmony_ci 34328c2ecf20Sopenharmony_ci /* Dump modified registers (dumped before modifying them) */ 34338c2ecf20Sopenharmony_ci if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS)) 34348c2ecf20Sopenharmony_ci offset += qed_grc_dump_modified_regs(p_hwfn, 34358c2ecf20Sopenharmony_ci p_ptt, 34368c2ecf20Sopenharmony_ci dump_buf + offset, dump); 34378c2ecf20Sopenharmony_ci 34388c2ecf20Sopenharmony_ci /* Stall storms */ 34398c2ecf20Sopenharmony_ci if (dump && 34408c2ecf20Sopenharmony_ci (qed_grc_is_included(p_hwfn, 34418c2ecf20Sopenharmony_ci DBG_GRC_PARAM_DUMP_IOR) || 34428c2ecf20Sopenharmony_ci qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC))) 34438c2ecf20Sopenharmony_ci qed_grc_stall_storms(p_hwfn, p_ptt, true); 34448c2ecf20Sopenharmony_ci 34458c2ecf20Sopenharmony_ci /* Dump all regs */ 34468c2ecf20Sopenharmony_ci if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS)) { 34478c2ecf20Sopenharmony_ci bool block_enable[MAX_BLOCK_ID]; 34488c2ecf20Sopenharmony_ci 34498c2ecf20Sopenharmony_ci /* Dump all blocks except MCP */ 34508c2ecf20Sopenharmony_ci for (i = 0; i < MAX_BLOCK_ID; i++) 34518c2ecf20Sopenharmony_ci block_enable[i] = true; 34528c2ecf20Sopenharmony_ci block_enable[BLOCK_MCP] = false; 34538c2ecf20Sopenharmony_ci offset += qed_grc_dump_registers(p_hwfn, 34548c2ecf20Sopenharmony_ci p_ptt, 34558c2ecf20Sopenharmony_ci dump_buf + 34568c2ecf20Sopenharmony_ci offset, 34578c2ecf20Sopenharmony_ci dump, 34588c2ecf20Sopenharmony_ci block_enable, NULL); 34598c2ecf20Sopenharmony_ci 34608c2ecf20Sopenharmony_ci /* Dump special registers */ 34618c2ecf20Sopenharmony_ci offset += qed_grc_dump_special_regs(p_hwfn, 34628c2ecf20Sopenharmony_ci p_ptt, 34638c2ecf20Sopenharmony_ci dump_buf + offset, dump); 34648c2ecf20Sopenharmony_ci } 34658c2ecf20Sopenharmony_ci 34668c2ecf20Sopenharmony_ci /* Dump memories */ 34678c2ecf20Sopenharmony_ci offset += qed_grc_dump_memories(p_hwfn, p_ptt, dump_buf + offset, dump); 34688c2ecf20Sopenharmony_ci 34698c2ecf20Sopenharmony_ci /* Dump MCP */ 34708c2ecf20Sopenharmony_ci if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP)) 34718c2ecf20Sopenharmony_ci offset += qed_grc_dump_mcp(p_hwfn, 34728c2ecf20Sopenharmony_ci p_ptt, dump_buf + offset, dump); 34738c2ecf20Sopenharmony_ci 34748c2ecf20Sopenharmony_ci /* Dump context */ 34758c2ecf20Sopenharmony_ci if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX)) 34768c2ecf20Sopenharmony_ci offset += qed_grc_dump_ctx(p_hwfn, 34778c2ecf20Sopenharmony_ci p_ptt, dump_buf + offset, dump); 34788c2ecf20Sopenharmony_ci 34798c2ecf20Sopenharmony_ci /* Dump RSS memories */ 34808c2ecf20Sopenharmony_ci if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RSS)) 34818c2ecf20Sopenharmony_ci offset += qed_grc_dump_rss(p_hwfn, 34828c2ecf20Sopenharmony_ci p_ptt, dump_buf + offset, dump); 34838c2ecf20Sopenharmony_ci 34848c2ecf20Sopenharmony_ci /* Dump Big RAM */ 34858c2ecf20Sopenharmony_ci for (i = 0; i < NUM_BIG_RAM_TYPES; i++) 34868c2ecf20Sopenharmony_ci if (qed_grc_is_included(p_hwfn, s_big_ram_defs[i].grc_param)) 34878c2ecf20Sopenharmony_ci offset += qed_grc_dump_big_ram(p_hwfn, 34888c2ecf20Sopenharmony_ci p_ptt, 34898c2ecf20Sopenharmony_ci dump_buf + offset, 34908c2ecf20Sopenharmony_ci dump, i); 34918c2ecf20Sopenharmony_ci 34928c2ecf20Sopenharmony_ci /* Dump VFC */ 34938c2ecf20Sopenharmony_ci if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)) { 34948c2ecf20Sopenharmony_ci dwords_read = qed_grc_dump_vfc(p_hwfn, 34958c2ecf20Sopenharmony_ci p_ptt, dump_buf + offset, dump); 34968c2ecf20Sopenharmony_ci offset += dwords_read; 34978c2ecf20Sopenharmony_ci if (!dwords_read) 34988c2ecf20Sopenharmony_ci return DBG_STATUS_VFC_READ_ERROR; 34998c2ecf20Sopenharmony_ci } 35008c2ecf20Sopenharmony_ci 35018c2ecf20Sopenharmony_ci /* Dump PHY tbus */ 35028c2ecf20Sopenharmony_ci if (qed_grc_is_included(p_hwfn, 35038c2ecf20Sopenharmony_ci DBG_GRC_PARAM_DUMP_PHY) && dev_data->chip_id == 35048c2ecf20Sopenharmony_ci CHIP_K2 && dev_data->hw_type == HW_TYPE_ASIC) 35058c2ecf20Sopenharmony_ci offset += qed_grc_dump_phy(p_hwfn, 35068c2ecf20Sopenharmony_ci p_ptt, dump_buf + offset, dump); 35078c2ecf20Sopenharmony_ci 35088c2ecf20Sopenharmony_ci /* Dump MCP HW Dump */ 35098c2ecf20Sopenharmony_ci if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP_HW_DUMP) && 35108c2ecf20Sopenharmony_ci !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP) && 1) 35118c2ecf20Sopenharmony_ci offset += qed_grc_dump_mcp_hw_dump(p_hwfn, 35128c2ecf20Sopenharmony_ci p_ptt, 35138c2ecf20Sopenharmony_ci dump_buf + offset, dump); 35148c2ecf20Sopenharmony_ci 35158c2ecf20Sopenharmony_ci /* Dump static debug data (only if not during debug bus recording) */ 35168c2ecf20Sopenharmony_ci if (qed_grc_is_included(p_hwfn, 35178c2ecf20Sopenharmony_ci DBG_GRC_PARAM_DUMP_STATIC) && 35188c2ecf20Sopenharmony_ci (!dump || dev_data->bus.state == DBG_BUS_STATE_IDLE)) 35198c2ecf20Sopenharmony_ci offset += qed_grc_dump_static_debug(p_hwfn, 35208c2ecf20Sopenharmony_ci p_ptt, 35218c2ecf20Sopenharmony_ci dump_buf + offset, dump); 35228c2ecf20Sopenharmony_ci 35238c2ecf20Sopenharmony_ci /* Dump last section */ 35248c2ecf20Sopenharmony_ci offset += qed_dump_last_section(dump_buf, offset, dump); 35258c2ecf20Sopenharmony_ci 35268c2ecf20Sopenharmony_ci if (dump) { 35278c2ecf20Sopenharmony_ci /* Unstall storms */ 35288c2ecf20Sopenharmony_ci if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_UNSTALL)) 35298c2ecf20Sopenharmony_ci qed_grc_stall_storms(p_hwfn, p_ptt, false); 35308c2ecf20Sopenharmony_ci 35318c2ecf20Sopenharmony_ci /* Clear parity status */ 35328c2ecf20Sopenharmony_ci qed_grc_clear_all_prty(p_hwfn, p_ptt); 35338c2ecf20Sopenharmony_ci 35348c2ecf20Sopenharmony_ci /* Enable all parities using MFW command */ 35358c2ecf20Sopenharmony_ci if (parities_masked) 35368c2ecf20Sopenharmony_ci qed_mcp_mask_parities(p_hwfn, p_ptt, 0); 35378c2ecf20Sopenharmony_ci } 35388c2ecf20Sopenharmony_ci 35398c2ecf20Sopenharmony_ci *num_dumped_dwords = offset; 35408c2ecf20Sopenharmony_ci 35418c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 35428c2ecf20Sopenharmony_ci} 35438c2ecf20Sopenharmony_ci 35448c2ecf20Sopenharmony_ci/* Writes the specified failing Idle Check rule to the specified buffer. 35458c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 35468c2ecf20Sopenharmony_ci */ 35478c2ecf20Sopenharmony_cistatic u32 qed_idle_chk_dump_failure(struct qed_hwfn *p_hwfn, 35488c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 35498c2ecf20Sopenharmony_ci u32 * 35508c2ecf20Sopenharmony_ci dump_buf, 35518c2ecf20Sopenharmony_ci bool dump, 35528c2ecf20Sopenharmony_ci u16 rule_id, 35538c2ecf20Sopenharmony_ci const struct dbg_idle_chk_rule *rule, 35548c2ecf20Sopenharmony_ci u16 fail_entry_id, u32 *cond_reg_values) 35558c2ecf20Sopenharmony_ci{ 35568c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 35578c2ecf20Sopenharmony_ci const struct dbg_idle_chk_cond_reg *cond_regs; 35588c2ecf20Sopenharmony_ci const struct dbg_idle_chk_info_reg *info_regs; 35598c2ecf20Sopenharmony_ci u32 i, next_reg_offset = 0, offset = 0; 35608c2ecf20Sopenharmony_ci struct dbg_idle_chk_result_hdr *hdr; 35618c2ecf20Sopenharmony_ci const union dbg_idle_chk_reg *regs; 35628c2ecf20Sopenharmony_ci u8 reg_id; 35638c2ecf20Sopenharmony_ci 35648c2ecf20Sopenharmony_ci hdr = (struct dbg_idle_chk_result_hdr *)dump_buf; 35658c2ecf20Sopenharmony_ci regs = (const union dbg_idle_chk_reg *) 35668c2ecf20Sopenharmony_ci p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr + 35678c2ecf20Sopenharmony_ci rule->reg_offset; 35688c2ecf20Sopenharmony_ci cond_regs = ®s[0].cond_reg; 35698c2ecf20Sopenharmony_ci info_regs = ®s[rule->num_cond_regs].info_reg; 35708c2ecf20Sopenharmony_ci 35718c2ecf20Sopenharmony_ci /* Dump rule data */ 35728c2ecf20Sopenharmony_ci if (dump) { 35738c2ecf20Sopenharmony_ci memset(hdr, 0, sizeof(*hdr)); 35748c2ecf20Sopenharmony_ci hdr->rule_id = rule_id; 35758c2ecf20Sopenharmony_ci hdr->mem_entry_id = fail_entry_id; 35768c2ecf20Sopenharmony_ci hdr->severity = rule->severity; 35778c2ecf20Sopenharmony_ci hdr->num_dumped_cond_regs = rule->num_cond_regs; 35788c2ecf20Sopenharmony_ci } 35798c2ecf20Sopenharmony_ci 35808c2ecf20Sopenharmony_ci offset += IDLE_CHK_RESULT_HDR_DWORDS; 35818c2ecf20Sopenharmony_ci 35828c2ecf20Sopenharmony_ci /* Dump condition register values */ 35838c2ecf20Sopenharmony_ci for (reg_id = 0; reg_id < rule->num_cond_regs; reg_id++) { 35848c2ecf20Sopenharmony_ci const struct dbg_idle_chk_cond_reg *reg = &cond_regs[reg_id]; 35858c2ecf20Sopenharmony_ci struct dbg_idle_chk_result_reg_hdr *reg_hdr; 35868c2ecf20Sopenharmony_ci 35878c2ecf20Sopenharmony_ci reg_hdr = 35888c2ecf20Sopenharmony_ci (struct dbg_idle_chk_result_reg_hdr *)(dump_buf + offset); 35898c2ecf20Sopenharmony_ci 35908c2ecf20Sopenharmony_ci /* Write register header */ 35918c2ecf20Sopenharmony_ci if (!dump) { 35928c2ecf20Sopenharmony_ci offset += IDLE_CHK_RESULT_REG_HDR_DWORDS + 35938c2ecf20Sopenharmony_ci reg->entry_size; 35948c2ecf20Sopenharmony_ci continue; 35958c2ecf20Sopenharmony_ci } 35968c2ecf20Sopenharmony_ci 35978c2ecf20Sopenharmony_ci offset += IDLE_CHK_RESULT_REG_HDR_DWORDS; 35988c2ecf20Sopenharmony_ci memset(reg_hdr, 0, sizeof(*reg_hdr)); 35998c2ecf20Sopenharmony_ci reg_hdr->start_entry = reg->start_entry; 36008c2ecf20Sopenharmony_ci reg_hdr->size = reg->entry_size; 36018c2ecf20Sopenharmony_ci SET_FIELD(reg_hdr->data, 36028c2ecf20Sopenharmony_ci DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM, 36038c2ecf20Sopenharmony_ci reg->num_entries > 1 || reg->start_entry > 0 ? 1 : 0); 36048c2ecf20Sopenharmony_ci SET_FIELD(reg_hdr->data, 36058c2ecf20Sopenharmony_ci DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID, reg_id); 36068c2ecf20Sopenharmony_ci 36078c2ecf20Sopenharmony_ci /* Write register values */ 36088c2ecf20Sopenharmony_ci for (i = 0; i < reg_hdr->size; i++, next_reg_offset++, offset++) 36098c2ecf20Sopenharmony_ci dump_buf[offset] = cond_reg_values[next_reg_offset]; 36108c2ecf20Sopenharmony_ci } 36118c2ecf20Sopenharmony_ci 36128c2ecf20Sopenharmony_ci /* Dump info register values */ 36138c2ecf20Sopenharmony_ci for (reg_id = 0; reg_id < rule->num_info_regs; reg_id++) { 36148c2ecf20Sopenharmony_ci const struct dbg_idle_chk_info_reg *reg = &info_regs[reg_id]; 36158c2ecf20Sopenharmony_ci u32 block_id; 36168c2ecf20Sopenharmony_ci 36178c2ecf20Sopenharmony_ci /* Check if register's block is in reset */ 36188c2ecf20Sopenharmony_ci if (!dump) { 36198c2ecf20Sopenharmony_ci offset += IDLE_CHK_RESULT_REG_HDR_DWORDS + reg->size; 36208c2ecf20Sopenharmony_ci continue; 36218c2ecf20Sopenharmony_ci } 36228c2ecf20Sopenharmony_ci 36238c2ecf20Sopenharmony_ci block_id = GET_FIELD(reg->data, DBG_IDLE_CHK_INFO_REG_BLOCK_ID); 36248c2ecf20Sopenharmony_ci if (block_id >= MAX_BLOCK_ID) { 36258c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, "Invalid block_id\n"); 36268c2ecf20Sopenharmony_ci return 0; 36278c2ecf20Sopenharmony_ci } 36288c2ecf20Sopenharmony_ci 36298c2ecf20Sopenharmony_ci if (!dev_data->block_in_reset[block_id]) { 36308c2ecf20Sopenharmony_ci struct dbg_idle_chk_result_reg_hdr *reg_hdr; 36318c2ecf20Sopenharmony_ci bool wide_bus, eval_mode, mode_match = true; 36328c2ecf20Sopenharmony_ci u16 modes_buf_offset; 36338c2ecf20Sopenharmony_ci u32 addr; 36348c2ecf20Sopenharmony_ci 36358c2ecf20Sopenharmony_ci reg_hdr = (struct dbg_idle_chk_result_reg_hdr *) 36368c2ecf20Sopenharmony_ci (dump_buf + offset); 36378c2ecf20Sopenharmony_ci 36388c2ecf20Sopenharmony_ci /* Check mode */ 36398c2ecf20Sopenharmony_ci eval_mode = GET_FIELD(reg->mode.data, 36408c2ecf20Sopenharmony_ci DBG_MODE_HDR_EVAL_MODE) > 0; 36418c2ecf20Sopenharmony_ci if (eval_mode) { 36428c2ecf20Sopenharmony_ci modes_buf_offset = 36438c2ecf20Sopenharmony_ci GET_FIELD(reg->mode.data, 36448c2ecf20Sopenharmony_ci DBG_MODE_HDR_MODES_BUF_OFFSET); 36458c2ecf20Sopenharmony_ci mode_match = 36468c2ecf20Sopenharmony_ci qed_is_mode_match(p_hwfn, 36478c2ecf20Sopenharmony_ci &modes_buf_offset); 36488c2ecf20Sopenharmony_ci } 36498c2ecf20Sopenharmony_ci 36508c2ecf20Sopenharmony_ci if (!mode_match) 36518c2ecf20Sopenharmony_ci continue; 36528c2ecf20Sopenharmony_ci 36538c2ecf20Sopenharmony_ci addr = GET_FIELD(reg->data, 36548c2ecf20Sopenharmony_ci DBG_IDLE_CHK_INFO_REG_ADDRESS); 36558c2ecf20Sopenharmony_ci wide_bus = GET_FIELD(reg->data, 36568c2ecf20Sopenharmony_ci DBG_IDLE_CHK_INFO_REG_WIDE_BUS); 36578c2ecf20Sopenharmony_ci 36588c2ecf20Sopenharmony_ci /* Write register header */ 36598c2ecf20Sopenharmony_ci offset += IDLE_CHK_RESULT_REG_HDR_DWORDS; 36608c2ecf20Sopenharmony_ci hdr->num_dumped_info_regs++; 36618c2ecf20Sopenharmony_ci memset(reg_hdr, 0, sizeof(*reg_hdr)); 36628c2ecf20Sopenharmony_ci reg_hdr->size = reg->size; 36638c2ecf20Sopenharmony_ci SET_FIELD(reg_hdr->data, 36648c2ecf20Sopenharmony_ci DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID, 36658c2ecf20Sopenharmony_ci rule->num_cond_regs + reg_id); 36668c2ecf20Sopenharmony_ci 36678c2ecf20Sopenharmony_ci /* Write register values */ 36688c2ecf20Sopenharmony_ci offset += qed_grc_dump_addr_range(p_hwfn, 36698c2ecf20Sopenharmony_ci p_ptt, 36708c2ecf20Sopenharmony_ci dump_buf + offset, 36718c2ecf20Sopenharmony_ci dump, 36728c2ecf20Sopenharmony_ci addr, 36738c2ecf20Sopenharmony_ci reg->size, wide_bus, 36748c2ecf20Sopenharmony_ci SPLIT_TYPE_NONE, 0); 36758c2ecf20Sopenharmony_ci } 36768c2ecf20Sopenharmony_ci } 36778c2ecf20Sopenharmony_ci 36788c2ecf20Sopenharmony_ci return offset; 36798c2ecf20Sopenharmony_ci} 36808c2ecf20Sopenharmony_ci 36818c2ecf20Sopenharmony_ci/* Dumps idle check rule entries. Returns the dumped size in dwords. */ 36828c2ecf20Sopenharmony_cistatic u32 36838c2ecf20Sopenharmony_ciqed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 36848c2ecf20Sopenharmony_ci u32 *dump_buf, bool dump, 36858c2ecf20Sopenharmony_ci const struct dbg_idle_chk_rule *input_rules, 36868c2ecf20Sopenharmony_ci u32 num_input_rules, u32 *num_failing_rules) 36878c2ecf20Sopenharmony_ci{ 36888c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 36898c2ecf20Sopenharmony_ci u32 cond_reg_values[IDLE_CHK_MAX_ENTRIES_SIZE]; 36908c2ecf20Sopenharmony_ci u32 i, offset = 0; 36918c2ecf20Sopenharmony_ci u16 entry_id; 36928c2ecf20Sopenharmony_ci u8 reg_id; 36938c2ecf20Sopenharmony_ci 36948c2ecf20Sopenharmony_ci *num_failing_rules = 0; 36958c2ecf20Sopenharmony_ci 36968c2ecf20Sopenharmony_ci for (i = 0; i < num_input_rules; i++) { 36978c2ecf20Sopenharmony_ci const struct dbg_idle_chk_cond_reg *cond_regs; 36988c2ecf20Sopenharmony_ci const struct dbg_idle_chk_rule *rule; 36998c2ecf20Sopenharmony_ci const union dbg_idle_chk_reg *regs; 37008c2ecf20Sopenharmony_ci u16 num_reg_entries = 1; 37018c2ecf20Sopenharmony_ci bool check_rule = true; 37028c2ecf20Sopenharmony_ci const u32 *imm_values; 37038c2ecf20Sopenharmony_ci 37048c2ecf20Sopenharmony_ci rule = &input_rules[i]; 37058c2ecf20Sopenharmony_ci regs = (const union dbg_idle_chk_reg *) 37068c2ecf20Sopenharmony_ci p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr + 37078c2ecf20Sopenharmony_ci rule->reg_offset; 37088c2ecf20Sopenharmony_ci cond_regs = ®s[0].cond_reg; 37098c2ecf20Sopenharmony_ci imm_values = 37108c2ecf20Sopenharmony_ci (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr + 37118c2ecf20Sopenharmony_ci rule->imm_offset; 37128c2ecf20Sopenharmony_ci 37138c2ecf20Sopenharmony_ci /* Check if all condition register blocks are out of reset, and 37148c2ecf20Sopenharmony_ci * find maximal number of entries (all condition registers that 37158c2ecf20Sopenharmony_ci * are memories must have the same size, which is > 1). 37168c2ecf20Sopenharmony_ci */ 37178c2ecf20Sopenharmony_ci for (reg_id = 0; reg_id < rule->num_cond_regs && check_rule; 37188c2ecf20Sopenharmony_ci reg_id++) { 37198c2ecf20Sopenharmony_ci u32 block_id = 37208c2ecf20Sopenharmony_ci GET_FIELD(cond_regs[reg_id].data, 37218c2ecf20Sopenharmony_ci DBG_IDLE_CHK_COND_REG_BLOCK_ID); 37228c2ecf20Sopenharmony_ci 37238c2ecf20Sopenharmony_ci if (block_id >= MAX_BLOCK_ID) { 37248c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, "Invalid block_id\n"); 37258c2ecf20Sopenharmony_ci return 0; 37268c2ecf20Sopenharmony_ci } 37278c2ecf20Sopenharmony_ci 37288c2ecf20Sopenharmony_ci check_rule = !dev_data->block_in_reset[block_id]; 37298c2ecf20Sopenharmony_ci if (cond_regs[reg_id].num_entries > num_reg_entries) 37308c2ecf20Sopenharmony_ci num_reg_entries = cond_regs[reg_id].num_entries; 37318c2ecf20Sopenharmony_ci } 37328c2ecf20Sopenharmony_ci 37338c2ecf20Sopenharmony_ci if (!check_rule && dump) 37348c2ecf20Sopenharmony_ci continue; 37358c2ecf20Sopenharmony_ci 37368c2ecf20Sopenharmony_ci if (!dump) { 37378c2ecf20Sopenharmony_ci u32 entry_dump_size = 37388c2ecf20Sopenharmony_ci qed_idle_chk_dump_failure(p_hwfn, 37398c2ecf20Sopenharmony_ci p_ptt, 37408c2ecf20Sopenharmony_ci dump_buf + offset, 37418c2ecf20Sopenharmony_ci false, 37428c2ecf20Sopenharmony_ci rule->rule_id, 37438c2ecf20Sopenharmony_ci rule, 37448c2ecf20Sopenharmony_ci 0, 37458c2ecf20Sopenharmony_ci NULL); 37468c2ecf20Sopenharmony_ci 37478c2ecf20Sopenharmony_ci offset += num_reg_entries * entry_dump_size; 37488c2ecf20Sopenharmony_ci (*num_failing_rules) += num_reg_entries; 37498c2ecf20Sopenharmony_ci continue; 37508c2ecf20Sopenharmony_ci } 37518c2ecf20Sopenharmony_ci 37528c2ecf20Sopenharmony_ci /* Go over all register entries (number of entries is the same 37538c2ecf20Sopenharmony_ci * for all condition registers). 37548c2ecf20Sopenharmony_ci */ 37558c2ecf20Sopenharmony_ci for (entry_id = 0; entry_id < num_reg_entries; entry_id++) { 37568c2ecf20Sopenharmony_ci u32 next_reg_offset = 0; 37578c2ecf20Sopenharmony_ci 37588c2ecf20Sopenharmony_ci /* Read current entry of all condition registers */ 37598c2ecf20Sopenharmony_ci for (reg_id = 0; reg_id < rule->num_cond_regs; 37608c2ecf20Sopenharmony_ci reg_id++) { 37618c2ecf20Sopenharmony_ci const struct dbg_idle_chk_cond_reg *reg = 37628c2ecf20Sopenharmony_ci &cond_regs[reg_id]; 37638c2ecf20Sopenharmony_ci u32 padded_entry_size, addr; 37648c2ecf20Sopenharmony_ci bool wide_bus; 37658c2ecf20Sopenharmony_ci 37668c2ecf20Sopenharmony_ci /* Find GRC address (if it's a memory, the 37678c2ecf20Sopenharmony_ci * address of the specific entry is calculated). 37688c2ecf20Sopenharmony_ci */ 37698c2ecf20Sopenharmony_ci addr = GET_FIELD(reg->data, 37708c2ecf20Sopenharmony_ci DBG_IDLE_CHK_COND_REG_ADDRESS); 37718c2ecf20Sopenharmony_ci wide_bus = 37728c2ecf20Sopenharmony_ci GET_FIELD(reg->data, 37738c2ecf20Sopenharmony_ci DBG_IDLE_CHK_COND_REG_WIDE_BUS); 37748c2ecf20Sopenharmony_ci if (reg->num_entries > 1 || 37758c2ecf20Sopenharmony_ci reg->start_entry > 0) { 37768c2ecf20Sopenharmony_ci padded_entry_size = 37778c2ecf20Sopenharmony_ci reg->entry_size > 1 ? 37788c2ecf20Sopenharmony_ci roundup_pow_of_two(reg->entry_size) : 37798c2ecf20Sopenharmony_ci 1; 37808c2ecf20Sopenharmony_ci addr += (reg->start_entry + entry_id) * 37818c2ecf20Sopenharmony_ci padded_entry_size; 37828c2ecf20Sopenharmony_ci } 37838c2ecf20Sopenharmony_ci 37848c2ecf20Sopenharmony_ci /* Read registers */ 37858c2ecf20Sopenharmony_ci if (next_reg_offset + reg->entry_size >= 37868c2ecf20Sopenharmony_ci IDLE_CHK_MAX_ENTRIES_SIZE) { 37878c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, 37888c2ecf20Sopenharmony_ci "idle check registers entry is too large\n"); 37898c2ecf20Sopenharmony_ci return 0; 37908c2ecf20Sopenharmony_ci } 37918c2ecf20Sopenharmony_ci 37928c2ecf20Sopenharmony_ci next_reg_offset += 37938c2ecf20Sopenharmony_ci qed_grc_dump_addr_range(p_hwfn, p_ptt, 37948c2ecf20Sopenharmony_ci cond_reg_values + 37958c2ecf20Sopenharmony_ci next_reg_offset, 37968c2ecf20Sopenharmony_ci dump, addr, 37978c2ecf20Sopenharmony_ci reg->entry_size, 37988c2ecf20Sopenharmony_ci wide_bus, 37998c2ecf20Sopenharmony_ci SPLIT_TYPE_NONE, 0); 38008c2ecf20Sopenharmony_ci } 38018c2ecf20Sopenharmony_ci 38028c2ecf20Sopenharmony_ci /* Call rule condition function. 38038c2ecf20Sopenharmony_ci * If returns true, it's a failure. 38048c2ecf20Sopenharmony_ci */ 38058c2ecf20Sopenharmony_ci if ((*cond_arr[rule->cond_id]) (cond_reg_values, 38068c2ecf20Sopenharmony_ci imm_values)) { 38078c2ecf20Sopenharmony_ci offset += qed_idle_chk_dump_failure(p_hwfn, 38088c2ecf20Sopenharmony_ci p_ptt, 38098c2ecf20Sopenharmony_ci dump_buf + offset, 38108c2ecf20Sopenharmony_ci dump, 38118c2ecf20Sopenharmony_ci rule->rule_id, 38128c2ecf20Sopenharmony_ci rule, 38138c2ecf20Sopenharmony_ci entry_id, 38148c2ecf20Sopenharmony_ci cond_reg_values); 38158c2ecf20Sopenharmony_ci (*num_failing_rules)++; 38168c2ecf20Sopenharmony_ci } 38178c2ecf20Sopenharmony_ci } 38188c2ecf20Sopenharmony_ci } 38198c2ecf20Sopenharmony_ci 38208c2ecf20Sopenharmony_ci return offset; 38218c2ecf20Sopenharmony_ci} 38228c2ecf20Sopenharmony_ci 38238c2ecf20Sopenharmony_ci/* Performs Idle Check Dump to the specified buffer. 38248c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 38258c2ecf20Sopenharmony_ci */ 38268c2ecf20Sopenharmony_cistatic u32 qed_idle_chk_dump(struct qed_hwfn *p_hwfn, 38278c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) 38288c2ecf20Sopenharmony_ci{ 38298c2ecf20Sopenharmony_ci struct virt_mem_desc *dbg_buf = 38308c2ecf20Sopenharmony_ci &p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES]; 38318c2ecf20Sopenharmony_ci u32 num_failing_rules_offset, offset = 0, 38328c2ecf20Sopenharmony_ci input_offset = 0, num_failing_rules = 0; 38338c2ecf20Sopenharmony_ci 38348c2ecf20Sopenharmony_ci /* Dump global params - 1 must match below amount of params */ 38358c2ecf20Sopenharmony_ci offset += qed_dump_common_global_params(p_hwfn, 38368c2ecf20Sopenharmony_ci p_ptt, 38378c2ecf20Sopenharmony_ci dump_buf + offset, dump, 1); 38388c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 38398c2ecf20Sopenharmony_ci dump, "dump-type", "idle-chk"); 38408c2ecf20Sopenharmony_ci 38418c2ecf20Sopenharmony_ci /* Dump idle check section header with a single parameter */ 38428c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, dump, "idle_chk", 1); 38438c2ecf20Sopenharmony_ci num_failing_rules_offset = offset; 38448c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, dump, "num_rules", 0); 38458c2ecf20Sopenharmony_ci 38468c2ecf20Sopenharmony_ci while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) { 38478c2ecf20Sopenharmony_ci const struct dbg_idle_chk_cond_hdr *cond_hdr = 38488c2ecf20Sopenharmony_ci (const struct dbg_idle_chk_cond_hdr *)dbg_buf->ptr + 38498c2ecf20Sopenharmony_ci input_offset++; 38508c2ecf20Sopenharmony_ci bool eval_mode, mode_match = true; 38518c2ecf20Sopenharmony_ci u32 curr_failing_rules; 38528c2ecf20Sopenharmony_ci u16 modes_buf_offset; 38538c2ecf20Sopenharmony_ci 38548c2ecf20Sopenharmony_ci /* Check mode */ 38558c2ecf20Sopenharmony_ci eval_mode = GET_FIELD(cond_hdr->mode.data, 38568c2ecf20Sopenharmony_ci DBG_MODE_HDR_EVAL_MODE) > 0; 38578c2ecf20Sopenharmony_ci if (eval_mode) { 38588c2ecf20Sopenharmony_ci modes_buf_offset = 38598c2ecf20Sopenharmony_ci GET_FIELD(cond_hdr->mode.data, 38608c2ecf20Sopenharmony_ci DBG_MODE_HDR_MODES_BUF_OFFSET); 38618c2ecf20Sopenharmony_ci mode_match = qed_is_mode_match(p_hwfn, 38628c2ecf20Sopenharmony_ci &modes_buf_offset); 38638c2ecf20Sopenharmony_ci } 38648c2ecf20Sopenharmony_ci 38658c2ecf20Sopenharmony_ci if (mode_match) { 38668c2ecf20Sopenharmony_ci const struct dbg_idle_chk_rule *rule = 38678c2ecf20Sopenharmony_ci (const struct dbg_idle_chk_rule *)((u32 *) 38688c2ecf20Sopenharmony_ci dbg_buf->ptr 38698c2ecf20Sopenharmony_ci + input_offset); 38708c2ecf20Sopenharmony_ci u32 num_input_rules = 38718c2ecf20Sopenharmony_ci cond_hdr->data_size / IDLE_CHK_RULE_SIZE_DWORDS; 38728c2ecf20Sopenharmony_ci offset += 38738c2ecf20Sopenharmony_ci qed_idle_chk_dump_rule_entries(p_hwfn, 38748c2ecf20Sopenharmony_ci p_ptt, 38758c2ecf20Sopenharmony_ci dump_buf + 38768c2ecf20Sopenharmony_ci offset, 38778c2ecf20Sopenharmony_ci dump, 38788c2ecf20Sopenharmony_ci rule, 38798c2ecf20Sopenharmony_ci num_input_rules, 38808c2ecf20Sopenharmony_ci &curr_failing_rules); 38818c2ecf20Sopenharmony_ci num_failing_rules += curr_failing_rules; 38828c2ecf20Sopenharmony_ci } 38838c2ecf20Sopenharmony_ci 38848c2ecf20Sopenharmony_ci input_offset += cond_hdr->data_size; 38858c2ecf20Sopenharmony_ci } 38868c2ecf20Sopenharmony_ci 38878c2ecf20Sopenharmony_ci /* Overwrite num_rules parameter */ 38888c2ecf20Sopenharmony_ci if (dump) 38898c2ecf20Sopenharmony_ci qed_dump_num_param(dump_buf + num_failing_rules_offset, 38908c2ecf20Sopenharmony_ci dump, "num_rules", num_failing_rules); 38918c2ecf20Sopenharmony_ci 38928c2ecf20Sopenharmony_ci /* Dump last section */ 38938c2ecf20Sopenharmony_ci offset += qed_dump_last_section(dump_buf, offset, dump); 38948c2ecf20Sopenharmony_ci 38958c2ecf20Sopenharmony_ci return offset; 38968c2ecf20Sopenharmony_ci} 38978c2ecf20Sopenharmony_ci 38988c2ecf20Sopenharmony_ci/* Finds the meta data image in NVRAM */ 38998c2ecf20Sopenharmony_cistatic enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn, 39008c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 39018c2ecf20Sopenharmony_ci u32 image_type, 39028c2ecf20Sopenharmony_ci u32 *nvram_offset_bytes, 39038c2ecf20Sopenharmony_ci u32 *nvram_size_bytes) 39048c2ecf20Sopenharmony_ci{ 39058c2ecf20Sopenharmony_ci u32 ret_mcp_resp, ret_mcp_param, ret_txn_size; 39068c2ecf20Sopenharmony_ci struct mcp_file_att file_att; 39078c2ecf20Sopenharmony_ci int nvm_result; 39088c2ecf20Sopenharmony_ci 39098c2ecf20Sopenharmony_ci /* Call NVRAM get file command */ 39108c2ecf20Sopenharmony_ci nvm_result = qed_mcp_nvm_rd_cmd(p_hwfn, 39118c2ecf20Sopenharmony_ci p_ptt, 39128c2ecf20Sopenharmony_ci DRV_MSG_CODE_NVM_GET_FILE_ATT, 39138c2ecf20Sopenharmony_ci image_type, 39148c2ecf20Sopenharmony_ci &ret_mcp_resp, 39158c2ecf20Sopenharmony_ci &ret_mcp_param, 39168c2ecf20Sopenharmony_ci &ret_txn_size, (u32 *)&file_att); 39178c2ecf20Sopenharmony_ci 39188c2ecf20Sopenharmony_ci /* Check response */ 39198c2ecf20Sopenharmony_ci if (nvm_result || 39208c2ecf20Sopenharmony_ci (ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK) 39218c2ecf20Sopenharmony_ci return DBG_STATUS_NVRAM_GET_IMAGE_FAILED; 39228c2ecf20Sopenharmony_ci 39238c2ecf20Sopenharmony_ci /* Update return values */ 39248c2ecf20Sopenharmony_ci *nvram_offset_bytes = file_att.nvm_start_addr; 39258c2ecf20Sopenharmony_ci *nvram_size_bytes = file_att.len; 39268c2ecf20Sopenharmony_ci 39278c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, 39288c2ecf20Sopenharmony_ci QED_MSG_DEBUG, 39298c2ecf20Sopenharmony_ci "find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\n", 39308c2ecf20Sopenharmony_ci image_type, *nvram_offset_bytes, *nvram_size_bytes); 39318c2ecf20Sopenharmony_ci 39328c2ecf20Sopenharmony_ci /* Check alignment */ 39338c2ecf20Sopenharmony_ci if (*nvram_size_bytes & 0x3) 39348c2ecf20Sopenharmony_ci return DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE; 39358c2ecf20Sopenharmony_ci 39368c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 39378c2ecf20Sopenharmony_ci} 39388c2ecf20Sopenharmony_ci 39398c2ecf20Sopenharmony_ci/* Reads data from NVRAM */ 39408c2ecf20Sopenharmony_cistatic enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn, 39418c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 39428c2ecf20Sopenharmony_ci u32 nvram_offset_bytes, 39438c2ecf20Sopenharmony_ci u32 nvram_size_bytes, u32 *ret_buf) 39448c2ecf20Sopenharmony_ci{ 39458c2ecf20Sopenharmony_ci u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy; 39468c2ecf20Sopenharmony_ci s32 bytes_left = nvram_size_bytes; 39478c2ecf20Sopenharmony_ci u32 read_offset = 0, param = 0; 39488c2ecf20Sopenharmony_ci 39498c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, 39508c2ecf20Sopenharmony_ci QED_MSG_DEBUG, 39518c2ecf20Sopenharmony_ci "nvram_read: reading image of size %d bytes from NVRAM\n", 39528c2ecf20Sopenharmony_ci nvram_size_bytes); 39538c2ecf20Sopenharmony_ci 39548c2ecf20Sopenharmony_ci do { 39558c2ecf20Sopenharmony_ci bytes_to_copy = 39568c2ecf20Sopenharmony_ci (bytes_left > 39578c2ecf20Sopenharmony_ci MCP_DRV_NVM_BUF_LEN) ? MCP_DRV_NVM_BUF_LEN : bytes_left; 39588c2ecf20Sopenharmony_ci 39598c2ecf20Sopenharmony_ci /* Call NVRAM read command */ 39608c2ecf20Sopenharmony_ci SET_MFW_FIELD(param, 39618c2ecf20Sopenharmony_ci DRV_MB_PARAM_NVM_OFFSET, 39628c2ecf20Sopenharmony_ci nvram_offset_bytes + read_offset); 39638c2ecf20Sopenharmony_ci SET_MFW_FIELD(param, DRV_MB_PARAM_NVM_LEN, bytes_to_copy); 39648c2ecf20Sopenharmony_ci if (qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt, 39658c2ecf20Sopenharmony_ci DRV_MSG_CODE_NVM_READ_NVRAM, param, 39668c2ecf20Sopenharmony_ci &ret_mcp_resp, 39678c2ecf20Sopenharmony_ci &ret_mcp_param, &ret_read_size, 39688c2ecf20Sopenharmony_ci (u32 *)((u8 *)ret_buf + read_offset))) 39698c2ecf20Sopenharmony_ci return DBG_STATUS_NVRAM_READ_FAILED; 39708c2ecf20Sopenharmony_ci 39718c2ecf20Sopenharmony_ci /* Check response */ 39728c2ecf20Sopenharmony_ci if ((ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK) 39738c2ecf20Sopenharmony_ci return DBG_STATUS_NVRAM_READ_FAILED; 39748c2ecf20Sopenharmony_ci 39758c2ecf20Sopenharmony_ci /* Update read offset */ 39768c2ecf20Sopenharmony_ci read_offset += ret_read_size; 39778c2ecf20Sopenharmony_ci bytes_left -= ret_read_size; 39788c2ecf20Sopenharmony_ci } while (bytes_left > 0); 39798c2ecf20Sopenharmony_ci 39808c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 39818c2ecf20Sopenharmony_ci} 39828c2ecf20Sopenharmony_ci 39838c2ecf20Sopenharmony_ci/* Get info on the MCP Trace data in the scratchpad: 39848c2ecf20Sopenharmony_ci * - trace_data_grc_addr (OUT): trace data GRC address in bytes 39858c2ecf20Sopenharmony_ci * - trace_data_size (OUT): trace data size in bytes (without the header) 39868c2ecf20Sopenharmony_ci */ 39878c2ecf20Sopenharmony_cistatic enum dbg_status qed_mcp_trace_get_data_info(struct qed_hwfn *p_hwfn, 39888c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 39898c2ecf20Sopenharmony_ci u32 *trace_data_grc_addr, 39908c2ecf20Sopenharmony_ci u32 *trace_data_size) 39918c2ecf20Sopenharmony_ci{ 39928c2ecf20Sopenharmony_ci u32 spad_trace_offsize, signature; 39938c2ecf20Sopenharmony_ci 39948c2ecf20Sopenharmony_ci /* Read trace section offsize structure from MCP scratchpad */ 39958c2ecf20Sopenharmony_ci spad_trace_offsize = qed_rd(p_hwfn, p_ptt, MCP_SPAD_TRACE_OFFSIZE_ADDR); 39968c2ecf20Sopenharmony_ci 39978c2ecf20Sopenharmony_ci /* Extract trace section address from offsize (in scratchpad) */ 39988c2ecf20Sopenharmony_ci *trace_data_grc_addr = 39998c2ecf20Sopenharmony_ci MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize); 40008c2ecf20Sopenharmony_ci 40018c2ecf20Sopenharmony_ci /* Read signature from MCP trace section */ 40028c2ecf20Sopenharmony_ci signature = qed_rd(p_hwfn, p_ptt, 40038c2ecf20Sopenharmony_ci *trace_data_grc_addr + 40048c2ecf20Sopenharmony_ci offsetof(struct mcp_trace, signature)); 40058c2ecf20Sopenharmony_ci 40068c2ecf20Sopenharmony_ci if (signature != MFW_TRACE_SIGNATURE) 40078c2ecf20Sopenharmony_ci return DBG_STATUS_INVALID_TRACE_SIGNATURE; 40088c2ecf20Sopenharmony_ci 40098c2ecf20Sopenharmony_ci /* Read trace size from MCP trace section */ 40108c2ecf20Sopenharmony_ci *trace_data_size = qed_rd(p_hwfn, 40118c2ecf20Sopenharmony_ci p_ptt, 40128c2ecf20Sopenharmony_ci *trace_data_grc_addr + 40138c2ecf20Sopenharmony_ci offsetof(struct mcp_trace, size)); 40148c2ecf20Sopenharmony_ci 40158c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 40168c2ecf20Sopenharmony_ci} 40178c2ecf20Sopenharmony_ci 40188c2ecf20Sopenharmony_ci/* Reads MCP trace meta data image from NVRAM 40198c2ecf20Sopenharmony_ci * - running_bundle_id (OUT): running bundle ID (invalid when loaded from file) 40208c2ecf20Sopenharmony_ci * - trace_meta_offset (OUT): trace meta offset in NVRAM in bytes (invalid when 40218c2ecf20Sopenharmony_ci * loaded from file). 40228c2ecf20Sopenharmony_ci * - trace_meta_size (OUT): size in bytes of the trace meta data. 40238c2ecf20Sopenharmony_ci */ 40248c2ecf20Sopenharmony_cistatic enum dbg_status qed_mcp_trace_get_meta_info(struct qed_hwfn *p_hwfn, 40258c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 40268c2ecf20Sopenharmony_ci u32 trace_data_size_bytes, 40278c2ecf20Sopenharmony_ci u32 *running_bundle_id, 40288c2ecf20Sopenharmony_ci u32 *trace_meta_offset, 40298c2ecf20Sopenharmony_ci u32 *trace_meta_size) 40308c2ecf20Sopenharmony_ci{ 40318c2ecf20Sopenharmony_ci u32 spad_trace_offsize, nvram_image_type, running_mfw_addr; 40328c2ecf20Sopenharmony_ci 40338c2ecf20Sopenharmony_ci /* Read MCP trace section offsize structure from MCP scratchpad */ 40348c2ecf20Sopenharmony_ci spad_trace_offsize = qed_rd(p_hwfn, p_ptt, MCP_SPAD_TRACE_OFFSIZE_ADDR); 40358c2ecf20Sopenharmony_ci 40368c2ecf20Sopenharmony_ci /* Find running bundle ID */ 40378c2ecf20Sopenharmony_ci running_mfw_addr = 40388c2ecf20Sopenharmony_ci MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize) + 40398c2ecf20Sopenharmony_ci QED_SECTION_SIZE(spad_trace_offsize) + trace_data_size_bytes; 40408c2ecf20Sopenharmony_ci *running_bundle_id = qed_rd(p_hwfn, p_ptt, running_mfw_addr); 40418c2ecf20Sopenharmony_ci if (*running_bundle_id > 1) 40428c2ecf20Sopenharmony_ci return DBG_STATUS_INVALID_NVRAM_BUNDLE; 40438c2ecf20Sopenharmony_ci 40448c2ecf20Sopenharmony_ci /* Find image in NVRAM */ 40458c2ecf20Sopenharmony_ci nvram_image_type = 40468c2ecf20Sopenharmony_ci (*running_bundle_id == 40478c2ecf20Sopenharmony_ci DIR_ID_1) ? NVM_TYPE_MFW_TRACE1 : NVM_TYPE_MFW_TRACE2; 40488c2ecf20Sopenharmony_ci return qed_find_nvram_image(p_hwfn, 40498c2ecf20Sopenharmony_ci p_ptt, 40508c2ecf20Sopenharmony_ci nvram_image_type, 40518c2ecf20Sopenharmony_ci trace_meta_offset, trace_meta_size); 40528c2ecf20Sopenharmony_ci} 40538c2ecf20Sopenharmony_ci 40548c2ecf20Sopenharmony_ci/* Reads the MCP Trace meta data from NVRAM into the specified buffer */ 40558c2ecf20Sopenharmony_cistatic enum dbg_status qed_mcp_trace_read_meta(struct qed_hwfn *p_hwfn, 40568c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 40578c2ecf20Sopenharmony_ci u32 nvram_offset_in_bytes, 40588c2ecf20Sopenharmony_ci u32 size_in_bytes, u32 *buf) 40598c2ecf20Sopenharmony_ci{ 40608c2ecf20Sopenharmony_ci u8 modules_num, module_len, i, *byte_buf = (u8 *)buf; 40618c2ecf20Sopenharmony_ci enum dbg_status status; 40628c2ecf20Sopenharmony_ci u32 signature; 40638c2ecf20Sopenharmony_ci 40648c2ecf20Sopenharmony_ci /* Read meta data from NVRAM */ 40658c2ecf20Sopenharmony_ci status = qed_nvram_read(p_hwfn, 40668c2ecf20Sopenharmony_ci p_ptt, 40678c2ecf20Sopenharmony_ci nvram_offset_in_bytes, size_in_bytes, buf); 40688c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 40698c2ecf20Sopenharmony_ci return status; 40708c2ecf20Sopenharmony_ci 40718c2ecf20Sopenharmony_ci /* Extract and check first signature */ 40728c2ecf20Sopenharmony_ci signature = qed_read_unaligned_dword(byte_buf); 40738c2ecf20Sopenharmony_ci byte_buf += sizeof(signature); 40748c2ecf20Sopenharmony_ci if (signature != NVM_MAGIC_VALUE) 40758c2ecf20Sopenharmony_ci return DBG_STATUS_INVALID_TRACE_SIGNATURE; 40768c2ecf20Sopenharmony_ci 40778c2ecf20Sopenharmony_ci /* Extract number of modules */ 40788c2ecf20Sopenharmony_ci modules_num = *(byte_buf++); 40798c2ecf20Sopenharmony_ci 40808c2ecf20Sopenharmony_ci /* Skip all modules */ 40818c2ecf20Sopenharmony_ci for (i = 0; i < modules_num; i++) { 40828c2ecf20Sopenharmony_ci module_len = *(byte_buf++); 40838c2ecf20Sopenharmony_ci byte_buf += module_len; 40848c2ecf20Sopenharmony_ci } 40858c2ecf20Sopenharmony_ci 40868c2ecf20Sopenharmony_ci /* Extract and check second signature */ 40878c2ecf20Sopenharmony_ci signature = qed_read_unaligned_dword(byte_buf); 40888c2ecf20Sopenharmony_ci byte_buf += sizeof(signature); 40898c2ecf20Sopenharmony_ci if (signature != NVM_MAGIC_VALUE) 40908c2ecf20Sopenharmony_ci return DBG_STATUS_INVALID_TRACE_SIGNATURE; 40918c2ecf20Sopenharmony_ci 40928c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 40938c2ecf20Sopenharmony_ci} 40948c2ecf20Sopenharmony_ci 40958c2ecf20Sopenharmony_ci/* Dump MCP Trace */ 40968c2ecf20Sopenharmony_cistatic enum dbg_status qed_mcp_trace_dump(struct qed_hwfn *p_hwfn, 40978c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 40988c2ecf20Sopenharmony_ci u32 *dump_buf, 40998c2ecf20Sopenharmony_ci bool dump, u32 *num_dumped_dwords) 41008c2ecf20Sopenharmony_ci{ 41018c2ecf20Sopenharmony_ci u32 trace_data_grc_addr, trace_data_size_bytes, trace_data_size_dwords; 41028c2ecf20Sopenharmony_ci u32 trace_meta_size_dwords = 0, running_bundle_id, offset = 0; 41038c2ecf20Sopenharmony_ci u32 trace_meta_offset_bytes = 0, trace_meta_size_bytes = 0; 41048c2ecf20Sopenharmony_ci enum dbg_status status; 41058c2ecf20Sopenharmony_ci int halted = 0; 41068c2ecf20Sopenharmony_ci bool use_mfw; 41078c2ecf20Sopenharmony_ci 41088c2ecf20Sopenharmony_ci *num_dumped_dwords = 0; 41098c2ecf20Sopenharmony_ci 41108c2ecf20Sopenharmony_ci use_mfw = !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP); 41118c2ecf20Sopenharmony_ci 41128c2ecf20Sopenharmony_ci /* Get trace data info */ 41138c2ecf20Sopenharmony_ci status = qed_mcp_trace_get_data_info(p_hwfn, 41148c2ecf20Sopenharmony_ci p_ptt, 41158c2ecf20Sopenharmony_ci &trace_data_grc_addr, 41168c2ecf20Sopenharmony_ci &trace_data_size_bytes); 41178c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 41188c2ecf20Sopenharmony_ci return status; 41198c2ecf20Sopenharmony_ci 41208c2ecf20Sopenharmony_ci /* Dump global params */ 41218c2ecf20Sopenharmony_ci offset += qed_dump_common_global_params(p_hwfn, 41228c2ecf20Sopenharmony_ci p_ptt, 41238c2ecf20Sopenharmony_ci dump_buf + offset, dump, 1); 41248c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 41258c2ecf20Sopenharmony_ci dump, "dump-type", "mcp-trace"); 41268c2ecf20Sopenharmony_ci 41278c2ecf20Sopenharmony_ci /* Halt MCP while reading from scratchpad so the read data will be 41288c2ecf20Sopenharmony_ci * consistent. if halt fails, MCP trace is taken anyway, with a small 41298c2ecf20Sopenharmony_ci * risk that it may be corrupt. 41308c2ecf20Sopenharmony_ci */ 41318c2ecf20Sopenharmony_ci if (dump && use_mfw) { 41328c2ecf20Sopenharmony_ci halted = !qed_mcp_halt(p_hwfn, p_ptt); 41338c2ecf20Sopenharmony_ci if (!halted) 41348c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, "MCP halt failed!\n"); 41358c2ecf20Sopenharmony_ci } 41368c2ecf20Sopenharmony_ci 41378c2ecf20Sopenharmony_ci /* Find trace data size */ 41388c2ecf20Sopenharmony_ci trace_data_size_dwords = 41398c2ecf20Sopenharmony_ci DIV_ROUND_UP(trace_data_size_bytes + sizeof(struct mcp_trace), 41408c2ecf20Sopenharmony_ci BYTES_IN_DWORD); 41418c2ecf20Sopenharmony_ci 41428c2ecf20Sopenharmony_ci /* Dump trace data section header and param */ 41438c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 41448c2ecf20Sopenharmony_ci dump, "mcp_trace_data", 1); 41458c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 41468c2ecf20Sopenharmony_ci dump, "size", trace_data_size_dwords); 41478c2ecf20Sopenharmony_ci 41488c2ecf20Sopenharmony_ci /* Read trace data from scratchpad into dump buffer */ 41498c2ecf20Sopenharmony_ci offset += qed_grc_dump_addr_range(p_hwfn, 41508c2ecf20Sopenharmony_ci p_ptt, 41518c2ecf20Sopenharmony_ci dump_buf + offset, 41528c2ecf20Sopenharmony_ci dump, 41538c2ecf20Sopenharmony_ci BYTES_TO_DWORDS(trace_data_grc_addr), 41548c2ecf20Sopenharmony_ci trace_data_size_dwords, false, 41558c2ecf20Sopenharmony_ci SPLIT_TYPE_NONE, 0); 41568c2ecf20Sopenharmony_ci 41578c2ecf20Sopenharmony_ci /* Resume MCP (only if halt succeeded) */ 41588c2ecf20Sopenharmony_ci if (halted && qed_mcp_resume(p_hwfn, p_ptt)) 41598c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n"); 41608c2ecf20Sopenharmony_ci 41618c2ecf20Sopenharmony_ci /* Dump trace meta section header */ 41628c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 41638c2ecf20Sopenharmony_ci dump, "mcp_trace_meta", 1); 41648c2ecf20Sopenharmony_ci 41658c2ecf20Sopenharmony_ci /* If MCP Trace meta size parameter was set, use it. 41668c2ecf20Sopenharmony_ci * Otherwise, read trace meta. 41678c2ecf20Sopenharmony_ci * trace_meta_size_bytes is dword-aligned. 41688c2ecf20Sopenharmony_ci */ 41698c2ecf20Sopenharmony_ci trace_meta_size_bytes = 41708c2ecf20Sopenharmony_ci qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_MCP_TRACE_META_SIZE); 41718c2ecf20Sopenharmony_ci if ((!trace_meta_size_bytes || dump) && use_mfw) 41728c2ecf20Sopenharmony_ci status = qed_mcp_trace_get_meta_info(p_hwfn, 41738c2ecf20Sopenharmony_ci p_ptt, 41748c2ecf20Sopenharmony_ci trace_data_size_bytes, 41758c2ecf20Sopenharmony_ci &running_bundle_id, 41768c2ecf20Sopenharmony_ci &trace_meta_offset_bytes, 41778c2ecf20Sopenharmony_ci &trace_meta_size_bytes); 41788c2ecf20Sopenharmony_ci if (status == DBG_STATUS_OK) 41798c2ecf20Sopenharmony_ci trace_meta_size_dwords = BYTES_TO_DWORDS(trace_meta_size_bytes); 41808c2ecf20Sopenharmony_ci 41818c2ecf20Sopenharmony_ci /* Dump trace meta size param */ 41828c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 41838c2ecf20Sopenharmony_ci dump, "size", trace_meta_size_dwords); 41848c2ecf20Sopenharmony_ci 41858c2ecf20Sopenharmony_ci /* Read trace meta image into dump buffer */ 41868c2ecf20Sopenharmony_ci if (dump && trace_meta_size_dwords) 41878c2ecf20Sopenharmony_ci status = qed_mcp_trace_read_meta(p_hwfn, 41888c2ecf20Sopenharmony_ci p_ptt, 41898c2ecf20Sopenharmony_ci trace_meta_offset_bytes, 41908c2ecf20Sopenharmony_ci trace_meta_size_bytes, 41918c2ecf20Sopenharmony_ci dump_buf + offset); 41928c2ecf20Sopenharmony_ci if (status == DBG_STATUS_OK) 41938c2ecf20Sopenharmony_ci offset += trace_meta_size_dwords; 41948c2ecf20Sopenharmony_ci 41958c2ecf20Sopenharmony_ci /* Dump last section */ 41968c2ecf20Sopenharmony_ci offset += qed_dump_last_section(dump_buf, offset, dump); 41978c2ecf20Sopenharmony_ci 41988c2ecf20Sopenharmony_ci *num_dumped_dwords = offset; 41998c2ecf20Sopenharmony_ci 42008c2ecf20Sopenharmony_ci /* If no mcp access, indicate that the dump doesn't contain the meta 42018c2ecf20Sopenharmony_ci * data from NVRAM. 42028c2ecf20Sopenharmony_ci */ 42038c2ecf20Sopenharmony_ci return use_mfw ? status : DBG_STATUS_NVRAM_GET_IMAGE_FAILED; 42048c2ecf20Sopenharmony_ci} 42058c2ecf20Sopenharmony_ci 42068c2ecf20Sopenharmony_ci/* Dump GRC FIFO */ 42078c2ecf20Sopenharmony_cistatic enum dbg_status qed_reg_fifo_dump(struct qed_hwfn *p_hwfn, 42088c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 42098c2ecf20Sopenharmony_ci u32 *dump_buf, 42108c2ecf20Sopenharmony_ci bool dump, u32 *num_dumped_dwords) 42118c2ecf20Sopenharmony_ci{ 42128c2ecf20Sopenharmony_ci u32 dwords_read, size_param_offset, offset = 0, addr, len; 42138c2ecf20Sopenharmony_ci bool fifo_has_data; 42148c2ecf20Sopenharmony_ci 42158c2ecf20Sopenharmony_ci *num_dumped_dwords = 0; 42168c2ecf20Sopenharmony_ci 42178c2ecf20Sopenharmony_ci /* Dump global params */ 42188c2ecf20Sopenharmony_ci offset += qed_dump_common_global_params(p_hwfn, 42198c2ecf20Sopenharmony_ci p_ptt, 42208c2ecf20Sopenharmony_ci dump_buf + offset, dump, 1); 42218c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 42228c2ecf20Sopenharmony_ci dump, "dump-type", "reg-fifo"); 42238c2ecf20Sopenharmony_ci 42248c2ecf20Sopenharmony_ci /* Dump fifo data section header and param. The size param is 0 for 42258c2ecf20Sopenharmony_ci * now, and is overwritten after reading the FIFO. 42268c2ecf20Sopenharmony_ci */ 42278c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 42288c2ecf20Sopenharmony_ci dump, "reg_fifo_data", 1); 42298c2ecf20Sopenharmony_ci size_param_offset = offset; 42308c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0); 42318c2ecf20Sopenharmony_ci 42328c2ecf20Sopenharmony_ci if (!dump) { 42338c2ecf20Sopenharmony_ci /* FIFO max size is REG_FIFO_DEPTH_DWORDS. There is no way to 42348c2ecf20Sopenharmony_ci * test how much data is available, except for reading it. 42358c2ecf20Sopenharmony_ci */ 42368c2ecf20Sopenharmony_ci offset += REG_FIFO_DEPTH_DWORDS; 42378c2ecf20Sopenharmony_ci goto out; 42388c2ecf20Sopenharmony_ci } 42398c2ecf20Sopenharmony_ci 42408c2ecf20Sopenharmony_ci fifo_has_data = qed_rd(p_hwfn, p_ptt, 42418c2ecf20Sopenharmony_ci GRC_REG_TRACE_FIFO_VALID_DATA) > 0; 42428c2ecf20Sopenharmony_ci 42438c2ecf20Sopenharmony_ci /* Pull available data from fifo. Use DMAE since this is widebus memory 42448c2ecf20Sopenharmony_ci * and must be accessed atomically. Test for dwords_read not passing 42458c2ecf20Sopenharmony_ci * buffer size since more entries could be added to the buffer as we are 42468c2ecf20Sopenharmony_ci * emptying it. 42478c2ecf20Sopenharmony_ci */ 42488c2ecf20Sopenharmony_ci addr = BYTES_TO_DWORDS(GRC_REG_TRACE_FIFO); 42498c2ecf20Sopenharmony_ci len = REG_FIFO_ELEMENT_DWORDS; 42508c2ecf20Sopenharmony_ci for (dwords_read = 0; 42518c2ecf20Sopenharmony_ci fifo_has_data && dwords_read < REG_FIFO_DEPTH_DWORDS; 42528c2ecf20Sopenharmony_ci dwords_read += REG_FIFO_ELEMENT_DWORDS) { 42538c2ecf20Sopenharmony_ci offset += qed_grc_dump_addr_range(p_hwfn, 42548c2ecf20Sopenharmony_ci p_ptt, 42558c2ecf20Sopenharmony_ci dump_buf + offset, 42568c2ecf20Sopenharmony_ci true, 42578c2ecf20Sopenharmony_ci addr, 42588c2ecf20Sopenharmony_ci len, 42598c2ecf20Sopenharmony_ci true, SPLIT_TYPE_NONE, 42608c2ecf20Sopenharmony_ci 0); 42618c2ecf20Sopenharmony_ci fifo_has_data = qed_rd(p_hwfn, p_ptt, 42628c2ecf20Sopenharmony_ci GRC_REG_TRACE_FIFO_VALID_DATA) > 0; 42638c2ecf20Sopenharmony_ci } 42648c2ecf20Sopenharmony_ci 42658c2ecf20Sopenharmony_ci qed_dump_num_param(dump_buf + size_param_offset, dump, "size", 42668c2ecf20Sopenharmony_ci dwords_read); 42678c2ecf20Sopenharmony_ciout: 42688c2ecf20Sopenharmony_ci /* Dump last section */ 42698c2ecf20Sopenharmony_ci offset += qed_dump_last_section(dump_buf, offset, dump); 42708c2ecf20Sopenharmony_ci 42718c2ecf20Sopenharmony_ci *num_dumped_dwords = offset; 42728c2ecf20Sopenharmony_ci 42738c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 42748c2ecf20Sopenharmony_ci} 42758c2ecf20Sopenharmony_ci 42768c2ecf20Sopenharmony_ci/* Dump IGU FIFO */ 42778c2ecf20Sopenharmony_cistatic enum dbg_status qed_igu_fifo_dump(struct qed_hwfn *p_hwfn, 42788c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 42798c2ecf20Sopenharmony_ci u32 *dump_buf, 42808c2ecf20Sopenharmony_ci bool dump, u32 *num_dumped_dwords) 42818c2ecf20Sopenharmony_ci{ 42828c2ecf20Sopenharmony_ci u32 dwords_read, size_param_offset, offset = 0, addr, len; 42838c2ecf20Sopenharmony_ci bool fifo_has_data; 42848c2ecf20Sopenharmony_ci 42858c2ecf20Sopenharmony_ci *num_dumped_dwords = 0; 42868c2ecf20Sopenharmony_ci 42878c2ecf20Sopenharmony_ci /* Dump global params */ 42888c2ecf20Sopenharmony_ci offset += qed_dump_common_global_params(p_hwfn, 42898c2ecf20Sopenharmony_ci p_ptt, 42908c2ecf20Sopenharmony_ci dump_buf + offset, dump, 1); 42918c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 42928c2ecf20Sopenharmony_ci dump, "dump-type", "igu-fifo"); 42938c2ecf20Sopenharmony_ci 42948c2ecf20Sopenharmony_ci /* Dump fifo data section header and param. The size param is 0 for 42958c2ecf20Sopenharmony_ci * now, and is overwritten after reading the FIFO. 42968c2ecf20Sopenharmony_ci */ 42978c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 42988c2ecf20Sopenharmony_ci dump, "igu_fifo_data", 1); 42998c2ecf20Sopenharmony_ci size_param_offset = offset; 43008c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0); 43018c2ecf20Sopenharmony_ci 43028c2ecf20Sopenharmony_ci if (!dump) { 43038c2ecf20Sopenharmony_ci /* FIFO max size is IGU_FIFO_DEPTH_DWORDS. There is no way to 43048c2ecf20Sopenharmony_ci * test how much data is available, except for reading it. 43058c2ecf20Sopenharmony_ci */ 43068c2ecf20Sopenharmony_ci offset += IGU_FIFO_DEPTH_DWORDS; 43078c2ecf20Sopenharmony_ci goto out; 43088c2ecf20Sopenharmony_ci } 43098c2ecf20Sopenharmony_ci 43108c2ecf20Sopenharmony_ci fifo_has_data = qed_rd(p_hwfn, p_ptt, 43118c2ecf20Sopenharmony_ci IGU_REG_ERROR_HANDLING_DATA_VALID) > 0; 43128c2ecf20Sopenharmony_ci 43138c2ecf20Sopenharmony_ci /* Pull available data from fifo. Use DMAE since this is widebus memory 43148c2ecf20Sopenharmony_ci * and must be accessed atomically. Test for dwords_read not passing 43158c2ecf20Sopenharmony_ci * buffer size since more entries could be added to the buffer as we are 43168c2ecf20Sopenharmony_ci * emptying it. 43178c2ecf20Sopenharmony_ci */ 43188c2ecf20Sopenharmony_ci addr = BYTES_TO_DWORDS(IGU_REG_ERROR_HANDLING_MEMORY); 43198c2ecf20Sopenharmony_ci len = IGU_FIFO_ELEMENT_DWORDS; 43208c2ecf20Sopenharmony_ci for (dwords_read = 0; 43218c2ecf20Sopenharmony_ci fifo_has_data && dwords_read < IGU_FIFO_DEPTH_DWORDS; 43228c2ecf20Sopenharmony_ci dwords_read += IGU_FIFO_ELEMENT_DWORDS) { 43238c2ecf20Sopenharmony_ci offset += qed_grc_dump_addr_range(p_hwfn, 43248c2ecf20Sopenharmony_ci p_ptt, 43258c2ecf20Sopenharmony_ci dump_buf + offset, 43268c2ecf20Sopenharmony_ci true, 43278c2ecf20Sopenharmony_ci addr, 43288c2ecf20Sopenharmony_ci len, 43298c2ecf20Sopenharmony_ci true, SPLIT_TYPE_NONE, 43308c2ecf20Sopenharmony_ci 0); 43318c2ecf20Sopenharmony_ci fifo_has_data = qed_rd(p_hwfn, p_ptt, 43328c2ecf20Sopenharmony_ci IGU_REG_ERROR_HANDLING_DATA_VALID) > 0; 43338c2ecf20Sopenharmony_ci } 43348c2ecf20Sopenharmony_ci 43358c2ecf20Sopenharmony_ci qed_dump_num_param(dump_buf + size_param_offset, dump, "size", 43368c2ecf20Sopenharmony_ci dwords_read); 43378c2ecf20Sopenharmony_ciout: 43388c2ecf20Sopenharmony_ci /* Dump last section */ 43398c2ecf20Sopenharmony_ci offset += qed_dump_last_section(dump_buf, offset, dump); 43408c2ecf20Sopenharmony_ci 43418c2ecf20Sopenharmony_ci *num_dumped_dwords = offset; 43428c2ecf20Sopenharmony_ci 43438c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 43448c2ecf20Sopenharmony_ci} 43458c2ecf20Sopenharmony_ci 43468c2ecf20Sopenharmony_ci/* Protection Override dump */ 43478c2ecf20Sopenharmony_cistatic enum dbg_status qed_protection_override_dump(struct qed_hwfn *p_hwfn, 43488c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 43498c2ecf20Sopenharmony_ci u32 *dump_buf, 43508c2ecf20Sopenharmony_ci bool dump, 43518c2ecf20Sopenharmony_ci u32 *num_dumped_dwords) 43528c2ecf20Sopenharmony_ci{ 43538c2ecf20Sopenharmony_ci u32 size_param_offset, override_window_dwords, offset = 0, addr; 43548c2ecf20Sopenharmony_ci 43558c2ecf20Sopenharmony_ci *num_dumped_dwords = 0; 43568c2ecf20Sopenharmony_ci 43578c2ecf20Sopenharmony_ci /* Dump global params */ 43588c2ecf20Sopenharmony_ci offset += qed_dump_common_global_params(p_hwfn, 43598c2ecf20Sopenharmony_ci p_ptt, 43608c2ecf20Sopenharmony_ci dump_buf + offset, dump, 1); 43618c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 43628c2ecf20Sopenharmony_ci dump, "dump-type", "protection-override"); 43638c2ecf20Sopenharmony_ci 43648c2ecf20Sopenharmony_ci /* Dump data section header and param. The size param is 0 for now, 43658c2ecf20Sopenharmony_ci * and is overwritten after reading the data. 43668c2ecf20Sopenharmony_ci */ 43678c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 43688c2ecf20Sopenharmony_ci dump, "protection_override_data", 1); 43698c2ecf20Sopenharmony_ci size_param_offset = offset; 43708c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0); 43718c2ecf20Sopenharmony_ci 43728c2ecf20Sopenharmony_ci if (!dump) { 43738c2ecf20Sopenharmony_ci offset += PROTECTION_OVERRIDE_DEPTH_DWORDS; 43748c2ecf20Sopenharmony_ci goto out; 43758c2ecf20Sopenharmony_ci } 43768c2ecf20Sopenharmony_ci 43778c2ecf20Sopenharmony_ci /* Add override window info to buffer */ 43788c2ecf20Sopenharmony_ci override_window_dwords = 43798c2ecf20Sopenharmony_ci qed_rd(p_hwfn, p_ptt, GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW) * 43808c2ecf20Sopenharmony_ci PROTECTION_OVERRIDE_ELEMENT_DWORDS; 43818c2ecf20Sopenharmony_ci if (override_window_dwords) { 43828c2ecf20Sopenharmony_ci addr = BYTES_TO_DWORDS(GRC_REG_PROTECTION_OVERRIDE_WINDOW); 43838c2ecf20Sopenharmony_ci offset += qed_grc_dump_addr_range(p_hwfn, 43848c2ecf20Sopenharmony_ci p_ptt, 43858c2ecf20Sopenharmony_ci dump_buf + offset, 43868c2ecf20Sopenharmony_ci true, 43878c2ecf20Sopenharmony_ci addr, 43888c2ecf20Sopenharmony_ci override_window_dwords, 43898c2ecf20Sopenharmony_ci true, SPLIT_TYPE_NONE, 0); 43908c2ecf20Sopenharmony_ci qed_dump_num_param(dump_buf + size_param_offset, dump, "size", 43918c2ecf20Sopenharmony_ci override_window_dwords); 43928c2ecf20Sopenharmony_ci } 43938c2ecf20Sopenharmony_ciout: 43948c2ecf20Sopenharmony_ci /* Dump last section */ 43958c2ecf20Sopenharmony_ci offset += qed_dump_last_section(dump_buf, offset, dump); 43968c2ecf20Sopenharmony_ci 43978c2ecf20Sopenharmony_ci *num_dumped_dwords = offset; 43988c2ecf20Sopenharmony_ci 43998c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 44008c2ecf20Sopenharmony_ci} 44018c2ecf20Sopenharmony_ci 44028c2ecf20Sopenharmony_ci/* Performs FW Asserts Dump to the specified buffer. 44038c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 44048c2ecf20Sopenharmony_ci */ 44058c2ecf20Sopenharmony_cistatic u32 qed_fw_asserts_dump(struct qed_hwfn *p_hwfn, 44068c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) 44078c2ecf20Sopenharmony_ci{ 44088c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 44098c2ecf20Sopenharmony_ci struct fw_asserts_ram_section *asserts; 44108c2ecf20Sopenharmony_ci char storm_letter_str[2] = "?"; 44118c2ecf20Sopenharmony_ci struct fw_info fw_info; 44128c2ecf20Sopenharmony_ci u32 offset = 0; 44138c2ecf20Sopenharmony_ci u8 storm_id; 44148c2ecf20Sopenharmony_ci 44158c2ecf20Sopenharmony_ci /* Dump global params */ 44168c2ecf20Sopenharmony_ci offset += qed_dump_common_global_params(p_hwfn, 44178c2ecf20Sopenharmony_ci p_ptt, 44188c2ecf20Sopenharmony_ci dump_buf + offset, dump, 1); 44198c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 44208c2ecf20Sopenharmony_ci dump, "dump-type", "fw-asserts"); 44218c2ecf20Sopenharmony_ci 44228c2ecf20Sopenharmony_ci /* Find Storm dump size */ 44238c2ecf20Sopenharmony_ci for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) { 44248c2ecf20Sopenharmony_ci u32 fw_asserts_section_addr, next_list_idx_addr, next_list_idx; 44258c2ecf20Sopenharmony_ci struct storm_defs *storm = &s_storm_defs[storm_id]; 44268c2ecf20Sopenharmony_ci u32 last_list_idx, addr; 44278c2ecf20Sopenharmony_ci 44288c2ecf20Sopenharmony_ci if (dev_data->block_in_reset[storm->sem_block_id]) 44298c2ecf20Sopenharmony_ci continue; 44308c2ecf20Sopenharmony_ci 44318c2ecf20Sopenharmony_ci /* Read FW info for the current Storm */ 44328c2ecf20Sopenharmony_ci qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, &fw_info); 44338c2ecf20Sopenharmony_ci 44348c2ecf20Sopenharmony_ci asserts = &fw_info.fw_asserts_section; 44358c2ecf20Sopenharmony_ci 44368c2ecf20Sopenharmony_ci /* Dump FW Asserts section header and params */ 44378c2ecf20Sopenharmony_ci storm_letter_str[0] = storm->letter; 44388c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 44398c2ecf20Sopenharmony_ci dump, "fw_asserts", 2); 44408c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 44418c2ecf20Sopenharmony_ci dump, "storm", storm_letter_str); 44428c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 44438c2ecf20Sopenharmony_ci dump, 44448c2ecf20Sopenharmony_ci "size", 44458c2ecf20Sopenharmony_ci asserts->list_element_dword_size); 44468c2ecf20Sopenharmony_ci 44478c2ecf20Sopenharmony_ci /* Read and dump FW Asserts data */ 44488c2ecf20Sopenharmony_ci if (!dump) { 44498c2ecf20Sopenharmony_ci offset += asserts->list_element_dword_size; 44508c2ecf20Sopenharmony_ci continue; 44518c2ecf20Sopenharmony_ci } 44528c2ecf20Sopenharmony_ci 44538c2ecf20Sopenharmony_ci addr = le16_to_cpu(asserts->section_ram_line_offset); 44548c2ecf20Sopenharmony_ci fw_asserts_section_addr = storm->sem_fast_mem_addr + 44558c2ecf20Sopenharmony_ci SEM_FAST_REG_INT_RAM + 44568c2ecf20Sopenharmony_ci RAM_LINES_TO_BYTES(addr); 44578c2ecf20Sopenharmony_ci 44588c2ecf20Sopenharmony_ci next_list_idx_addr = fw_asserts_section_addr + 44598c2ecf20Sopenharmony_ci DWORDS_TO_BYTES(asserts->list_next_index_dword_offset); 44608c2ecf20Sopenharmony_ci next_list_idx = qed_rd(p_hwfn, p_ptt, next_list_idx_addr); 44618c2ecf20Sopenharmony_ci last_list_idx = (next_list_idx > 0 ? 44628c2ecf20Sopenharmony_ci next_list_idx : 44638c2ecf20Sopenharmony_ci asserts->list_num_elements) - 1; 44648c2ecf20Sopenharmony_ci addr = BYTES_TO_DWORDS(fw_asserts_section_addr) + 44658c2ecf20Sopenharmony_ci asserts->list_dword_offset + 44668c2ecf20Sopenharmony_ci last_list_idx * asserts->list_element_dword_size; 44678c2ecf20Sopenharmony_ci offset += 44688c2ecf20Sopenharmony_ci qed_grc_dump_addr_range(p_hwfn, p_ptt, 44698c2ecf20Sopenharmony_ci dump_buf + offset, 44708c2ecf20Sopenharmony_ci dump, addr, 44718c2ecf20Sopenharmony_ci asserts->list_element_dword_size, 44728c2ecf20Sopenharmony_ci false, SPLIT_TYPE_NONE, 0); 44738c2ecf20Sopenharmony_ci } 44748c2ecf20Sopenharmony_ci 44758c2ecf20Sopenharmony_ci /* Dump last section */ 44768c2ecf20Sopenharmony_ci offset += qed_dump_last_section(dump_buf, offset, dump); 44778c2ecf20Sopenharmony_ci 44788c2ecf20Sopenharmony_ci return offset; 44798c2ecf20Sopenharmony_ci} 44808c2ecf20Sopenharmony_ci 44818c2ecf20Sopenharmony_ci/* Dumps the specified ILT pages to the specified buffer. 44828c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 44838c2ecf20Sopenharmony_ci */ 44848c2ecf20Sopenharmony_cistatic u32 qed_ilt_dump_pages_range(u32 *dump_buf, 44858c2ecf20Sopenharmony_ci bool dump, 44868c2ecf20Sopenharmony_ci u32 start_page_id, 44878c2ecf20Sopenharmony_ci u32 num_pages, 44888c2ecf20Sopenharmony_ci struct phys_mem_desc *ilt_pages, 44898c2ecf20Sopenharmony_ci bool dump_page_ids) 44908c2ecf20Sopenharmony_ci{ 44918c2ecf20Sopenharmony_ci u32 page_id, end_page_id, offset = 0; 44928c2ecf20Sopenharmony_ci 44938c2ecf20Sopenharmony_ci if (num_pages == 0) 44948c2ecf20Sopenharmony_ci return offset; 44958c2ecf20Sopenharmony_ci 44968c2ecf20Sopenharmony_ci end_page_id = start_page_id + num_pages - 1; 44978c2ecf20Sopenharmony_ci 44988c2ecf20Sopenharmony_ci for (page_id = start_page_id; page_id <= end_page_id; page_id++) { 44998c2ecf20Sopenharmony_ci struct phys_mem_desc *mem_desc = &ilt_pages[page_id]; 45008c2ecf20Sopenharmony_ci 45018c2ecf20Sopenharmony_ci /** 45028c2ecf20Sopenharmony_ci * 45038c2ecf20Sopenharmony_ci * if (page_id >= ->p_cxt_mngr->ilt_shadow_size) 45048c2ecf20Sopenharmony_ci * break; 45058c2ecf20Sopenharmony_ci */ 45068c2ecf20Sopenharmony_ci 45078c2ecf20Sopenharmony_ci if (!ilt_pages[page_id].virt_addr) 45088c2ecf20Sopenharmony_ci continue; 45098c2ecf20Sopenharmony_ci 45108c2ecf20Sopenharmony_ci if (dump_page_ids) { 45118c2ecf20Sopenharmony_ci /* Copy page ID to dump buffer */ 45128c2ecf20Sopenharmony_ci if (dump) 45138c2ecf20Sopenharmony_ci *(dump_buf + offset) = page_id; 45148c2ecf20Sopenharmony_ci offset++; 45158c2ecf20Sopenharmony_ci } else { 45168c2ecf20Sopenharmony_ci /* Copy page memory to dump buffer */ 45178c2ecf20Sopenharmony_ci if (dump) 45188c2ecf20Sopenharmony_ci memcpy(dump_buf + offset, 45198c2ecf20Sopenharmony_ci mem_desc->virt_addr, mem_desc->size); 45208c2ecf20Sopenharmony_ci offset += BYTES_TO_DWORDS(mem_desc->size); 45218c2ecf20Sopenharmony_ci } 45228c2ecf20Sopenharmony_ci } 45238c2ecf20Sopenharmony_ci 45248c2ecf20Sopenharmony_ci return offset; 45258c2ecf20Sopenharmony_ci} 45268c2ecf20Sopenharmony_ci 45278c2ecf20Sopenharmony_ci/* Dumps a section containing the dumped ILT pages. 45288c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 45298c2ecf20Sopenharmony_ci */ 45308c2ecf20Sopenharmony_cistatic u32 qed_ilt_dump_pages_section(struct qed_hwfn *p_hwfn, 45318c2ecf20Sopenharmony_ci u32 *dump_buf, 45328c2ecf20Sopenharmony_ci bool dump, 45338c2ecf20Sopenharmony_ci u32 valid_conn_pf_pages, 45348c2ecf20Sopenharmony_ci u32 valid_conn_vf_pages, 45358c2ecf20Sopenharmony_ci struct phys_mem_desc *ilt_pages, 45368c2ecf20Sopenharmony_ci bool dump_page_ids) 45378c2ecf20Sopenharmony_ci{ 45388c2ecf20Sopenharmony_ci struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients; 45398c2ecf20Sopenharmony_ci u32 pf_start_line, start_page_id, offset = 0; 45408c2ecf20Sopenharmony_ci u32 cdut_pf_init_pages, cdut_vf_init_pages; 45418c2ecf20Sopenharmony_ci u32 cdut_pf_work_pages, cdut_vf_work_pages; 45428c2ecf20Sopenharmony_ci u32 base_data_offset, size_param_offset; 45438c2ecf20Sopenharmony_ci u32 cdut_pf_pages, cdut_vf_pages; 45448c2ecf20Sopenharmony_ci const char *section_name; 45458c2ecf20Sopenharmony_ci u8 i; 45468c2ecf20Sopenharmony_ci 45478c2ecf20Sopenharmony_ci section_name = dump_page_ids ? "ilt_page_ids" : "ilt_page_mem"; 45488c2ecf20Sopenharmony_ci cdut_pf_init_pages = qed_get_cdut_num_pf_init_pages(p_hwfn); 45498c2ecf20Sopenharmony_ci cdut_vf_init_pages = qed_get_cdut_num_vf_init_pages(p_hwfn); 45508c2ecf20Sopenharmony_ci cdut_pf_work_pages = qed_get_cdut_num_pf_work_pages(p_hwfn); 45518c2ecf20Sopenharmony_ci cdut_vf_work_pages = qed_get_cdut_num_vf_work_pages(p_hwfn); 45528c2ecf20Sopenharmony_ci cdut_pf_pages = cdut_pf_init_pages + cdut_pf_work_pages; 45538c2ecf20Sopenharmony_ci cdut_vf_pages = cdut_vf_init_pages + cdut_vf_work_pages; 45548c2ecf20Sopenharmony_ci pf_start_line = p_hwfn->p_cxt_mngr->pf_start_line; 45558c2ecf20Sopenharmony_ci 45568c2ecf20Sopenharmony_ci offset += 45578c2ecf20Sopenharmony_ci qed_dump_section_hdr(dump_buf + offset, dump, section_name, 1); 45588c2ecf20Sopenharmony_ci 45598c2ecf20Sopenharmony_ci /* Dump size parameter (0 for now, overwritten with real size later) */ 45608c2ecf20Sopenharmony_ci size_param_offset = offset; 45618c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0); 45628c2ecf20Sopenharmony_ci base_data_offset = offset; 45638c2ecf20Sopenharmony_ci 45648c2ecf20Sopenharmony_ci /* CDUC pages are ordered as follows: 45658c2ecf20Sopenharmony_ci * - PF pages - valid section (included in PF connection type mapping) 45668c2ecf20Sopenharmony_ci * - PF pages - invalid section (not dumped) 45678c2ecf20Sopenharmony_ci * - For each VF in the PF: 45688c2ecf20Sopenharmony_ci * - VF pages - valid section (included in VF connection type mapping) 45698c2ecf20Sopenharmony_ci * - VF pages - invalid section (not dumped) 45708c2ecf20Sopenharmony_ci */ 45718c2ecf20Sopenharmony_ci if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUC)) { 45728c2ecf20Sopenharmony_ci /* Dump connection PF pages */ 45738c2ecf20Sopenharmony_ci start_page_id = clients[ILT_CLI_CDUC].first.val - pf_start_line; 45748c2ecf20Sopenharmony_ci offset += qed_ilt_dump_pages_range(dump_buf + offset, 45758c2ecf20Sopenharmony_ci dump, 45768c2ecf20Sopenharmony_ci start_page_id, 45778c2ecf20Sopenharmony_ci valid_conn_pf_pages, 45788c2ecf20Sopenharmony_ci ilt_pages, dump_page_ids); 45798c2ecf20Sopenharmony_ci 45808c2ecf20Sopenharmony_ci /* Dump connection VF pages */ 45818c2ecf20Sopenharmony_ci start_page_id += clients[ILT_CLI_CDUC].pf_total_lines; 45828c2ecf20Sopenharmony_ci for (i = 0; i < p_hwfn->p_cxt_mngr->vf_count; 45838c2ecf20Sopenharmony_ci i++, start_page_id += clients[ILT_CLI_CDUC].vf_total_lines) 45848c2ecf20Sopenharmony_ci offset += qed_ilt_dump_pages_range(dump_buf + offset, 45858c2ecf20Sopenharmony_ci dump, 45868c2ecf20Sopenharmony_ci start_page_id, 45878c2ecf20Sopenharmony_ci valid_conn_vf_pages, 45888c2ecf20Sopenharmony_ci ilt_pages, 45898c2ecf20Sopenharmony_ci dump_page_ids); 45908c2ecf20Sopenharmony_ci } 45918c2ecf20Sopenharmony_ci 45928c2ecf20Sopenharmony_ci /* CDUT pages are ordered as follows: 45938c2ecf20Sopenharmony_ci * - PF init pages (not dumped) 45948c2ecf20Sopenharmony_ci * - PF work pages 45958c2ecf20Sopenharmony_ci * - For each VF in the PF: 45968c2ecf20Sopenharmony_ci * - VF init pages (not dumped) 45978c2ecf20Sopenharmony_ci * - VF work pages 45988c2ecf20Sopenharmony_ci */ 45998c2ecf20Sopenharmony_ci if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUT)) { 46008c2ecf20Sopenharmony_ci /* Dump task PF pages */ 46018c2ecf20Sopenharmony_ci start_page_id = clients[ILT_CLI_CDUT].first.val + 46028c2ecf20Sopenharmony_ci cdut_pf_init_pages - pf_start_line; 46038c2ecf20Sopenharmony_ci offset += qed_ilt_dump_pages_range(dump_buf + offset, 46048c2ecf20Sopenharmony_ci dump, 46058c2ecf20Sopenharmony_ci start_page_id, 46068c2ecf20Sopenharmony_ci cdut_pf_work_pages, 46078c2ecf20Sopenharmony_ci ilt_pages, dump_page_ids); 46088c2ecf20Sopenharmony_ci 46098c2ecf20Sopenharmony_ci /* Dump task VF pages */ 46108c2ecf20Sopenharmony_ci start_page_id = clients[ILT_CLI_CDUT].first.val + 46118c2ecf20Sopenharmony_ci cdut_pf_pages + cdut_vf_init_pages - pf_start_line; 46128c2ecf20Sopenharmony_ci for (i = 0; i < p_hwfn->p_cxt_mngr->vf_count; 46138c2ecf20Sopenharmony_ci i++, start_page_id += cdut_vf_pages) 46148c2ecf20Sopenharmony_ci offset += qed_ilt_dump_pages_range(dump_buf + offset, 46158c2ecf20Sopenharmony_ci dump, 46168c2ecf20Sopenharmony_ci start_page_id, 46178c2ecf20Sopenharmony_ci cdut_vf_work_pages, 46188c2ecf20Sopenharmony_ci ilt_pages, 46198c2ecf20Sopenharmony_ci dump_page_ids); 46208c2ecf20Sopenharmony_ci } 46218c2ecf20Sopenharmony_ci 46228c2ecf20Sopenharmony_ci /* Overwrite size param */ 46238c2ecf20Sopenharmony_ci if (dump) 46248c2ecf20Sopenharmony_ci qed_dump_num_param(dump_buf + size_param_offset, 46258c2ecf20Sopenharmony_ci dump, "size", offset - base_data_offset); 46268c2ecf20Sopenharmony_ci 46278c2ecf20Sopenharmony_ci return offset; 46288c2ecf20Sopenharmony_ci} 46298c2ecf20Sopenharmony_ci 46308c2ecf20Sopenharmony_ci/* Performs ILT Dump to the specified buffer. 46318c2ecf20Sopenharmony_ci * Returns the dumped size in dwords. 46328c2ecf20Sopenharmony_ci */ 46338c2ecf20Sopenharmony_cistatic u32 qed_ilt_dump(struct qed_hwfn *p_hwfn, 46348c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, u32 *dump_buf, bool dump) 46358c2ecf20Sopenharmony_ci{ 46368c2ecf20Sopenharmony_ci struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients; 46378c2ecf20Sopenharmony_ci u32 valid_conn_vf_cids, valid_conn_vf_pages, offset = 0; 46388c2ecf20Sopenharmony_ci u32 valid_conn_pf_cids, valid_conn_pf_pages, num_pages; 46398c2ecf20Sopenharmony_ci u32 num_cids_per_page, conn_ctx_size; 46408c2ecf20Sopenharmony_ci u32 cduc_page_size, cdut_page_size; 46418c2ecf20Sopenharmony_ci struct phys_mem_desc *ilt_pages; 46428c2ecf20Sopenharmony_ci u8 conn_type; 46438c2ecf20Sopenharmony_ci 46448c2ecf20Sopenharmony_ci cduc_page_size = 1 << 46458c2ecf20Sopenharmony_ci (clients[ILT_CLI_CDUC].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN); 46468c2ecf20Sopenharmony_ci cdut_page_size = 1 << 46478c2ecf20Sopenharmony_ci (clients[ILT_CLI_CDUT].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN); 46488c2ecf20Sopenharmony_ci conn_ctx_size = p_hwfn->p_cxt_mngr->conn_ctx_size; 46498c2ecf20Sopenharmony_ci num_cids_per_page = (int)(cduc_page_size / conn_ctx_size); 46508c2ecf20Sopenharmony_ci ilt_pages = p_hwfn->p_cxt_mngr->ilt_shadow; 46518c2ecf20Sopenharmony_ci 46528c2ecf20Sopenharmony_ci /* Dump global params - 22 must match number of params below */ 46538c2ecf20Sopenharmony_ci offset += qed_dump_common_global_params(p_hwfn, p_ptt, 46548c2ecf20Sopenharmony_ci dump_buf + offset, dump, 22); 46558c2ecf20Sopenharmony_ci offset += qed_dump_str_param(dump_buf + offset, 46568c2ecf20Sopenharmony_ci dump, "dump-type", "ilt-dump"); 46578c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 46588c2ecf20Sopenharmony_ci dump, 46598c2ecf20Sopenharmony_ci "cduc-page-size", cduc_page_size); 46608c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 46618c2ecf20Sopenharmony_ci dump, 46628c2ecf20Sopenharmony_ci "cduc-first-page-id", 46638c2ecf20Sopenharmony_ci clients[ILT_CLI_CDUC].first.val); 46648c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 46658c2ecf20Sopenharmony_ci dump, 46668c2ecf20Sopenharmony_ci "cduc-last-page-id", 46678c2ecf20Sopenharmony_ci clients[ILT_CLI_CDUC].last.val); 46688c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 46698c2ecf20Sopenharmony_ci dump, 46708c2ecf20Sopenharmony_ci "cduc-num-pf-pages", 46718c2ecf20Sopenharmony_ci clients 46728c2ecf20Sopenharmony_ci [ILT_CLI_CDUC].pf_total_lines); 46738c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 46748c2ecf20Sopenharmony_ci dump, 46758c2ecf20Sopenharmony_ci "cduc-num-vf-pages", 46768c2ecf20Sopenharmony_ci clients 46778c2ecf20Sopenharmony_ci [ILT_CLI_CDUC].vf_total_lines); 46788c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 46798c2ecf20Sopenharmony_ci dump, 46808c2ecf20Sopenharmony_ci "max-conn-ctx-size", 46818c2ecf20Sopenharmony_ci conn_ctx_size); 46828c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 46838c2ecf20Sopenharmony_ci dump, 46848c2ecf20Sopenharmony_ci "cdut-page-size", cdut_page_size); 46858c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 46868c2ecf20Sopenharmony_ci dump, 46878c2ecf20Sopenharmony_ci "cdut-first-page-id", 46888c2ecf20Sopenharmony_ci clients[ILT_CLI_CDUT].first.val); 46898c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 46908c2ecf20Sopenharmony_ci dump, 46918c2ecf20Sopenharmony_ci "cdut-last-page-id", 46928c2ecf20Sopenharmony_ci clients[ILT_CLI_CDUT].last.val); 46938c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 46948c2ecf20Sopenharmony_ci dump, 46958c2ecf20Sopenharmony_ci "cdut-num-pf-init-pages", 46968c2ecf20Sopenharmony_ci qed_get_cdut_num_pf_init_pages(p_hwfn)); 46978c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 46988c2ecf20Sopenharmony_ci dump, 46998c2ecf20Sopenharmony_ci "cdut-num-vf-init-pages", 47008c2ecf20Sopenharmony_ci qed_get_cdut_num_vf_init_pages(p_hwfn)); 47018c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 47028c2ecf20Sopenharmony_ci dump, 47038c2ecf20Sopenharmony_ci "cdut-num-pf-work-pages", 47048c2ecf20Sopenharmony_ci qed_get_cdut_num_pf_work_pages(p_hwfn)); 47058c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 47068c2ecf20Sopenharmony_ci dump, 47078c2ecf20Sopenharmony_ci "cdut-num-vf-work-pages", 47088c2ecf20Sopenharmony_ci qed_get_cdut_num_vf_work_pages(p_hwfn)); 47098c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 47108c2ecf20Sopenharmony_ci dump, 47118c2ecf20Sopenharmony_ci "max-task-ctx-size", 47128c2ecf20Sopenharmony_ci p_hwfn->p_cxt_mngr->task_ctx_size); 47138c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 47148c2ecf20Sopenharmony_ci dump, 47158c2ecf20Sopenharmony_ci "task-type-id", 47168c2ecf20Sopenharmony_ci p_hwfn->p_cxt_mngr->task_type_id); 47178c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 47188c2ecf20Sopenharmony_ci dump, 47198c2ecf20Sopenharmony_ci "first-vf-id-in-pf", 47208c2ecf20Sopenharmony_ci p_hwfn->p_cxt_mngr->first_vf_in_pf); 47218c2ecf20Sopenharmony_ci offset += /* 18 */ qed_dump_num_param(dump_buf + offset, 47228c2ecf20Sopenharmony_ci dump, 47238c2ecf20Sopenharmony_ci "num-vfs-in-pf", 47248c2ecf20Sopenharmony_ci p_hwfn->p_cxt_mngr->vf_count); 47258c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 47268c2ecf20Sopenharmony_ci dump, 47278c2ecf20Sopenharmony_ci "ptr-size-bytes", sizeof(void *)); 47288c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 47298c2ecf20Sopenharmony_ci dump, 47308c2ecf20Sopenharmony_ci "pf-start-line", 47318c2ecf20Sopenharmony_ci p_hwfn->p_cxt_mngr->pf_start_line); 47328c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 47338c2ecf20Sopenharmony_ci dump, 47348c2ecf20Sopenharmony_ci "page-mem-desc-size-dwords", 47358c2ecf20Sopenharmony_ci PAGE_MEM_DESC_SIZE_DWORDS); 47368c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 47378c2ecf20Sopenharmony_ci dump, 47388c2ecf20Sopenharmony_ci "ilt-shadow-size", 47398c2ecf20Sopenharmony_ci p_hwfn->p_cxt_mngr->ilt_shadow_size); 47408c2ecf20Sopenharmony_ci /* Additional/Less parameters require matching of number in call to 47418c2ecf20Sopenharmony_ci * dump_common_global_params() 47428c2ecf20Sopenharmony_ci */ 47438c2ecf20Sopenharmony_ci 47448c2ecf20Sopenharmony_ci /* Dump section containing number of PF CIDs per connection type */ 47458c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 47468c2ecf20Sopenharmony_ci dump, "num_pf_cids_per_conn_type", 1); 47478c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 47488c2ecf20Sopenharmony_ci dump, "size", NUM_OF_CONNECTION_TYPES_E4); 47498c2ecf20Sopenharmony_ci for (conn_type = 0, valid_conn_pf_cids = 0; 47508c2ecf20Sopenharmony_ci conn_type < NUM_OF_CONNECTION_TYPES_E4; conn_type++, offset++) { 47518c2ecf20Sopenharmony_ci u32 num_pf_cids = 47528c2ecf20Sopenharmony_ci p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cid_count; 47538c2ecf20Sopenharmony_ci 47548c2ecf20Sopenharmony_ci if (dump) 47558c2ecf20Sopenharmony_ci *(dump_buf + offset) = num_pf_cids; 47568c2ecf20Sopenharmony_ci valid_conn_pf_cids += num_pf_cids; 47578c2ecf20Sopenharmony_ci } 47588c2ecf20Sopenharmony_ci 47598c2ecf20Sopenharmony_ci /* Dump section containing number of VF CIDs per connection type */ 47608c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 47618c2ecf20Sopenharmony_ci dump, "num_vf_cids_per_conn_type", 1); 47628c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 47638c2ecf20Sopenharmony_ci dump, "size", NUM_OF_CONNECTION_TYPES_E4); 47648c2ecf20Sopenharmony_ci for (conn_type = 0, valid_conn_vf_cids = 0; 47658c2ecf20Sopenharmony_ci conn_type < NUM_OF_CONNECTION_TYPES_E4; conn_type++, offset++) { 47668c2ecf20Sopenharmony_ci u32 num_vf_cids = 47678c2ecf20Sopenharmony_ci p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cids_per_vf; 47688c2ecf20Sopenharmony_ci 47698c2ecf20Sopenharmony_ci if (dump) 47708c2ecf20Sopenharmony_ci *(dump_buf + offset) = num_vf_cids; 47718c2ecf20Sopenharmony_ci valid_conn_vf_cids += num_vf_cids; 47728c2ecf20Sopenharmony_ci } 47738c2ecf20Sopenharmony_ci 47748c2ecf20Sopenharmony_ci /* Dump section containing physical memory descs for each ILT page */ 47758c2ecf20Sopenharmony_ci num_pages = p_hwfn->p_cxt_mngr->ilt_shadow_size; 47768c2ecf20Sopenharmony_ci offset += qed_dump_section_hdr(dump_buf + offset, 47778c2ecf20Sopenharmony_ci dump, "ilt_page_desc", 1); 47788c2ecf20Sopenharmony_ci offset += qed_dump_num_param(dump_buf + offset, 47798c2ecf20Sopenharmony_ci dump, 47808c2ecf20Sopenharmony_ci "size", 47818c2ecf20Sopenharmony_ci num_pages * PAGE_MEM_DESC_SIZE_DWORDS); 47828c2ecf20Sopenharmony_ci 47838c2ecf20Sopenharmony_ci /* Copy memory descriptors to dump buffer */ 47848c2ecf20Sopenharmony_ci if (dump) { 47858c2ecf20Sopenharmony_ci u32 page_id; 47868c2ecf20Sopenharmony_ci 47878c2ecf20Sopenharmony_ci for (page_id = 0; page_id < num_pages; 47888c2ecf20Sopenharmony_ci page_id++, offset += PAGE_MEM_DESC_SIZE_DWORDS) 47898c2ecf20Sopenharmony_ci memcpy(dump_buf + offset, 47908c2ecf20Sopenharmony_ci &ilt_pages[page_id], 47918c2ecf20Sopenharmony_ci DWORDS_TO_BYTES(PAGE_MEM_DESC_SIZE_DWORDS)); 47928c2ecf20Sopenharmony_ci } else { 47938c2ecf20Sopenharmony_ci offset += num_pages * PAGE_MEM_DESC_SIZE_DWORDS; 47948c2ecf20Sopenharmony_ci } 47958c2ecf20Sopenharmony_ci 47968c2ecf20Sopenharmony_ci valid_conn_pf_pages = DIV_ROUND_UP(valid_conn_pf_cids, 47978c2ecf20Sopenharmony_ci num_cids_per_page); 47988c2ecf20Sopenharmony_ci valid_conn_vf_pages = DIV_ROUND_UP(valid_conn_vf_cids, 47998c2ecf20Sopenharmony_ci num_cids_per_page); 48008c2ecf20Sopenharmony_ci 48018c2ecf20Sopenharmony_ci /* Dump ILT pages IDs */ 48028c2ecf20Sopenharmony_ci offset += qed_ilt_dump_pages_section(p_hwfn, 48038c2ecf20Sopenharmony_ci dump_buf + offset, 48048c2ecf20Sopenharmony_ci dump, 48058c2ecf20Sopenharmony_ci valid_conn_pf_pages, 48068c2ecf20Sopenharmony_ci valid_conn_vf_pages, 48078c2ecf20Sopenharmony_ci ilt_pages, true); 48088c2ecf20Sopenharmony_ci 48098c2ecf20Sopenharmony_ci /* Dump ILT pages memory */ 48108c2ecf20Sopenharmony_ci offset += qed_ilt_dump_pages_section(p_hwfn, 48118c2ecf20Sopenharmony_ci dump_buf + offset, 48128c2ecf20Sopenharmony_ci dump, 48138c2ecf20Sopenharmony_ci valid_conn_pf_pages, 48148c2ecf20Sopenharmony_ci valid_conn_vf_pages, 48158c2ecf20Sopenharmony_ci ilt_pages, false); 48168c2ecf20Sopenharmony_ci 48178c2ecf20Sopenharmony_ci /* Dump last section */ 48188c2ecf20Sopenharmony_ci offset += qed_dump_last_section(dump_buf, offset, dump); 48198c2ecf20Sopenharmony_ci 48208c2ecf20Sopenharmony_ci return offset; 48218c2ecf20Sopenharmony_ci} 48228c2ecf20Sopenharmony_ci 48238c2ecf20Sopenharmony_ci/***************************** Public Functions *******************************/ 48248c2ecf20Sopenharmony_ci 48258c2ecf20Sopenharmony_cienum dbg_status qed_dbg_set_bin_ptr(struct qed_hwfn *p_hwfn, 48268c2ecf20Sopenharmony_ci const u8 * const bin_ptr) 48278c2ecf20Sopenharmony_ci{ 48288c2ecf20Sopenharmony_ci struct bin_buffer_hdr *buf_hdrs = (struct bin_buffer_hdr *)bin_ptr; 48298c2ecf20Sopenharmony_ci u8 buf_id; 48308c2ecf20Sopenharmony_ci 48318c2ecf20Sopenharmony_ci /* Convert binary data to debug arrays */ 48328c2ecf20Sopenharmony_ci for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++) 48338c2ecf20Sopenharmony_ci qed_set_dbg_bin_buf(p_hwfn, 48348c2ecf20Sopenharmony_ci buf_id, 48358c2ecf20Sopenharmony_ci (u32 *)(bin_ptr + buf_hdrs[buf_id].offset), 48368c2ecf20Sopenharmony_ci buf_hdrs[buf_id].length); 48378c2ecf20Sopenharmony_ci 48388c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 48398c2ecf20Sopenharmony_ci} 48408c2ecf20Sopenharmony_ci 48418c2ecf20Sopenharmony_cibool qed_read_fw_info(struct qed_hwfn *p_hwfn, 48428c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, struct fw_info *fw_info) 48438c2ecf20Sopenharmony_ci{ 48448c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 48458c2ecf20Sopenharmony_ci u8 storm_id; 48468c2ecf20Sopenharmony_ci 48478c2ecf20Sopenharmony_ci for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) { 48488c2ecf20Sopenharmony_ci struct storm_defs *storm = &s_storm_defs[storm_id]; 48498c2ecf20Sopenharmony_ci 48508c2ecf20Sopenharmony_ci /* Skip Storm if it's in reset */ 48518c2ecf20Sopenharmony_ci if (dev_data->block_in_reset[storm->sem_block_id]) 48528c2ecf20Sopenharmony_ci continue; 48538c2ecf20Sopenharmony_ci 48548c2ecf20Sopenharmony_ci /* Read FW info for the current Storm */ 48558c2ecf20Sopenharmony_ci qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, fw_info); 48568c2ecf20Sopenharmony_ci 48578c2ecf20Sopenharmony_ci return true; 48588c2ecf20Sopenharmony_ci } 48598c2ecf20Sopenharmony_ci 48608c2ecf20Sopenharmony_ci return false; 48618c2ecf20Sopenharmony_ci} 48628c2ecf20Sopenharmony_ci 48638c2ecf20Sopenharmony_cienum dbg_status qed_dbg_grc_config(struct qed_hwfn *p_hwfn, 48648c2ecf20Sopenharmony_ci enum dbg_grc_params grc_param, u32 val) 48658c2ecf20Sopenharmony_ci{ 48668c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 48678c2ecf20Sopenharmony_ci enum dbg_status status; 48688c2ecf20Sopenharmony_ci int i; 48698c2ecf20Sopenharmony_ci 48708c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, 48718c2ecf20Sopenharmony_ci QED_MSG_DEBUG, 48728c2ecf20Sopenharmony_ci "dbg_grc_config: paramId = %d, val = %d\n", grc_param, val); 48738c2ecf20Sopenharmony_ci 48748c2ecf20Sopenharmony_ci status = qed_dbg_dev_init(p_hwfn); 48758c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 48768c2ecf20Sopenharmony_ci return status; 48778c2ecf20Sopenharmony_ci 48788c2ecf20Sopenharmony_ci /* Initializes the GRC parameters (if not initialized). Needed in order 48798c2ecf20Sopenharmony_ci * to set the default parameter values for the first time. 48808c2ecf20Sopenharmony_ci */ 48818c2ecf20Sopenharmony_ci qed_dbg_grc_init_params(p_hwfn); 48828c2ecf20Sopenharmony_ci 48838c2ecf20Sopenharmony_ci if (grc_param >= MAX_DBG_GRC_PARAMS) 48848c2ecf20Sopenharmony_ci return DBG_STATUS_INVALID_ARGS; 48858c2ecf20Sopenharmony_ci if (val < s_grc_param_defs[grc_param].min || 48868c2ecf20Sopenharmony_ci val > s_grc_param_defs[grc_param].max) 48878c2ecf20Sopenharmony_ci return DBG_STATUS_INVALID_ARGS; 48888c2ecf20Sopenharmony_ci 48898c2ecf20Sopenharmony_ci if (s_grc_param_defs[grc_param].is_preset) { 48908c2ecf20Sopenharmony_ci /* Preset param */ 48918c2ecf20Sopenharmony_ci 48928c2ecf20Sopenharmony_ci /* Disabling a preset is not allowed. Call 48938c2ecf20Sopenharmony_ci * dbg_grc_set_params_default instead. 48948c2ecf20Sopenharmony_ci */ 48958c2ecf20Sopenharmony_ci if (!val) 48968c2ecf20Sopenharmony_ci return DBG_STATUS_INVALID_ARGS; 48978c2ecf20Sopenharmony_ci 48988c2ecf20Sopenharmony_ci /* Update all params with the preset values */ 48998c2ecf20Sopenharmony_ci for (i = 0; i < MAX_DBG_GRC_PARAMS; i++) { 49008c2ecf20Sopenharmony_ci struct grc_param_defs *defs = &s_grc_param_defs[i]; 49018c2ecf20Sopenharmony_ci u32 preset_val; 49028c2ecf20Sopenharmony_ci /* Skip persistent params */ 49038c2ecf20Sopenharmony_ci if (defs->is_persistent) 49048c2ecf20Sopenharmony_ci continue; 49058c2ecf20Sopenharmony_ci 49068c2ecf20Sopenharmony_ci /* Find preset value */ 49078c2ecf20Sopenharmony_ci if (grc_param == DBG_GRC_PARAM_EXCLUDE_ALL) 49088c2ecf20Sopenharmony_ci preset_val = 49098c2ecf20Sopenharmony_ci defs->exclude_all_preset_val; 49108c2ecf20Sopenharmony_ci else if (grc_param == DBG_GRC_PARAM_CRASH) 49118c2ecf20Sopenharmony_ci preset_val = 49128c2ecf20Sopenharmony_ci defs->crash_preset_val[dev_data->chip_id]; 49138c2ecf20Sopenharmony_ci else 49148c2ecf20Sopenharmony_ci return DBG_STATUS_INVALID_ARGS; 49158c2ecf20Sopenharmony_ci 49168c2ecf20Sopenharmony_ci qed_grc_set_param(p_hwfn, i, preset_val); 49178c2ecf20Sopenharmony_ci } 49188c2ecf20Sopenharmony_ci } else { 49198c2ecf20Sopenharmony_ci /* Regular param - set its value */ 49208c2ecf20Sopenharmony_ci qed_grc_set_param(p_hwfn, grc_param, val); 49218c2ecf20Sopenharmony_ci } 49228c2ecf20Sopenharmony_ci 49238c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 49248c2ecf20Sopenharmony_ci} 49258c2ecf20Sopenharmony_ci 49268c2ecf20Sopenharmony_ci/* Assign default GRC param values */ 49278c2ecf20Sopenharmony_civoid qed_dbg_grc_set_params_default(struct qed_hwfn *p_hwfn) 49288c2ecf20Sopenharmony_ci{ 49298c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 49308c2ecf20Sopenharmony_ci u32 i; 49318c2ecf20Sopenharmony_ci 49328c2ecf20Sopenharmony_ci for (i = 0; i < MAX_DBG_GRC_PARAMS; i++) 49338c2ecf20Sopenharmony_ci if (!s_grc_param_defs[i].is_persistent) 49348c2ecf20Sopenharmony_ci dev_data->grc.param_val[i] = 49358c2ecf20Sopenharmony_ci s_grc_param_defs[i].default_val[dev_data->chip_id]; 49368c2ecf20Sopenharmony_ci} 49378c2ecf20Sopenharmony_ci 49388c2ecf20Sopenharmony_cienum dbg_status qed_dbg_grc_get_dump_buf_size(struct qed_hwfn *p_hwfn, 49398c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 49408c2ecf20Sopenharmony_ci u32 *buf_size) 49418c2ecf20Sopenharmony_ci{ 49428c2ecf20Sopenharmony_ci enum dbg_status status = qed_dbg_dev_init(p_hwfn); 49438c2ecf20Sopenharmony_ci 49448c2ecf20Sopenharmony_ci *buf_size = 0; 49458c2ecf20Sopenharmony_ci 49468c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 49478c2ecf20Sopenharmony_ci return status; 49488c2ecf20Sopenharmony_ci 49498c2ecf20Sopenharmony_ci if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr || 49508c2ecf20Sopenharmony_ci !p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr || 49518c2ecf20Sopenharmony_ci !p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr || 49528c2ecf20Sopenharmony_ci !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr || 49538c2ecf20Sopenharmony_ci !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr) 49548c2ecf20Sopenharmony_ci return DBG_STATUS_DBG_ARRAY_NOT_SET; 49558c2ecf20Sopenharmony_ci 49568c2ecf20Sopenharmony_ci return qed_grc_dump(p_hwfn, p_ptt, NULL, false, buf_size); 49578c2ecf20Sopenharmony_ci} 49588c2ecf20Sopenharmony_ci 49598c2ecf20Sopenharmony_cienum dbg_status qed_dbg_grc_dump(struct qed_hwfn *p_hwfn, 49608c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 49618c2ecf20Sopenharmony_ci u32 *dump_buf, 49628c2ecf20Sopenharmony_ci u32 buf_size_in_dwords, 49638c2ecf20Sopenharmony_ci u32 *num_dumped_dwords) 49648c2ecf20Sopenharmony_ci{ 49658c2ecf20Sopenharmony_ci u32 needed_buf_size_in_dwords; 49668c2ecf20Sopenharmony_ci enum dbg_status status; 49678c2ecf20Sopenharmony_ci 49688c2ecf20Sopenharmony_ci *num_dumped_dwords = 0; 49698c2ecf20Sopenharmony_ci 49708c2ecf20Sopenharmony_ci status = qed_dbg_grc_get_dump_buf_size(p_hwfn, 49718c2ecf20Sopenharmony_ci p_ptt, 49728c2ecf20Sopenharmony_ci &needed_buf_size_in_dwords); 49738c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 49748c2ecf20Sopenharmony_ci return status; 49758c2ecf20Sopenharmony_ci 49768c2ecf20Sopenharmony_ci if (buf_size_in_dwords < needed_buf_size_in_dwords) 49778c2ecf20Sopenharmony_ci return DBG_STATUS_DUMP_BUF_TOO_SMALL; 49788c2ecf20Sopenharmony_ci 49798c2ecf20Sopenharmony_ci /* GRC Dump */ 49808c2ecf20Sopenharmony_ci status = qed_grc_dump(p_hwfn, p_ptt, dump_buf, true, num_dumped_dwords); 49818c2ecf20Sopenharmony_ci 49828c2ecf20Sopenharmony_ci /* Revert GRC params to their default */ 49838c2ecf20Sopenharmony_ci qed_dbg_grc_set_params_default(p_hwfn); 49848c2ecf20Sopenharmony_ci 49858c2ecf20Sopenharmony_ci return status; 49868c2ecf20Sopenharmony_ci} 49878c2ecf20Sopenharmony_ci 49888c2ecf20Sopenharmony_cienum dbg_status qed_dbg_idle_chk_get_dump_buf_size(struct qed_hwfn *p_hwfn, 49898c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 49908c2ecf20Sopenharmony_ci u32 *buf_size) 49918c2ecf20Sopenharmony_ci{ 49928c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 49938c2ecf20Sopenharmony_ci struct idle_chk_data *idle_chk = &dev_data->idle_chk; 49948c2ecf20Sopenharmony_ci enum dbg_status status; 49958c2ecf20Sopenharmony_ci 49968c2ecf20Sopenharmony_ci *buf_size = 0; 49978c2ecf20Sopenharmony_ci 49988c2ecf20Sopenharmony_ci status = qed_dbg_dev_init(p_hwfn); 49998c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 50008c2ecf20Sopenharmony_ci return status; 50018c2ecf20Sopenharmony_ci 50028c2ecf20Sopenharmony_ci if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr || 50038c2ecf20Sopenharmony_ci !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr || 50048c2ecf20Sopenharmony_ci !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr || 50058c2ecf20Sopenharmony_ci !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr) 50068c2ecf20Sopenharmony_ci return DBG_STATUS_DBG_ARRAY_NOT_SET; 50078c2ecf20Sopenharmony_ci 50088c2ecf20Sopenharmony_ci if (!idle_chk->buf_size_set) { 50098c2ecf20Sopenharmony_ci idle_chk->buf_size = qed_idle_chk_dump(p_hwfn, 50108c2ecf20Sopenharmony_ci p_ptt, NULL, false); 50118c2ecf20Sopenharmony_ci idle_chk->buf_size_set = true; 50128c2ecf20Sopenharmony_ci } 50138c2ecf20Sopenharmony_ci 50148c2ecf20Sopenharmony_ci *buf_size = idle_chk->buf_size; 50158c2ecf20Sopenharmony_ci 50168c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 50178c2ecf20Sopenharmony_ci} 50188c2ecf20Sopenharmony_ci 50198c2ecf20Sopenharmony_cienum dbg_status qed_dbg_idle_chk_dump(struct qed_hwfn *p_hwfn, 50208c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 50218c2ecf20Sopenharmony_ci u32 *dump_buf, 50228c2ecf20Sopenharmony_ci u32 buf_size_in_dwords, 50238c2ecf20Sopenharmony_ci u32 *num_dumped_dwords) 50248c2ecf20Sopenharmony_ci{ 50258c2ecf20Sopenharmony_ci u32 needed_buf_size_in_dwords; 50268c2ecf20Sopenharmony_ci enum dbg_status status; 50278c2ecf20Sopenharmony_ci 50288c2ecf20Sopenharmony_ci *num_dumped_dwords = 0; 50298c2ecf20Sopenharmony_ci 50308c2ecf20Sopenharmony_ci status = qed_dbg_idle_chk_get_dump_buf_size(p_hwfn, 50318c2ecf20Sopenharmony_ci p_ptt, 50328c2ecf20Sopenharmony_ci &needed_buf_size_in_dwords); 50338c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 50348c2ecf20Sopenharmony_ci return status; 50358c2ecf20Sopenharmony_ci 50368c2ecf20Sopenharmony_ci if (buf_size_in_dwords < needed_buf_size_in_dwords) 50378c2ecf20Sopenharmony_ci return DBG_STATUS_DUMP_BUF_TOO_SMALL; 50388c2ecf20Sopenharmony_ci 50398c2ecf20Sopenharmony_ci /* Update reset state */ 50408c2ecf20Sopenharmony_ci qed_grc_unreset_blocks(p_hwfn, p_ptt, true); 50418c2ecf20Sopenharmony_ci qed_update_blocks_reset_state(p_hwfn, p_ptt); 50428c2ecf20Sopenharmony_ci 50438c2ecf20Sopenharmony_ci /* Idle Check Dump */ 50448c2ecf20Sopenharmony_ci *num_dumped_dwords = qed_idle_chk_dump(p_hwfn, p_ptt, dump_buf, true); 50458c2ecf20Sopenharmony_ci 50468c2ecf20Sopenharmony_ci /* Revert GRC params to their default */ 50478c2ecf20Sopenharmony_ci qed_dbg_grc_set_params_default(p_hwfn); 50488c2ecf20Sopenharmony_ci 50498c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 50508c2ecf20Sopenharmony_ci} 50518c2ecf20Sopenharmony_ci 50528c2ecf20Sopenharmony_cienum dbg_status qed_dbg_mcp_trace_get_dump_buf_size(struct qed_hwfn *p_hwfn, 50538c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 50548c2ecf20Sopenharmony_ci u32 *buf_size) 50558c2ecf20Sopenharmony_ci{ 50568c2ecf20Sopenharmony_ci enum dbg_status status = qed_dbg_dev_init(p_hwfn); 50578c2ecf20Sopenharmony_ci 50588c2ecf20Sopenharmony_ci *buf_size = 0; 50598c2ecf20Sopenharmony_ci 50608c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 50618c2ecf20Sopenharmony_ci return status; 50628c2ecf20Sopenharmony_ci 50638c2ecf20Sopenharmony_ci return qed_mcp_trace_dump(p_hwfn, p_ptt, NULL, false, buf_size); 50648c2ecf20Sopenharmony_ci} 50658c2ecf20Sopenharmony_ci 50668c2ecf20Sopenharmony_cienum dbg_status qed_dbg_mcp_trace_dump(struct qed_hwfn *p_hwfn, 50678c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 50688c2ecf20Sopenharmony_ci u32 *dump_buf, 50698c2ecf20Sopenharmony_ci u32 buf_size_in_dwords, 50708c2ecf20Sopenharmony_ci u32 *num_dumped_dwords) 50718c2ecf20Sopenharmony_ci{ 50728c2ecf20Sopenharmony_ci u32 needed_buf_size_in_dwords; 50738c2ecf20Sopenharmony_ci enum dbg_status status; 50748c2ecf20Sopenharmony_ci 50758c2ecf20Sopenharmony_ci status = 50768c2ecf20Sopenharmony_ci qed_dbg_mcp_trace_get_dump_buf_size(p_hwfn, 50778c2ecf20Sopenharmony_ci p_ptt, 50788c2ecf20Sopenharmony_ci &needed_buf_size_in_dwords); 50798c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK && status != 50808c2ecf20Sopenharmony_ci DBG_STATUS_NVRAM_GET_IMAGE_FAILED) 50818c2ecf20Sopenharmony_ci return status; 50828c2ecf20Sopenharmony_ci 50838c2ecf20Sopenharmony_ci if (buf_size_in_dwords < needed_buf_size_in_dwords) 50848c2ecf20Sopenharmony_ci return DBG_STATUS_DUMP_BUF_TOO_SMALL; 50858c2ecf20Sopenharmony_ci 50868c2ecf20Sopenharmony_ci /* Update reset state */ 50878c2ecf20Sopenharmony_ci qed_update_blocks_reset_state(p_hwfn, p_ptt); 50888c2ecf20Sopenharmony_ci 50898c2ecf20Sopenharmony_ci /* Perform dump */ 50908c2ecf20Sopenharmony_ci status = qed_mcp_trace_dump(p_hwfn, 50918c2ecf20Sopenharmony_ci p_ptt, dump_buf, true, num_dumped_dwords); 50928c2ecf20Sopenharmony_ci 50938c2ecf20Sopenharmony_ci /* Revert GRC params to their default */ 50948c2ecf20Sopenharmony_ci qed_dbg_grc_set_params_default(p_hwfn); 50958c2ecf20Sopenharmony_ci 50968c2ecf20Sopenharmony_ci return status; 50978c2ecf20Sopenharmony_ci} 50988c2ecf20Sopenharmony_ci 50998c2ecf20Sopenharmony_cienum dbg_status qed_dbg_reg_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn, 51008c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 51018c2ecf20Sopenharmony_ci u32 *buf_size) 51028c2ecf20Sopenharmony_ci{ 51038c2ecf20Sopenharmony_ci enum dbg_status status = qed_dbg_dev_init(p_hwfn); 51048c2ecf20Sopenharmony_ci 51058c2ecf20Sopenharmony_ci *buf_size = 0; 51068c2ecf20Sopenharmony_ci 51078c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 51088c2ecf20Sopenharmony_ci return status; 51098c2ecf20Sopenharmony_ci 51108c2ecf20Sopenharmony_ci return qed_reg_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size); 51118c2ecf20Sopenharmony_ci} 51128c2ecf20Sopenharmony_ci 51138c2ecf20Sopenharmony_cienum dbg_status qed_dbg_reg_fifo_dump(struct qed_hwfn *p_hwfn, 51148c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 51158c2ecf20Sopenharmony_ci u32 *dump_buf, 51168c2ecf20Sopenharmony_ci u32 buf_size_in_dwords, 51178c2ecf20Sopenharmony_ci u32 *num_dumped_dwords) 51188c2ecf20Sopenharmony_ci{ 51198c2ecf20Sopenharmony_ci u32 needed_buf_size_in_dwords; 51208c2ecf20Sopenharmony_ci enum dbg_status status; 51218c2ecf20Sopenharmony_ci 51228c2ecf20Sopenharmony_ci *num_dumped_dwords = 0; 51238c2ecf20Sopenharmony_ci 51248c2ecf20Sopenharmony_ci status = qed_dbg_reg_fifo_get_dump_buf_size(p_hwfn, 51258c2ecf20Sopenharmony_ci p_ptt, 51268c2ecf20Sopenharmony_ci &needed_buf_size_in_dwords); 51278c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 51288c2ecf20Sopenharmony_ci return status; 51298c2ecf20Sopenharmony_ci 51308c2ecf20Sopenharmony_ci if (buf_size_in_dwords < needed_buf_size_in_dwords) 51318c2ecf20Sopenharmony_ci return DBG_STATUS_DUMP_BUF_TOO_SMALL; 51328c2ecf20Sopenharmony_ci 51338c2ecf20Sopenharmony_ci /* Update reset state */ 51348c2ecf20Sopenharmony_ci qed_update_blocks_reset_state(p_hwfn, p_ptt); 51358c2ecf20Sopenharmony_ci 51368c2ecf20Sopenharmony_ci status = qed_reg_fifo_dump(p_hwfn, 51378c2ecf20Sopenharmony_ci p_ptt, dump_buf, true, num_dumped_dwords); 51388c2ecf20Sopenharmony_ci 51398c2ecf20Sopenharmony_ci /* Revert GRC params to their default */ 51408c2ecf20Sopenharmony_ci qed_dbg_grc_set_params_default(p_hwfn); 51418c2ecf20Sopenharmony_ci 51428c2ecf20Sopenharmony_ci return status; 51438c2ecf20Sopenharmony_ci} 51448c2ecf20Sopenharmony_ci 51458c2ecf20Sopenharmony_cienum dbg_status qed_dbg_igu_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn, 51468c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 51478c2ecf20Sopenharmony_ci u32 *buf_size) 51488c2ecf20Sopenharmony_ci{ 51498c2ecf20Sopenharmony_ci enum dbg_status status = qed_dbg_dev_init(p_hwfn); 51508c2ecf20Sopenharmony_ci 51518c2ecf20Sopenharmony_ci *buf_size = 0; 51528c2ecf20Sopenharmony_ci 51538c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 51548c2ecf20Sopenharmony_ci return status; 51558c2ecf20Sopenharmony_ci 51568c2ecf20Sopenharmony_ci return qed_igu_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size); 51578c2ecf20Sopenharmony_ci} 51588c2ecf20Sopenharmony_ci 51598c2ecf20Sopenharmony_cienum dbg_status qed_dbg_igu_fifo_dump(struct qed_hwfn *p_hwfn, 51608c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 51618c2ecf20Sopenharmony_ci u32 *dump_buf, 51628c2ecf20Sopenharmony_ci u32 buf_size_in_dwords, 51638c2ecf20Sopenharmony_ci u32 *num_dumped_dwords) 51648c2ecf20Sopenharmony_ci{ 51658c2ecf20Sopenharmony_ci u32 needed_buf_size_in_dwords; 51668c2ecf20Sopenharmony_ci enum dbg_status status; 51678c2ecf20Sopenharmony_ci 51688c2ecf20Sopenharmony_ci *num_dumped_dwords = 0; 51698c2ecf20Sopenharmony_ci 51708c2ecf20Sopenharmony_ci status = qed_dbg_igu_fifo_get_dump_buf_size(p_hwfn, 51718c2ecf20Sopenharmony_ci p_ptt, 51728c2ecf20Sopenharmony_ci &needed_buf_size_in_dwords); 51738c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 51748c2ecf20Sopenharmony_ci return status; 51758c2ecf20Sopenharmony_ci 51768c2ecf20Sopenharmony_ci if (buf_size_in_dwords < needed_buf_size_in_dwords) 51778c2ecf20Sopenharmony_ci return DBG_STATUS_DUMP_BUF_TOO_SMALL; 51788c2ecf20Sopenharmony_ci 51798c2ecf20Sopenharmony_ci /* Update reset state */ 51808c2ecf20Sopenharmony_ci qed_update_blocks_reset_state(p_hwfn, p_ptt); 51818c2ecf20Sopenharmony_ci 51828c2ecf20Sopenharmony_ci status = qed_igu_fifo_dump(p_hwfn, 51838c2ecf20Sopenharmony_ci p_ptt, dump_buf, true, num_dumped_dwords); 51848c2ecf20Sopenharmony_ci /* Revert GRC params to their default */ 51858c2ecf20Sopenharmony_ci qed_dbg_grc_set_params_default(p_hwfn); 51868c2ecf20Sopenharmony_ci 51878c2ecf20Sopenharmony_ci return status; 51888c2ecf20Sopenharmony_ci} 51898c2ecf20Sopenharmony_ci 51908c2ecf20Sopenharmony_cienum dbg_status 51918c2ecf20Sopenharmony_ciqed_dbg_protection_override_get_dump_buf_size(struct qed_hwfn *p_hwfn, 51928c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 51938c2ecf20Sopenharmony_ci u32 *buf_size) 51948c2ecf20Sopenharmony_ci{ 51958c2ecf20Sopenharmony_ci enum dbg_status status = qed_dbg_dev_init(p_hwfn); 51968c2ecf20Sopenharmony_ci 51978c2ecf20Sopenharmony_ci *buf_size = 0; 51988c2ecf20Sopenharmony_ci 51998c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 52008c2ecf20Sopenharmony_ci return status; 52018c2ecf20Sopenharmony_ci 52028c2ecf20Sopenharmony_ci return qed_protection_override_dump(p_hwfn, 52038c2ecf20Sopenharmony_ci p_ptt, NULL, false, buf_size); 52048c2ecf20Sopenharmony_ci} 52058c2ecf20Sopenharmony_ci 52068c2ecf20Sopenharmony_cienum dbg_status qed_dbg_protection_override_dump(struct qed_hwfn *p_hwfn, 52078c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 52088c2ecf20Sopenharmony_ci u32 *dump_buf, 52098c2ecf20Sopenharmony_ci u32 buf_size_in_dwords, 52108c2ecf20Sopenharmony_ci u32 *num_dumped_dwords) 52118c2ecf20Sopenharmony_ci{ 52128c2ecf20Sopenharmony_ci u32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords; 52138c2ecf20Sopenharmony_ci enum dbg_status status; 52148c2ecf20Sopenharmony_ci 52158c2ecf20Sopenharmony_ci *num_dumped_dwords = 0; 52168c2ecf20Sopenharmony_ci 52178c2ecf20Sopenharmony_ci status = 52188c2ecf20Sopenharmony_ci qed_dbg_protection_override_get_dump_buf_size(p_hwfn, 52198c2ecf20Sopenharmony_ci p_ptt, 52208c2ecf20Sopenharmony_ci p_size); 52218c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 52228c2ecf20Sopenharmony_ci return status; 52238c2ecf20Sopenharmony_ci 52248c2ecf20Sopenharmony_ci if (buf_size_in_dwords < needed_buf_size_in_dwords) 52258c2ecf20Sopenharmony_ci return DBG_STATUS_DUMP_BUF_TOO_SMALL; 52268c2ecf20Sopenharmony_ci 52278c2ecf20Sopenharmony_ci /* Update reset state */ 52288c2ecf20Sopenharmony_ci qed_update_blocks_reset_state(p_hwfn, p_ptt); 52298c2ecf20Sopenharmony_ci 52308c2ecf20Sopenharmony_ci status = qed_protection_override_dump(p_hwfn, 52318c2ecf20Sopenharmony_ci p_ptt, 52328c2ecf20Sopenharmony_ci dump_buf, 52338c2ecf20Sopenharmony_ci true, num_dumped_dwords); 52348c2ecf20Sopenharmony_ci 52358c2ecf20Sopenharmony_ci /* Revert GRC params to their default */ 52368c2ecf20Sopenharmony_ci qed_dbg_grc_set_params_default(p_hwfn); 52378c2ecf20Sopenharmony_ci 52388c2ecf20Sopenharmony_ci return status; 52398c2ecf20Sopenharmony_ci} 52408c2ecf20Sopenharmony_ci 52418c2ecf20Sopenharmony_cienum dbg_status qed_dbg_fw_asserts_get_dump_buf_size(struct qed_hwfn *p_hwfn, 52428c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 52438c2ecf20Sopenharmony_ci u32 *buf_size) 52448c2ecf20Sopenharmony_ci{ 52458c2ecf20Sopenharmony_ci enum dbg_status status = qed_dbg_dev_init(p_hwfn); 52468c2ecf20Sopenharmony_ci 52478c2ecf20Sopenharmony_ci *buf_size = 0; 52488c2ecf20Sopenharmony_ci 52498c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 52508c2ecf20Sopenharmony_ci return status; 52518c2ecf20Sopenharmony_ci 52528c2ecf20Sopenharmony_ci /* Update reset state */ 52538c2ecf20Sopenharmony_ci qed_update_blocks_reset_state(p_hwfn, p_ptt); 52548c2ecf20Sopenharmony_ci 52558c2ecf20Sopenharmony_ci *buf_size = qed_fw_asserts_dump(p_hwfn, p_ptt, NULL, false); 52568c2ecf20Sopenharmony_ci 52578c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 52588c2ecf20Sopenharmony_ci} 52598c2ecf20Sopenharmony_ci 52608c2ecf20Sopenharmony_cienum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn *p_hwfn, 52618c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 52628c2ecf20Sopenharmony_ci u32 *dump_buf, 52638c2ecf20Sopenharmony_ci u32 buf_size_in_dwords, 52648c2ecf20Sopenharmony_ci u32 *num_dumped_dwords) 52658c2ecf20Sopenharmony_ci{ 52668c2ecf20Sopenharmony_ci u32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords; 52678c2ecf20Sopenharmony_ci enum dbg_status status; 52688c2ecf20Sopenharmony_ci 52698c2ecf20Sopenharmony_ci *num_dumped_dwords = 0; 52708c2ecf20Sopenharmony_ci 52718c2ecf20Sopenharmony_ci status = 52728c2ecf20Sopenharmony_ci qed_dbg_fw_asserts_get_dump_buf_size(p_hwfn, 52738c2ecf20Sopenharmony_ci p_ptt, 52748c2ecf20Sopenharmony_ci p_size); 52758c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 52768c2ecf20Sopenharmony_ci return status; 52778c2ecf20Sopenharmony_ci 52788c2ecf20Sopenharmony_ci if (buf_size_in_dwords < needed_buf_size_in_dwords) 52798c2ecf20Sopenharmony_ci return DBG_STATUS_DUMP_BUF_TOO_SMALL; 52808c2ecf20Sopenharmony_ci 52818c2ecf20Sopenharmony_ci *num_dumped_dwords = qed_fw_asserts_dump(p_hwfn, p_ptt, dump_buf, true); 52828c2ecf20Sopenharmony_ci 52838c2ecf20Sopenharmony_ci /* Revert GRC params to their default */ 52848c2ecf20Sopenharmony_ci qed_dbg_grc_set_params_default(p_hwfn); 52858c2ecf20Sopenharmony_ci 52868c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 52878c2ecf20Sopenharmony_ci} 52888c2ecf20Sopenharmony_ci 52898c2ecf20Sopenharmony_cistatic enum dbg_status qed_dbg_ilt_get_dump_buf_size(struct qed_hwfn *p_hwfn, 52908c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 52918c2ecf20Sopenharmony_ci u32 *buf_size) 52928c2ecf20Sopenharmony_ci{ 52938c2ecf20Sopenharmony_ci enum dbg_status status = qed_dbg_dev_init(p_hwfn); 52948c2ecf20Sopenharmony_ci 52958c2ecf20Sopenharmony_ci *buf_size = 0; 52968c2ecf20Sopenharmony_ci 52978c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 52988c2ecf20Sopenharmony_ci return status; 52998c2ecf20Sopenharmony_ci 53008c2ecf20Sopenharmony_ci *buf_size = qed_ilt_dump(p_hwfn, p_ptt, NULL, false); 53018c2ecf20Sopenharmony_ci 53028c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 53038c2ecf20Sopenharmony_ci} 53048c2ecf20Sopenharmony_ci 53058c2ecf20Sopenharmony_cistatic enum dbg_status qed_dbg_ilt_dump(struct qed_hwfn *p_hwfn, 53068c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 53078c2ecf20Sopenharmony_ci u32 *dump_buf, 53088c2ecf20Sopenharmony_ci u32 buf_size_in_dwords, 53098c2ecf20Sopenharmony_ci u32 *num_dumped_dwords) 53108c2ecf20Sopenharmony_ci{ 53118c2ecf20Sopenharmony_ci u32 needed_buf_size_in_dwords; 53128c2ecf20Sopenharmony_ci enum dbg_status status; 53138c2ecf20Sopenharmony_ci 53148c2ecf20Sopenharmony_ci *num_dumped_dwords = 0; 53158c2ecf20Sopenharmony_ci 53168c2ecf20Sopenharmony_ci status = qed_dbg_ilt_get_dump_buf_size(p_hwfn, 53178c2ecf20Sopenharmony_ci p_ptt, 53188c2ecf20Sopenharmony_ci &needed_buf_size_in_dwords); 53198c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 53208c2ecf20Sopenharmony_ci return status; 53218c2ecf20Sopenharmony_ci 53228c2ecf20Sopenharmony_ci if (buf_size_in_dwords < needed_buf_size_in_dwords) 53238c2ecf20Sopenharmony_ci return DBG_STATUS_DUMP_BUF_TOO_SMALL; 53248c2ecf20Sopenharmony_ci 53258c2ecf20Sopenharmony_ci *num_dumped_dwords = qed_ilt_dump(p_hwfn, p_ptt, dump_buf, true); 53268c2ecf20Sopenharmony_ci 53278c2ecf20Sopenharmony_ci /* Reveret GRC params to their default */ 53288c2ecf20Sopenharmony_ci qed_dbg_grc_set_params_default(p_hwfn); 53298c2ecf20Sopenharmony_ci 53308c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 53318c2ecf20Sopenharmony_ci} 53328c2ecf20Sopenharmony_ci 53338c2ecf20Sopenharmony_cienum dbg_status qed_dbg_read_attn(struct qed_hwfn *p_hwfn, 53348c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 53358c2ecf20Sopenharmony_ci enum block_id block_id, 53368c2ecf20Sopenharmony_ci enum dbg_attn_type attn_type, 53378c2ecf20Sopenharmony_ci bool clear_status, 53388c2ecf20Sopenharmony_ci struct dbg_attn_block_result *results) 53398c2ecf20Sopenharmony_ci{ 53408c2ecf20Sopenharmony_ci enum dbg_status status = qed_dbg_dev_init(p_hwfn); 53418c2ecf20Sopenharmony_ci u8 reg_idx, num_attn_regs, num_result_regs = 0; 53428c2ecf20Sopenharmony_ci const struct dbg_attn_reg *attn_reg_arr; 53438c2ecf20Sopenharmony_ci 53448c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 53458c2ecf20Sopenharmony_ci return status; 53468c2ecf20Sopenharmony_ci 53478c2ecf20Sopenharmony_ci if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr || 53488c2ecf20Sopenharmony_ci !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr || 53498c2ecf20Sopenharmony_ci !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr) 53508c2ecf20Sopenharmony_ci return DBG_STATUS_DBG_ARRAY_NOT_SET; 53518c2ecf20Sopenharmony_ci 53528c2ecf20Sopenharmony_ci attn_reg_arr = qed_get_block_attn_regs(p_hwfn, 53538c2ecf20Sopenharmony_ci block_id, 53548c2ecf20Sopenharmony_ci attn_type, &num_attn_regs); 53558c2ecf20Sopenharmony_ci 53568c2ecf20Sopenharmony_ci for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) { 53578c2ecf20Sopenharmony_ci const struct dbg_attn_reg *reg_data = &attn_reg_arr[reg_idx]; 53588c2ecf20Sopenharmony_ci struct dbg_attn_reg_result *reg_result; 53598c2ecf20Sopenharmony_ci u32 sts_addr, sts_val; 53608c2ecf20Sopenharmony_ci u16 modes_buf_offset; 53618c2ecf20Sopenharmony_ci bool eval_mode; 53628c2ecf20Sopenharmony_ci 53638c2ecf20Sopenharmony_ci /* Check mode */ 53648c2ecf20Sopenharmony_ci eval_mode = GET_FIELD(reg_data->mode.data, 53658c2ecf20Sopenharmony_ci DBG_MODE_HDR_EVAL_MODE) > 0; 53668c2ecf20Sopenharmony_ci modes_buf_offset = GET_FIELD(reg_data->mode.data, 53678c2ecf20Sopenharmony_ci DBG_MODE_HDR_MODES_BUF_OFFSET); 53688c2ecf20Sopenharmony_ci if (eval_mode && !qed_is_mode_match(p_hwfn, &modes_buf_offset)) 53698c2ecf20Sopenharmony_ci continue; 53708c2ecf20Sopenharmony_ci 53718c2ecf20Sopenharmony_ci /* Mode match - read attention status register */ 53728c2ecf20Sopenharmony_ci sts_addr = DWORDS_TO_BYTES(clear_status ? 53738c2ecf20Sopenharmony_ci reg_data->sts_clr_address : 53748c2ecf20Sopenharmony_ci GET_FIELD(reg_data->data, 53758c2ecf20Sopenharmony_ci DBG_ATTN_REG_STS_ADDRESS)); 53768c2ecf20Sopenharmony_ci sts_val = qed_rd(p_hwfn, p_ptt, sts_addr); 53778c2ecf20Sopenharmony_ci if (!sts_val) 53788c2ecf20Sopenharmony_ci continue; 53798c2ecf20Sopenharmony_ci 53808c2ecf20Sopenharmony_ci /* Non-zero attention status - add to results */ 53818c2ecf20Sopenharmony_ci reg_result = &results->reg_results[num_result_regs]; 53828c2ecf20Sopenharmony_ci SET_FIELD(reg_result->data, 53838c2ecf20Sopenharmony_ci DBG_ATTN_REG_RESULT_STS_ADDRESS, sts_addr); 53848c2ecf20Sopenharmony_ci SET_FIELD(reg_result->data, 53858c2ecf20Sopenharmony_ci DBG_ATTN_REG_RESULT_NUM_REG_ATTN, 53868c2ecf20Sopenharmony_ci GET_FIELD(reg_data->data, DBG_ATTN_REG_NUM_REG_ATTN)); 53878c2ecf20Sopenharmony_ci reg_result->block_attn_offset = reg_data->block_attn_offset; 53888c2ecf20Sopenharmony_ci reg_result->sts_val = sts_val; 53898c2ecf20Sopenharmony_ci reg_result->mask_val = qed_rd(p_hwfn, 53908c2ecf20Sopenharmony_ci p_ptt, 53918c2ecf20Sopenharmony_ci DWORDS_TO_BYTES 53928c2ecf20Sopenharmony_ci (reg_data->mask_address)); 53938c2ecf20Sopenharmony_ci num_result_regs++; 53948c2ecf20Sopenharmony_ci } 53958c2ecf20Sopenharmony_ci 53968c2ecf20Sopenharmony_ci results->block_id = (u8)block_id; 53978c2ecf20Sopenharmony_ci results->names_offset = 53988c2ecf20Sopenharmony_ci qed_get_block_attn_data(p_hwfn, block_id, attn_type)->names_offset; 53998c2ecf20Sopenharmony_ci SET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE, attn_type); 54008c2ecf20Sopenharmony_ci SET_FIELD(results->data, 54018c2ecf20Sopenharmony_ci DBG_ATTN_BLOCK_RESULT_NUM_REGS, num_result_regs); 54028c2ecf20Sopenharmony_ci 54038c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 54048c2ecf20Sopenharmony_ci} 54058c2ecf20Sopenharmony_ci 54068c2ecf20Sopenharmony_ci/******************************* Data Types **********************************/ 54078c2ecf20Sopenharmony_ci 54088c2ecf20Sopenharmony_ci/* REG fifo element */ 54098c2ecf20Sopenharmony_cistruct reg_fifo_element { 54108c2ecf20Sopenharmony_ci u64 data; 54118c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_ADDRESS_SHIFT 0 54128c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_ADDRESS_MASK 0x7fffff 54138c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_ACCESS_SHIFT 23 54148c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_ACCESS_MASK 0x1 54158c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_PF_SHIFT 24 54168c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_PF_MASK 0xf 54178c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_VF_SHIFT 28 54188c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_VF_MASK 0xff 54198c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_PORT_SHIFT 36 54208c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_PORT_MASK 0x3 54218c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_PRIVILEGE_SHIFT 38 54228c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_PRIVILEGE_MASK 0x3 54238c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_PROTECTION_SHIFT 40 54248c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_PROTECTION_MASK 0x7 54258c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_MASTER_SHIFT 43 54268c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_MASTER_MASK 0xf 54278c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_ERROR_SHIFT 47 54288c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_ERROR_MASK 0x1f 54298c2ecf20Sopenharmony_ci}; 54308c2ecf20Sopenharmony_ci 54318c2ecf20Sopenharmony_ci/* REG fifo error element */ 54328c2ecf20Sopenharmony_cistruct reg_fifo_err { 54338c2ecf20Sopenharmony_ci u32 err_code; 54348c2ecf20Sopenharmony_ci const char *err_msg; 54358c2ecf20Sopenharmony_ci}; 54368c2ecf20Sopenharmony_ci 54378c2ecf20Sopenharmony_ci/* IGU fifo element */ 54388c2ecf20Sopenharmony_cistruct igu_fifo_element { 54398c2ecf20Sopenharmony_ci u32 dword0; 54408c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD0_FID_SHIFT 0 54418c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD0_FID_MASK 0xff 54428c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD0_IS_PF_SHIFT 8 54438c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD0_IS_PF_MASK 0x1 54448c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD0_SOURCE_SHIFT 9 54458c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD0_SOURCE_MASK 0xf 54468c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_SHIFT 13 54478c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_MASK 0xf 54488c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_SHIFT 17 54498c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_MASK 0x7fff 54508c2ecf20Sopenharmony_ci u32 dword1; 54518c2ecf20Sopenharmony_ci u32 dword2; 54528c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_SHIFT 0 54538c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_MASK 0x1 54548c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_SHIFT 1 54558c2ecf20Sopenharmony_ci#define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_MASK 0xffffffff 54568c2ecf20Sopenharmony_ci u32 reserved; 54578c2ecf20Sopenharmony_ci}; 54588c2ecf20Sopenharmony_ci 54598c2ecf20Sopenharmony_cistruct igu_fifo_wr_data { 54608c2ecf20Sopenharmony_ci u32 data; 54618c2ecf20Sopenharmony_ci#define IGU_FIFO_WR_DATA_PROD_CONS_SHIFT 0 54628c2ecf20Sopenharmony_ci#define IGU_FIFO_WR_DATA_PROD_CONS_MASK 0xffffff 54638c2ecf20Sopenharmony_ci#define IGU_FIFO_WR_DATA_UPDATE_FLAG_SHIFT 24 54648c2ecf20Sopenharmony_ci#define IGU_FIFO_WR_DATA_UPDATE_FLAG_MASK 0x1 54658c2ecf20Sopenharmony_ci#define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_SHIFT 25 54668c2ecf20Sopenharmony_ci#define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_MASK 0x3 54678c2ecf20Sopenharmony_ci#define IGU_FIFO_WR_DATA_SEGMENT_SHIFT 27 54688c2ecf20Sopenharmony_ci#define IGU_FIFO_WR_DATA_SEGMENT_MASK 0x1 54698c2ecf20Sopenharmony_ci#define IGU_FIFO_WR_DATA_TIMER_MASK_SHIFT 28 54708c2ecf20Sopenharmony_ci#define IGU_FIFO_WR_DATA_TIMER_MASK_MASK 0x1 54718c2ecf20Sopenharmony_ci#define IGU_FIFO_WR_DATA_CMD_TYPE_SHIFT 31 54728c2ecf20Sopenharmony_ci#define IGU_FIFO_WR_DATA_CMD_TYPE_MASK 0x1 54738c2ecf20Sopenharmony_ci}; 54748c2ecf20Sopenharmony_ci 54758c2ecf20Sopenharmony_cistruct igu_fifo_cleanup_wr_data { 54768c2ecf20Sopenharmony_ci u32 data; 54778c2ecf20Sopenharmony_ci#define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_SHIFT 0 54788c2ecf20Sopenharmony_ci#define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_MASK 0x7ffffff 54798c2ecf20Sopenharmony_ci#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_SHIFT 27 54808c2ecf20Sopenharmony_ci#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_MASK 0x1 54818c2ecf20Sopenharmony_ci#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_SHIFT 28 54828c2ecf20Sopenharmony_ci#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_MASK 0x7 54838c2ecf20Sopenharmony_ci#define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_SHIFT 31 54848c2ecf20Sopenharmony_ci#define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_MASK 0x1 54858c2ecf20Sopenharmony_ci}; 54868c2ecf20Sopenharmony_ci 54878c2ecf20Sopenharmony_ci/* Protection override element */ 54888c2ecf20Sopenharmony_cistruct protection_override_element { 54898c2ecf20Sopenharmony_ci u64 data; 54908c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_SHIFT 0 54918c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_MASK 0x7fffff 54928c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_SHIFT 23 54938c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_MASK 0xffffff 54948c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_READ_SHIFT 47 54958c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_READ_MASK 0x1 54968c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_WRITE_SHIFT 48 54978c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_WRITE_MASK 0x1 54988c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_SHIFT 49 54998c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_MASK 0x7 55008c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_SHIFT 52 55018c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_MASK 0x7 55028c2ecf20Sopenharmony_ci}; 55038c2ecf20Sopenharmony_ci 55048c2ecf20Sopenharmony_cienum igu_fifo_sources { 55058c2ecf20Sopenharmony_ci IGU_SRC_PXP0, 55068c2ecf20Sopenharmony_ci IGU_SRC_PXP1, 55078c2ecf20Sopenharmony_ci IGU_SRC_PXP2, 55088c2ecf20Sopenharmony_ci IGU_SRC_PXP3, 55098c2ecf20Sopenharmony_ci IGU_SRC_PXP4, 55108c2ecf20Sopenharmony_ci IGU_SRC_PXP5, 55118c2ecf20Sopenharmony_ci IGU_SRC_PXP6, 55128c2ecf20Sopenharmony_ci IGU_SRC_PXP7, 55138c2ecf20Sopenharmony_ci IGU_SRC_CAU, 55148c2ecf20Sopenharmony_ci IGU_SRC_ATTN, 55158c2ecf20Sopenharmony_ci IGU_SRC_GRC 55168c2ecf20Sopenharmony_ci}; 55178c2ecf20Sopenharmony_ci 55188c2ecf20Sopenharmony_cienum igu_fifo_addr_types { 55198c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_MSIX_MEM, 55208c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_WRITE_PBA, 55218c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_WRITE_INT_ACK, 55228c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_WRITE_ATTN_BITS, 55238c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_READ_INT, 55248c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_WRITE_PROD_UPDATE, 55258c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_RESERVED 55268c2ecf20Sopenharmony_ci}; 55278c2ecf20Sopenharmony_ci 55288c2ecf20Sopenharmony_cistruct igu_fifo_addr_data { 55298c2ecf20Sopenharmony_ci u16 start_addr; 55308c2ecf20Sopenharmony_ci u16 end_addr; 55318c2ecf20Sopenharmony_ci char *desc; 55328c2ecf20Sopenharmony_ci char *vf_desc; 55338c2ecf20Sopenharmony_ci enum igu_fifo_addr_types type; 55348c2ecf20Sopenharmony_ci}; 55358c2ecf20Sopenharmony_ci 55368c2ecf20Sopenharmony_ci/******************************** Constants **********************************/ 55378c2ecf20Sopenharmony_ci 55388c2ecf20Sopenharmony_ci#define MAX_MSG_LEN 1024 55398c2ecf20Sopenharmony_ci 55408c2ecf20Sopenharmony_ci#define MCP_TRACE_MAX_MODULE_LEN 8 55418c2ecf20Sopenharmony_ci#define MCP_TRACE_FORMAT_MAX_PARAMS 3 55428c2ecf20Sopenharmony_ci#define MCP_TRACE_FORMAT_PARAM_WIDTH \ 55438c2ecf20Sopenharmony_ci (MCP_TRACE_FORMAT_P2_SIZE_OFFSET - MCP_TRACE_FORMAT_P1_SIZE_OFFSET) 55448c2ecf20Sopenharmony_ci 55458c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_ADDR_FACTOR 4 55468c2ecf20Sopenharmony_ci#define REG_FIFO_ELEMENT_IS_PF_VF_VAL 127 55478c2ecf20Sopenharmony_ci 55488c2ecf20Sopenharmony_ci#define PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR 4 55498c2ecf20Sopenharmony_ci 55508c2ecf20Sopenharmony_ci/***************************** Constant Arrays *******************************/ 55518c2ecf20Sopenharmony_ci 55528c2ecf20Sopenharmony_ci/* Status string array */ 55538c2ecf20Sopenharmony_cistatic const char * const s_status_str[] = { 55548c2ecf20Sopenharmony_ci /* DBG_STATUS_OK */ 55558c2ecf20Sopenharmony_ci "Operation completed successfully", 55568c2ecf20Sopenharmony_ci 55578c2ecf20Sopenharmony_ci /* DBG_STATUS_APP_VERSION_NOT_SET */ 55588c2ecf20Sopenharmony_ci "Debug application version wasn't set", 55598c2ecf20Sopenharmony_ci 55608c2ecf20Sopenharmony_ci /* DBG_STATUS_UNSUPPORTED_APP_VERSION */ 55618c2ecf20Sopenharmony_ci "Unsupported debug application version", 55628c2ecf20Sopenharmony_ci 55638c2ecf20Sopenharmony_ci /* DBG_STATUS_DBG_BLOCK_NOT_RESET */ 55648c2ecf20Sopenharmony_ci "The debug block wasn't reset since the last recording", 55658c2ecf20Sopenharmony_ci 55668c2ecf20Sopenharmony_ci /* DBG_STATUS_INVALID_ARGS */ 55678c2ecf20Sopenharmony_ci "Invalid arguments", 55688c2ecf20Sopenharmony_ci 55698c2ecf20Sopenharmony_ci /* DBG_STATUS_OUTPUT_ALREADY_SET */ 55708c2ecf20Sopenharmony_ci "The debug output was already set", 55718c2ecf20Sopenharmony_ci 55728c2ecf20Sopenharmony_ci /* DBG_STATUS_INVALID_PCI_BUF_SIZE */ 55738c2ecf20Sopenharmony_ci "Invalid PCI buffer size", 55748c2ecf20Sopenharmony_ci 55758c2ecf20Sopenharmony_ci /* DBG_STATUS_PCI_BUF_ALLOC_FAILED */ 55768c2ecf20Sopenharmony_ci "PCI buffer allocation failed", 55778c2ecf20Sopenharmony_ci 55788c2ecf20Sopenharmony_ci /* DBG_STATUS_PCI_BUF_NOT_ALLOCATED */ 55798c2ecf20Sopenharmony_ci "A PCI buffer wasn't allocated", 55808c2ecf20Sopenharmony_ci 55818c2ecf20Sopenharmony_ci /* DBG_STATUS_INVALID_FILTER_TRIGGER_DWORDS */ 55828c2ecf20Sopenharmony_ci "The filter/trigger constraint dword offsets are not enabled for recording", 55838c2ecf20Sopenharmony_ci /* DBG_STATUS_NO_MATCHING_FRAMING_MODE */ 55848c2ecf20Sopenharmony_ci "No matching framing mode", 55858c2ecf20Sopenharmony_ci 55868c2ecf20Sopenharmony_ci /* DBG_STATUS_VFC_READ_ERROR */ 55878c2ecf20Sopenharmony_ci "Error reading from VFC", 55888c2ecf20Sopenharmony_ci 55898c2ecf20Sopenharmony_ci /* DBG_STATUS_STORM_ALREADY_ENABLED */ 55908c2ecf20Sopenharmony_ci "The Storm was already enabled", 55918c2ecf20Sopenharmony_ci 55928c2ecf20Sopenharmony_ci /* DBG_STATUS_STORM_NOT_ENABLED */ 55938c2ecf20Sopenharmony_ci "The specified Storm wasn't enabled", 55948c2ecf20Sopenharmony_ci 55958c2ecf20Sopenharmony_ci /* DBG_STATUS_BLOCK_ALREADY_ENABLED */ 55968c2ecf20Sopenharmony_ci "The block was already enabled", 55978c2ecf20Sopenharmony_ci 55988c2ecf20Sopenharmony_ci /* DBG_STATUS_BLOCK_NOT_ENABLED */ 55998c2ecf20Sopenharmony_ci "The specified block wasn't enabled", 56008c2ecf20Sopenharmony_ci 56018c2ecf20Sopenharmony_ci /* DBG_STATUS_NO_INPUT_ENABLED */ 56028c2ecf20Sopenharmony_ci "No input was enabled for recording", 56038c2ecf20Sopenharmony_ci 56048c2ecf20Sopenharmony_ci /* DBG_STATUS_NO_FILTER_TRIGGER_256B */ 56058c2ecf20Sopenharmony_ci "Filters and triggers are not allowed in E4 256-bit mode", 56068c2ecf20Sopenharmony_ci 56078c2ecf20Sopenharmony_ci /* DBG_STATUS_FILTER_ALREADY_ENABLED */ 56088c2ecf20Sopenharmony_ci "The filter was already enabled", 56098c2ecf20Sopenharmony_ci 56108c2ecf20Sopenharmony_ci /* DBG_STATUS_TRIGGER_ALREADY_ENABLED */ 56118c2ecf20Sopenharmony_ci "The trigger was already enabled", 56128c2ecf20Sopenharmony_ci 56138c2ecf20Sopenharmony_ci /* DBG_STATUS_TRIGGER_NOT_ENABLED */ 56148c2ecf20Sopenharmony_ci "The trigger wasn't enabled", 56158c2ecf20Sopenharmony_ci 56168c2ecf20Sopenharmony_ci /* DBG_STATUS_CANT_ADD_CONSTRAINT */ 56178c2ecf20Sopenharmony_ci "A constraint can be added only after a filter was enabled or a trigger state was added", 56188c2ecf20Sopenharmony_ci 56198c2ecf20Sopenharmony_ci /* DBG_STATUS_TOO_MANY_TRIGGER_STATES */ 56208c2ecf20Sopenharmony_ci "Cannot add more than 3 trigger states", 56218c2ecf20Sopenharmony_ci 56228c2ecf20Sopenharmony_ci /* DBG_STATUS_TOO_MANY_CONSTRAINTS */ 56238c2ecf20Sopenharmony_ci "Cannot add more than 4 constraints per filter or trigger state", 56248c2ecf20Sopenharmony_ci 56258c2ecf20Sopenharmony_ci /* DBG_STATUS_RECORDING_NOT_STARTED */ 56268c2ecf20Sopenharmony_ci "The recording wasn't started", 56278c2ecf20Sopenharmony_ci 56288c2ecf20Sopenharmony_ci /* DBG_STATUS_DATA_DIDNT_TRIGGER */ 56298c2ecf20Sopenharmony_ci "A trigger was configured, but it didn't trigger", 56308c2ecf20Sopenharmony_ci 56318c2ecf20Sopenharmony_ci /* DBG_STATUS_NO_DATA_RECORDED */ 56328c2ecf20Sopenharmony_ci "No data was recorded", 56338c2ecf20Sopenharmony_ci 56348c2ecf20Sopenharmony_ci /* DBG_STATUS_DUMP_BUF_TOO_SMALL */ 56358c2ecf20Sopenharmony_ci "Dump buffer is too small", 56368c2ecf20Sopenharmony_ci 56378c2ecf20Sopenharmony_ci /* DBG_STATUS_DUMP_NOT_CHUNK_ALIGNED */ 56388c2ecf20Sopenharmony_ci "Dumped data is not aligned to chunks", 56398c2ecf20Sopenharmony_ci 56408c2ecf20Sopenharmony_ci /* DBG_STATUS_UNKNOWN_CHIP */ 56418c2ecf20Sopenharmony_ci "Unknown chip", 56428c2ecf20Sopenharmony_ci 56438c2ecf20Sopenharmony_ci /* DBG_STATUS_VIRT_MEM_ALLOC_FAILED */ 56448c2ecf20Sopenharmony_ci "Failed allocating virtual memory", 56458c2ecf20Sopenharmony_ci 56468c2ecf20Sopenharmony_ci /* DBG_STATUS_BLOCK_IN_RESET */ 56478c2ecf20Sopenharmony_ci "The input block is in reset", 56488c2ecf20Sopenharmony_ci 56498c2ecf20Sopenharmony_ci /* DBG_STATUS_INVALID_TRACE_SIGNATURE */ 56508c2ecf20Sopenharmony_ci "Invalid MCP trace signature found in NVRAM", 56518c2ecf20Sopenharmony_ci 56528c2ecf20Sopenharmony_ci /* DBG_STATUS_INVALID_NVRAM_BUNDLE */ 56538c2ecf20Sopenharmony_ci "Invalid bundle ID found in NVRAM", 56548c2ecf20Sopenharmony_ci 56558c2ecf20Sopenharmony_ci /* DBG_STATUS_NVRAM_GET_IMAGE_FAILED */ 56568c2ecf20Sopenharmony_ci "Failed getting NVRAM image", 56578c2ecf20Sopenharmony_ci 56588c2ecf20Sopenharmony_ci /* DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE */ 56598c2ecf20Sopenharmony_ci "NVRAM image is not dword-aligned", 56608c2ecf20Sopenharmony_ci 56618c2ecf20Sopenharmony_ci /* DBG_STATUS_NVRAM_READ_FAILED */ 56628c2ecf20Sopenharmony_ci "Failed reading from NVRAM", 56638c2ecf20Sopenharmony_ci 56648c2ecf20Sopenharmony_ci /* DBG_STATUS_IDLE_CHK_PARSE_FAILED */ 56658c2ecf20Sopenharmony_ci "Idle check parsing failed", 56668c2ecf20Sopenharmony_ci 56678c2ecf20Sopenharmony_ci /* DBG_STATUS_MCP_TRACE_BAD_DATA */ 56688c2ecf20Sopenharmony_ci "MCP Trace data is corrupt", 56698c2ecf20Sopenharmony_ci 56708c2ecf20Sopenharmony_ci /* DBG_STATUS_MCP_TRACE_NO_META */ 56718c2ecf20Sopenharmony_ci "Dump doesn't contain meta data - it must be provided in image file", 56728c2ecf20Sopenharmony_ci 56738c2ecf20Sopenharmony_ci /* DBG_STATUS_MCP_COULD_NOT_HALT */ 56748c2ecf20Sopenharmony_ci "Failed to halt MCP", 56758c2ecf20Sopenharmony_ci 56768c2ecf20Sopenharmony_ci /* DBG_STATUS_MCP_COULD_NOT_RESUME */ 56778c2ecf20Sopenharmony_ci "Failed to resume MCP after halt", 56788c2ecf20Sopenharmony_ci 56798c2ecf20Sopenharmony_ci /* DBG_STATUS_RESERVED0 */ 56808c2ecf20Sopenharmony_ci "", 56818c2ecf20Sopenharmony_ci 56828c2ecf20Sopenharmony_ci /* DBG_STATUS_SEMI_FIFO_NOT_EMPTY */ 56838c2ecf20Sopenharmony_ci "Failed to empty SEMI sync FIFO", 56848c2ecf20Sopenharmony_ci 56858c2ecf20Sopenharmony_ci /* DBG_STATUS_IGU_FIFO_BAD_DATA */ 56868c2ecf20Sopenharmony_ci "IGU FIFO data is corrupt", 56878c2ecf20Sopenharmony_ci 56888c2ecf20Sopenharmony_ci /* DBG_STATUS_MCP_COULD_NOT_MASK_PRTY */ 56898c2ecf20Sopenharmony_ci "MCP failed to mask parities", 56908c2ecf20Sopenharmony_ci 56918c2ecf20Sopenharmony_ci /* DBG_STATUS_FW_ASSERTS_PARSE_FAILED */ 56928c2ecf20Sopenharmony_ci "FW Asserts parsing failed", 56938c2ecf20Sopenharmony_ci 56948c2ecf20Sopenharmony_ci /* DBG_STATUS_REG_FIFO_BAD_DATA */ 56958c2ecf20Sopenharmony_ci "GRC FIFO data is corrupt", 56968c2ecf20Sopenharmony_ci 56978c2ecf20Sopenharmony_ci /* DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA */ 56988c2ecf20Sopenharmony_ci "Protection Override data is corrupt", 56998c2ecf20Sopenharmony_ci 57008c2ecf20Sopenharmony_ci /* DBG_STATUS_DBG_ARRAY_NOT_SET */ 57018c2ecf20Sopenharmony_ci "Debug arrays were not set (when using binary files, dbg_set_bin_ptr must be called)", 57028c2ecf20Sopenharmony_ci 57038c2ecf20Sopenharmony_ci /* DBG_STATUS_RESERVED1 */ 57048c2ecf20Sopenharmony_ci "", 57058c2ecf20Sopenharmony_ci 57068c2ecf20Sopenharmony_ci /* DBG_STATUS_NON_MATCHING_LINES */ 57078c2ecf20Sopenharmony_ci "Non-matching debug lines - in E4, all lines must be of the same type (either 128b or 256b)", 57088c2ecf20Sopenharmony_ci 57098c2ecf20Sopenharmony_ci /* DBG_STATUS_INSUFFICIENT_HW_IDS */ 57108c2ecf20Sopenharmony_ci "Insufficient HW IDs. Try to record less Storms/blocks", 57118c2ecf20Sopenharmony_ci 57128c2ecf20Sopenharmony_ci /* DBG_STATUS_DBG_BUS_IN_USE */ 57138c2ecf20Sopenharmony_ci "The debug bus is in use", 57148c2ecf20Sopenharmony_ci 57158c2ecf20Sopenharmony_ci /* DBG_STATUS_INVALID_STORM_DBG_MODE */ 57168c2ecf20Sopenharmony_ci "The storm debug mode is not supported in the current chip", 57178c2ecf20Sopenharmony_ci 57188c2ecf20Sopenharmony_ci /* DBG_STATUS_OTHER_ENGINE_BB_ONLY */ 57198c2ecf20Sopenharmony_ci "Other engine is supported only in BB", 57208c2ecf20Sopenharmony_ci 57218c2ecf20Sopenharmony_ci /* DBG_STATUS_FILTER_SINGLE_HW_ID */ 57228c2ecf20Sopenharmony_ci "The configured filter mode requires a single Storm/block input", 57238c2ecf20Sopenharmony_ci 57248c2ecf20Sopenharmony_ci /* DBG_STATUS_TRIGGER_SINGLE_HW_ID */ 57258c2ecf20Sopenharmony_ci "The configured filter mode requires that all the constraints of a single trigger state will be defined on a single Storm/block input", 57268c2ecf20Sopenharmony_ci 57278c2ecf20Sopenharmony_ci /* DBG_STATUS_MISSING_TRIGGER_STATE_STORM */ 57288c2ecf20Sopenharmony_ci "When triggering on Storm data, the Storm to trigger on must be specified" 57298c2ecf20Sopenharmony_ci}; 57308c2ecf20Sopenharmony_ci 57318c2ecf20Sopenharmony_ci/* Idle check severity names array */ 57328c2ecf20Sopenharmony_cistatic const char * const s_idle_chk_severity_str[] = { 57338c2ecf20Sopenharmony_ci "Error", 57348c2ecf20Sopenharmony_ci "Error if no traffic", 57358c2ecf20Sopenharmony_ci "Warning" 57368c2ecf20Sopenharmony_ci}; 57378c2ecf20Sopenharmony_ci 57388c2ecf20Sopenharmony_ci/* MCP Trace level names array */ 57398c2ecf20Sopenharmony_cistatic const char * const s_mcp_trace_level_str[] = { 57408c2ecf20Sopenharmony_ci "ERROR", 57418c2ecf20Sopenharmony_ci "TRACE", 57428c2ecf20Sopenharmony_ci "DEBUG" 57438c2ecf20Sopenharmony_ci}; 57448c2ecf20Sopenharmony_ci 57458c2ecf20Sopenharmony_ci/* Access type names array */ 57468c2ecf20Sopenharmony_cistatic const char * const s_access_strs[] = { 57478c2ecf20Sopenharmony_ci "read", 57488c2ecf20Sopenharmony_ci "write" 57498c2ecf20Sopenharmony_ci}; 57508c2ecf20Sopenharmony_ci 57518c2ecf20Sopenharmony_ci/* Privilege type names array */ 57528c2ecf20Sopenharmony_cistatic const char * const s_privilege_strs[] = { 57538c2ecf20Sopenharmony_ci "VF", 57548c2ecf20Sopenharmony_ci "PDA", 57558c2ecf20Sopenharmony_ci "HV", 57568c2ecf20Sopenharmony_ci "UA" 57578c2ecf20Sopenharmony_ci}; 57588c2ecf20Sopenharmony_ci 57598c2ecf20Sopenharmony_ci/* Protection type names array */ 57608c2ecf20Sopenharmony_cistatic const char * const s_protection_strs[] = { 57618c2ecf20Sopenharmony_ci "(default)", 57628c2ecf20Sopenharmony_ci "(default)", 57638c2ecf20Sopenharmony_ci "(default)", 57648c2ecf20Sopenharmony_ci "(default)", 57658c2ecf20Sopenharmony_ci "override VF", 57668c2ecf20Sopenharmony_ci "override PDA", 57678c2ecf20Sopenharmony_ci "override HV", 57688c2ecf20Sopenharmony_ci "override UA" 57698c2ecf20Sopenharmony_ci}; 57708c2ecf20Sopenharmony_ci 57718c2ecf20Sopenharmony_ci/* Master type names array */ 57728c2ecf20Sopenharmony_cistatic const char * const s_master_strs[] = { 57738c2ecf20Sopenharmony_ci "???", 57748c2ecf20Sopenharmony_ci "pxp", 57758c2ecf20Sopenharmony_ci "mcp", 57768c2ecf20Sopenharmony_ci "msdm", 57778c2ecf20Sopenharmony_ci "psdm", 57788c2ecf20Sopenharmony_ci "ysdm", 57798c2ecf20Sopenharmony_ci "usdm", 57808c2ecf20Sopenharmony_ci "tsdm", 57818c2ecf20Sopenharmony_ci "xsdm", 57828c2ecf20Sopenharmony_ci "dbu", 57838c2ecf20Sopenharmony_ci "dmae", 57848c2ecf20Sopenharmony_ci "jdap", 57858c2ecf20Sopenharmony_ci "???", 57868c2ecf20Sopenharmony_ci "???", 57878c2ecf20Sopenharmony_ci "???", 57888c2ecf20Sopenharmony_ci "???" 57898c2ecf20Sopenharmony_ci}; 57908c2ecf20Sopenharmony_ci 57918c2ecf20Sopenharmony_ci/* REG FIFO error messages array */ 57928c2ecf20Sopenharmony_cistatic struct reg_fifo_err s_reg_fifo_errors[] = { 57938c2ecf20Sopenharmony_ci {1, "grc timeout"}, 57948c2ecf20Sopenharmony_ci {2, "address doesn't belong to any block"}, 57958c2ecf20Sopenharmony_ci {4, "reserved address in block or write to read-only address"}, 57968c2ecf20Sopenharmony_ci {8, "privilege/protection mismatch"}, 57978c2ecf20Sopenharmony_ci {16, "path isolation error"}, 57988c2ecf20Sopenharmony_ci {17, "RSL error"} 57998c2ecf20Sopenharmony_ci}; 58008c2ecf20Sopenharmony_ci 58018c2ecf20Sopenharmony_ci/* IGU FIFO sources array */ 58028c2ecf20Sopenharmony_cistatic const char * const s_igu_fifo_source_strs[] = { 58038c2ecf20Sopenharmony_ci "TSTORM", 58048c2ecf20Sopenharmony_ci "MSTORM", 58058c2ecf20Sopenharmony_ci "USTORM", 58068c2ecf20Sopenharmony_ci "XSTORM", 58078c2ecf20Sopenharmony_ci "YSTORM", 58088c2ecf20Sopenharmony_ci "PSTORM", 58098c2ecf20Sopenharmony_ci "PCIE", 58108c2ecf20Sopenharmony_ci "NIG_QM_PBF", 58118c2ecf20Sopenharmony_ci "CAU", 58128c2ecf20Sopenharmony_ci "ATTN", 58138c2ecf20Sopenharmony_ci "GRC", 58148c2ecf20Sopenharmony_ci}; 58158c2ecf20Sopenharmony_ci 58168c2ecf20Sopenharmony_ci/* IGU FIFO error messages */ 58178c2ecf20Sopenharmony_cistatic const char * const s_igu_fifo_error_strs[] = { 58188c2ecf20Sopenharmony_ci "no error", 58198c2ecf20Sopenharmony_ci "length error", 58208c2ecf20Sopenharmony_ci "function disabled", 58218c2ecf20Sopenharmony_ci "VF sent command to attention address", 58228c2ecf20Sopenharmony_ci "host sent prod update command", 58238c2ecf20Sopenharmony_ci "read of during interrupt register while in MIMD mode", 58248c2ecf20Sopenharmony_ci "access to PXP BAR reserved address", 58258c2ecf20Sopenharmony_ci "producer update command to attention index", 58268c2ecf20Sopenharmony_ci "unknown error", 58278c2ecf20Sopenharmony_ci "SB index not valid", 58288c2ecf20Sopenharmony_ci "SB relative index and FID not found", 58298c2ecf20Sopenharmony_ci "FID not match", 58308c2ecf20Sopenharmony_ci "command with error flag asserted (PCI error or CAU discard)", 58318c2ecf20Sopenharmony_ci "VF sent cleanup and RF cleanup is disabled", 58328c2ecf20Sopenharmony_ci "cleanup command on type bigger than 4" 58338c2ecf20Sopenharmony_ci}; 58348c2ecf20Sopenharmony_ci 58358c2ecf20Sopenharmony_ci/* IGU FIFO address data */ 58368c2ecf20Sopenharmony_cistatic const struct igu_fifo_addr_data s_igu_fifo_addr_data[] = { 58378c2ecf20Sopenharmony_ci {0x0, 0x101, "MSI-X Memory", NULL, 58388c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_MSIX_MEM}, 58398c2ecf20Sopenharmony_ci {0x102, 0x1ff, "reserved", NULL, 58408c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_RESERVED}, 58418c2ecf20Sopenharmony_ci {0x200, 0x200, "Write PBA[0:63]", NULL, 58428c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_WRITE_PBA}, 58438c2ecf20Sopenharmony_ci {0x201, 0x201, "Write PBA[64:127]", "reserved", 58448c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_WRITE_PBA}, 58458c2ecf20Sopenharmony_ci {0x202, 0x202, "Write PBA[128]", "reserved", 58468c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_WRITE_PBA}, 58478c2ecf20Sopenharmony_ci {0x203, 0x3ff, "reserved", NULL, 58488c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_RESERVED}, 58498c2ecf20Sopenharmony_ci {0x400, 0x5ef, "Write interrupt acknowledgment", NULL, 58508c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_WRITE_INT_ACK}, 58518c2ecf20Sopenharmony_ci {0x5f0, 0x5f0, "Attention bits update", NULL, 58528c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_WRITE_ATTN_BITS}, 58538c2ecf20Sopenharmony_ci {0x5f1, 0x5f1, "Attention bits set", NULL, 58548c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_WRITE_ATTN_BITS}, 58558c2ecf20Sopenharmony_ci {0x5f2, 0x5f2, "Attention bits clear", NULL, 58568c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_WRITE_ATTN_BITS}, 58578c2ecf20Sopenharmony_ci {0x5f3, 0x5f3, "Read interrupt 0:63 with mask", NULL, 58588c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_READ_INT}, 58598c2ecf20Sopenharmony_ci {0x5f4, 0x5f4, "Read interrupt 0:31 with mask", NULL, 58608c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_READ_INT}, 58618c2ecf20Sopenharmony_ci {0x5f5, 0x5f5, "Read interrupt 32:63 with mask", NULL, 58628c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_READ_INT}, 58638c2ecf20Sopenharmony_ci {0x5f6, 0x5f6, "Read interrupt 0:63 without mask", NULL, 58648c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_READ_INT}, 58658c2ecf20Sopenharmony_ci {0x5f7, 0x5ff, "reserved", NULL, 58668c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_RESERVED}, 58678c2ecf20Sopenharmony_ci {0x600, 0x7ff, "Producer update", NULL, 58688c2ecf20Sopenharmony_ci IGU_ADDR_TYPE_WRITE_PROD_UPDATE} 58698c2ecf20Sopenharmony_ci}; 58708c2ecf20Sopenharmony_ci 58718c2ecf20Sopenharmony_ci/******************************** Variables **********************************/ 58728c2ecf20Sopenharmony_ci 58738c2ecf20Sopenharmony_ci/* Temporary buffer, used for print size calculations */ 58748c2ecf20Sopenharmony_cistatic char s_temp_buf[MAX_MSG_LEN]; 58758c2ecf20Sopenharmony_ci 58768c2ecf20Sopenharmony_ci/**************************** Private Functions ******************************/ 58778c2ecf20Sopenharmony_ci 58788c2ecf20Sopenharmony_cistatic u32 qed_cyclic_add(u32 a, u32 b, u32 size) 58798c2ecf20Sopenharmony_ci{ 58808c2ecf20Sopenharmony_ci return (a + b) % size; 58818c2ecf20Sopenharmony_ci} 58828c2ecf20Sopenharmony_ci 58838c2ecf20Sopenharmony_cistatic u32 qed_cyclic_sub(u32 a, u32 b, u32 size) 58848c2ecf20Sopenharmony_ci{ 58858c2ecf20Sopenharmony_ci return (size + a - b) % size; 58868c2ecf20Sopenharmony_ci} 58878c2ecf20Sopenharmony_ci 58888c2ecf20Sopenharmony_ci/* Reads the specified number of bytes from the specified cyclic buffer (up to 4 58898c2ecf20Sopenharmony_ci * bytes) and returns them as a dword value. the specified buffer offset is 58908c2ecf20Sopenharmony_ci * updated. 58918c2ecf20Sopenharmony_ci */ 58928c2ecf20Sopenharmony_cistatic u32 qed_read_from_cyclic_buf(void *buf, 58938c2ecf20Sopenharmony_ci u32 *offset, 58948c2ecf20Sopenharmony_ci u32 buf_size, u8 num_bytes_to_read) 58958c2ecf20Sopenharmony_ci{ 58968c2ecf20Sopenharmony_ci u8 i, *val_ptr, *bytes_buf = (u8 *)buf; 58978c2ecf20Sopenharmony_ci u32 val = 0; 58988c2ecf20Sopenharmony_ci 58998c2ecf20Sopenharmony_ci val_ptr = (u8 *)&val; 59008c2ecf20Sopenharmony_ci 59018c2ecf20Sopenharmony_ci /* Assume running on a LITTLE ENDIAN and the buffer is network order 59028c2ecf20Sopenharmony_ci * (BIG ENDIAN), as high order bytes are placed in lower memory address. 59038c2ecf20Sopenharmony_ci */ 59048c2ecf20Sopenharmony_ci for (i = 0; i < num_bytes_to_read; i++) { 59058c2ecf20Sopenharmony_ci val_ptr[i] = bytes_buf[*offset]; 59068c2ecf20Sopenharmony_ci *offset = qed_cyclic_add(*offset, 1, buf_size); 59078c2ecf20Sopenharmony_ci } 59088c2ecf20Sopenharmony_ci 59098c2ecf20Sopenharmony_ci return val; 59108c2ecf20Sopenharmony_ci} 59118c2ecf20Sopenharmony_ci 59128c2ecf20Sopenharmony_ci/* Reads and returns the next byte from the specified buffer. 59138c2ecf20Sopenharmony_ci * The specified buffer offset is updated. 59148c2ecf20Sopenharmony_ci */ 59158c2ecf20Sopenharmony_cistatic u8 qed_read_byte_from_buf(void *buf, u32 *offset) 59168c2ecf20Sopenharmony_ci{ 59178c2ecf20Sopenharmony_ci return ((u8 *)buf)[(*offset)++]; 59188c2ecf20Sopenharmony_ci} 59198c2ecf20Sopenharmony_ci 59208c2ecf20Sopenharmony_ci/* Reads and returns the next dword from the specified buffer. 59218c2ecf20Sopenharmony_ci * The specified buffer offset is updated. 59228c2ecf20Sopenharmony_ci */ 59238c2ecf20Sopenharmony_cistatic u32 qed_read_dword_from_buf(void *buf, u32 *offset) 59248c2ecf20Sopenharmony_ci{ 59258c2ecf20Sopenharmony_ci u32 dword_val = *(u32 *)&((u8 *)buf)[*offset]; 59268c2ecf20Sopenharmony_ci 59278c2ecf20Sopenharmony_ci *offset += 4; 59288c2ecf20Sopenharmony_ci 59298c2ecf20Sopenharmony_ci return dword_val; 59308c2ecf20Sopenharmony_ci} 59318c2ecf20Sopenharmony_ci 59328c2ecf20Sopenharmony_ci/* Reads the next string from the specified buffer, and copies it to the 59338c2ecf20Sopenharmony_ci * specified pointer. The specified buffer offset is updated. 59348c2ecf20Sopenharmony_ci */ 59358c2ecf20Sopenharmony_cistatic void qed_read_str_from_buf(void *buf, u32 *offset, u32 size, char *dest) 59368c2ecf20Sopenharmony_ci{ 59378c2ecf20Sopenharmony_ci const char *source_str = &((const char *)buf)[*offset]; 59388c2ecf20Sopenharmony_ci 59398c2ecf20Sopenharmony_ci strncpy(dest, source_str, size); 59408c2ecf20Sopenharmony_ci dest[size - 1] = '\0'; 59418c2ecf20Sopenharmony_ci *offset += size; 59428c2ecf20Sopenharmony_ci} 59438c2ecf20Sopenharmony_ci 59448c2ecf20Sopenharmony_ci/* Returns a pointer to the specified offset (in bytes) of the specified buffer. 59458c2ecf20Sopenharmony_ci * If the specified buffer in NULL, a temporary buffer pointer is returned. 59468c2ecf20Sopenharmony_ci */ 59478c2ecf20Sopenharmony_cistatic char *qed_get_buf_ptr(void *buf, u32 offset) 59488c2ecf20Sopenharmony_ci{ 59498c2ecf20Sopenharmony_ci return buf ? (char *)buf + offset : s_temp_buf; 59508c2ecf20Sopenharmony_ci} 59518c2ecf20Sopenharmony_ci 59528c2ecf20Sopenharmony_ci/* Reads a param from the specified buffer. Returns the number of dwords read. 59538c2ecf20Sopenharmony_ci * If the returned str_param is NULL, the param is numeric and its value is 59548c2ecf20Sopenharmony_ci * returned in num_param. 59558c2ecf20Sopenharmony_ci * Otheriwise, the param is a string and its pointer is returned in str_param. 59568c2ecf20Sopenharmony_ci */ 59578c2ecf20Sopenharmony_cistatic u32 qed_read_param(u32 *dump_buf, 59588c2ecf20Sopenharmony_ci const char **param_name, 59598c2ecf20Sopenharmony_ci const char **param_str_val, u32 *param_num_val) 59608c2ecf20Sopenharmony_ci{ 59618c2ecf20Sopenharmony_ci char *char_buf = (char *)dump_buf; 59628c2ecf20Sopenharmony_ci size_t offset = 0; 59638c2ecf20Sopenharmony_ci 59648c2ecf20Sopenharmony_ci /* Extract param name */ 59658c2ecf20Sopenharmony_ci *param_name = char_buf; 59668c2ecf20Sopenharmony_ci offset += strlen(*param_name) + 1; 59678c2ecf20Sopenharmony_ci 59688c2ecf20Sopenharmony_ci /* Check param type */ 59698c2ecf20Sopenharmony_ci if (*(char_buf + offset++)) { 59708c2ecf20Sopenharmony_ci /* String param */ 59718c2ecf20Sopenharmony_ci *param_str_val = char_buf + offset; 59728c2ecf20Sopenharmony_ci *param_num_val = 0; 59738c2ecf20Sopenharmony_ci offset += strlen(*param_str_val) + 1; 59748c2ecf20Sopenharmony_ci if (offset & 0x3) 59758c2ecf20Sopenharmony_ci offset += (4 - (offset & 0x3)); 59768c2ecf20Sopenharmony_ci } else { 59778c2ecf20Sopenharmony_ci /* Numeric param */ 59788c2ecf20Sopenharmony_ci *param_str_val = NULL; 59798c2ecf20Sopenharmony_ci if (offset & 0x3) 59808c2ecf20Sopenharmony_ci offset += (4 - (offset & 0x3)); 59818c2ecf20Sopenharmony_ci *param_num_val = *(u32 *)(char_buf + offset); 59828c2ecf20Sopenharmony_ci offset += 4; 59838c2ecf20Sopenharmony_ci } 59848c2ecf20Sopenharmony_ci 59858c2ecf20Sopenharmony_ci return (u32)offset / 4; 59868c2ecf20Sopenharmony_ci} 59878c2ecf20Sopenharmony_ci 59888c2ecf20Sopenharmony_ci/* Reads a section header from the specified buffer. 59898c2ecf20Sopenharmony_ci * Returns the number of dwords read. 59908c2ecf20Sopenharmony_ci */ 59918c2ecf20Sopenharmony_cistatic u32 qed_read_section_hdr(u32 *dump_buf, 59928c2ecf20Sopenharmony_ci const char **section_name, 59938c2ecf20Sopenharmony_ci u32 *num_section_params) 59948c2ecf20Sopenharmony_ci{ 59958c2ecf20Sopenharmony_ci const char *param_str_val; 59968c2ecf20Sopenharmony_ci 59978c2ecf20Sopenharmony_ci return qed_read_param(dump_buf, 59988c2ecf20Sopenharmony_ci section_name, ¶m_str_val, num_section_params); 59998c2ecf20Sopenharmony_ci} 60008c2ecf20Sopenharmony_ci 60018c2ecf20Sopenharmony_ci/* Reads section params from the specified buffer and prints them to the results 60028c2ecf20Sopenharmony_ci * buffer. Returns the number of dwords read. 60038c2ecf20Sopenharmony_ci */ 60048c2ecf20Sopenharmony_cistatic u32 qed_print_section_params(u32 *dump_buf, 60058c2ecf20Sopenharmony_ci u32 num_section_params, 60068c2ecf20Sopenharmony_ci char *results_buf, u32 *num_chars_printed) 60078c2ecf20Sopenharmony_ci{ 60088c2ecf20Sopenharmony_ci u32 i, dump_offset = 0, results_offset = 0; 60098c2ecf20Sopenharmony_ci 60108c2ecf20Sopenharmony_ci for (i = 0; i < num_section_params; i++) { 60118c2ecf20Sopenharmony_ci const char *param_name, *param_str_val; 60128c2ecf20Sopenharmony_ci u32 param_num_val = 0; 60138c2ecf20Sopenharmony_ci 60148c2ecf20Sopenharmony_ci dump_offset += qed_read_param(dump_buf + dump_offset, 60158c2ecf20Sopenharmony_ci ¶m_name, 60168c2ecf20Sopenharmony_ci ¶m_str_val, ¶m_num_val); 60178c2ecf20Sopenharmony_ci 60188c2ecf20Sopenharmony_ci if (param_str_val) 60198c2ecf20Sopenharmony_ci results_offset += 60208c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 60218c2ecf20Sopenharmony_ci results_offset), 60228c2ecf20Sopenharmony_ci "%s: %s\n", param_name, param_str_val); 60238c2ecf20Sopenharmony_ci else if (strcmp(param_name, "fw-timestamp")) 60248c2ecf20Sopenharmony_ci results_offset += 60258c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 60268c2ecf20Sopenharmony_ci results_offset), 60278c2ecf20Sopenharmony_ci "%s: %d\n", param_name, param_num_val); 60288c2ecf20Sopenharmony_ci } 60298c2ecf20Sopenharmony_ci 60308c2ecf20Sopenharmony_ci results_offset += sprintf(qed_get_buf_ptr(results_buf, results_offset), 60318c2ecf20Sopenharmony_ci "\n"); 60328c2ecf20Sopenharmony_ci 60338c2ecf20Sopenharmony_ci *num_chars_printed = results_offset; 60348c2ecf20Sopenharmony_ci 60358c2ecf20Sopenharmony_ci return dump_offset; 60368c2ecf20Sopenharmony_ci} 60378c2ecf20Sopenharmony_ci 60388c2ecf20Sopenharmony_ci/* Returns the block name that matches the specified block ID, 60398c2ecf20Sopenharmony_ci * or NULL if not found. 60408c2ecf20Sopenharmony_ci */ 60418c2ecf20Sopenharmony_cistatic const char *qed_dbg_get_block_name(struct qed_hwfn *p_hwfn, 60428c2ecf20Sopenharmony_ci enum block_id block_id) 60438c2ecf20Sopenharmony_ci{ 60448c2ecf20Sopenharmony_ci const struct dbg_block_user *block = 60458c2ecf20Sopenharmony_ci (const struct dbg_block_user *) 60468c2ecf20Sopenharmony_ci p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS_USER_DATA].ptr + block_id; 60478c2ecf20Sopenharmony_ci 60488c2ecf20Sopenharmony_ci return (const char *)block->name; 60498c2ecf20Sopenharmony_ci} 60508c2ecf20Sopenharmony_ci 60518c2ecf20Sopenharmony_cistatic struct dbg_tools_user_data *qed_dbg_get_user_data(struct qed_hwfn 60528c2ecf20Sopenharmony_ci *p_hwfn) 60538c2ecf20Sopenharmony_ci{ 60548c2ecf20Sopenharmony_ci return (struct dbg_tools_user_data *)p_hwfn->dbg_user_info; 60558c2ecf20Sopenharmony_ci} 60568c2ecf20Sopenharmony_ci 60578c2ecf20Sopenharmony_ci/* Parses the idle check rules and returns the number of characters printed. 60588c2ecf20Sopenharmony_ci * In case of parsing error, returns 0. 60598c2ecf20Sopenharmony_ci */ 60608c2ecf20Sopenharmony_cistatic u32 qed_parse_idle_chk_dump_rules(struct qed_hwfn *p_hwfn, 60618c2ecf20Sopenharmony_ci u32 *dump_buf, 60628c2ecf20Sopenharmony_ci u32 *dump_buf_end, 60638c2ecf20Sopenharmony_ci u32 num_rules, 60648c2ecf20Sopenharmony_ci bool print_fw_idle_chk, 60658c2ecf20Sopenharmony_ci char *results_buf, 60668c2ecf20Sopenharmony_ci u32 *num_errors, u32 *num_warnings) 60678c2ecf20Sopenharmony_ci{ 60688c2ecf20Sopenharmony_ci /* Offset in results_buf in bytes */ 60698c2ecf20Sopenharmony_ci u32 results_offset = 0; 60708c2ecf20Sopenharmony_ci 60718c2ecf20Sopenharmony_ci u32 rule_idx; 60728c2ecf20Sopenharmony_ci u16 i, j; 60738c2ecf20Sopenharmony_ci 60748c2ecf20Sopenharmony_ci *num_errors = 0; 60758c2ecf20Sopenharmony_ci *num_warnings = 0; 60768c2ecf20Sopenharmony_ci 60778c2ecf20Sopenharmony_ci /* Go over dumped results */ 60788c2ecf20Sopenharmony_ci for (rule_idx = 0; rule_idx < num_rules && dump_buf < dump_buf_end; 60798c2ecf20Sopenharmony_ci rule_idx++) { 60808c2ecf20Sopenharmony_ci const struct dbg_idle_chk_rule_parsing_data *rule_parsing_data; 60818c2ecf20Sopenharmony_ci struct dbg_idle_chk_result_hdr *hdr; 60828c2ecf20Sopenharmony_ci const char *parsing_str, *lsi_msg; 60838c2ecf20Sopenharmony_ci u32 parsing_str_offset; 60848c2ecf20Sopenharmony_ci bool has_fw_msg; 60858c2ecf20Sopenharmony_ci u8 curr_reg_id; 60868c2ecf20Sopenharmony_ci 60878c2ecf20Sopenharmony_ci hdr = (struct dbg_idle_chk_result_hdr *)dump_buf; 60888c2ecf20Sopenharmony_ci rule_parsing_data = 60898c2ecf20Sopenharmony_ci (const struct dbg_idle_chk_rule_parsing_data *) 60908c2ecf20Sopenharmony_ci p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr + 60918c2ecf20Sopenharmony_ci hdr->rule_id; 60928c2ecf20Sopenharmony_ci parsing_str_offset = 60938c2ecf20Sopenharmony_ci GET_FIELD(rule_parsing_data->data, 60948c2ecf20Sopenharmony_ci DBG_IDLE_CHK_RULE_PARSING_DATA_STR_OFFSET); 60958c2ecf20Sopenharmony_ci has_fw_msg = 60968c2ecf20Sopenharmony_ci GET_FIELD(rule_parsing_data->data, 60978c2ecf20Sopenharmony_ci DBG_IDLE_CHK_RULE_PARSING_DATA_HAS_FW_MSG) > 0; 60988c2ecf20Sopenharmony_ci parsing_str = (const char *) 60998c2ecf20Sopenharmony_ci p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr + 61008c2ecf20Sopenharmony_ci parsing_str_offset; 61018c2ecf20Sopenharmony_ci lsi_msg = parsing_str; 61028c2ecf20Sopenharmony_ci curr_reg_id = 0; 61038c2ecf20Sopenharmony_ci 61048c2ecf20Sopenharmony_ci if (hdr->severity >= MAX_DBG_IDLE_CHK_SEVERITY_TYPES) 61058c2ecf20Sopenharmony_ci return 0; 61068c2ecf20Sopenharmony_ci 61078c2ecf20Sopenharmony_ci /* Skip rule header */ 61088c2ecf20Sopenharmony_ci dump_buf += BYTES_TO_DWORDS(sizeof(*hdr)); 61098c2ecf20Sopenharmony_ci 61108c2ecf20Sopenharmony_ci /* Update errors/warnings count */ 61118c2ecf20Sopenharmony_ci if (hdr->severity == IDLE_CHK_SEVERITY_ERROR || 61128c2ecf20Sopenharmony_ci hdr->severity == IDLE_CHK_SEVERITY_ERROR_NO_TRAFFIC) 61138c2ecf20Sopenharmony_ci (*num_errors)++; 61148c2ecf20Sopenharmony_ci else 61158c2ecf20Sopenharmony_ci (*num_warnings)++; 61168c2ecf20Sopenharmony_ci 61178c2ecf20Sopenharmony_ci /* Print rule severity */ 61188c2ecf20Sopenharmony_ci results_offset += 61198c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 61208c2ecf20Sopenharmony_ci results_offset), "%s: ", 61218c2ecf20Sopenharmony_ci s_idle_chk_severity_str[hdr->severity]); 61228c2ecf20Sopenharmony_ci 61238c2ecf20Sopenharmony_ci /* Print rule message */ 61248c2ecf20Sopenharmony_ci if (has_fw_msg) 61258c2ecf20Sopenharmony_ci parsing_str += strlen(parsing_str) + 1; 61268c2ecf20Sopenharmony_ci results_offset += 61278c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 61288c2ecf20Sopenharmony_ci results_offset), "%s.", 61298c2ecf20Sopenharmony_ci has_fw_msg && 61308c2ecf20Sopenharmony_ci print_fw_idle_chk ? parsing_str : lsi_msg); 61318c2ecf20Sopenharmony_ci parsing_str += strlen(parsing_str) + 1; 61328c2ecf20Sopenharmony_ci 61338c2ecf20Sopenharmony_ci /* Print register values */ 61348c2ecf20Sopenharmony_ci results_offset += 61358c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 61368c2ecf20Sopenharmony_ci results_offset), " Registers:"); 61378c2ecf20Sopenharmony_ci for (i = 0; 61388c2ecf20Sopenharmony_ci i < hdr->num_dumped_cond_regs + hdr->num_dumped_info_regs; 61398c2ecf20Sopenharmony_ci i++) { 61408c2ecf20Sopenharmony_ci struct dbg_idle_chk_result_reg_hdr *reg_hdr; 61418c2ecf20Sopenharmony_ci bool is_mem; 61428c2ecf20Sopenharmony_ci u8 reg_id; 61438c2ecf20Sopenharmony_ci 61448c2ecf20Sopenharmony_ci reg_hdr = 61458c2ecf20Sopenharmony_ci (struct dbg_idle_chk_result_reg_hdr *)dump_buf; 61468c2ecf20Sopenharmony_ci is_mem = GET_FIELD(reg_hdr->data, 61478c2ecf20Sopenharmony_ci DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM); 61488c2ecf20Sopenharmony_ci reg_id = GET_FIELD(reg_hdr->data, 61498c2ecf20Sopenharmony_ci DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID); 61508c2ecf20Sopenharmony_ci 61518c2ecf20Sopenharmony_ci /* Skip reg header */ 61528c2ecf20Sopenharmony_ci dump_buf += BYTES_TO_DWORDS(sizeof(*reg_hdr)); 61538c2ecf20Sopenharmony_ci 61548c2ecf20Sopenharmony_ci /* Skip register names until the required reg_id is 61558c2ecf20Sopenharmony_ci * reached. 61568c2ecf20Sopenharmony_ci */ 61578c2ecf20Sopenharmony_ci for (; reg_id > curr_reg_id; 61588c2ecf20Sopenharmony_ci curr_reg_id++, 61598c2ecf20Sopenharmony_ci parsing_str += strlen(parsing_str) + 1); 61608c2ecf20Sopenharmony_ci 61618c2ecf20Sopenharmony_ci results_offset += 61628c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 61638c2ecf20Sopenharmony_ci results_offset), " %s", 61648c2ecf20Sopenharmony_ci parsing_str); 61658c2ecf20Sopenharmony_ci if (i < hdr->num_dumped_cond_regs && is_mem) 61668c2ecf20Sopenharmony_ci results_offset += 61678c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 61688c2ecf20Sopenharmony_ci results_offset), 61698c2ecf20Sopenharmony_ci "[%d]", hdr->mem_entry_id + 61708c2ecf20Sopenharmony_ci reg_hdr->start_entry); 61718c2ecf20Sopenharmony_ci results_offset += 61728c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 61738c2ecf20Sopenharmony_ci results_offset), "="); 61748c2ecf20Sopenharmony_ci for (j = 0; j < reg_hdr->size; j++, dump_buf++) { 61758c2ecf20Sopenharmony_ci results_offset += 61768c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 61778c2ecf20Sopenharmony_ci results_offset), 61788c2ecf20Sopenharmony_ci "0x%x", *dump_buf); 61798c2ecf20Sopenharmony_ci if (j < reg_hdr->size - 1) 61808c2ecf20Sopenharmony_ci results_offset += 61818c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr 61828c2ecf20Sopenharmony_ci (results_buf, 61838c2ecf20Sopenharmony_ci results_offset), ","); 61848c2ecf20Sopenharmony_ci } 61858c2ecf20Sopenharmony_ci } 61868c2ecf20Sopenharmony_ci 61878c2ecf20Sopenharmony_ci results_offset += 61888c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, results_offset), "\n"); 61898c2ecf20Sopenharmony_ci } 61908c2ecf20Sopenharmony_ci 61918c2ecf20Sopenharmony_ci /* Check if end of dump buffer was exceeded */ 61928c2ecf20Sopenharmony_ci if (dump_buf > dump_buf_end) 61938c2ecf20Sopenharmony_ci return 0; 61948c2ecf20Sopenharmony_ci 61958c2ecf20Sopenharmony_ci return results_offset; 61968c2ecf20Sopenharmony_ci} 61978c2ecf20Sopenharmony_ci 61988c2ecf20Sopenharmony_ci/* Parses an idle check dump buffer. 61998c2ecf20Sopenharmony_ci * If result_buf is not NULL, the idle check results are printed to it. 62008c2ecf20Sopenharmony_ci * In any case, the required results buffer size is assigned to 62018c2ecf20Sopenharmony_ci * parsed_results_bytes. 62028c2ecf20Sopenharmony_ci * The parsing status is returned. 62038c2ecf20Sopenharmony_ci */ 62048c2ecf20Sopenharmony_cistatic enum dbg_status qed_parse_idle_chk_dump(struct qed_hwfn *p_hwfn, 62058c2ecf20Sopenharmony_ci u32 *dump_buf, 62068c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 62078c2ecf20Sopenharmony_ci char *results_buf, 62088c2ecf20Sopenharmony_ci u32 *parsed_results_bytes, 62098c2ecf20Sopenharmony_ci u32 *num_errors, 62108c2ecf20Sopenharmony_ci u32 *num_warnings) 62118c2ecf20Sopenharmony_ci{ 62128c2ecf20Sopenharmony_ci const char *section_name, *param_name, *param_str_val; 62138c2ecf20Sopenharmony_ci u32 *dump_buf_end = dump_buf + num_dumped_dwords; 62148c2ecf20Sopenharmony_ci u32 num_section_params = 0, num_rules; 62158c2ecf20Sopenharmony_ci 62168c2ecf20Sopenharmony_ci /* Offset in results_buf in bytes */ 62178c2ecf20Sopenharmony_ci u32 results_offset = 0; 62188c2ecf20Sopenharmony_ci 62198c2ecf20Sopenharmony_ci *parsed_results_bytes = 0; 62208c2ecf20Sopenharmony_ci *num_errors = 0; 62218c2ecf20Sopenharmony_ci *num_warnings = 0; 62228c2ecf20Sopenharmony_ci 62238c2ecf20Sopenharmony_ci if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr || 62248c2ecf20Sopenharmony_ci !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr) 62258c2ecf20Sopenharmony_ci return DBG_STATUS_DBG_ARRAY_NOT_SET; 62268c2ecf20Sopenharmony_ci 62278c2ecf20Sopenharmony_ci /* Read global_params section */ 62288c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 62298c2ecf20Sopenharmony_ci §ion_name, &num_section_params); 62308c2ecf20Sopenharmony_ci if (strcmp(section_name, "global_params")) 62318c2ecf20Sopenharmony_ci return DBG_STATUS_IDLE_CHK_PARSE_FAILED; 62328c2ecf20Sopenharmony_ci 62338c2ecf20Sopenharmony_ci /* Print global params */ 62348c2ecf20Sopenharmony_ci dump_buf += qed_print_section_params(dump_buf, 62358c2ecf20Sopenharmony_ci num_section_params, 62368c2ecf20Sopenharmony_ci results_buf, &results_offset); 62378c2ecf20Sopenharmony_ci 62388c2ecf20Sopenharmony_ci /* Read idle_chk section */ 62398c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 62408c2ecf20Sopenharmony_ci §ion_name, &num_section_params); 62418c2ecf20Sopenharmony_ci if (strcmp(section_name, "idle_chk") || num_section_params != 1) 62428c2ecf20Sopenharmony_ci return DBG_STATUS_IDLE_CHK_PARSE_FAILED; 62438c2ecf20Sopenharmony_ci dump_buf += qed_read_param(dump_buf, 62448c2ecf20Sopenharmony_ci ¶m_name, ¶m_str_val, &num_rules); 62458c2ecf20Sopenharmony_ci if (strcmp(param_name, "num_rules")) 62468c2ecf20Sopenharmony_ci return DBG_STATUS_IDLE_CHK_PARSE_FAILED; 62478c2ecf20Sopenharmony_ci 62488c2ecf20Sopenharmony_ci if (num_rules) { 62498c2ecf20Sopenharmony_ci u32 rules_print_size; 62508c2ecf20Sopenharmony_ci 62518c2ecf20Sopenharmony_ci /* Print FW output */ 62528c2ecf20Sopenharmony_ci results_offset += 62538c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 62548c2ecf20Sopenharmony_ci results_offset), 62558c2ecf20Sopenharmony_ci "FW_IDLE_CHECK:\n"); 62568c2ecf20Sopenharmony_ci rules_print_size = 62578c2ecf20Sopenharmony_ci qed_parse_idle_chk_dump_rules(p_hwfn, 62588c2ecf20Sopenharmony_ci dump_buf, 62598c2ecf20Sopenharmony_ci dump_buf_end, 62608c2ecf20Sopenharmony_ci num_rules, 62618c2ecf20Sopenharmony_ci true, 62628c2ecf20Sopenharmony_ci results_buf ? 62638c2ecf20Sopenharmony_ci results_buf + 62648c2ecf20Sopenharmony_ci results_offset : 62658c2ecf20Sopenharmony_ci NULL, 62668c2ecf20Sopenharmony_ci num_errors, 62678c2ecf20Sopenharmony_ci num_warnings); 62688c2ecf20Sopenharmony_ci results_offset += rules_print_size; 62698c2ecf20Sopenharmony_ci if (!rules_print_size) 62708c2ecf20Sopenharmony_ci return DBG_STATUS_IDLE_CHK_PARSE_FAILED; 62718c2ecf20Sopenharmony_ci 62728c2ecf20Sopenharmony_ci /* Print LSI output */ 62738c2ecf20Sopenharmony_ci results_offset += 62748c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 62758c2ecf20Sopenharmony_ci results_offset), 62768c2ecf20Sopenharmony_ci "\nLSI_IDLE_CHECK:\n"); 62778c2ecf20Sopenharmony_ci rules_print_size = 62788c2ecf20Sopenharmony_ci qed_parse_idle_chk_dump_rules(p_hwfn, 62798c2ecf20Sopenharmony_ci dump_buf, 62808c2ecf20Sopenharmony_ci dump_buf_end, 62818c2ecf20Sopenharmony_ci num_rules, 62828c2ecf20Sopenharmony_ci false, 62838c2ecf20Sopenharmony_ci results_buf ? 62848c2ecf20Sopenharmony_ci results_buf + 62858c2ecf20Sopenharmony_ci results_offset : 62868c2ecf20Sopenharmony_ci NULL, 62878c2ecf20Sopenharmony_ci num_errors, 62888c2ecf20Sopenharmony_ci num_warnings); 62898c2ecf20Sopenharmony_ci results_offset += rules_print_size; 62908c2ecf20Sopenharmony_ci if (!rules_print_size) 62918c2ecf20Sopenharmony_ci return DBG_STATUS_IDLE_CHK_PARSE_FAILED; 62928c2ecf20Sopenharmony_ci } 62938c2ecf20Sopenharmony_ci 62948c2ecf20Sopenharmony_ci /* Print errors/warnings count */ 62958c2ecf20Sopenharmony_ci if (*num_errors) 62968c2ecf20Sopenharmony_ci results_offset += 62978c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 62988c2ecf20Sopenharmony_ci results_offset), 62998c2ecf20Sopenharmony_ci "\nIdle Check failed!!! (with %d errors and %d warnings)\n", 63008c2ecf20Sopenharmony_ci *num_errors, *num_warnings); 63018c2ecf20Sopenharmony_ci else if (*num_warnings) 63028c2ecf20Sopenharmony_ci results_offset += 63038c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 63048c2ecf20Sopenharmony_ci results_offset), 63058c2ecf20Sopenharmony_ci "\nIdle Check completed successfully (with %d warnings)\n", 63068c2ecf20Sopenharmony_ci *num_warnings); 63078c2ecf20Sopenharmony_ci else 63088c2ecf20Sopenharmony_ci results_offset += 63098c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 63108c2ecf20Sopenharmony_ci results_offset), 63118c2ecf20Sopenharmony_ci "\nIdle Check completed successfully\n"); 63128c2ecf20Sopenharmony_ci 63138c2ecf20Sopenharmony_ci /* Add 1 for string NULL termination */ 63148c2ecf20Sopenharmony_ci *parsed_results_bytes = results_offset + 1; 63158c2ecf20Sopenharmony_ci 63168c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 63178c2ecf20Sopenharmony_ci} 63188c2ecf20Sopenharmony_ci 63198c2ecf20Sopenharmony_ci/* Allocates and fills MCP Trace meta data based on the specified meta data 63208c2ecf20Sopenharmony_ci * dump buffer. 63218c2ecf20Sopenharmony_ci * Returns debug status code. 63228c2ecf20Sopenharmony_ci */ 63238c2ecf20Sopenharmony_cistatic enum dbg_status 63248c2ecf20Sopenharmony_ciqed_mcp_trace_alloc_meta_data(struct qed_hwfn *p_hwfn, 63258c2ecf20Sopenharmony_ci const u32 *meta_buf) 63268c2ecf20Sopenharmony_ci{ 63278c2ecf20Sopenharmony_ci struct dbg_tools_user_data *dev_user_data; 63288c2ecf20Sopenharmony_ci u32 offset = 0, signature, i; 63298c2ecf20Sopenharmony_ci struct mcp_trace_meta *meta; 63308c2ecf20Sopenharmony_ci u8 *meta_buf_bytes; 63318c2ecf20Sopenharmony_ci 63328c2ecf20Sopenharmony_ci dev_user_data = qed_dbg_get_user_data(p_hwfn); 63338c2ecf20Sopenharmony_ci meta = &dev_user_data->mcp_trace_meta; 63348c2ecf20Sopenharmony_ci meta_buf_bytes = (u8 *)meta_buf; 63358c2ecf20Sopenharmony_ci 63368c2ecf20Sopenharmony_ci /* Free the previous meta before loading a new one. */ 63378c2ecf20Sopenharmony_ci if (meta->is_allocated) 63388c2ecf20Sopenharmony_ci qed_mcp_trace_free_meta_data(p_hwfn); 63398c2ecf20Sopenharmony_ci 63408c2ecf20Sopenharmony_ci memset(meta, 0, sizeof(*meta)); 63418c2ecf20Sopenharmony_ci 63428c2ecf20Sopenharmony_ci /* Read first signature */ 63438c2ecf20Sopenharmony_ci signature = qed_read_dword_from_buf(meta_buf_bytes, &offset); 63448c2ecf20Sopenharmony_ci if (signature != NVM_MAGIC_VALUE) 63458c2ecf20Sopenharmony_ci return DBG_STATUS_INVALID_TRACE_SIGNATURE; 63468c2ecf20Sopenharmony_ci 63478c2ecf20Sopenharmony_ci /* Read no. of modules and allocate memory for their pointers */ 63488c2ecf20Sopenharmony_ci meta->modules_num = qed_read_byte_from_buf(meta_buf_bytes, &offset); 63498c2ecf20Sopenharmony_ci meta->modules = kcalloc(meta->modules_num, sizeof(char *), 63508c2ecf20Sopenharmony_ci GFP_KERNEL); 63518c2ecf20Sopenharmony_ci if (!meta->modules) 63528c2ecf20Sopenharmony_ci return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; 63538c2ecf20Sopenharmony_ci 63548c2ecf20Sopenharmony_ci /* Allocate and read all module strings */ 63558c2ecf20Sopenharmony_ci for (i = 0; i < meta->modules_num; i++) { 63568c2ecf20Sopenharmony_ci u8 module_len = qed_read_byte_from_buf(meta_buf_bytes, &offset); 63578c2ecf20Sopenharmony_ci 63588c2ecf20Sopenharmony_ci *(meta->modules + i) = kzalloc(module_len, GFP_KERNEL); 63598c2ecf20Sopenharmony_ci if (!(*(meta->modules + i))) { 63608c2ecf20Sopenharmony_ci /* Update number of modules to be released */ 63618c2ecf20Sopenharmony_ci meta->modules_num = i ? i - 1 : 0; 63628c2ecf20Sopenharmony_ci return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; 63638c2ecf20Sopenharmony_ci } 63648c2ecf20Sopenharmony_ci 63658c2ecf20Sopenharmony_ci qed_read_str_from_buf(meta_buf_bytes, &offset, module_len, 63668c2ecf20Sopenharmony_ci *(meta->modules + i)); 63678c2ecf20Sopenharmony_ci if (module_len > MCP_TRACE_MAX_MODULE_LEN) 63688c2ecf20Sopenharmony_ci (*(meta->modules + i))[MCP_TRACE_MAX_MODULE_LEN] = '\0'; 63698c2ecf20Sopenharmony_ci } 63708c2ecf20Sopenharmony_ci 63718c2ecf20Sopenharmony_ci /* Read second signature */ 63728c2ecf20Sopenharmony_ci signature = qed_read_dword_from_buf(meta_buf_bytes, &offset); 63738c2ecf20Sopenharmony_ci if (signature != NVM_MAGIC_VALUE) 63748c2ecf20Sopenharmony_ci return DBG_STATUS_INVALID_TRACE_SIGNATURE; 63758c2ecf20Sopenharmony_ci 63768c2ecf20Sopenharmony_ci /* Read number of formats and allocate memory for all formats */ 63778c2ecf20Sopenharmony_ci meta->formats_num = qed_read_dword_from_buf(meta_buf_bytes, &offset); 63788c2ecf20Sopenharmony_ci meta->formats = kcalloc(meta->formats_num, 63798c2ecf20Sopenharmony_ci sizeof(struct mcp_trace_format), 63808c2ecf20Sopenharmony_ci GFP_KERNEL); 63818c2ecf20Sopenharmony_ci if (!meta->formats) 63828c2ecf20Sopenharmony_ci return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; 63838c2ecf20Sopenharmony_ci 63848c2ecf20Sopenharmony_ci /* Allocate and read all strings */ 63858c2ecf20Sopenharmony_ci for (i = 0; i < meta->formats_num; i++) { 63868c2ecf20Sopenharmony_ci struct mcp_trace_format *format_ptr = &meta->formats[i]; 63878c2ecf20Sopenharmony_ci u8 format_len; 63888c2ecf20Sopenharmony_ci 63898c2ecf20Sopenharmony_ci format_ptr->data = qed_read_dword_from_buf(meta_buf_bytes, 63908c2ecf20Sopenharmony_ci &offset); 63918c2ecf20Sopenharmony_ci format_len = GET_MFW_FIELD(format_ptr->data, 63928c2ecf20Sopenharmony_ci MCP_TRACE_FORMAT_LEN); 63938c2ecf20Sopenharmony_ci format_ptr->format_str = kzalloc(format_len, GFP_KERNEL); 63948c2ecf20Sopenharmony_ci if (!format_ptr->format_str) { 63958c2ecf20Sopenharmony_ci /* Update number of modules to be released */ 63968c2ecf20Sopenharmony_ci meta->formats_num = i ? i - 1 : 0; 63978c2ecf20Sopenharmony_ci return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; 63988c2ecf20Sopenharmony_ci } 63998c2ecf20Sopenharmony_ci 64008c2ecf20Sopenharmony_ci qed_read_str_from_buf(meta_buf_bytes, 64018c2ecf20Sopenharmony_ci &offset, 64028c2ecf20Sopenharmony_ci format_len, format_ptr->format_str); 64038c2ecf20Sopenharmony_ci } 64048c2ecf20Sopenharmony_ci 64058c2ecf20Sopenharmony_ci meta->is_allocated = true; 64068c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 64078c2ecf20Sopenharmony_ci} 64088c2ecf20Sopenharmony_ci 64098c2ecf20Sopenharmony_ci/* Parses an MCP trace buffer. If result_buf is not NULL, the MCP Trace results 64108c2ecf20Sopenharmony_ci * are printed to it. The parsing status is returned. 64118c2ecf20Sopenharmony_ci * Arguments: 64128c2ecf20Sopenharmony_ci * trace_buf - MCP trace cyclic buffer 64138c2ecf20Sopenharmony_ci * trace_buf_size - MCP trace cyclic buffer size in bytes 64148c2ecf20Sopenharmony_ci * data_offset - offset in bytes of the data to parse in the MCP trace cyclic 64158c2ecf20Sopenharmony_ci * buffer. 64168c2ecf20Sopenharmony_ci * data_size - size in bytes of data to parse. 64178c2ecf20Sopenharmony_ci * parsed_buf - destination buffer for parsed data. 64188c2ecf20Sopenharmony_ci * parsed_results_bytes - size of parsed data in bytes. 64198c2ecf20Sopenharmony_ci */ 64208c2ecf20Sopenharmony_cistatic enum dbg_status qed_parse_mcp_trace_buf(struct qed_hwfn *p_hwfn, 64218c2ecf20Sopenharmony_ci u8 *trace_buf, 64228c2ecf20Sopenharmony_ci u32 trace_buf_size, 64238c2ecf20Sopenharmony_ci u32 data_offset, 64248c2ecf20Sopenharmony_ci u32 data_size, 64258c2ecf20Sopenharmony_ci char *parsed_buf, 64268c2ecf20Sopenharmony_ci u32 *parsed_results_bytes) 64278c2ecf20Sopenharmony_ci{ 64288c2ecf20Sopenharmony_ci struct dbg_tools_user_data *dev_user_data; 64298c2ecf20Sopenharmony_ci struct mcp_trace_meta *meta; 64308c2ecf20Sopenharmony_ci u32 param_mask, param_shift; 64318c2ecf20Sopenharmony_ci enum dbg_status status; 64328c2ecf20Sopenharmony_ci 64338c2ecf20Sopenharmony_ci dev_user_data = qed_dbg_get_user_data(p_hwfn); 64348c2ecf20Sopenharmony_ci meta = &dev_user_data->mcp_trace_meta; 64358c2ecf20Sopenharmony_ci *parsed_results_bytes = 0; 64368c2ecf20Sopenharmony_ci 64378c2ecf20Sopenharmony_ci if (!meta->is_allocated) 64388c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_TRACE_BAD_DATA; 64398c2ecf20Sopenharmony_ci 64408c2ecf20Sopenharmony_ci status = DBG_STATUS_OK; 64418c2ecf20Sopenharmony_ci 64428c2ecf20Sopenharmony_ci while (data_size) { 64438c2ecf20Sopenharmony_ci struct mcp_trace_format *format_ptr; 64448c2ecf20Sopenharmony_ci u8 format_level, format_module; 64458c2ecf20Sopenharmony_ci u32 params[3] = { 0, 0, 0 }; 64468c2ecf20Sopenharmony_ci u32 header, format_idx, i; 64478c2ecf20Sopenharmony_ci 64488c2ecf20Sopenharmony_ci if (data_size < MFW_TRACE_ENTRY_SIZE) 64498c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_TRACE_BAD_DATA; 64508c2ecf20Sopenharmony_ci 64518c2ecf20Sopenharmony_ci header = qed_read_from_cyclic_buf(trace_buf, 64528c2ecf20Sopenharmony_ci &data_offset, 64538c2ecf20Sopenharmony_ci trace_buf_size, 64548c2ecf20Sopenharmony_ci MFW_TRACE_ENTRY_SIZE); 64558c2ecf20Sopenharmony_ci data_size -= MFW_TRACE_ENTRY_SIZE; 64568c2ecf20Sopenharmony_ci format_idx = header & MFW_TRACE_EVENTID_MASK; 64578c2ecf20Sopenharmony_ci 64588c2ecf20Sopenharmony_ci /* Skip message if its index doesn't exist in the meta data */ 64598c2ecf20Sopenharmony_ci if (format_idx >= meta->formats_num) { 64608c2ecf20Sopenharmony_ci u8 format_size = (u8)GET_MFW_FIELD(header, 64618c2ecf20Sopenharmony_ci MFW_TRACE_PRM_SIZE); 64628c2ecf20Sopenharmony_ci 64638c2ecf20Sopenharmony_ci if (data_size < format_size) 64648c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_TRACE_BAD_DATA; 64658c2ecf20Sopenharmony_ci 64668c2ecf20Sopenharmony_ci data_offset = qed_cyclic_add(data_offset, 64678c2ecf20Sopenharmony_ci format_size, 64688c2ecf20Sopenharmony_ci trace_buf_size); 64698c2ecf20Sopenharmony_ci data_size -= format_size; 64708c2ecf20Sopenharmony_ci continue; 64718c2ecf20Sopenharmony_ci } 64728c2ecf20Sopenharmony_ci 64738c2ecf20Sopenharmony_ci format_ptr = &meta->formats[format_idx]; 64748c2ecf20Sopenharmony_ci 64758c2ecf20Sopenharmony_ci for (i = 0, 64768c2ecf20Sopenharmony_ci param_mask = MCP_TRACE_FORMAT_P1_SIZE_MASK, param_shift = 64778c2ecf20Sopenharmony_ci MCP_TRACE_FORMAT_P1_SIZE_OFFSET; 64788c2ecf20Sopenharmony_ci i < MCP_TRACE_FORMAT_MAX_PARAMS; 64798c2ecf20Sopenharmony_ci i++, param_mask <<= MCP_TRACE_FORMAT_PARAM_WIDTH, 64808c2ecf20Sopenharmony_ci param_shift += MCP_TRACE_FORMAT_PARAM_WIDTH) { 64818c2ecf20Sopenharmony_ci /* Extract param size (0..3) */ 64828c2ecf20Sopenharmony_ci u8 param_size = (u8)((format_ptr->data & param_mask) >> 64838c2ecf20Sopenharmony_ci param_shift); 64848c2ecf20Sopenharmony_ci 64858c2ecf20Sopenharmony_ci /* If the param size is zero, there are no other 64868c2ecf20Sopenharmony_ci * parameters. 64878c2ecf20Sopenharmony_ci */ 64888c2ecf20Sopenharmony_ci if (!param_size) 64898c2ecf20Sopenharmony_ci break; 64908c2ecf20Sopenharmony_ci 64918c2ecf20Sopenharmony_ci /* Size is encoded using 2 bits, where 3 is used to 64928c2ecf20Sopenharmony_ci * encode 4. 64938c2ecf20Sopenharmony_ci */ 64948c2ecf20Sopenharmony_ci if (param_size == 3) 64958c2ecf20Sopenharmony_ci param_size = 4; 64968c2ecf20Sopenharmony_ci 64978c2ecf20Sopenharmony_ci if (data_size < param_size) 64988c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_TRACE_BAD_DATA; 64998c2ecf20Sopenharmony_ci 65008c2ecf20Sopenharmony_ci params[i] = qed_read_from_cyclic_buf(trace_buf, 65018c2ecf20Sopenharmony_ci &data_offset, 65028c2ecf20Sopenharmony_ci trace_buf_size, 65038c2ecf20Sopenharmony_ci param_size); 65048c2ecf20Sopenharmony_ci data_size -= param_size; 65058c2ecf20Sopenharmony_ci } 65068c2ecf20Sopenharmony_ci 65078c2ecf20Sopenharmony_ci format_level = (u8)GET_MFW_FIELD(format_ptr->data, 65088c2ecf20Sopenharmony_ci MCP_TRACE_FORMAT_LEVEL); 65098c2ecf20Sopenharmony_ci format_module = (u8)GET_MFW_FIELD(format_ptr->data, 65108c2ecf20Sopenharmony_ci MCP_TRACE_FORMAT_MODULE); 65118c2ecf20Sopenharmony_ci if (format_level >= ARRAY_SIZE(s_mcp_trace_level_str)) 65128c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_TRACE_BAD_DATA; 65138c2ecf20Sopenharmony_ci 65148c2ecf20Sopenharmony_ci /* Print current message to results buffer */ 65158c2ecf20Sopenharmony_ci *parsed_results_bytes += 65168c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(parsed_buf, 65178c2ecf20Sopenharmony_ci *parsed_results_bytes), 65188c2ecf20Sopenharmony_ci "%s %-8s: ", 65198c2ecf20Sopenharmony_ci s_mcp_trace_level_str[format_level], 65208c2ecf20Sopenharmony_ci meta->modules[format_module]); 65218c2ecf20Sopenharmony_ci *parsed_results_bytes += 65228c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(parsed_buf, *parsed_results_bytes), 65238c2ecf20Sopenharmony_ci format_ptr->format_str, 65248c2ecf20Sopenharmony_ci params[0], params[1], params[2]); 65258c2ecf20Sopenharmony_ci } 65268c2ecf20Sopenharmony_ci 65278c2ecf20Sopenharmony_ci /* Add string NULL terminator */ 65288c2ecf20Sopenharmony_ci (*parsed_results_bytes)++; 65298c2ecf20Sopenharmony_ci 65308c2ecf20Sopenharmony_ci return status; 65318c2ecf20Sopenharmony_ci} 65328c2ecf20Sopenharmony_ci 65338c2ecf20Sopenharmony_ci/* Parses an MCP Trace dump buffer. 65348c2ecf20Sopenharmony_ci * If result_buf is not NULL, the MCP Trace results are printed to it. 65358c2ecf20Sopenharmony_ci * In any case, the required results buffer size is assigned to 65368c2ecf20Sopenharmony_ci * parsed_results_bytes. 65378c2ecf20Sopenharmony_ci * The parsing status is returned. 65388c2ecf20Sopenharmony_ci */ 65398c2ecf20Sopenharmony_cistatic enum dbg_status qed_parse_mcp_trace_dump(struct qed_hwfn *p_hwfn, 65408c2ecf20Sopenharmony_ci u32 *dump_buf, 65418c2ecf20Sopenharmony_ci char *results_buf, 65428c2ecf20Sopenharmony_ci u32 *parsed_results_bytes, 65438c2ecf20Sopenharmony_ci bool free_meta_data) 65448c2ecf20Sopenharmony_ci{ 65458c2ecf20Sopenharmony_ci const char *section_name, *param_name, *param_str_val; 65468c2ecf20Sopenharmony_ci u32 data_size, trace_data_dwords, trace_meta_dwords; 65478c2ecf20Sopenharmony_ci u32 offset, results_offset, results_buf_bytes; 65488c2ecf20Sopenharmony_ci u32 param_num_val, num_section_params; 65498c2ecf20Sopenharmony_ci struct mcp_trace *trace; 65508c2ecf20Sopenharmony_ci enum dbg_status status; 65518c2ecf20Sopenharmony_ci const u32 *meta_buf; 65528c2ecf20Sopenharmony_ci u8 *trace_buf; 65538c2ecf20Sopenharmony_ci 65548c2ecf20Sopenharmony_ci *parsed_results_bytes = 0; 65558c2ecf20Sopenharmony_ci 65568c2ecf20Sopenharmony_ci /* Read global_params section */ 65578c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 65588c2ecf20Sopenharmony_ci §ion_name, &num_section_params); 65598c2ecf20Sopenharmony_ci if (strcmp(section_name, "global_params")) 65608c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_TRACE_BAD_DATA; 65618c2ecf20Sopenharmony_ci 65628c2ecf20Sopenharmony_ci /* Print global params */ 65638c2ecf20Sopenharmony_ci dump_buf += qed_print_section_params(dump_buf, 65648c2ecf20Sopenharmony_ci num_section_params, 65658c2ecf20Sopenharmony_ci results_buf, &results_offset); 65668c2ecf20Sopenharmony_ci 65678c2ecf20Sopenharmony_ci /* Read trace_data section */ 65688c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 65698c2ecf20Sopenharmony_ci §ion_name, &num_section_params); 65708c2ecf20Sopenharmony_ci if (strcmp(section_name, "mcp_trace_data") || num_section_params != 1) 65718c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_TRACE_BAD_DATA; 65728c2ecf20Sopenharmony_ci dump_buf += qed_read_param(dump_buf, 65738c2ecf20Sopenharmony_ci ¶m_name, ¶m_str_val, ¶m_num_val); 65748c2ecf20Sopenharmony_ci if (strcmp(param_name, "size")) 65758c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_TRACE_BAD_DATA; 65768c2ecf20Sopenharmony_ci trace_data_dwords = param_num_val; 65778c2ecf20Sopenharmony_ci 65788c2ecf20Sopenharmony_ci /* Prepare trace info */ 65798c2ecf20Sopenharmony_ci trace = (struct mcp_trace *)dump_buf; 65808c2ecf20Sopenharmony_ci if (trace->signature != MFW_TRACE_SIGNATURE || !trace->size) 65818c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_TRACE_BAD_DATA; 65828c2ecf20Sopenharmony_ci 65838c2ecf20Sopenharmony_ci trace_buf = (u8 *)dump_buf + sizeof(*trace); 65848c2ecf20Sopenharmony_ci offset = trace->trace_oldest; 65858c2ecf20Sopenharmony_ci data_size = qed_cyclic_sub(trace->trace_prod, offset, trace->size); 65868c2ecf20Sopenharmony_ci dump_buf += trace_data_dwords; 65878c2ecf20Sopenharmony_ci 65888c2ecf20Sopenharmony_ci /* Read meta_data section */ 65898c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 65908c2ecf20Sopenharmony_ci §ion_name, &num_section_params); 65918c2ecf20Sopenharmony_ci if (strcmp(section_name, "mcp_trace_meta")) 65928c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_TRACE_BAD_DATA; 65938c2ecf20Sopenharmony_ci dump_buf += qed_read_param(dump_buf, 65948c2ecf20Sopenharmony_ci ¶m_name, ¶m_str_val, ¶m_num_val); 65958c2ecf20Sopenharmony_ci if (strcmp(param_name, "size")) 65968c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_TRACE_BAD_DATA; 65978c2ecf20Sopenharmony_ci trace_meta_dwords = param_num_val; 65988c2ecf20Sopenharmony_ci 65998c2ecf20Sopenharmony_ci /* Choose meta data buffer */ 66008c2ecf20Sopenharmony_ci if (!trace_meta_dwords) { 66018c2ecf20Sopenharmony_ci /* Dump doesn't include meta data */ 66028c2ecf20Sopenharmony_ci struct dbg_tools_user_data *dev_user_data = 66038c2ecf20Sopenharmony_ci qed_dbg_get_user_data(p_hwfn); 66048c2ecf20Sopenharmony_ci 66058c2ecf20Sopenharmony_ci if (!dev_user_data->mcp_trace_user_meta_buf) 66068c2ecf20Sopenharmony_ci return DBG_STATUS_MCP_TRACE_NO_META; 66078c2ecf20Sopenharmony_ci 66088c2ecf20Sopenharmony_ci meta_buf = dev_user_data->mcp_trace_user_meta_buf; 66098c2ecf20Sopenharmony_ci } else { 66108c2ecf20Sopenharmony_ci /* Dump includes meta data */ 66118c2ecf20Sopenharmony_ci meta_buf = dump_buf; 66128c2ecf20Sopenharmony_ci } 66138c2ecf20Sopenharmony_ci 66148c2ecf20Sopenharmony_ci /* Allocate meta data memory */ 66158c2ecf20Sopenharmony_ci status = qed_mcp_trace_alloc_meta_data(p_hwfn, meta_buf); 66168c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 66178c2ecf20Sopenharmony_ci return status; 66188c2ecf20Sopenharmony_ci 66198c2ecf20Sopenharmony_ci status = qed_parse_mcp_trace_buf(p_hwfn, 66208c2ecf20Sopenharmony_ci trace_buf, 66218c2ecf20Sopenharmony_ci trace->size, 66228c2ecf20Sopenharmony_ci offset, 66238c2ecf20Sopenharmony_ci data_size, 66248c2ecf20Sopenharmony_ci results_buf ? 66258c2ecf20Sopenharmony_ci results_buf + results_offset : 66268c2ecf20Sopenharmony_ci NULL, 66278c2ecf20Sopenharmony_ci &results_buf_bytes); 66288c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 66298c2ecf20Sopenharmony_ci return status; 66308c2ecf20Sopenharmony_ci 66318c2ecf20Sopenharmony_ci if (free_meta_data) 66328c2ecf20Sopenharmony_ci qed_mcp_trace_free_meta_data(p_hwfn); 66338c2ecf20Sopenharmony_ci 66348c2ecf20Sopenharmony_ci *parsed_results_bytes = results_offset + results_buf_bytes; 66358c2ecf20Sopenharmony_ci 66368c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 66378c2ecf20Sopenharmony_ci} 66388c2ecf20Sopenharmony_ci 66398c2ecf20Sopenharmony_ci/* Parses a Reg FIFO dump buffer. 66408c2ecf20Sopenharmony_ci * If result_buf is not NULL, the Reg FIFO results are printed to it. 66418c2ecf20Sopenharmony_ci * In any case, the required results buffer size is assigned to 66428c2ecf20Sopenharmony_ci * parsed_results_bytes. 66438c2ecf20Sopenharmony_ci * The parsing status is returned. 66448c2ecf20Sopenharmony_ci */ 66458c2ecf20Sopenharmony_cistatic enum dbg_status qed_parse_reg_fifo_dump(u32 *dump_buf, 66468c2ecf20Sopenharmony_ci char *results_buf, 66478c2ecf20Sopenharmony_ci u32 *parsed_results_bytes) 66488c2ecf20Sopenharmony_ci{ 66498c2ecf20Sopenharmony_ci const char *section_name, *param_name, *param_str_val; 66508c2ecf20Sopenharmony_ci u32 param_num_val, num_section_params, num_elements; 66518c2ecf20Sopenharmony_ci struct reg_fifo_element *elements; 66528c2ecf20Sopenharmony_ci u8 i, j, err_code, vf_val; 66538c2ecf20Sopenharmony_ci u32 results_offset = 0; 66548c2ecf20Sopenharmony_ci char vf_str[4]; 66558c2ecf20Sopenharmony_ci 66568c2ecf20Sopenharmony_ci /* Read global_params section */ 66578c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 66588c2ecf20Sopenharmony_ci §ion_name, &num_section_params); 66598c2ecf20Sopenharmony_ci if (strcmp(section_name, "global_params")) 66608c2ecf20Sopenharmony_ci return DBG_STATUS_REG_FIFO_BAD_DATA; 66618c2ecf20Sopenharmony_ci 66628c2ecf20Sopenharmony_ci /* Print global params */ 66638c2ecf20Sopenharmony_ci dump_buf += qed_print_section_params(dump_buf, 66648c2ecf20Sopenharmony_ci num_section_params, 66658c2ecf20Sopenharmony_ci results_buf, &results_offset); 66668c2ecf20Sopenharmony_ci 66678c2ecf20Sopenharmony_ci /* Read reg_fifo_data section */ 66688c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 66698c2ecf20Sopenharmony_ci §ion_name, &num_section_params); 66708c2ecf20Sopenharmony_ci if (strcmp(section_name, "reg_fifo_data")) 66718c2ecf20Sopenharmony_ci return DBG_STATUS_REG_FIFO_BAD_DATA; 66728c2ecf20Sopenharmony_ci dump_buf += qed_read_param(dump_buf, 66738c2ecf20Sopenharmony_ci ¶m_name, ¶m_str_val, ¶m_num_val); 66748c2ecf20Sopenharmony_ci if (strcmp(param_name, "size")) 66758c2ecf20Sopenharmony_ci return DBG_STATUS_REG_FIFO_BAD_DATA; 66768c2ecf20Sopenharmony_ci if (param_num_val % REG_FIFO_ELEMENT_DWORDS) 66778c2ecf20Sopenharmony_ci return DBG_STATUS_REG_FIFO_BAD_DATA; 66788c2ecf20Sopenharmony_ci num_elements = param_num_val / REG_FIFO_ELEMENT_DWORDS; 66798c2ecf20Sopenharmony_ci elements = (struct reg_fifo_element *)dump_buf; 66808c2ecf20Sopenharmony_ci 66818c2ecf20Sopenharmony_ci /* Decode elements */ 66828c2ecf20Sopenharmony_ci for (i = 0; i < num_elements; i++) { 66838c2ecf20Sopenharmony_ci const char *err_msg = NULL; 66848c2ecf20Sopenharmony_ci 66858c2ecf20Sopenharmony_ci /* Discover if element belongs to a VF or a PF */ 66868c2ecf20Sopenharmony_ci vf_val = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_VF); 66878c2ecf20Sopenharmony_ci if (vf_val == REG_FIFO_ELEMENT_IS_PF_VF_VAL) 66888c2ecf20Sopenharmony_ci sprintf(vf_str, "%s", "N/A"); 66898c2ecf20Sopenharmony_ci else 66908c2ecf20Sopenharmony_ci sprintf(vf_str, "%d", vf_val); 66918c2ecf20Sopenharmony_ci 66928c2ecf20Sopenharmony_ci /* Find error message */ 66938c2ecf20Sopenharmony_ci err_code = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_ERROR); 66948c2ecf20Sopenharmony_ci for (j = 0; j < ARRAY_SIZE(s_reg_fifo_errors) && !err_msg; j++) 66958c2ecf20Sopenharmony_ci if (err_code == s_reg_fifo_errors[j].err_code) 66968c2ecf20Sopenharmony_ci err_msg = s_reg_fifo_errors[j].err_msg; 66978c2ecf20Sopenharmony_ci 66988c2ecf20Sopenharmony_ci /* Add parsed element to parsed buffer */ 66998c2ecf20Sopenharmony_ci results_offset += 67008c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 67018c2ecf20Sopenharmony_ci results_offset), 67028c2ecf20Sopenharmony_ci "raw: 0x%016llx, address: 0x%07x, access: %-5s, pf: %2d, vf: %s, port: %d, privilege: %-3s, protection: %-12s, master: %-4s, error: %s\n", 67038c2ecf20Sopenharmony_ci elements[i].data, 67048c2ecf20Sopenharmony_ci (u32)GET_FIELD(elements[i].data, 67058c2ecf20Sopenharmony_ci REG_FIFO_ELEMENT_ADDRESS) * 67068c2ecf20Sopenharmony_ci REG_FIFO_ELEMENT_ADDR_FACTOR, 67078c2ecf20Sopenharmony_ci s_access_strs[GET_FIELD(elements[i].data, 67088c2ecf20Sopenharmony_ci REG_FIFO_ELEMENT_ACCESS)], 67098c2ecf20Sopenharmony_ci (u32)GET_FIELD(elements[i].data, 67108c2ecf20Sopenharmony_ci REG_FIFO_ELEMENT_PF), 67118c2ecf20Sopenharmony_ci vf_str, 67128c2ecf20Sopenharmony_ci (u32)GET_FIELD(elements[i].data, 67138c2ecf20Sopenharmony_ci REG_FIFO_ELEMENT_PORT), 67148c2ecf20Sopenharmony_ci s_privilege_strs[GET_FIELD(elements[i].data, 67158c2ecf20Sopenharmony_ci REG_FIFO_ELEMENT_PRIVILEGE)], 67168c2ecf20Sopenharmony_ci s_protection_strs[GET_FIELD(elements[i].data, 67178c2ecf20Sopenharmony_ci REG_FIFO_ELEMENT_PROTECTION)], 67188c2ecf20Sopenharmony_ci s_master_strs[GET_FIELD(elements[i].data, 67198c2ecf20Sopenharmony_ci REG_FIFO_ELEMENT_MASTER)], 67208c2ecf20Sopenharmony_ci err_msg ? err_msg : "unknown error code"); 67218c2ecf20Sopenharmony_ci } 67228c2ecf20Sopenharmony_ci 67238c2ecf20Sopenharmony_ci results_offset += sprintf(qed_get_buf_ptr(results_buf, 67248c2ecf20Sopenharmony_ci results_offset), 67258c2ecf20Sopenharmony_ci "fifo contained %d elements", num_elements); 67268c2ecf20Sopenharmony_ci 67278c2ecf20Sopenharmony_ci /* Add 1 for string NULL termination */ 67288c2ecf20Sopenharmony_ci *parsed_results_bytes = results_offset + 1; 67298c2ecf20Sopenharmony_ci 67308c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 67318c2ecf20Sopenharmony_ci} 67328c2ecf20Sopenharmony_ci 67338c2ecf20Sopenharmony_cistatic enum dbg_status qed_parse_igu_fifo_element(struct igu_fifo_element 67348c2ecf20Sopenharmony_ci *element, char 67358c2ecf20Sopenharmony_ci *results_buf, 67368c2ecf20Sopenharmony_ci u32 *results_offset) 67378c2ecf20Sopenharmony_ci{ 67388c2ecf20Sopenharmony_ci const struct igu_fifo_addr_data *found_addr = NULL; 67398c2ecf20Sopenharmony_ci u8 source, err_type, i, is_cleanup; 67408c2ecf20Sopenharmony_ci char parsed_addr_data[32]; 67418c2ecf20Sopenharmony_ci char parsed_wr_data[256]; 67428c2ecf20Sopenharmony_ci u32 wr_data, prod_cons; 67438c2ecf20Sopenharmony_ci bool is_wr_cmd, is_pf; 67448c2ecf20Sopenharmony_ci u16 cmd_addr; 67458c2ecf20Sopenharmony_ci u64 dword12; 67468c2ecf20Sopenharmony_ci 67478c2ecf20Sopenharmony_ci /* Dword12 (dword index 1 and 2) contains bits 32..95 of the 67488c2ecf20Sopenharmony_ci * FIFO element. 67498c2ecf20Sopenharmony_ci */ 67508c2ecf20Sopenharmony_ci dword12 = ((u64)element->dword2 << 32) | element->dword1; 67518c2ecf20Sopenharmony_ci is_wr_cmd = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD); 67528c2ecf20Sopenharmony_ci is_pf = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_IS_PF); 67538c2ecf20Sopenharmony_ci cmd_addr = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR); 67548c2ecf20Sopenharmony_ci source = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_SOURCE); 67558c2ecf20Sopenharmony_ci err_type = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE); 67568c2ecf20Sopenharmony_ci 67578c2ecf20Sopenharmony_ci if (source >= ARRAY_SIZE(s_igu_fifo_source_strs)) 67588c2ecf20Sopenharmony_ci return DBG_STATUS_IGU_FIFO_BAD_DATA; 67598c2ecf20Sopenharmony_ci if (err_type >= ARRAY_SIZE(s_igu_fifo_error_strs)) 67608c2ecf20Sopenharmony_ci return DBG_STATUS_IGU_FIFO_BAD_DATA; 67618c2ecf20Sopenharmony_ci 67628c2ecf20Sopenharmony_ci /* Find address data */ 67638c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(s_igu_fifo_addr_data) && !found_addr; i++) { 67648c2ecf20Sopenharmony_ci const struct igu_fifo_addr_data *curr_addr = 67658c2ecf20Sopenharmony_ci &s_igu_fifo_addr_data[i]; 67668c2ecf20Sopenharmony_ci 67678c2ecf20Sopenharmony_ci if (cmd_addr >= curr_addr->start_addr && cmd_addr <= 67688c2ecf20Sopenharmony_ci curr_addr->end_addr) 67698c2ecf20Sopenharmony_ci found_addr = curr_addr; 67708c2ecf20Sopenharmony_ci } 67718c2ecf20Sopenharmony_ci 67728c2ecf20Sopenharmony_ci if (!found_addr) 67738c2ecf20Sopenharmony_ci return DBG_STATUS_IGU_FIFO_BAD_DATA; 67748c2ecf20Sopenharmony_ci 67758c2ecf20Sopenharmony_ci /* Prepare parsed address data */ 67768c2ecf20Sopenharmony_ci switch (found_addr->type) { 67778c2ecf20Sopenharmony_ci case IGU_ADDR_TYPE_MSIX_MEM: 67788c2ecf20Sopenharmony_ci sprintf(parsed_addr_data, " vector_num = 0x%x", cmd_addr / 2); 67798c2ecf20Sopenharmony_ci break; 67808c2ecf20Sopenharmony_ci case IGU_ADDR_TYPE_WRITE_INT_ACK: 67818c2ecf20Sopenharmony_ci case IGU_ADDR_TYPE_WRITE_PROD_UPDATE: 67828c2ecf20Sopenharmony_ci sprintf(parsed_addr_data, 67838c2ecf20Sopenharmony_ci " SB = 0x%x", cmd_addr - found_addr->start_addr); 67848c2ecf20Sopenharmony_ci break; 67858c2ecf20Sopenharmony_ci default: 67868c2ecf20Sopenharmony_ci parsed_addr_data[0] = '\0'; 67878c2ecf20Sopenharmony_ci } 67888c2ecf20Sopenharmony_ci 67898c2ecf20Sopenharmony_ci if (!is_wr_cmd) { 67908c2ecf20Sopenharmony_ci parsed_wr_data[0] = '\0'; 67918c2ecf20Sopenharmony_ci goto out; 67928c2ecf20Sopenharmony_ci } 67938c2ecf20Sopenharmony_ci 67948c2ecf20Sopenharmony_ci /* Prepare parsed write data */ 67958c2ecf20Sopenharmony_ci wr_data = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_WR_DATA); 67968c2ecf20Sopenharmony_ci prod_cons = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_PROD_CONS); 67978c2ecf20Sopenharmony_ci is_cleanup = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_CMD_TYPE); 67988c2ecf20Sopenharmony_ci 67998c2ecf20Sopenharmony_ci if (source == IGU_SRC_ATTN) { 68008c2ecf20Sopenharmony_ci sprintf(parsed_wr_data, "prod: 0x%x, ", prod_cons); 68018c2ecf20Sopenharmony_ci } else { 68028c2ecf20Sopenharmony_ci if (is_cleanup) { 68038c2ecf20Sopenharmony_ci u8 cleanup_val, cleanup_type; 68048c2ecf20Sopenharmony_ci 68058c2ecf20Sopenharmony_ci cleanup_val = 68068c2ecf20Sopenharmony_ci GET_FIELD(wr_data, 68078c2ecf20Sopenharmony_ci IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL); 68088c2ecf20Sopenharmony_ci cleanup_type = 68098c2ecf20Sopenharmony_ci GET_FIELD(wr_data, 68108c2ecf20Sopenharmony_ci IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE); 68118c2ecf20Sopenharmony_ci 68128c2ecf20Sopenharmony_ci sprintf(parsed_wr_data, 68138c2ecf20Sopenharmony_ci "cmd_type: cleanup, cleanup_val: %s, cleanup_type : %d, ", 68148c2ecf20Sopenharmony_ci cleanup_val ? "set" : "clear", 68158c2ecf20Sopenharmony_ci cleanup_type); 68168c2ecf20Sopenharmony_ci } else { 68178c2ecf20Sopenharmony_ci u8 update_flag, en_dis_int_for_sb, segment; 68188c2ecf20Sopenharmony_ci u8 timer_mask; 68198c2ecf20Sopenharmony_ci 68208c2ecf20Sopenharmony_ci update_flag = GET_FIELD(wr_data, 68218c2ecf20Sopenharmony_ci IGU_FIFO_WR_DATA_UPDATE_FLAG); 68228c2ecf20Sopenharmony_ci en_dis_int_for_sb = 68238c2ecf20Sopenharmony_ci GET_FIELD(wr_data, 68248c2ecf20Sopenharmony_ci IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB); 68258c2ecf20Sopenharmony_ci segment = GET_FIELD(wr_data, 68268c2ecf20Sopenharmony_ci IGU_FIFO_WR_DATA_SEGMENT); 68278c2ecf20Sopenharmony_ci timer_mask = GET_FIELD(wr_data, 68288c2ecf20Sopenharmony_ci IGU_FIFO_WR_DATA_TIMER_MASK); 68298c2ecf20Sopenharmony_ci 68308c2ecf20Sopenharmony_ci sprintf(parsed_wr_data, 68318c2ecf20Sopenharmony_ci "cmd_type: prod/cons update, prod/cons: 0x%x, update_flag: %s, en_dis_int_for_sb : %s, segment : %s, timer_mask = %d, ", 68328c2ecf20Sopenharmony_ci prod_cons, 68338c2ecf20Sopenharmony_ci update_flag ? "update" : "nop", 68348c2ecf20Sopenharmony_ci en_dis_int_for_sb ? 68358c2ecf20Sopenharmony_ci (en_dis_int_for_sb == 1 ? "disable" : "nop") : 68368c2ecf20Sopenharmony_ci "enable", 68378c2ecf20Sopenharmony_ci segment ? "attn" : "regular", 68388c2ecf20Sopenharmony_ci timer_mask); 68398c2ecf20Sopenharmony_ci } 68408c2ecf20Sopenharmony_ci } 68418c2ecf20Sopenharmony_ciout: 68428c2ecf20Sopenharmony_ci /* Add parsed element to parsed buffer */ 68438c2ecf20Sopenharmony_ci *results_offset += sprintf(qed_get_buf_ptr(results_buf, 68448c2ecf20Sopenharmony_ci *results_offset), 68458c2ecf20Sopenharmony_ci "raw: 0x%01x%08x%08x, %s: %d, source : %s, type : %s, cmd_addr : 0x%x(%s%s), %serror: %s\n", 68468c2ecf20Sopenharmony_ci element->dword2, element->dword1, 68478c2ecf20Sopenharmony_ci element->dword0, 68488c2ecf20Sopenharmony_ci is_pf ? "pf" : "vf", 68498c2ecf20Sopenharmony_ci GET_FIELD(element->dword0, 68508c2ecf20Sopenharmony_ci IGU_FIFO_ELEMENT_DWORD0_FID), 68518c2ecf20Sopenharmony_ci s_igu_fifo_source_strs[source], 68528c2ecf20Sopenharmony_ci is_wr_cmd ? "wr" : "rd", 68538c2ecf20Sopenharmony_ci cmd_addr, 68548c2ecf20Sopenharmony_ci (!is_pf && found_addr->vf_desc) 68558c2ecf20Sopenharmony_ci ? found_addr->vf_desc 68568c2ecf20Sopenharmony_ci : found_addr->desc, 68578c2ecf20Sopenharmony_ci parsed_addr_data, 68588c2ecf20Sopenharmony_ci parsed_wr_data, 68598c2ecf20Sopenharmony_ci s_igu_fifo_error_strs[err_type]); 68608c2ecf20Sopenharmony_ci 68618c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 68628c2ecf20Sopenharmony_ci} 68638c2ecf20Sopenharmony_ci 68648c2ecf20Sopenharmony_ci/* Parses an IGU FIFO dump buffer. 68658c2ecf20Sopenharmony_ci * If result_buf is not NULL, the IGU FIFO results are printed to it. 68668c2ecf20Sopenharmony_ci * In any case, the required results buffer size is assigned to 68678c2ecf20Sopenharmony_ci * parsed_results_bytes. 68688c2ecf20Sopenharmony_ci * The parsing status is returned. 68698c2ecf20Sopenharmony_ci */ 68708c2ecf20Sopenharmony_cistatic enum dbg_status qed_parse_igu_fifo_dump(u32 *dump_buf, 68718c2ecf20Sopenharmony_ci char *results_buf, 68728c2ecf20Sopenharmony_ci u32 *parsed_results_bytes) 68738c2ecf20Sopenharmony_ci{ 68748c2ecf20Sopenharmony_ci const char *section_name, *param_name, *param_str_val; 68758c2ecf20Sopenharmony_ci u32 param_num_val, num_section_params, num_elements; 68768c2ecf20Sopenharmony_ci struct igu_fifo_element *elements; 68778c2ecf20Sopenharmony_ci enum dbg_status status; 68788c2ecf20Sopenharmony_ci u32 results_offset = 0; 68798c2ecf20Sopenharmony_ci u8 i; 68808c2ecf20Sopenharmony_ci 68818c2ecf20Sopenharmony_ci /* Read global_params section */ 68828c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 68838c2ecf20Sopenharmony_ci §ion_name, &num_section_params); 68848c2ecf20Sopenharmony_ci if (strcmp(section_name, "global_params")) 68858c2ecf20Sopenharmony_ci return DBG_STATUS_IGU_FIFO_BAD_DATA; 68868c2ecf20Sopenharmony_ci 68878c2ecf20Sopenharmony_ci /* Print global params */ 68888c2ecf20Sopenharmony_ci dump_buf += qed_print_section_params(dump_buf, 68898c2ecf20Sopenharmony_ci num_section_params, 68908c2ecf20Sopenharmony_ci results_buf, &results_offset); 68918c2ecf20Sopenharmony_ci 68928c2ecf20Sopenharmony_ci /* Read igu_fifo_data section */ 68938c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 68948c2ecf20Sopenharmony_ci §ion_name, &num_section_params); 68958c2ecf20Sopenharmony_ci if (strcmp(section_name, "igu_fifo_data")) 68968c2ecf20Sopenharmony_ci return DBG_STATUS_IGU_FIFO_BAD_DATA; 68978c2ecf20Sopenharmony_ci dump_buf += qed_read_param(dump_buf, 68988c2ecf20Sopenharmony_ci ¶m_name, ¶m_str_val, ¶m_num_val); 68998c2ecf20Sopenharmony_ci if (strcmp(param_name, "size")) 69008c2ecf20Sopenharmony_ci return DBG_STATUS_IGU_FIFO_BAD_DATA; 69018c2ecf20Sopenharmony_ci if (param_num_val % IGU_FIFO_ELEMENT_DWORDS) 69028c2ecf20Sopenharmony_ci return DBG_STATUS_IGU_FIFO_BAD_DATA; 69038c2ecf20Sopenharmony_ci num_elements = param_num_val / IGU_FIFO_ELEMENT_DWORDS; 69048c2ecf20Sopenharmony_ci elements = (struct igu_fifo_element *)dump_buf; 69058c2ecf20Sopenharmony_ci 69068c2ecf20Sopenharmony_ci /* Decode elements */ 69078c2ecf20Sopenharmony_ci for (i = 0; i < num_elements; i++) { 69088c2ecf20Sopenharmony_ci status = qed_parse_igu_fifo_element(&elements[i], 69098c2ecf20Sopenharmony_ci results_buf, 69108c2ecf20Sopenharmony_ci &results_offset); 69118c2ecf20Sopenharmony_ci if (status != DBG_STATUS_OK) 69128c2ecf20Sopenharmony_ci return status; 69138c2ecf20Sopenharmony_ci } 69148c2ecf20Sopenharmony_ci 69158c2ecf20Sopenharmony_ci results_offset += sprintf(qed_get_buf_ptr(results_buf, 69168c2ecf20Sopenharmony_ci results_offset), 69178c2ecf20Sopenharmony_ci "fifo contained %d elements", num_elements); 69188c2ecf20Sopenharmony_ci 69198c2ecf20Sopenharmony_ci /* Add 1 for string NULL termination */ 69208c2ecf20Sopenharmony_ci *parsed_results_bytes = results_offset + 1; 69218c2ecf20Sopenharmony_ci 69228c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 69238c2ecf20Sopenharmony_ci} 69248c2ecf20Sopenharmony_ci 69258c2ecf20Sopenharmony_cistatic enum dbg_status 69268c2ecf20Sopenharmony_ciqed_parse_protection_override_dump(u32 *dump_buf, 69278c2ecf20Sopenharmony_ci char *results_buf, 69288c2ecf20Sopenharmony_ci u32 *parsed_results_bytes) 69298c2ecf20Sopenharmony_ci{ 69308c2ecf20Sopenharmony_ci const char *section_name, *param_name, *param_str_val; 69318c2ecf20Sopenharmony_ci u32 param_num_val, num_section_params, num_elements; 69328c2ecf20Sopenharmony_ci struct protection_override_element *elements; 69338c2ecf20Sopenharmony_ci u32 results_offset = 0; 69348c2ecf20Sopenharmony_ci u8 i; 69358c2ecf20Sopenharmony_ci 69368c2ecf20Sopenharmony_ci /* Read global_params section */ 69378c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 69388c2ecf20Sopenharmony_ci §ion_name, &num_section_params); 69398c2ecf20Sopenharmony_ci if (strcmp(section_name, "global_params")) 69408c2ecf20Sopenharmony_ci return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA; 69418c2ecf20Sopenharmony_ci 69428c2ecf20Sopenharmony_ci /* Print global params */ 69438c2ecf20Sopenharmony_ci dump_buf += qed_print_section_params(dump_buf, 69448c2ecf20Sopenharmony_ci num_section_params, 69458c2ecf20Sopenharmony_ci results_buf, &results_offset); 69468c2ecf20Sopenharmony_ci 69478c2ecf20Sopenharmony_ci /* Read protection_override_data section */ 69488c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 69498c2ecf20Sopenharmony_ci §ion_name, &num_section_params); 69508c2ecf20Sopenharmony_ci if (strcmp(section_name, "protection_override_data")) 69518c2ecf20Sopenharmony_ci return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA; 69528c2ecf20Sopenharmony_ci dump_buf += qed_read_param(dump_buf, 69538c2ecf20Sopenharmony_ci ¶m_name, ¶m_str_val, ¶m_num_val); 69548c2ecf20Sopenharmony_ci if (strcmp(param_name, "size")) 69558c2ecf20Sopenharmony_ci return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA; 69568c2ecf20Sopenharmony_ci if (param_num_val % PROTECTION_OVERRIDE_ELEMENT_DWORDS) 69578c2ecf20Sopenharmony_ci return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA; 69588c2ecf20Sopenharmony_ci num_elements = param_num_val / PROTECTION_OVERRIDE_ELEMENT_DWORDS; 69598c2ecf20Sopenharmony_ci elements = (struct protection_override_element *)dump_buf; 69608c2ecf20Sopenharmony_ci 69618c2ecf20Sopenharmony_ci /* Decode elements */ 69628c2ecf20Sopenharmony_ci for (i = 0; i < num_elements; i++) { 69638c2ecf20Sopenharmony_ci u32 address = GET_FIELD(elements[i].data, 69648c2ecf20Sopenharmony_ci PROTECTION_OVERRIDE_ELEMENT_ADDRESS) * 69658c2ecf20Sopenharmony_ci PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR; 69668c2ecf20Sopenharmony_ci 69678c2ecf20Sopenharmony_ci results_offset += 69688c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 69698c2ecf20Sopenharmony_ci results_offset), 69708c2ecf20Sopenharmony_ci "window %2d, address: 0x%07x, size: %7d regs, read: %d, write: %d, read protection: %-12s, write protection: %-12s\n", 69718c2ecf20Sopenharmony_ci i, address, 69728c2ecf20Sopenharmony_ci (u32)GET_FIELD(elements[i].data, 69738c2ecf20Sopenharmony_ci PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE), 69748c2ecf20Sopenharmony_ci (u32)GET_FIELD(elements[i].data, 69758c2ecf20Sopenharmony_ci PROTECTION_OVERRIDE_ELEMENT_READ), 69768c2ecf20Sopenharmony_ci (u32)GET_FIELD(elements[i].data, 69778c2ecf20Sopenharmony_ci PROTECTION_OVERRIDE_ELEMENT_WRITE), 69788c2ecf20Sopenharmony_ci s_protection_strs[GET_FIELD(elements[i].data, 69798c2ecf20Sopenharmony_ci PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION)], 69808c2ecf20Sopenharmony_ci s_protection_strs[GET_FIELD(elements[i].data, 69818c2ecf20Sopenharmony_ci PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION)]); 69828c2ecf20Sopenharmony_ci } 69838c2ecf20Sopenharmony_ci 69848c2ecf20Sopenharmony_ci results_offset += sprintf(qed_get_buf_ptr(results_buf, 69858c2ecf20Sopenharmony_ci results_offset), 69868c2ecf20Sopenharmony_ci "protection override contained %d elements", 69878c2ecf20Sopenharmony_ci num_elements); 69888c2ecf20Sopenharmony_ci 69898c2ecf20Sopenharmony_ci /* Add 1 for string NULL termination */ 69908c2ecf20Sopenharmony_ci *parsed_results_bytes = results_offset + 1; 69918c2ecf20Sopenharmony_ci 69928c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 69938c2ecf20Sopenharmony_ci} 69948c2ecf20Sopenharmony_ci 69958c2ecf20Sopenharmony_ci/* Parses a FW Asserts dump buffer. 69968c2ecf20Sopenharmony_ci * If result_buf is not NULL, the FW Asserts results are printed to it. 69978c2ecf20Sopenharmony_ci * In any case, the required results buffer size is assigned to 69988c2ecf20Sopenharmony_ci * parsed_results_bytes. 69998c2ecf20Sopenharmony_ci * The parsing status is returned. 70008c2ecf20Sopenharmony_ci */ 70018c2ecf20Sopenharmony_cistatic enum dbg_status qed_parse_fw_asserts_dump(u32 *dump_buf, 70028c2ecf20Sopenharmony_ci char *results_buf, 70038c2ecf20Sopenharmony_ci u32 *parsed_results_bytes) 70048c2ecf20Sopenharmony_ci{ 70058c2ecf20Sopenharmony_ci u32 num_section_params, param_num_val, i, results_offset = 0; 70068c2ecf20Sopenharmony_ci const char *param_name, *param_str_val, *section_name; 70078c2ecf20Sopenharmony_ci bool last_section_found = false; 70088c2ecf20Sopenharmony_ci 70098c2ecf20Sopenharmony_ci *parsed_results_bytes = 0; 70108c2ecf20Sopenharmony_ci 70118c2ecf20Sopenharmony_ci /* Read global_params section */ 70128c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 70138c2ecf20Sopenharmony_ci §ion_name, &num_section_params); 70148c2ecf20Sopenharmony_ci if (strcmp(section_name, "global_params")) 70158c2ecf20Sopenharmony_ci return DBG_STATUS_FW_ASSERTS_PARSE_FAILED; 70168c2ecf20Sopenharmony_ci 70178c2ecf20Sopenharmony_ci /* Print global params */ 70188c2ecf20Sopenharmony_ci dump_buf += qed_print_section_params(dump_buf, 70198c2ecf20Sopenharmony_ci num_section_params, 70208c2ecf20Sopenharmony_ci results_buf, &results_offset); 70218c2ecf20Sopenharmony_ci 70228c2ecf20Sopenharmony_ci while (!last_section_found) { 70238c2ecf20Sopenharmony_ci dump_buf += qed_read_section_hdr(dump_buf, 70248c2ecf20Sopenharmony_ci §ion_name, 70258c2ecf20Sopenharmony_ci &num_section_params); 70268c2ecf20Sopenharmony_ci if (!strcmp(section_name, "fw_asserts")) { 70278c2ecf20Sopenharmony_ci /* Extract params */ 70288c2ecf20Sopenharmony_ci const char *storm_letter = NULL; 70298c2ecf20Sopenharmony_ci u32 storm_dump_size = 0; 70308c2ecf20Sopenharmony_ci 70318c2ecf20Sopenharmony_ci for (i = 0; i < num_section_params; i++) { 70328c2ecf20Sopenharmony_ci dump_buf += qed_read_param(dump_buf, 70338c2ecf20Sopenharmony_ci ¶m_name, 70348c2ecf20Sopenharmony_ci ¶m_str_val, 70358c2ecf20Sopenharmony_ci ¶m_num_val); 70368c2ecf20Sopenharmony_ci if (!strcmp(param_name, "storm")) 70378c2ecf20Sopenharmony_ci storm_letter = param_str_val; 70388c2ecf20Sopenharmony_ci else if (!strcmp(param_name, "size")) 70398c2ecf20Sopenharmony_ci storm_dump_size = param_num_val; 70408c2ecf20Sopenharmony_ci else 70418c2ecf20Sopenharmony_ci return 70428c2ecf20Sopenharmony_ci DBG_STATUS_FW_ASSERTS_PARSE_FAILED; 70438c2ecf20Sopenharmony_ci } 70448c2ecf20Sopenharmony_ci 70458c2ecf20Sopenharmony_ci if (!storm_letter || !storm_dump_size) 70468c2ecf20Sopenharmony_ci return DBG_STATUS_FW_ASSERTS_PARSE_FAILED; 70478c2ecf20Sopenharmony_ci 70488c2ecf20Sopenharmony_ci /* Print data */ 70498c2ecf20Sopenharmony_ci results_offset += 70508c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 70518c2ecf20Sopenharmony_ci results_offset), 70528c2ecf20Sopenharmony_ci "\n%sSTORM_ASSERT: size=%d\n", 70538c2ecf20Sopenharmony_ci storm_letter, storm_dump_size); 70548c2ecf20Sopenharmony_ci for (i = 0; i < storm_dump_size; i++, dump_buf++) 70558c2ecf20Sopenharmony_ci results_offset += 70568c2ecf20Sopenharmony_ci sprintf(qed_get_buf_ptr(results_buf, 70578c2ecf20Sopenharmony_ci results_offset), 70588c2ecf20Sopenharmony_ci "%08x\n", *dump_buf); 70598c2ecf20Sopenharmony_ci } else if (!strcmp(section_name, "last")) { 70608c2ecf20Sopenharmony_ci last_section_found = true; 70618c2ecf20Sopenharmony_ci } else { 70628c2ecf20Sopenharmony_ci return DBG_STATUS_FW_ASSERTS_PARSE_FAILED; 70638c2ecf20Sopenharmony_ci } 70648c2ecf20Sopenharmony_ci } 70658c2ecf20Sopenharmony_ci 70668c2ecf20Sopenharmony_ci /* Add 1 for string NULL termination */ 70678c2ecf20Sopenharmony_ci *parsed_results_bytes = results_offset + 1; 70688c2ecf20Sopenharmony_ci 70698c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 70708c2ecf20Sopenharmony_ci} 70718c2ecf20Sopenharmony_ci 70728c2ecf20Sopenharmony_ci/***************************** Public Functions *******************************/ 70738c2ecf20Sopenharmony_ci 70748c2ecf20Sopenharmony_cienum dbg_status qed_dbg_user_set_bin_ptr(struct qed_hwfn *p_hwfn, 70758c2ecf20Sopenharmony_ci const u8 * const bin_ptr) 70768c2ecf20Sopenharmony_ci{ 70778c2ecf20Sopenharmony_ci struct bin_buffer_hdr *buf_hdrs = (struct bin_buffer_hdr *)bin_ptr; 70788c2ecf20Sopenharmony_ci u8 buf_id; 70798c2ecf20Sopenharmony_ci 70808c2ecf20Sopenharmony_ci /* Convert binary data to debug arrays */ 70818c2ecf20Sopenharmony_ci for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++) 70828c2ecf20Sopenharmony_ci qed_set_dbg_bin_buf(p_hwfn, 70838c2ecf20Sopenharmony_ci (enum bin_dbg_buffer_type)buf_id, 70848c2ecf20Sopenharmony_ci (u32 *)(bin_ptr + buf_hdrs[buf_id].offset), 70858c2ecf20Sopenharmony_ci buf_hdrs[buf_id].length); 70868c2ecf20Sopenharmony_ci 70878c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 70888c2ecf20Sopenharmony_ci} 70898c2ecf20Sopenharmony_ci 70908c2ecf20Sopenharmony_cienum dbg_status qed_dbg_alloc_user_data(struct qed_hwfn *p_hwfn, 70918c2ecf20Sopenharmony_ci void **user_data_ptr) 70928c2ecf20Sopenharmony_ci{ 70938c2ecf20Sopenharmony_ci *user_data_ptr = kzalloc(sizeof(struct dbg_tools_user_data), 70948c2ecf20Sopenharmony_ci GFP_KERNEL); 70958c2ecf20Sopenharmony_ci if (!(*user_data_ptr)) 70968c2ecf20Sopenharmony_ci return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; 70978c2ecf20Sopenharmony_ci 70988c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 70998c2ecf20Sopenharmony_ci} 71008c2ecf20Sopenharmony_ci 71018c2ecf20Sopenharmony_ciconst char *qed_dbg_get_status_str(enum dbg_status status) 71028c2ecf20Sopenharmony_ci{ 71038c2ecf20Sopenharmony_ci return (status < 71048c2ecf20Sopenharmony_ci MAX_DBG_STATUS) ? s_status_str[status] : "Invalid debug status"; 71058c2ecf20Sopenharmony_ci} 71068c2ecf20Sopenharmony_ci 71078c2ecf20Sopenharmony_cienum dbg_status qed_get_idle_chk_results_buf_size(struct qed_hwfn *p_hwfn, 71088c2ecf20Sopenharmony_ci u32 *dump_buf, 71098c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 71108c2ecf20Sopenharmony_ci u32 *results_buf_size) 71118c2ecf20Sopenharmony_ci{ 71128c2ecf20Sopenharmony_ci u32 num_errors, num_warnings; 71138c2ecf20Sopenharmony_ci 71148c2ecf20Sopenharmony_ci return qed_parse_idle_chk_dump(p_hwfn, 71158c2ecf20Sopenharmony_ci dump_buf, 71168c2ecf20Sopenharmony_ci num_dumped_dwords, 71178c2ecf20Sopenharmony_ci NULL, 71188c2ecf20Sopenharmony_ci results_buf_size, 71198c2ecf20Sopenharmony_ci &num_errors, &num_warnings); 71208c2ecf20Sopenharmony_ci} 71218c2ecf20Sopenharmony_ci 71228c2ecf20Sopenharmony_cienum dbg_status qed_print_idle_chk_results(struct qed_hwfn *p_hwfn, 71238c2ecf20Sopenharmony_ci u32 *dump_buf, 71248c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 71258c2ecf20Sopenharmony_ci char *results_buf, 71268c2ecf20Sopenharmony_ci u32 *num_errors, 71278c2ecf20Sopenharmony_ci u32 *num_warnings) 71288c2ecf20Sopenharmony_ci{ 71298c2ecf20Sopenharmony_ci u32 parsed_buf_size; 71308c2ecf20Sopenharmony_ci 71318c2ecf20Sopenharmony_ci return qed_parse_idle_chk_dump(p_hwfn, 71328c2ecf20Sopenharmony_ci dump_buf, 71338c2ecf20Sopenharmony_ci num_dumped_dwords, 71348c2ecf20Sopenharmony_ci results_buf, 71358c2ecf20Sopenharmony_ci &parsed_buf_size, 71368c2ecf20Sopenharmony_ci num_errors, num_warnings); 71378c2ecf20Sopenharmony_ci} 71388c2ecf20Sopenharmony_ci 71398c2ecf20Sopenharmony_civoid qed_dbg_mcp_trace_set_meta_data(struct qed_hwfn *p_hwfn, 71408c2ecf20Sopenharmony_ci const u32 *meta_buf) 71418c2ecf20Sopenharmony_ci{ 71428c2ecf20Sopenharmony_ci struct dbg_tools_user_data *dev_user_data = 71438c2ecf20Sopenharmony_ci qed_dbg_get_user_data(p_hwfn); 71448c2ecf20Sopenharmony_ci 71458c2ecf20Sopenharmony_ci dev_user_data->mcp_trace_user_meta_buf = meta_buf; 71468c2ecf20Sopenharmony_ci} 71478c2ecf20Sopenharmony_ci 71488c2ecf20Sopenharmony_cienum dbg_status qed_get_mcp_trace_results_buf_size(struct qed_hwfn *p_hwfn, 71498c2ecf20Sopenharmony_ci u32 *dump_buf, 71508c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 71518c2ecf20Sopenharmony_ci u32 *results_buf_size) 71528c2ecf20Sopenharmony_ci{ 71538c2ecf20Sopenharmony_ci return qed_parse_mcp_trace_dump(p_hwfn, 71548c2ecf20Sopenharmony_ci dump_buf, NULL, results_buf_size, true); 71558c2ecf20Sopenharmony_ci} 71568c2ecf20Sopenharmony_ci 71578c2ecf20Sopenharmony_cienum dbg_status qed_print_mcp_trace_results(struct qed_hwfn *p_hwfn, 71588c2ecf20Sopenharmony_ci u32 *dump_buf, 71598c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 71608c2ecf20Sopenharmony_ci char *results_buf) 71618c2ecf20Sopenharmony_ci{ 71628c2ecf20Sopenharmony_ci u32 parsed_buf_size; 71638c2ecf20Sopenharmony_ci 71648c2ecf20Sopenharmony_ci return qed_parse_mcp_trace_dump(p_hwfn, 71658c2ecf20Sopenharmony_ci dump_buf, 71668c2ecf20Sopenharmony_ci results_buf, &parsed_buf_size, true); 71678c2ecf20Sopenharmony_ci} 71688c2ecf20Sopenharmony_ci 71698c2ecf20Sopenharmony_cienum dbg_status qed_print_mcp_trace_results_cont(struct qed_hwfn *p_hwfn, 71708c2ecf20Sopenharmony_ci u32 *dump_buf, 71718c2ecf20Sopenharmony_ci char *results_buf) 71728c2ecf20Sopenharmony_ci{ 71738c2ecf20Sopenharmony_ci u32 parsed_buf_size; 71748c2ecf20Sopenharmony_ci 71758c2ecf20Sopenharmony_ci return qed_parse_mcp_trace_dump(p_hwfn, dump_buf, results_buf, 71768c2ecf20Sopenharmony_ci &parsed_buf_size, false); 71778c2ecf20Sopenharmony_ci} 71788c2ecf20Sopenharmony_ci 71798c2ecf20Sopenharmony_cienum dbg_status qed_print_mcp_trace_line(struct qed_hwfn *p_hwfn, 71808c2ecf20Sopenharmony_ci u8 *dump_buf, 71818c2ecf20Sopenharmony_ci u32 num_dumped_bytes, 71828c2ecf20Sopenharmony_ci char *results_buf) 71838c2ecf20Sopenharmony_ci{ 71848c2ecf20Sopenharmony_ci u32 parsed_results_bytes; 71858c2ecf20Sopenharmony_ci 71868c2ecf20Sopenharmony_ci return qed_parse_mcp_trace_buf(p_hwfn, 71878c2ecf20Sopenharmony_ci dump_buf, 71888c2ecf20Sopenharmony_ci num_dumped_bytes, 71898c2ecf20Sopenharmony_ci 0, 71908c2ecf20Sopenharmony_ci num_dumped_bytes, 71918c2ecf20Sopenharmony_ci results_buf, &parsed_results_bytes); 71928c2ecf20Sopenharmony_ci} 71938c2ecf20Sopenharmony_ci 71948c2ecf20Sopenharmony_ci/* Frees the specified MCP Trace meta data */ 71958c2ecf20Sopenharmony_civoid qed_mcp_trace_free_meta_data(struct qed_hwfn *p_hwfn) 71968c2ecf20Sopenharmony_ci{ 71978c2ecf20Sopenharmony_ci struct dbg_tools_user_data *dev_user_data; 71988c2ecf20Sopenharmony_ci struct mcp_trace_meta *meta; 71998c2ecf20Sopenharmony_ci u32 i; 72008c2ecf20Sopenharmony_ci 72018c2ecf20Sopenharmony_ci dev_user_data = qed_dbg_get_user_data(p_hwfn); 72028c2ecf20Sopenharmony_ci meta = &dev_user_data->mcp_trace_meta; 72038c2ecf20Sopenharmony_ci if (!meta->is_allocated) 72048c2ecf20Sopenharmony_ci return; 72058c2ecf20Sopenharmony_ci 72068c2ecf20Sopenharmony_ci /* Release modules */ 72078c2ecf20Sopenharmony_ci if (meta->modules) { 72088c2ecf20Sopenharmony_ci for (i = 0; i < meta->modules_num; i++) 72098c2ecf20Sopenharmony_ci kfree(meta->modules[i]); 72108c2ecf20Sopenharmony_ci kfree(meta->modules); 72118c2ecf20Sopenharmony_ci } 72128c2ecf20Sopenharmony_ci 72138c2ecf20Sopenharmony_ci /* Release formats */ 72148c2ecf20Sopenharmony_ci if (meta->formats) { 72158c2ecf20Sopenharmony_ci for (i = 0; i < meta->formats_num; i++) 72168c2ecf20Sopenharmony_ci kfree(meta->formats[i].format_str); 72178c2ecf20Sopenharmony_ci kfree(meta->formats); 72188c2ecf20Sopenharmony_ci } 72198c2ecf20Sopenharmony_ci 72208c2ecf20Sopenharmony_ci meta->is_allocated = false; 72218c2ecf20Sopenharmony_ci} 72228c2ecf20Sopenharmony_ci 72238c2ecf20Sopenharmony_cienum dbg_status qed_get_reg_fifo_results_buf_size(struct qed_hwfn *p_hwfn, 72248c2ecf20Sopenharmony_ci u32 *dump_buf, 72258c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 72268c2ecf20Sopenharmony_ci u32 *results_buf_size) 72278c2ecf20Sopenharmony_ci{ 72288c2ecf20Sopenharmony_ci return qed_parse_reg_fifo_dump(dump_buf, NULL, results_buf_size); 72298c2ecf20Sopenharmony_ci} 72308c2ecf20Sopenharmony_ci 72318c2ecf20Sopenharmony_cienum dbg_status qed_print_reg_fifo_results(struct qed_hwfn *p_hwfn, 72328c2ecf20Sopenharmony_ci u32 *dump_buf, 72338c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 72348c2ecf20Sopenharmony_ci char *results_buf) 72358c2ecf20Sopenharmony_ci{ 72368c2ecf20Sopenharmony_ci u32 parsed_buf_size; 72378c2ecf20Sopenharmony_ci 72388c2ecf20Sopenharmony_ci return qed_parse_reg_fifo_dump(dump_buf, results_buf, &parsed_buf_size); 72398c2ecf20Sopenharmony_ci} 72408c2ecf20Sopenharmony_ci 72418c2ecf20Sopenharmony_cienum dbg_status qed_get_igu_fifo_results_buf_size(struct qed_hwfn *p_hwfn, 72428c2ecf20Sopenharmony_ci u32 *dump_buf, 72438c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 72448c2ecf20Sopenharmony_ci u32 *results_buf_size) 72458c2ecf20Sopenharmony_ci{ 72468c2ecf20Sopenharmony_ci return qed_parse_igu_fifo_dump(dump_buf, NULL, results_buf_size); 72478c2ecf20Sopenharmony_ci} 72488c2ecf20Sopenharmony_ci 72498c2ecf20Sopenharmony_cienum dbg_status qed_print_igu_fifo_results(struct qed_hwfn *p_hwfn, 72508c2ecf20Sopenharmony_ci u32 *dump_buf, 72518c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 72528c2ecf20Sopenharmony_ci char *results_buf) 72538c2ecf20Sopenharmony_ci{ 72548c2ecf20Sopenharmony_ci u32 parsed_buf_size; 72558c2ecf20Sopenharmony_ci 72568c2ecf20Sopenharmony_ci return qed_parse_igu_fifo_dump(dump_buf, results_buf, &parsed_buf_size); 72578c2ecf20Sopenharmony_ci} 72588c2ecf20Sopenharmony_ci 72598c2ecf20Sopenharmony_cienum dbg_status 72608c2ecf20Sopenharmony_ciqed_get_protection_override_results_buf_size(struct qed_hwfn *p_hwfn, 72618c2ecf20Sopenharmony_ci u32 *dump_buf, 72628c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 72638c2ecf20Sopenharmony_ci u32 *results_buf_size) 72648c2ecf20Sopenharmony_ci{ 72658c2ecf20Sopenharmony_ci return qed_parse_protection_override_dump(dump_buf, 72668c2ecf20Sopenharmony_ci NULL, results_buf_size); 72678c2ecf20Sopenharmony_ci} 72688c2ecf20Sopenharmony_ci 72698c2ecf20Sopenharmony_cienum dbg_status qed_print_protection_override_results(struct qed_hwfn *p_hwfn, 72708c2ecf20Sopenharmony_ci u32 *dump_buf, 72718c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 72728c2ecf20Sopenharmony_ci char *results_buf) 72738c2ecf20Sopenharmony_ci{ 72748c2ecf20Sopenharmony_ci u32 parsed_buf_size; 72758c2ecf20Sopenharmony_ci 72768c2ecf20Sopenharmony_ci return qed_parse_protection_override_dump(dump_buf, 72778c2ecf20Sopenharmony_ci results_buf, 72788c2ecf20Sopenharmony_ci &parsed_buf_size); 72798c2ecf20Sopenharmony_ci} 72808c2ecf20Sopenharmony_ci 72818c2ecf20Sopenharmony_cienum dbg_status qed_get_fw_asserts_results_buf_size(struct qed_hwfn *p_hwfn, 72828c2ecf20Sopenharmony_ci u32 *dump_buf, 72838c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 72848c2ecf20Sopenharmony_ci u32 *results_buf_size) 72858c2ecf20Sopenharmony_ci{ 72868c2ecf20Sopenharmony_ci return qed_parse_fw_asserts_dump(dump_buf, NULL, results_buf_size); 72878c2ecf20Sopenharmony_ci} 72888c2ecf20Sopenharmony_ci 72898c2ecf20Sopenharmony_cienum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn, 72908c2ecf20Sopenharmony_ci u32 *dump_buf, 72918c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 72928c2ecf20Sopenharmony_ci char *results_buf) 72938c2ecf20Sopenharmony_ci{ 72948c2ecf20Sopenharmony_ci u32 parsed_buf_size; 72958c2ecf20Sopenharmony_ci 72968c2ecf20Sopenharmony_ci return qed_parse_fw_asserts_dump(dump_buf, 72978c2ecf20Sopenharmony_ci results_buf, &parsed_buf_size); 72988c2ecf20Sopenharmony_ci} 72998c2ecf20Sopenharmony_ci 73008c2ecf20Sopenharmony_cienum dbg_status qed_dbg_parse_attn(struct qed_hwfn *p_hwfn, 73018c2ecf20Sopenharmony_ci struct dbg_attn_block_result *results) 73028c2ecf20Sopenharmony_ci{ 73038c2ecf20Sopenharmony_ci const u32 *block_attn_name_offsets; 73048c2ecf20Sopenharmony_ci const char *attn_name_base; 73058c2ecf20Sopenharmony_ci const char *block_name; 73068c2ecf20Sopenharmony_ci enum dbg_attn_type attn_type; 73078c2ecf20Sopenharmony_ci u8 num_regs, i, j; 73088c2ecf20Sopenharmony_ci 73098c2ecf20Sopenharmony_ci num_regs = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_NUM_REGS); 73108c2ecf20Sopenharmony_ci attn_type = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE); 73118c2ecf20Sopenharmony_ci block_name = qed_dbg_get_block_name(p_hwfn, results->block_id); 73128c2ecf20Sopenharmony_ci if (!block_name) 73138c2ecf20Sopenharmony_ci return DBG_STATUS_INVALID_ARGS; 73148c2ecf20Sopenharmony_ci 73158c2ecf20Sopenharmony_ci if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr || 73168c2ecf20Sopenharmony_ci !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr || 73178c2ecf20Sopenharmony_ci !p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr) 73188c2ecf20Sopenharmony_ci return DBG_STATUS_DBG_ARRAY_NOT_SET; 73198c2ecf20Sopenharmony_ci 73208c2ecf20Sopenharmony_ci block_attn_name_offsets = 73218c2ecf20Sopenharmony_ci (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr + 73228c2ecf20Sopenharmony_ci results->names_offset; 73238c2ecf20Sopenharmony_ci 73248c2ecf20Sopenharmony_ci attn_name_base = p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr; 73258c2ecf20Sopenharmony_ci 73268c2ecf20Sopenharmony_ci /* Go over registers with a non-zero attention status */ 73278c2ecf20Sopenharmony_ci for (i = 0; i < num_regs; i++) { 73288c2ecf20Sopenharmony_ci struct dbg_attn_bit_mapping *bit_mapping; 73298c2ecf20Sopenharmony_ci struct dbg_attn_reg_result *reg_result; 73308c2ecf20Sopenharmony_ci u8 num_reg_attn, bit_idx = 0; 73318c2ecf20Sopenharmony_ci 73328c2ecf20Sopenharmony_ci reg_result = &results->reg_results[i]; 73338c2ecf20Sopenharmony_ci num_reg_attn = GET_FIELD(reg_result->data, 73348c2ecf20Sopenharmony_ci DBG_ATTN_REG_RESULT_NUM_REG_ATTN); 73358c2ecf20Sopenharmony_ci bit_mapping = (struct dbg_attn_bit_mapping *) 73368c2ecf20Sopenharmony_ci p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr + 73378c2ecf20Sopenharmony_ci reg_result->block_attn_offset; 73388c2ecf20Sopenharmony_ci 73398c2ecf20Sopenharmony_ci /* Go over attention status bits */ 73408c2ecf20Sopenharmony_ci for (j = 0; j < num_reg_attn; j++, bit_idx++) { 73418c2ecf20Sopenharmony_ci u16 attn_idx_val = GET_FIELD(bit_mapping[j].data, 73428c2ecf20Sopenharmony_ci DBG_ATTN_BIT_MAPPING_VAL); 73438c2ecf20Sopenharmony_ci const char *attn_name, *attn_type_str, *masked_str; 73448c2ecf20Sopenharmony_ci u32 attn_name_offset; 73458c2ecf20Sopenharmony_ci u32 sts_addr; 73468c2ecf20Sopenharmony_ci 73478c2ecf20Sopenharmony_ci /* Check if bit mask should be advanced (due to unused 73488c2ecf20Sopenharmony_ci * bits). 73498c2ecf20Sopenharmony_ci */ 73508c2ecf20Sopenharmony_ci if (GET_FIELD(bit_mapping[j].data, 73518c2ecf20Sopenharmony_ci DBG_ATTN_BIT_MAPPING_IS_UNUSED_BIT_CNT)) { 73528c2ecf20Sopenharmony_ci bit_idx += (u8)attn_idx_val; 73538c2ecf20Sopenharmony_ci continue; 73548c2ecf20Sopenharmony_ci } 73558c2ecf20Sopenharmony_ci 73568c2ecf20Sopenharmony_ci /* Check current bit index */ 73578c2ecf20Sopenharmony_ci if (!(reg_result->sts_val & BIT(bit_idx))) 73588c2ecf20Sopenharmony_ci continue; 73598c2ecf20Sopenharmony_ci 73608c2ecf20Sopenharmony_ci /* An attention bit with value=1 was found 73618c2ecf20Sopenharmony_ci * Find attention name 73628c2ecf20Sopenharmony_ci */ 73638c2ecf20Sopenharmony_ci attn_name_offset = 73648c2ecf20Sopenharmony_ci block_attn_name_offsets[attn_idx_val]; 73658c2ecf20Sopenharmony_ci attn_name = attn_name_base + attn_name_offset; 73668c2ecf20Sopenharmony_ci attn_type_str = 73678c2ecf20Sopenharmony_ci (attn_type == 73688c2ecf20Sopenharmony_ci ATTN_TYPE_INTERRUPT ? "Interrupt" : 73698c2ecf20Sopenharmony_ci "Parity"); 73708c2ecf20Sopenharmony_ci masked_str = reg_result->mask_val & BIT(bit_idx) ? 73718c2ecf20Sopenharmony_ci " [masked]" : ""; 73728c2ecf20Sopenharmony_ci sts_addr = GET_FIELD(reg_result->data, 73738c2ecf20Sopenharmony_ci DBG_ATTN_REG_RESULT_STS_ADDRESS); 73748c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, 73758c2ecf20Sopenharmony_ci "%s (%s) : %s [address 0x%08x, bit %d]%s\n", 73768c2ecf20Sopenharmony_ci block_name, attn_type_str, attn_name, 73778c2ecf20Sopenharmony_ci sts_addr * 4, bit_idx, masked_str); 73788c2ecf20Sopenharmony_ci } 73798c2ecf20Sopenharmony_ci } 73808c2ecf20Sopenharmony_ci 73818c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 73828c2ecf20Sopenharmony_ci} 73838c2ecf20Sopenharmony_ci 73848c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(qed_dbg_lock); 73858c2ecf20Sopenharmony_ci 73868c2ecf20Sopenharmony_ci/* Wrapper for unifying the idle_chk and mcp_trace api */ 73878c2ecf20Sopenharmony_cistatic enum dbg_status 73888c2ecf20Sopenharmony_ciqed_print_idle_chk_results_wrapper(struct qed_hwfn *p_hwfn, 73898c2ecf20Sopenharmony_ci u32 *dump_buf, 73908c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 73918c2ecf20Sopenharmony_ci char *results_buf) 73928c2ecf20Sopenharmony_ci{ 73938c2ecf20Sopenharmony_ci u32 num_errors, num_warnnings; 73948c2ecf20Sopenharmony_ci 73958c2ecf20Sopenharmony_ci return qed_print_idle_chk_results(p_hwfn, dump_buf, num_dumped_dwords, 73968c2ecf20Sopenharmony_ci results_buf, &num_errors, 73978c2ecf20Sopenharmony_ci &num_warnnings); 73988c2ecf20Sopenharmony_ci} 73998c2ecf20Sopenharmony_ci 74008c2ecf20Sopenharmony_ci/* Feature meta data lookup table */ 74018c2ecf20Sopenharmony_cistatic struct { 74028c2ecf20Sopenharmony_ci char *name; 74038c2ecf20Sopenharmony_ci enum dbg_status (*get_size)(struct qed_hwfn *p_hwfn, 74048c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, u32 *size); 74058c2ecf20Sopenharmony_ci enum dbg_status (*perform_dump)(struct qed_hwfn *p_hwfn, 74068c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, u32 *dump_buf, 74078c2ecf20Sopenharmony_ci u32 buf_size, u32 *dumped_dwords); 74088c2ecf20Sopenharmony_ci enum dbg_status (*print_results)(struct qed_hwfn *p_hwfn, 74098c2ecf20Sopenharmony_ci u32 *dump_buf, u32 num_dumped_dwords, 74108c2ecf20Sopenharmony_ci char *results_buf); 74118c2ecf20Sopenharmony_ci enum dbg_status (*results_buf_size)(struct qed_hwfn *p_hwfn, 74128c2ecf20Sopenharmony_ci u32 *dump_buf, 74138c2ecf20Sopenharmony_ci u32 num_dumped_dwords, 74148c2ecf20Sopenharmony_ci u32 *results_buf_size); 74158c2ecf20Sopenharmony_ci} qed_features_lookup[] = { 74168c2ecf20Sopenharmony_ci { 74178c2ecf20Sopenharmony_ci "grc", qed_dbg_grc_get_dump_buf_size, 74188c2ecf20Sopenharmony_ci qed_dbg_grc_dump, NULL, NULL}, { 74198c2ecf20Sopenharmony_ci "idle_chk", 74208c2ecf20Sopenharmony_ci qed_dbg_idle_chk_get_dump_buf_size, 74218c2ecf20Sopenharmony_ci qed_dbg_idle_chk_dump, 74228c2ecf20Sopenharmony_ci qed_print_idle_chk_results_wrapper, 74238c2ecf20Sopenharmony_ci qed_get_idle_chk_results_buf_size}, { 74248c2ecf20Sopenharmony_ci "mcp_trace", 74258c2ecf20Sopenharmony_ci qed_dbg_mcp_trace_get_dump_buf_size, 74268c2ecf20Sopenharmony_ci qed_dbg_mcp_trace_dump, qed_print_mcp_trace_results, 74278c2ecf20Sopenharmony_ci qed_get_mcp_trace_results_buf_size}, { 74288c2ecf20Sopenharmony_ci "reg_fifo", 74298c2ecf20Sopenharmony_ci qed_dbg_reg_fifo_get_dump_buf_size, 74308c2ecf20Sopenharmony_ci qed_dbg_reg_fifo_dump, qed_print_reg_fifo_results, 74318c2ecf20Sopenharmony_ci qed_get_reg_fifo_results_buf_size}, { 74328c2ecf20Sopenharmony_ci "igu_fifo", 74338c2ecf20Sopenharmony_ci qed_dbg_igu_fifo_get_dump_buf_size, 74348c2ecf20Sopenharmony_ci qed_dbg_igu_fifo_dump, qed_print_igu_fifo_results, 74358c2ecf20Sopenharmony_ci qed_get_igu_fifo_results_buf_size}, { 74368c2ecf20Sopenharmony_ci "protection_override", 74378c2ecf20Sopenharmony_ci qed_dbg_protection_override_get_dump_buf_size, 74388c2ecf20Sopenharmony_ci qed_dbg_protection_override_dump, 74398c2ecf20Sopenharmony_ci qed_print_protection_override_results, 74408c2ecf20Sopenharmony_ci qed_get_protection_override_results_buf_size}, { 74418c2ecf20Sopenharmony_ci "fw_asserts", 74428c2ecf20Sopenharmony_ci qed_dbg_fw_asserts_get_dump_buf_size, 74438c2ecf20Sopenharmony_ci qed_dbg_fw_asserts_dump, 74448c2ecf20Sopenharmony_ci qed_print_fw_asserts_results, 74458c2ecf20Sopenharmony_ci qed_get_fw_asserts_results_buf_size}, { 74468c2ecf20Sopenharmony_ci "ilt", 74478c2ecf20Sopenharmony_ci qed_dbg_ilt_get_dump_buf_size, 74488c2ecf20Sopenharmony_ci qed_dbg_ilt_dump, NULL, NULL},}; 74498c2ecf20Sopenharmony_ci 74508c2ecf20Sopenharmony_cistatic void qed_dbg_print_feature(u8 *p_text_buf, u32 text_size) 74518c2ecf20Sopenharmony_ci{ 74528c2ecf20Sopenharmony_ci u32 i, precision = 80; 74538c2ecf20Sopenharmony_ci 74548c2ecf20Sopenharmony_ci if (!p_text_buf) 74558c2ecf20Sopenharmony_ci return; 74568c2ecf20Sopenharmony_ci 74578c2ecf20Sopenharmony_ci pr_notice("\n%.*s", precision, p_text_buf); 74588c2ecf20Sopenharmony_ci for (i = precision; i < text_size; i += precision) 74598c2ecf20Sopenharmony_ci pr_cont("%.*s", precision, p_text_buf + i); 74608c2ecf20Sopenharmony_ci pr_cont("\n"); 74618c2ecf20Sopenharmony_ci} 74628c2ecf20Sopenharmony_ci 74638c2ecf20Sopenharmony_ci#define QED_RESULTS_BUF_MIN_SIZE 16 74648c2ecf20Sopenharmony_ci/* Generic function for decoding debug feature info */ 74658c2ecf20Sopenharmony_cistatic enum dbg_status format_feature(struct qed_hwfn *p_hwfn, 74668c2ecf20Sopenharmony_ci enum qed_dbg_features feature_idx) 74678c2ecf20Sopenharmony_ci{ 74688c2ecf20Sopenharmony_ci struct qed_dbg_feature *feature = 74698c2ecf20Sopenharmony_ci &p_hwfn->cdev->dbg_features[feature_idx]; 74708c2ecf20Sopenharmony_ci u32 text_size_bytes, null_char_pos, i; 74718c2ecf20Sopenharmony_ci enum dbg_status rc; 74728c2ecf20Sopenharmony_ci char *text_buf; 74738c2ecf20Sopenharmony_ci 74748c2ecf20Sopenharmony_ci /* Check if feature supports formatting capability */ 74758c2ecf20Sopenharmony_ci if (!qed_features_lookup[feature_idx].results_buf_size) 74768c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 74778c2ecf20Sopenharmony_ci 74788c2ecf20Sopenharmony_ci /* Obtain size of formatted output */ 74798c2ecf20Sopenharmony_ci rc = qed_features_lookup[feature_idx]. 74808c2ecf20Sopenharmony_ci results_buf_size(p_hwfn, (u32 *)feature->dump_buf, 74818c2ecf20Sopenharmony_ci feature->dumped_dwords, &text_size_bytes); 74828c2ecf20Sopenharmony_ci if (rc != DBG_STATUS_OK) 74838c2ecf20Sopenharmony_ci return rc; 74848c2ecf20Sopenharmony_ci 74858c2ecf20Sopenharmony_ci /* Make sure that the allocated size is a multiple of dword (4 bytes) */ 74868c2ecf20Sopenharmony_ci null_char_pos = text_size_bytes - 1; 74878c2ecf20Sopenharmony_ci text_size_bytes = (text_size_bytes + 3) & ~0x3; 74888c2ecf20Sopenharmony_ci 74898c2ecf20Sopenharmony_ci if (text_size_bytes < QED_RESULTS_BUF_MIN_SIZE) { 74908c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn->cdev, 74918c2ecf20Sopenharmony_ci "formatted size of feature was too small %d. Aborting\n", 74928c2ecf20Sopenharmony_ci text_size_bytes); 74938c2ecf20Sopenharmony_ci return DBG_STATUS_INVALID_ARGS; 74948c2ecf20Sopenharmony_ci } 74958c2ecf20Sopenharmony_ci 74968c2ecf20Sopenharmony_ci /* Allocate temp text buf */ 74978c2ecf20Sopenharmony_ci text_buf = vzalloc(text_size_bytes); 74988c2ecf20Sopenharmony_ci if (!text_buf) 74998c2ecf20Sopenharmony_ci return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; 75008c2ecf20Sopenharmony_ci 75018c2ecf20Sopenharmony_ci /* Decode feature opcodes to string on temp buf */ 75028c2ecf20Sopenharmony_ci rc = qed_features_lookup[feature_idx]. 75038c2ecf20Sopenharmony_ci print_results(p_hwfn, (u32 *)feature->dump_buf, 75048c2ecf20Sopenharmony_ci feature->dumped_dwords, text_buf); 75058c2ecf20Sopenharmony_ci if (rc != DBG_STATUS_OK) { 75068c2ecf20Sopenharmony_ci vfree(text_buf); 75078c2ecf20Sopenharmony_ci return rc; 75088c2ecf20Sopenharmony_ci } 75098c2ecf20Sopenharmony_ci 75108c2ecf20Sopenharmony_ci /* Replace the original null character with a '\n' character. 75118c2ecf20Sopenharmony_ci * The bytes that were added as a result of the dword alignment are also 75128c2ecf20Sopenharmony_ci * padded with '\n' characters. 75138c2ecf20Sopenharmony_ci */ 75148c2ecf20Sopenharmony_ci for (i = null_char_pos; i < text_size_bytes; i++) 75158c2ecf20Sopenharmony_ci text_buf[i] = '\n'; 75168c2ecf20Sopenharmony_ci 75178c2ecf20Sopenharmony_ci /* Dump printable feature to log */ 75188c2ecf20Sopenharmony_ci if (p_hwfn->cdev->print_dbg_data) 75198c2ecf20Sopenharmony_ci qed_dbg_print_feature(text_buf, text_size_bytes); 75208c2ecf20Sopenharmony_ci 75218c2ecf20Sopenharmony_ci /* Just return the original binary buffer if requested */ 75228c2ecf20Sopenharmony_ci if (p_hwfn->cdev->dbg_bin_dump) { 75238c2ecf20Sopenharmony_ci vfree(text_buf); 75248c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 75258c2ecf20Sopenharmony_ci } 75268c2ecf20Sopenharmony_ci 75278c2ecf20Sopenharmony_ci /* Free the old dump_buf and point the dump_buf to the newly allocagted 75288c2ecf20Sopenharmony_ci * and formatted text buffer. 75298c2ecf20Sopenharmony_ci */ 75308c2ecf20Sopenharmony_ci vfree(feature->dump_buf); 75318c2ecf20Sopenharmony_ci feature->dump_buf = text_buf; 75328c2ecf20Sopenharmony_ci feature->buf_size = text_size_bytes; 75338c2ecf20Sopenharmony_ci feature->dumped_dwords = text_size_bytes / 4; 75348c2ecf20Sopenharmony_ci return rc; 75358c2ecf20Sopenharmony_ci} 75368c2ecf20Sopenharmony_ci 75378c2ecf20Sopenharmony_ci#define MAX_DBG_FEATURE_SIZE_DWORDS 0x3FFFFFFF 75388c2ecf20Sopenharmony_ci 75398c2ecf20Sopenharmony_ci/* Generic function for performing the dump of a debug feature. */ 75408c2ecf20Sopenharmony_cistatic enum dbg_status qed_dbg_dump(struct qed_hwfn *p_hwfn, 75418c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 75428c2ecf20Sopenharmony_ci enum qed_dbg_features feature_idx) 75438c2ecf20Sopenharmony_ci{ 75448c2ecf20Sopenharmony_ci struct qed_dbg_feature *feature = 75458c2ecf20Sopenharmony_ci &p_hwfn->cdev->dbg_features[feature_idx]; 75468c2ecf20Sopenharmony_ci u32 buf_size_dwords; 75478c2ecf20Sopenharmony_ci enum dbg_status rc; 75488c2ecf20Sopenharmony_ci 75498c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn->cdev, "Collecting a debug feature [\"%s\"]\n", 75508c2ecf20Sopenharmony_ci qed_features_lookup[feature_idx].name); 75518c2ecf20Sopenharmony_ci 75528c2ecf20Sopenharmony_ci /* Dump_buf was already allocated need to free (this can happen if dump 75538c2ecf20Sopenharmony_ci * was called but file was never read). 75548c2ecf20Sopenharmony_ci * We can't use the buffer as is since size may have changed. 75558c2ecf20Sopenharmony_ci */ 75568c2ecf20Sopenharmony_ci if (feature->dump_buf) { 75578c2ecf20Sopenharmony_ci vfree(feature->dump_buf); 75588c2ecf20Sopenharmony_ci feature->dump_buf = NULL; 75598c2ecf20Sopenharmony_ci } 75608c2ecf20Sopenharmony_ci 75618c2ecf20Sopenharmony_ci /* Get buffer size from hsi, allocate accordingly, and perform the 75628c2ecf20Sopenharmony_ci * dump. 75638c2ecf20Sopenharmony_ci */ 75648c2ecf20Sopenharmony_ci rc = qed_features_lookup[feature_idx].get_size(p_hwfn, p_ptt, 75658c2ecf20Sopenharmony_ci &buf_size_dwords); 75668c2ecf20Sopenharmony_ci if (rc != DBG_STATUS_OK && rc != DBG_STATUS_NVRAM_GET_IMAGE_FAILED) 75678c2ecf20Sopenharmony_ci return rc; 75688c2ecf20Sopenharmony_ci 75698c2ecf20Sopenharmony_ci if (buf_size_dwords > MAX_DBG_FEATURE_SIZE_DWORDS) { 75708c2ecf20Sopenharmony_ci feature->buf_size = 0; 75718c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn->cdev, 75728c2ecf20Sopenharmony_ci "Debug feature [\"%s\"] size (0x%x dwords) exceeds maximum size (0x%x dwords)\n", 75738c2ecf20Sopenharmony_ci qed_features_lookup[feature_idx].name, 75748c2ecf20Sopenharmony_ci buf_size_dwords, MAX_DBG_FEATURE_SIZE_DWORDS); 75758c2ecf20Sopenharmony_ci 75768c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 75778c2ecf20Sopenharmony_ci } 75788c2ecf20Sopenharmony_ci 75798c2ecf20Sopenharmony_ci feature->buf_size = buf_size_dwords * sizeof(u32); 75808c2ecf20Sopenharmony_ci feature->dump_buf = vmalloc(feature->buf_size); 75818c2ecf20Sopenharmony_ci if (!feature->dump_buf) 75828c2ecf20Sopenharmony_ci return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; 75838c2ecf20Sopenharmony_ci 75848c2ecf20Sopenharmony_ci rc = qed_features_lookup[feature_idx]. 75858c2ecf20Sopenharmony_ci perform_dump(p_hwfn, p_ptt, (u32 *)feature->dump_buf, 75868c2ecf20Sopenharmony_ci feature->buf_size / sizeof(u32), 75878c2ecf20Sopenharmony_ci &feature->dumped_dwords); 75888c2ecf20Sopenharmony_ci 75898c2ecf20Sopenharmony_ci /* If mcp is stuck we get DBG_STATUS_NVRAM_GET_IMAGE_FAILED error. 75908c2ecf20Sopenharmony_ci * In this case the buffer holds valid binary data, but we wont able 75918c2ecf20Sopenharmony_ci * to parse it (since parsing relies on data in NVRAM which is only 75928c2ecf20Sopenharmony_ci * accessible when MFW is responsive). skip the formatting but return 75938c2ecf20Sopenharmony_ci * success so that binary data is provided. 75948c2ecf20Sopenharmony_ci */ 75958c2ecf20Sopenharmony_ci if (rc == DBG_STATUS_NVRAM_GET_IMAGE_FAILED) 75968c2ecf20Sopenharmony_ci return DBG_STATUS_OK; 75978c2ecf20Sopenharmony_ci 75988c2ecf20Sopenharmony_ci if (rc != DBG_STATUS_OK) 75998c2ecf20Sopenharmony_ci return rc; 76008c2ecf20Sopenharmony_ci 76018c2ecf20Sopenharmony_ci /* Format output */ 76028c2ecf20Sopenharmony_ci rc = format_feature(p_hwfn, feature_idx); 76038c2ecf20Sopenharmony_ci return rc; 76048c2ecf20Sopenharmony_ci} 76058c2ecf20Sopenharmony_ci 76068c2ecf20Sopenharmony_ciint qed_dbg_grc(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes) 76078c2ecf20Sopenharmony_ci{ 76088c2ecf20Sopenharmony_ci return qed_dbg_feature(cdev, buffer, DBG_FEATURE_GRC, num_dumped_bytes); 76098c2ecf20Sopenharmony_ci} 76108c2ecf20Sopenharmony_ci 76118c2ecf20Sopenharmony_ciint qed_dbg_grc_size(struct qed_dev *cdev) 76128c2ecf20Sopenharmony_ci{ 76138c2ecf20Sopenharmony_ci return qed_dbg_feature_size(cdev, DBG_FEATURE_GRC); 76148c2ecf20Sopenharmony_ci} 76158c2ecf20Sopenharmony_ci 76168c2ecf20Sopenharmony_ciint qed_dbg_idle_chk(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes) 76178c2ecf20Sopenharmony_ci{ 76188c2ecf20Sopenharmony_ci return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IDLE_CHK, 76198c2ecf20Sopenharmony_ci num_dumped_bytes); 76208c2ecf20Sopenharmony_ci} 76218c2ecf20Sopenharmony_ci 76228c2ecf20Sopenharmony_ciint qed_dbg_idle_chk_size(struct qed_dev *cdev) 76238c2ecf20Sopenharmony_ci{ 76248c2ecf20Sopenharmony_ci return qed_dbg_feature_size(cdev, DBG_FEATURE_IDLE_CHK); 76258c2ecf20Sopenharmony_ci} 76268c2ecf20Sopenharmony_ci 76278c2ecf20Sopenharmony_ciint qed_dbg_reg_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes) 76288c2ecf20Sopenharmony_ci{ 76298c2ecf20Sopenharmony_ci return qed_dbg_feature(cdev, buffer, DBG_FEATURE_REG_FIFO, 76308c2ecf20Sopenharmony_ci num_dumped_bytes); 76318c2ecf20Sopenharmony_ci} 76328c2ecf20Sopenharmony_ci 76338c2ecf20Sopenharmony_ciint qed_dbg_reg_fifo_size(struct qed_dev *cdev) 76348c2ecf20Sopenharmony_ci{ 76358c2ecf20Sopenharmony_ci return qed_dbg_feature_size(cdev, DBG_FEATURE_REG_FIFO); 76368c2ecf20Sopenharmony_ci} 76378c2ecf20Sopenharmony_ci 76388c2ecf20Sopenharmony_ciint qed_dbg_igu_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes) 76398c2ecf20Sopenharmony_ci{ 76408c2ecf20Sopenharmony_ci return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IGU_FIFO, 76418c2ecf20Sopenharmony_ci num_dumped_bytes); 76428c2ecf20Sopenharmony_ci} 76438c2ecf20Sopenharmony_ci 76448c2ecf20Sopenharmony_ciint qed_dbg_igu_fifo_size(struct qed_dev *cdev) 76458c2ecf20Sopenharmony_ci{ 76468c2ecf20Sopenharmony_ci return qed_dbg_feature_size(cdev, DBG_FEATURE_IGU_FIFO); 76478c2ecf20Sopenharmony_ci} 76488c2ecf20Sopenharmony_ci 76498c2ecf20Sopenharmony_cistatic int qed_dbg_nvm_image_length(struct qed_hwfn *p_hwfn, 76508c2ecf20Sopenharmony_ci enum qed_nvm_images image_id, u32 *length) 76518c2ecf20Sopenharmony_ci{ 76528c2ecf20Sopenharmony_ci struct qed_nvm_image_att image_att; 76538c2ecf20Sopenharmony_ci int rc; 76548c2ecf20Sopenharmony_ci 76558c2ecf20Sopenharmony_ci *length = 0; 76568c2ecf20Sopenharmony_ci rc = qed_mcp_get_nvm_image_att(p_hwfn, image_id, &image_att); 76578c2ecf20Sopenharmony_ci if (rc) 76588c2ecf20Sopenharmony_ci return rc; 76598c2ecf20Sopenharmony_ci 76608c2ecf20Sopenharmony_ci *length = image_att.length; 76618c2ecf20Sopenharmony_ci 76628c2ecf20Sopenharmony_ci return rc; 76638c2ecf20Sopenharmony_ci} 76648c2ecf20Sopenharmony_ci 76658c2ecf20Sopenharmony_cistatic int qed_dbg_nvm_image(struct qed_dev *cdev, void *buffer, 76668c2ecf20Sopenharmony_ci u32 *num_dumped_bytes, 76678c2ecf20Sopenharmony_ci enum qed_nvm_images image_id) 76688c2ecf20Sopenharmony_ci{ 76698c2ecf20Sopenharmony_ci struct qed_hwfn *p_hwfn = 76708c2ecf20Sopenharmony_ci &cdev->hwfns[cdev->engine_for_debug]; 76718c2ecf20Sopenharmony_ci u32 len_rounded; 76728c2ecf20Sopenharmony_ci int rc; 76738c2ecf20Sopenharmony_ci 76748c2ecf20Sopenharmony_ci *num_dumped_bytes = 0; 76758c2ecf20Sopenharmony_ci rc = qed_dbg_nvm_image_length(p_hwfn, image_id, &len_rounded); 76768c2ecf20Sopenharmony_ci if (rc) 76778c2ecf20Sopenharmony_ci return rc; 76788c2ecf20Sopenharmony_ci 76798c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn->cdev, 76808c2ecf20Sopenharmony_ci "Collecting a debug feature [\"nvram image %d\"]\n", 76818c2ecf20Sopenharmony_ci image_id); 76828c2ecf20Sopenharmony_ci 76838c2ecf20Sopenharmony_ci len_rounded = roundup(len_rounded, sizeof(u32)); 76848c2ecf20Sopenharmony_ci rc = qed_mcp_get_nvm_image(p_hwfn, image_id, buffer, len_rounded); 76858c2ecf20Sopenharmony_ci if (rc) 76868c2ecf20Sopenharmony_ci return rc; 76878c2ecf20Sopenharmony_ci 76888c2ecf20Sopenharmony_ci /* QED_NVM_IMAGE_NVM_META image is not swapped like other images */ 76898c2ecf20Sopenharmony_ci if (image_id != QED_NVM_IMAGE_NVM_META) 76908c2ecf20Sopenharmony_ci cpu_to_be32_array((__force __be32 *)buffer, 76918c2ecf20Sopenharmony_ci (const u32 *)buffer, 76928c2ecf20Sopenharmony_ci len_rounded / sizeof(u32)); 76938c2ecf20Sopenharmony_ci 76948c2ecf20Sopenharmony_ci *num_dumped_bytes = len_rounded; 76958c2ecf20Sopenharmony_ci 76968c2ecf20Sopenharmony_ci return rc; 76978c2ecf20Sopenharmony_ci} 76988c2ecf20Sopenharmony_ci 76998c2ecf20Sopenharmony_ciint qed_dbg_protection_override(struct qed_dev *cdev, void *buffer, 77008c2ecf20Sopenharmony_ci u32 *num_dumped_bytes) 77018c2ecf20Sopenharmony_ci{ 77028c2ecf20Sopenharmony_ci return qed_dbg_feature(cdev, buffer, DBG_FEATURE_PROTECTION_OVERRIDE, 77038c2ecf20Sopenharmony_ci num_dumped_bytes); 77048c2ecf20Sopenharmony_ci} 77058c2ecf20Sopenharmony_ci 77068c2ecf20Sopenharmony_ciint qed_dbg_protection_override_size(struct qed_dev *cdev) 77078c2ecf20Sopenharmony_ci{ 77088c2ecf20Sopenharmony_ci return qed_dbg_feature_size(cdev, DBG_FEATURE_PROTECTION_OVERRIDE); 77098c2ecf20Sopenharmony_ci} 77108c2ecf20Sopenharmony_ci 77118c2ecf20Sopenharmony_ciint qed_dbg_fw_asserts(struct qed_dev *cdev, void *buffer, 77128c2ecf20Sopenharmony_ci u32 *num_dumped_bytes) 77138c2ecf20Sopenharmony_ci{ 77148c2ecf20Sopenharmony_ci return qed_dbg_feature(cdev, buffer, DBG_FEATURE_FW_ASSERTS, 77158c2ecf20Sopenharmony_ci num_dumped_bytes); 77168c2ecf20Sopenharmony_ci} 77178c2ecf20Sopenharmony_ci 77188c2ecf20Sopenharmony_ciint qed_dbg_fw_asserts_size(struct qed_dev *cdev) 77198c2ecf20Sopenharmony_ci{ 77208c2ecf20Sopenharmony_ci return qed_dbg_feature_size(cdev, DBG_FEATURE_FW_ASSERTS); 77218c2ecf20Sopenharmony_ci} 77228c2ecf20Sopenharmony_ci 77238c2ecf20Sopenharmony_ciint qed_dbg_ilt(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes) 77248c2ecf20Sopenharmony_ci{ 77258c2ecf20Sopenharmony_ci return qed_dbg_feature(cdev, buffer, DBG_FEATURE_ILT, num_dumped_bytes); 77268c2ecf20Sopenharmony_ci} 77278c2ecf20Sopenharmony_ci 77288c2ecf20Sopenharmony_ciint qed_dbg_ilt_size(struct qed_dev *cdev) 77298c2ecf20Sopenharmony_ci{ 77308c2ecf20Sopenharmony_ci return qed_dbg_feature_size(cdev, DBG_FEATURE_ILT); 77318c2ecf20Sopenharmony_ci} 77328c2ecf20Sopenharmony_ci 77338c2ecf20Sopenharmony_ciint qed_dbg_mcp_trace(struct qed_dev *cdev, void *buffer, 77348c2ecf20Sopenharmony_ci u32 *num_dumped_bytes) 77358c2ecf20Sopenharmony_ci{ 77368c2ecf20Sopenharmony_ci return qed_dbg_feature(cdev, buffer, DBG_FEATURE_MCP_TRACE, 77378c2ecf20Sopenharmony_ci num_dumped_bytes); 77388c2ecf20Sopenharmony_ci} 77398c2ecf20Sopenharmony_ci 77408c2ecf20Sopenharmony_ciint qed_dbg_mcp_trace_size(struct qed_dev *cdev) 77418c2ecf20Sopenharmony_ci{ 77428c2ecf20Sopenharmony_ci return qed_dbg_feature_size(cdev, DBG_FEATURE_MCP_TRACE); 77438c2ecf20Sopenharmony_ci} 77448c2ecf20Sopenharmony_ci 77458c2ecf20Sopenharmony_ci/* Defines the amount of bytes allocated for recording the length of debugfs 77468c2ecf20Sopenharmony_ci * feature buffer. 77478c2ecf20Sopenharmony_ci */ 77488c2ecf20Sopenharmony_ci#define REGDUMP_HEADER_SIZE sizeof(u32) 77498c2ecf20Sopenharmony_ci#define REGDUMP_HEADER_SIZE_SHIFT 0 77508c2ecf20Sopenharmony_ci#define REGDUMP_HEADER_SIZE_MASK 0xffffff 77518c2ecf20Sopenharmony_ci#define REGDUMP_HEADER_FEATURE_SHIFT 24 77528c2ecf20Sopenharmony_ci#define REGDUMP_HEADER_FEATURE_MASK 0x1f 77538c2ecf20Sopenharmony_ci#define REGDUMP_HEADER_BIN_DUMP_SHIFT 29 77548c2ecf20Sopenharmony_ci#define REGDUMP_HEADER_BIN_DUMP_MASK 0x1 77558c2ecf20Sopenharmony_ci#define REGDUMP_HEADER_OMIT_ENGINE_SHIFT 30 77568c2ecf20Sopenharmony_ci#define REGDUMP_HEADER_OMIT_ENGINE_MASK 0x1 77578c2ecf20Sopenharmony_ci#define REGDUMP_HEADER_ENGINE_SHIFT 31 77588c2ecf20Sopenharmony_ci#define REGDUMP_HEADER_ENGINE_MASK 0x1 77598c2ecf20Sopenharmony_ci#define REGDUMP_MAX_SIZE 0x1000000 77608c2ecf20Sopenharmony_ci#define ILT_DUMP_MAX_SIZE (1024 * 1024 * 15) 77618c2ecf20Sopenharmony_ci 77628c2ecf20Sopenharmony_cienum debug_print_features { 77638c2ecf20Sopenharmony_ci OLD_MODE = 0, 77648c2ecf20Sopenharmony_ci IDLE_CHK = 1, 77658c2ecf20Sopenharmony_ci GRC_DUMP = 2, 77668c2ecf20Sopenharmony_ci MCP_TRACE = 3, 77678c2ecf20Sopenharmony_ci REG_FIFO = 4, 77688c2ecf20Sopenharmony_ci PROTECTION_OVERRIDE = 5, 77698c2ecf20Sopenharmony_ci IGU_FIFO = 6, 77708c2ecf20Sopenharmony_ci PHY = 7, 77718c2ecf20Sopenharmony_ci FW_ASSERTS = 8, 77728c2ecf20Sopenharmony_ci NVM_CFG1 = 9, 77738c2ecf20Sopenharmony_ci DEFAULT_CFG = 10, 77748c2ecf20Sopenharmony_ci NVM_META = 11, 77758c2ecf20Sopenharmony_ci MDUMP = 12, 77768c2ecf20Sopenharmony_ci ILT_DUMP = 13, 77778c2ecf20Sopenharmony_ci}; 77788c2ecf20Sopenharmony_ci 77798c2ecf20Sopenharmony_cistatic u32 qed_calc_regdump_header(struct qed_dev *cdev, 77808c2ecf20Sopenharmony_ci enum debug_print_features feature, 77818c2ecf20Sopenharmony_ci int engine, u32 feature_size, u8 omit_engine) 77828c2ecf20Sopenharmony_ci{ 77838c2ecf20Sopenharmony_ci u32 res = 0; 77848c2ecf20Sopenharmony_ci 77858c2ecf20Sopenharmony_ci SET_FIELD(res, REGDUMP_HEADER_SIZE, feature_size); 77868c2ecf20Sopenharmony_ci if (res != feature_size) 77878c2ecf20Sopenharmony_ci DP_NOTICE(cdev, 77888c2ecf20Sopenharmony_ci "Feature %d is too large (size 0x%x) and will corrupt the dump\n", 77898c2ecf20Sopenharmony_ci feature, feature_size); 77908c2ecf20Sopenharmony_ci 77918c2ecf20Sopenharmony_ci SET_FIELD(res, REGDUMP_HEADER_FEATURE, feature); 77928c2ecf20Sopenharmony_ci SET_FIELD(res, REGDUMP_HEADER_BIN_DUMP, 1); 77938c2ecf20Sopenharmony_ci SET_FIELD(res, REGDUMP_HEADER_OMIT_ENGINE, omit_engine); 77948c2ecf20Sopenharmony_ci SET_FIELD(res, REGDUMP_HEADER_ENGINE, engine); 77958c2ecf20Sopenharmony_ci 77968c2ecf20Sopenharmony_ci return res; 77978c2ecf20Sopenharmony_ci} 77988c2ecf20Sopenharmony_ci 77998c2ecf20Sopenharmony_ciint qed_dbg_all_data(struct qed_dev *cdev, void *buffer) 78008c2ecf20Sopenharmony_ci{ 78018c2ecf20Sopenharmony_ci u8 cur_engine, omit_engine = 0, org_engine; 78028c2ecf20Sopenharmony_ci struct qed_hwfn *p_hwfn = 78038c2ecf20Sopenharmony_ci &cdev->hwfns[cdev->engine_for_debug]; 78048c2ecf20Sopenharmony_ci struct dbg_tools_data *dev_data = &p_hwfn->dbg_info; 78058c2ecf20Sopenharmony_ci int grc_params[MAX_DBG_GRC_PARAMS], i; 78068c2ecf20Sopenharmony_ci u32 offset = 0, feature_size; 78078c2ecf20Sopenharmony_ci int rc; 78088c2ecf20Sopenharmony_ci 78098c2ecf20Sopenharmony_ci for (i = 0; i < MAX_DBG_GRC_PARAMS; i++) 78108c2ecf20Sopenharmony_ci grc_params[i] = dev_data->grc.param_val[i]; 78118c2ecf20Sopenharmony_ci 78128c2ecf20Sopenharmony_ci if (!QED_IS_CMT(cdev)) 78138c2ecf20Sopenharmony_ci omit_engine = 1; 78148c2ecf20Sopenharmony_ci 78158c2ecf20Sopenharmony_ci mutex_lock(&qed_dbg_lock); 78168c2ecf20Sopenharmony_ci cdev->dbg_bin_dump = true; 78178c2ecf20Sopenharmony_ci 78188c2ecf20Sopenharmony_ci org_engine = qed_get_debug_engine(cdev); 78198c2ecf20Sopenharmony_ci for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) { 78208c2ecf20Sopenharmony_ci /* Collect idle_chks and grcDump for each hw function */ 78218c2ecf20Sopenharmony_ci DP_VERBOSE(cdev, QED_MSG_DEBUG, 78228c2ecf20Sopenharmony_ci "obtaining idle_chk and grcdump for current engine\n"); 78238c2ecf20Sopenharmony_ci qed_set_debug_engine(cdev, cur_engine); 78248c2ecf20Sopenharmony_ci 78258c2ecf20Sopenharmony_ci /* First idle_chk */ 78268c2ecf20Sopenharmony_ci rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset + 78278c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE, &feature_size); 78288c2ecf20Sopenharmony_ci if (!rc) { 78298c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 78308c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, IDLE_CHK, cur_engine, 78318c2ecf20Sopenharmony_ci feature_size, omit_engine); 78328c2ecf20Sopenharmony_ci offset += (feature_size + REGDUMP_HEADER_SIZE); 78338c2ecf20Sopenharmony_ci } else { 78348c2ecf20Sopenharmony_ci DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc); 78358c2ecf20Sopenharmony_ci } 78368c2ecf20Sopenharmony_ci 78378c2ecf20Sopenharmony_ci /* Second idle_chk */ 78388c2ecf20Sopenharmony_ci rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset + 78398c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE, &feature_size); 78408c2ecf20Sopenharmony_ci if (!rc) { 78418c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 78428c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, IDLE_CHK, cur_engine, 78438c2ecf20Sopenharmony_ci feature_size, omit_engine); 78448c2ecf20Sopenharmony_ci offset += (feature_size + REGDUMP_HEADER_SIZE); 78458c2ecf20Sopenharmony_ci } else { 78468c2ecf20Sopenharmony_ci DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc); 78478c2ecf20Sopenharmony_ci } 78488c2ecf20Sopenharmony_ci 78498c2ecf20Sopenharmony_ci /* reg_fifo dump */ 78508c2ecf20Sopenharmony_ci rc = qed_dbg_reg_fifo(cdev, (u8 *)buffer + offset + 78518c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE, &feature_size); 78528c2ecf20Sopenharmony_ci if (!rc) { 78538c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 78548c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, REG_FIFO, cur_engine, 78558c2ecf20Sopenharmony_ci feature_size, omit_engine); 78568c2ecf20Sopenharmony_ci offset += (feature_size + REGDUMP_HEADER_SIZE); 78578c2ecf20Sopenharmony_ci } else { 78588c2ecf20Sopenharmony_ci DP_ERR(cdev, "qed_dbg_reg_fifo failed. rc = %d\n", rc); 78598c2ecf20Sopenharmony_ci } 78608c2ecf20Sopenharmony_ci 78618c2ecf20Sopenharmony_ci /* igu_fifo dump */ 78628c2ecf20Sopenharmony_ci rc = qed_dbg_igu_fifo(cdev, (u8 *)buffer + offset + 78638c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE, &feature_size); 78648c2ecf20Sopenharmony_ci if (!rc) { 78658c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 78668c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, IGU_FIFO, cur_engine, 78678c2ecf20Sopenharmony_ci feature_size, omit_engine); 78688c2ecf20Sopenharmony_ci offset += (feature_size + REGDUMP_HEADER_SIZE); 78698c2ecf20Sopenharmony_ci } else { 78708c2ecf20Sopenharmony_ci DP_ERR(cdev, "qed_dbg_igu_fifo failed. rc = %d", rc); 78718c2ecf20Sopenharmony_ci } 78728c2ecf20Sopenharmony_ci 78738c2ecf20Sopenharmony_ci /* protection_override dump */ 78748c2ecf20Sopenharmony_ci rc = qed_dbg_protection_override(cdev, (u8 *)buffer + offset + 78758c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE, 78768c2ecf20Sopenharmony_ci &feature_size); 78778c2ecf20Sopenharmony_ci if (!rc) { 78788c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 78798c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, PROTECTION_OVERRIDE, 78808c2ecf20Sopenharmony_ci cur_engine, 78818c2ecf20Sopenharmony_ci feature_size, omit_engine); 78828c2ecf20Sopenharmony_ci offset += (feature_size + REGDUMP_HEADER_SIZE); 78838c2ecf20Sopenharmony_ci } else { 78848c2ecf20Sopenharmony_ci DP_ERR(cdev, 78858c2ecf20Sopenharmony_ci "qed_dbg_protection_override failed. rc = %d\n", 78868c2ecf20Sopenharmony_ci rc); 78878c2ecf20Sopenharmony_ci } 78888c2ecf20Sopenharmony_ci 78898c2ecf20Sopenharmony_ci /* fw_asserts dump */ 78908c2ecf20Sopenharmony_ci rc = qed_dbg_fw_asserts(cdev, (u8 *)buffer + offset + 78918c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE, &feature_size); 78928c2ecf20Sopenharmony_ci if (!rc) { 78938c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 78948c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, FW_ASSERTS, 78958c2ecf20Sopenharmony_ci cur_engine, feature_size, 78968c2ecf20Sopenharmony_ci omit_engine); 78978c2ecf20Sopenharmony_ci offset += (feature_size + REGDUMP_HEADER_SIZE); 78988c2ecf20Sopenharmony_ci } else { 78998c2ecf20Sopenharmony_ci DP_ERR(cdev, "qed_dbg_fw_asserts failed. rc = %d\n", 79008c2ecf20Sopenharmony_ci rc); 79018c2ecf20Sopenharmony_ci } 79028c2ecf20Sopenharmony_ci 79038c2ecf20Sopenharmony_ci feature_size = qed_dbg_ilt_size(cdev); 79048c2ecf20Sopenharmony_ci if (!cdev->disable_ilt_dump && 79058c2ecf20Sopenharmony_ci feature_size < ILT_DUMP_MAX_SIZE) { 79068c2ecf20Sopenharmony_ci rc = qed_dbg_ilt(cdev, (u8 *)buffer + offset + 79078c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE, &feature_size); 79088c2ecf20Sopenharmony_ci if (!rc) { 79098c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 79108c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, ILT_DUMP, 79118c2ecf20Sopenharmony_ci cur_engine, 79128c2ecf20Sopenharmony_ci feature_size, 79138c2ecf20Sopenharmony_ci omit_engine); 79148c2ecf20Sopenharmony_ci offset += feature_size + REGDUMP_HEADER_SIZE; 79158c2ecf20Sopenharmony_ci } else { 79168c2ecf20Sopenharmony_ci DP_ERR(cdev, "qed_dbg_ilt failed. rc = %d\n", 79178c2ecf20Sopenharmony_ci rc); 79188c2ecf20Sopenharmony_ci } 79198c2ecf20Sopenharmony_ci } 79208c2ecf20Sopenharmony_ci 79218c2ecf20Sopenharmony_ci /* GRC dump - must be last because when mcp stuck it will 79228c2ecf20Sopenharmony_ci * clutter idle_chk, reg_fifo, ... 79238c2ecf20Sopenharmony_ci */ 79248c2ecf20Sopenharmony_ci for (i = 0; i < MAX_DBG_GRC_PARAMS; i++) 79258c2ecf20Sopenharmony_ci dev_data->grc.param_val[i] = grc_params[i]; 79268c2ecf20Sopenharmony_ci 79278c2ecf20Sopenharmony_ci rc = qed_dbg_grc(cdev, (u8 *)buffer + offset + 79288c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE, &feature_size); 79298c2ecf20Sopenharmony_ci if (!rc) { 79308c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 79318c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, GRC_DUMP, 79328c2ecf20Sopenharmony_ci cur_engine, 79338c2ecf20Sopenharmony_ci feature_size, omit_engine); 79348c2ecf20Sopenharmony_ci offset += (feature_size + REGDUMP_HEADER_SIZE); 79358c2ecf20Sopenharmony_ci } else { 79368c2ecf20Sopenharmony_ci DP_ERR(cdev, "qed_dbg_grc failed. rc = %d", rc); 79378c2ecf20Sopenharmony_ci } 79388c2ecf20Sopenharmony_ci } 79398c2ecf20Sopenharmony_ci 79408c2ecf20Sopenharmony_ci qed_set_debug_engine(cdev, org_engine); 79418c2ecf20Sopenharmony_ci 79428c2ecf20Sopenharmony_ci /* mcp_trace */ 79438c2ecf20Sopenharmony_ci rc = qed_dbg_mcp_trace(cdev, (u8 *)buffer + offset + 79448c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE, &feature_size); 79458c2ecf20Sopenharmony_ci if (!rc) { 79468c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 79478c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, MCP_TRACE, cur_engine, 79488c2ecf20Sopenharmony_ci feature_size, omit_engine); 79498c2ecf20Sopenharmony_ci offset += (feature_size + REGDUMP_HEADER_SIZE); 79508c2ecf20Sopenharmony_ci } else { 79518c2ecf20Sopenharmony_ci DP_ERR(cdev, "qed_dbg_mcp_trace failed. rc = %d\n", rc); 79528c2ecf20Sopenharmony_ci } 79538c2ecf20Sopenharmony_ci 79548c2ecf20Sopenharmony_ci /* Re-populate nvm attribute info */ 79558c2ecf20Sopenharmony_ci qed_mcp_nvm_info_free(p_hwfn); 79568c2ecf20Sopenharmony_ci qed_mcp_nvm_info_populate(p_hwfn); 79578c2ecf20Sopenharmony_ci 79588c2ecf20Sopenharmony_ci /* nvm cfg1 */ 79598c2ecf20Sopenharmony_ci rc = qed_dbg_nvm_image(cdev, 79608c2ecf20Sopenharmony_ci (u8 *)buffer + offset + 79618c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE, &feature_size, 79628c2ecf20Sopenharmony_ci QED_NVM_IMAGE_NVM_CFG1); 79638c2ecf20Sopenharmony_ci if (!rc) { 79648c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 79658c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, NVM_CFG1, cur_engine, 79668c2ecf20Sopenharmony_ci feature_size, omit_engine); 79678c2ecf20Sopenharmony_ci offset += (feature_size + REGDUMP_HEADER_SIZE); 79688c2ecf20Sopenharmony_ci } else if (rc != -ENOENT) { 79698c2ecf20Sopenharmony_ci DP_ERR(cdev, 79708c2ecf20Sopenharmony_ci "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n", 79718c2ecf20Sopenharmony_ci QED_NVM_IMAGE_NVM_CFG1, "QED_NVM_IMAGE_NVM_CFG1", rc); 79728c2ecf20Sopenharmony_ci } 79738c2ecf20Sopenharmony_ci 79748c2ecf20Sopenharmony_ci /* nvm default */ 79758c2ecf20Sopenharmony_ci rc = qed_dbg_nvm_image(cdev, 79768c2ecf20Sopenharmony_ci (u8 *)buffer + offset + REGDUMP_HEADER_SIZE, 79778c2ecf20Sopenharmony_ci &feature_size, QED_NVM_IMAGE_DEFAULT_CFG); 79788c2ecf20Sopenharmony_ci if (!rc) { 79798c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 79808c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, DEFAULT_CFG, cur_engine, 79818c2ecf20Sopenharmony_ci feature_size, omit_engine); 79828c2ecf20Sopenharmony_ci offset += (feature_size + REGDUMP_HEADER_SIZE); 79838c2ecf20Sopenharmony_ci } else if (rc != -ENOENT) { 79848c2ecf20Sopenharmony_ci DP_ERR(cdev, 79858c2ecf20Sopenharmony_ci "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n", 79868c2ecf20Sopenharmony_ci QED_NVM_IMAGE_DEFAULT_CFG, "QED_NVM_IMAGE_DEFAULT_CFG", 79878c2ecf20Sopenharmony_ci rc); 79888c2ecf20Sopenharmony_ci } 79898c2ecf20Sopenharmony_ci 79908c2ecf20Sopenharmony_ci /* nvm meta */ 79918c2ecf20Sopenharmony_ci rc = qed_dbg_nvm_image(cdev, 79928c2ecf20Sopenharmony_ci (u8 *)buffer + offset + REGDUMP_HEADER_SIZE, 79938c2ecf20Sopenharmony_ci &feature_size, QED_NVM_IMAGE_NVM_META); 79948c2ecf20Sopenharmony_ci if (!rc) { 79958c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 79968c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, NVM_META, cur_engine, 79978c2ecf20Sopenharmony_ci feature_size, omit_engine); 79988c2ecf20Sopenharmony_ci offset += (feature_size + REGDUMP_HEADER_SIZE); 79998c2ecf20Sopenharmony_ci } else if (rc != -ENOENT) { 80008c2ecf20Sopenharmony_ci DP_ERR(cdev, 80018c2ecf20Sopenharmony_ci "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n", 80028c2ecf20Sopenharmony_ci QED_NVM_IMAGE_NVM_META, "QED_NVM_IMAGE_NVM_META", rc); 80038c2ecf20Sopenharmony_ci } 80048c2ecf20Sopenharmony_ci 80058c2ecf20Sopenharmony_ci /* nvm mdump */ 80068c2ecf20Sopenharmony_ci rc = qed_dbg_nvm_image(cdev, (u8 *)buffer + offset + 80078c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE, &feature_size, 80088c2ecf20Sopenharmony_ci QED_NVM_IMAGE_MDUMP); 80098c2ecf20Sopenharmony_ci if (!rc) { 80108c2ecf20Sopenharmony_ci *(u32 *)((u8 *)buffer + offset) = 80118c2ecf20Sopenharmony_ci qed_calc_regdump_header(cdev, MDUMP, cur_engine, 80128c2ecf20Sopenharmony_ci feature_size, omit_engine); 80138c2ecf20Sopenharmony_ci offset += (feature_size + REGDUMP_HEADER_SIZE); 80148c2ecf20Sopenharmony_ci } else if (rc != -ENOENT) { 80158c2ecf20Sopenharmony_ci DP_ERR(cdev, 80168c2ecf20Sopenharmony_ci "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n", 80178c2ecf20Sopenharmony_ci QED_NVM_IMAGE_MDUMP, "QED_NVM_IMAGE_MDUMP", rc); 80188c2ecf20Sopenharmony_ci } 80198c2ecf20Sopenharmony_ci 80208c2ecf20Sopenharmony_ci cdev->dbg_bin_dump = false; 80218c2ecf20Sopenharmony_ci mutex_unlock(&qed_dbg_lock); 80228c2ecf20Sopenharmony_ci 80238c2ecf20Sopenharmony_ci return 0; 80248c2ecf20Sopenharmony_ci} 80258c2ecf20Sopenharmony_ci 80268c2ecf20Sopenharmony_ciint qed_dbg_all_data_size(struct qed_dev *cdev) 80278c2ecf20Sopenharmony_ci{ 80288c2ecf20Sopenharmony_ci struct qed_hwfn *p_hwfn = 80298c2ecf20Sopenharmony_ci &cdev->hwfns[cdev->engine_for_debug]; 80308c2ecf20Sopenharmony_ci u32 regs_len = 0, image_len = 0, ilt_len = 0, total_ilt_len = 0; 80318c2ecf20Sopenharmony_ci u8 cur_engine, org_engine; 80328c2ecf20Sopenharmony_ci 80338c2ecf20Sopenharmony_ci cdev->disable_ilt_dump = false; 80348c2ecf20Sopenharmony_ci org_engine = qed_get_debug_engine(cdev); 80358c2ecf20Sopenharmony_ci for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) { 80368c2ecf20Sopenharmony_ci /* Engine specific */ 80378c2ecf20Sopenharmony_ci DP_VERBOSE(cdev, QED_MSG_DEBUG, 80388c2ecf20Sopenharmony_ci "calculating idle_chk and grcdump register length for current engine\n"); 80398c2ecf20Sopenharmony_ci qed_set_debug_engine(cdev, cur_engine); 80408c2ecf20Sopenharmony_ci regs_len += REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) + 80418c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) + 80428c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE + qed_dbg_grc_size(cdev) + 80438c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE + qed_dbg_reg_fifo_size(cdev) + 80448c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE + qed_dbg_igu_fifo_size(cdev) + 80458c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE + 80468c2ecf20Sopenharmony_ci qed_dbg_protection_override_size(cdev) + 80478c2ecf20Sopenharmony_ci REGDUMP_HEADER_SIZE + qed_dbg_fw_asserts_size(cdev); 80488c2ecf20Sopenharmony_ci 80498c2ecf20Sopenharmony_ci ilt_len = REGDUMP_HEADER_SIZE + qed_dbg_ilt_size(cdev); 80508c2ecf20Sopenharmony_ci if (ilt_len < ILT_DUMP_MAX_SIZE) { 80518c2ecf20Sopenharmony_ci total_ilt_len += ilt_len; 80528c2ecf20Sopenharmony_ci regs_len += ilt_len; 80538c2ecf20Sopenharmony_ci } 80548c2ecf20Sopenharmony_ci } 80558c2ecf20Sopenharmony_ci 80568c2ecf20Sopenharmony_ci qed_set_debug_engine(cdev, org_engine); 80578c2ecf20Sopenharmony_ci 80588c2ecf20Sopenharmony_ci /* Engine common */ 80598c2ecf20Sopenharmony_ci regs_len += REGDUMP_HEADER_SIZE + qed_dbg_mcp_trace_size(cdev); 80608c2ecf20Sopenharmony_ci qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_CFG1, &image_len); 80618c2ecf20Sopenharmony_ci if (image_len) 80628c2ecf20Sopenharmony_ci regs_len += REGDUMP_HEADER_SIZE + image_len; 80638c2ecf20Sopenharmony_ci qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_DEFAULT_CFG, &image_len); 80648c2ecf20Sopenharmony_ci if (image_len) 80658c2ecf20Sopenharmony_ci regs_len += REGDUMP_HEADER_SIZE + image_len; 80668c2ecf20Sopenharmony_ci qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_META, &image_len); 80678c2ecf20Sopenharmony_ci if (image_len) 80688c2ecf20Sopenharmony_ci regs_len += REGDUMP_HEADER_SIZE + image_len; 80698c2ecf20Sopenharmony_ci qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_MDUMP, &image_len); 80708c2ecf20Sopenharmony_ci if (image_len) 80718c2ecf20Sopenharmony_ci regs_len += REGDUMP_HEADER_SIZE + image_len; 80728c2ecf20Sopenharmony_ci 80738c2ecf20Sopenharmony_ci if (regs_len > REGDUMP_MAX_SIZE) { 80748c2ecf20Sopenharmony_ci DP_VERBOSE(cdev, QED_MSG_DEBUG, 80758c2ecf20Sopenharmony_ci "Dump exceeds max size 0x%x, disable ILT dump\n", 80768c2ecf20Sopenharmony_ci REGDUMP_MAX_SIZE); 80778c2ecf20Sopenharmony_ci cdev->disable_ilt_dump = true; 80788c2ecf20Sopenharmony_ci regs_len -= total_ilt_len; 80798c2ecf20Sopenharmony_ci } 80808c2ecf20Sopenharmony_ci 80818c2ecf20Sopenharmony_ci return regs_len; 80828c2ecf20Sopenharmony_ci} 80838c2ecf20Sopenharmony_ci 80848c2ecf20Sopenharmony_ciint qed_dbg_feature(struct qed_dev *cdev, void *buffer, 80858c2ecf20Sopenharmony_ci enum qed_dbg_features feature, u32 *num_dumped_bytes) 80868c2ecf20Sopenharmony_ci{ 80878c2ecf20Sopenharmony_ci struct qed_hwfn *p_hwfn = 80888c2ecf20Sopenharmony_ci &cdev->hwfns[cdev->engine_for_debug]; 80898c2ecf20Sopenharmony_ci struct qed_dbg_feature *qed_feature = 80908c2ecf20Sopenharmony_ci &cdev->dbg_features[feature]; 80918c2ecf20Sopenharmony_ci enum dbg_status dbg_rc; 80928c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt; 80938c2ecf20Sopenharmony_ci int rc = 0; 80948c2ecf20Sopenharmony_ci 80958c2ecf20Sopenharmony_ci /* Acquire ptt */ 80968c2ecf20Sopenharmony_ci p_ptt = qed_ptt_acquire(p_hwfn); 80978c2ecf20Sopenharmony_ci if (!p_ptt) 80988c2ecf20Sopenharmony_ci return -EINVAL; 80998c2ecf20Sopenharmony_ci 81008c2ecf20Sopenharmony_ci /* Get dump */ 81018c2ecf20Sopenharmony_ci dbg_rc = qed_dbg_dump(p_hwfn, p_ptt, feature); 81028c2ecf20Sopenharmony_ci if (dbg_rc != DBG_STATUS_OK) { 81038c2ecf20Sopenharmony_ci DP_VERBOSE(cdev, QED_MSG_DEBUG, "%s\n", 81048c2ecf20Sopenharmony_ci qed_dbg_get_status_str(dbg_rc)); 81058c2ecf20Sopenharmony_ci *num_dumped_bytes = 0; 81068c2ecf20Sopenharmony_ci rc = -EINVAL; 81078c2ecf20Sopenharmony_ci goto out; 81088c2ecf20Sopenharmony_ci } 81098c2ecf20Sopenharmony_ci 81108c2ecf20Sopenharmony_ci DP_VERBOSE(cdev, QED_MSG_DEBUG, 81118c2ecf20Sopenharmony_ci "copying debugfs feature to external buffer\n"); 81128c2ecf20Sopenharmony_ci memcpy(buffer, qed_feature->dump_buf, qed_feature->buf_size); 81138c2ecf20Sopenharmony_ci *num_dumped_bytes = cdev->dbg_features[feature].dumped_dwords * 81148c2ecf20Sopenharmony_ci 4; 81158c2ecf20Sopenharmony_ci 81168c2ecf20Sopenharmony_ciout: 81178c2ecf20Sopenharmony_ci qed_ptt_release(p_hwfn, p_ptt); 81188c2ecf20Sopenharmony_ci return rc; 81198c2ecf20Sopenharmony_ci} 81208c2ecf20Sopenharmony_ci 81218c2ecf20Sopenharmony_ciint qed_dbg_feature_size(struct qed_dev *cdev, enum qed_dbg_features feature) 81228c2ecf20Sopenharmony_ci{ 81238c2ecf20Sopenharmony_ci struct qed_hwfn *p_hwfn = 81248c2ecf20Sopenharmony_ci &cdev->hwfns[cdev->engine_for_debug]; 81258c2ecf20Sopenharmony_ci struct qed_dbg_feature *qed_feature = &cdev->dbg_features[feature]; 81268c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn); 81278c2ecf20Sopenharmony_ci u32 buf_size_dwords; 81288c2ecf20Sopenharmony_ci enum dbg_status rc; 81298c2ecf20Sopenharmony_ci 81308c2ecf20Sopenharmony_ci if (!p_ptt) 81318c2ecf20Sopenharmony_ci return -EINVAL; 81328c2ecf20Sopenharmony_ci 81338c2ecf20Sopenharmony_ci rc = qed_features_lookup[feature].get_size(p_hwfn, p_ptt, 81348c2ecf20Sopenharmony_ci &buf_size_dwords); 81358c2ecf20Sopenharmony_ci if (rc != DBG_STATUS_OK) 81368c2ecf20Sopenharmony_ci buf_size_dwords = 0; 81378c2ecf20Sopenharmony_ci 81388c2ecf20Sopenharmony_ci /* Feature will not be dumped if it exceeds maximum size */ 81398c2ecf20Sopenharmony_ci if (buf_size_dwords > MAX_DBG_FEATURE_SIZE_DWORDS) 81408c2ecf20Sopenharmony_ci buf_size_dwords = 0; 81418c2ecf20Sopenharmony_ci 81428c2ecf20Sopenharmony_ci qed_ptt_release(p_hwfn, p_ptt); 81438c2ecf20Sopenharmony_ci qed_feature->buf_size = buf_size_dwords * sizeof(u32); 81448c2ecf20Sopenharmony_ci return qed_feature->buf_size; 81458c2ecf20Sopenharmony_ci} 81468c2ecf20Sopenharmony_ci 81478c2ecf20Sopenharmony_ciu8 qed_get_debug_engine(struct qed_dev *cdev) 81488c2ecf20Sopenharmony_ci{ 81498c2ecf20Sopenharmony_ci return cdev->engine_for_debug; 81508c2ecf20Sopenharmony_ci} 81518c2ecf20Sopenharmony_ci 81528c2ecf20Sopenharmony_civoid qed_set_debug_engine(struct qed_dev *cdev, int engine_number) 81538c2ecf20Sopenharmony_ci{ 81548c2ecf20Sopenharmony_ci DP_VERBOSE(cdev, QED_MSG_DEBUG, "set debug engine to %d\n", 81558c2ecf20Sopenharmony_ci engine_number); 81568c2ecf20Sopenharmony_ci cdev->engine_for_debug = engine_number; 81578c2ecf20Sopenharmony_ci} 81588c2ecf20Sopenharmony_ci 81598c2ecf20Sopenharmony_civoid qed_dbg_pf_init(struct qed_dev *cdev) 81608c2ecf20Sopenharmony_ci{ 81618c2ecf20Sopenharmony_ci const u8 *dbg_values = NULL; 81628c2ecf20Sopenharmony_ci int i; 81638c2ecf20Sopenharmony_ci 81648c2ecf20Sopenharmony_ci /* Debug values are after init values. 81658c2ecf20Sopenharmony_ci * The offset is the first dword of the file. 81668c2ecf20Sopenharmony_ci */ 81678c2ecf20Sopenharmony_ci dbg_values = cdev->firmware->data + *(u32 *)cdev->firmware->data; 81688c2ecf20Sopenharmony_ci 81698c2ecf20Sopenharmony_ci for_each_hwfn(cdev, i) { 81708c2ecf20Sopenharmony_ci qed_dbg_set_bin_ptr(&cdev->hwfns[i], dbg_values); 81718c2ecf20Sopenharmony_ci qed_dbg_user_set_bin_ptr(&cdev->hwfns[i], dbg_values); 81728c2ecf20Sopenharmony_ci } 81738c2ecf20Sopenharmony_ci 81748c2ecf20Sopenharmony_ci /* Set the hwfn to be 0 as default */ 81758c2ecf20Sopenharmony_ci cdev->engine_for_debug = 0; 81768c2ecf20Sopenharmony_ci} 81778c2ecf20Sopenharmony_ci 81788c2ecf20Sopenharmony_civoid qed_dbg_pf_exit(struct qed_dev *cdev) 81798c2ecf20Sopenharmony_ci{ 81808c2ecf20Sopenharmony_ci struct qed_dbg_feature *feature = NULL; 81818c2ecf20Sopenharmony_ci enum qed_dbg_features feature_idx; 81828c2ecf20Sopenharmony_ci 81838c2ecf20Sopenharmony_ci /* debug features' buffers may be allocated if debug feature was used 81848c2ecf20Sopenharmony_ci * but dump wasn't called 81858c2ecf20Sopenharmony_ci */ 81868c2ecf20Sopenharmony_ci for (feature_idx = 0; feature_idx < DBG_FEATURE_NUM; feature_idx++) { 81878c2ecf20Sopenharmony_ci feature = &cdev->dbg_features[feature_idx]; 81888c2ecf20Sopenharmony_ci if (feature->dump_buf) { 81898c2ecf20Sopenharmony_ci vfree(feature->dump_buf); 81908c2ecf20Sopenharmony_ci feature->dump_buf = NULL; 81918c2ecf20Sopenharmony_ci } 81928c2ecf20Sopenharmony_ci } 81938c2ecf20Sopenharmony_ci} 8194