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 = &regs[0].cond_reg;
35698c2ecf20Sopenharmony_ci	info_regs = &regs[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 = &regs[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, &param_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					      &param_name,
60168c2ecf20Sopenharmony_ci					      &param_str_val, &param_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					 &section_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					 &section_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				   &param_name, &param_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					 &section_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					 &section_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				   &param_name, &param_str_val, &param_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					 &section_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				   &param_name, &param_str_val, &param_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					 &section_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					 &section_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				   &param_name, &param_str_val, &param_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					 &section_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					 &section_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				   &param_name, &param_str_val, &param_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					 &section_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					 &section_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				   &param_name, &param_str_val, &param_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					 &section_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						 &section_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							   &param_name,
70348c2ecf20Sopenharmony_ci							   &param_str_val,
70358c2ecf20Sopenharmony_ci							   &param_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