cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qed_debug.c (245686B)


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