File Index
Files and directories
Sign in
FILE

qed_debug.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/qlogic/qed/qed_debug.c C
   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					    bool b_can_sleep)
1837{
1838	u32 ret_mcp_resp, ret_mcp_param, ret_txn_size;
1839	struct mcp_file_att file_att;
1840	int nvm_result;
1841
1842	/* Call NVRAM get file command */
1843	nvm_result = qed_mcp_nvm_rd_cmd(p_hwfn,
1844					p_ptt,
1845					DRV_MSG_CODE_NVM_GET_FILE_ATT,
1846					image_type,
1847					&ret_mcp_resp,
1848					&ret_mcp_param,
1849					&ret_txn_size,
1850					(u32 *)&file_att,
1851					b_can_sleep);
1852
1853	/* Check response */
1854	if (nvm_result || (ret_mcp_resp & FW_MSG_CODE_MASK) !=
1855	    FW_MSG_CODE_NVM_OK)
1856		return DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
1857
1858	/* Update return values */
1859	*nvram_offset_bytes = file_att.nvm_start_addr;
1860	*nvram_size_bytes = file_att.len;
1861
1862	DP_VERBOSE(p_hwfn,
1863		   QED_MSG_DEBUG,
1864		   "find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\n",
1865		   image_type, *nvram_offset_bytes, *nvram_size_bytes);
1866
1867	/* Check alignment */
1868	if (*nvram_size_bytes & 0x3)
1869		return DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE;
1870
1871	return DBG_STATUS_OK;
1872}
1873
1874/* Reads data from NVRAM */
1875static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
1876				      struct qed_ptt *p_ptt,
1877				      u32 nvram_offset_bytes,
1878				      u32 nvram_size_bytes,
1879				      u32 *ret_buf,
1880				      bool b_can_sleep)
1881{
1882	u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy;
1883	s32 bytes_left = nvram_size_bytes;
1884	u32 read_offset = 0, param = 0;
1885
1886	DP_VERBOSE(p_hwfn,
1887		   QED_MSG_DEBUG,
1888		   "nvram_read: reading image of size %d bytes from NVRAM\n",
1889		   nvram_size_bytes);
1890
1891	do {
1892		bytes_to_copy =
1893		    (bytes_left >
1894		     MCP_DRV_NVM_BUF_LEN) ? MCP_DRV_NVM_BUF_LEN : bytes_left;
1895
1896		/* Call NVRAM read command */
1897		SET_MFW_FIELD(param,
1898			      DRV_MB_PARAM_NVM_OFFSET,
1899			      nvram_offset_bytes + read_offset);
1900		SET_MFW_FIELD(param, DRV_MB_PARAM_NVM_LEN, bytes_to_copy);
1901		if (qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt,
1902				       DRV_MSG_CODE_NVM_READ_NVRAM, param,
1903				       &ret_mcp_resp,
1904				       &ret_mcp_param, &ret_read_size,
1905				       (u32 *)((u8 *)ret_buf + read_offset),
1906				       b_can_sleep))
1907			return DBG_STATUS_NVRAM_READ_FAILED;
1908
1909		/* Check response */
1910		if ((ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
1911			return DBG_STATUS_NVRAM_READ_FAILED;
1912
1913		/* Update read offset */
1914		read_offset += ret_read_size;
1915		bytes_left -= ret_read_size;
1916	} while (bytes_left > 0);
1917
1918	return DBG_STATUS_OK;
1919}
1920
1921/* Dumps GRC registers section header. Returns the dumped size in dwords.
1922 * the following parameters are dumped:
1923 * - count: no. of dumped entries
1924 * - split_type: split type
1925 * - split_id: split ID (dumped only if split_id != SPLIT_TYPE_NONE)
1926 * - reg_type_name: register type name (dumped only if reg_type_name != NULL)
1927 */
1928static u32 qed_grc_dump_regs_hdr(u32 *dump_buf,
1929				 bool dump,
1930				 u32 num_reg_entries,
1931				 enum init_split_types split_type,
1932				 u8 split_id, const char *reg_type_name)
1933{
1934	u8 num_params = 2 +
1935	    (split_type != SPLIT_TYPE_NONE ? 1 : 0) + (reg_type_name ? 1 : 0);
1936	u32 offset = 0;
1937
1938	offset += qed_dump_section_hdr(dump_buf + offset,
1939				       dump, "grc_regs", num_params);
1940	offset += qed_dump_num_param(dump_buf + offset,
1941				     dump, "count", num_reg_entries);
1942	offset += qed_dump_str_param(dump_buf + offset,
1943				     dump, "split",
1944				     s_split_type_defs[split_type].name);
1945	if (split_type != SPLIT_TYPE_NONE)
1946		offset += qed_dump_num_param(dump_buf + offset,
1947					     dump, "id", split_id);
1948	if (reg_type_name)
1949		offset += qed_dump_str_param(dump_buf + offset,
1950					     dump, "type", reg_type_name);
1951
1952	return offset;
1953}
1954
1955/* Reads the specified registers into the specified buffer.
1956 * The addr and len arguments are specified in dwords.
1957 */
1958void qed_read_regs(struct qed_hwfn *p_hwfn,
1959		   struct qed_ptt *p_ptt, u32 *buf, u32 addr, u32 len)
1960{
1961	u32 i;
1962
1963	for (i = 0; i < len; i++)
1964		buf[i] = qed_rd(p_hwfn, p_ptt, DWORDS_TO_BYTES(addr + i));
1965}
1966
1967/* Dumps the GRC registers in the specified address range.
1968 * Returns the dumped size in dwords.
1969 * The addr and len arguments are specified in dwords.
1970 */
1971static u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn,
1972				   struct qed_ptt *p_ptt,
1973				   u32 *dump_buf,
1974				   bool dump, u32 addr, u32 len, bool wide_bus,
1975				   enum init_split_types split_type,
1976				   u8 split_id)
1977{
1978	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1979	u8 port_id = 0, pf_id = 0, vf_id = 0;
1980	bool read_using_dmae = false;
1981	u32 thresh;
1982	u16 fid;
1983
1984	if (!dump)
1985		return len;
1986
1987	switch (split_type) {
1988	case SPLIT_TYPE_PORT:
1989		port_id = split_id;
1990		break;
1991	case SPLIT_TYPE_PF:
1992		pf_id = split_id;
1993		break;
1994	case SPLIT_TYPE_PORT_PF:
1995		port_id = split_id / dev_data->num_pfs_per_port;
1996		pf_id = port_id + dev_data->num_ports *
1997		    (split_id % dev_data->num_pfs_per_port);
1998		break;
1999	case SPLIT_TYPE_VF:
2000		vf_id = split_id;
2001		break;
2002	default:
2003		break;
2004	}
2005
2006	/* Try reading using DMAE */
2007	if (dev_data->use_dmae && split_type != SPLIT_TYPE_VF &&
2008	    (len >= s_hw_type_defs[dev_data->hw_type].dmae_thresh ||
2009	     (PROTECT_WIDE_BUS && wide_bus))) {
2010		struct qed_dmae_params dmae_params;
2011
2012		/* Set DMAE params */
2013		memset(&dmae_params, 0, sizeof(dmae_params));
2014		SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_COMPLETION_DST, 1);
2015		switch (split_type) {
2016		case SPLIT_TYPE_PORT:
2017			SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_PORT_VALID,
2018				  1);
2019			dmae_params.port_id = port_id;
2020			break;
2021		case SPLIT_TYPE_PF:
2022			SET_FIELD(dmae_params.flags,
2023				  QED_DMAE_PARAMS_SRC_PF_VALID, 1);
2024			dmae_params.src_pfid = pf_id;
2025			break;
2026		case SPLIT_TYPE_PORT_PF:
2027			SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_PORT_VALID,
2028				  1);
2029			SET_FIELD(dmae_params.flags,
2030				  QED_DMAE_PARAMS_SRC_PF_VALID, 1);
2031			dmae_params.port_id = port_id;
2032			dmae_params.src_pfid = pf_id;
2033			break;
2034		default:
2035			break;
2036		}
2037
2038		/* Execute DMAE command */
2039		read_using_dmae = !qed_dmae_grc2host(p_hwfn,
2040						     p_ptt,
2041						     DWORDS_TO_BYTES(addr),
2042						     (u64)(uintptr_t)(dump_buf),
2043						     len, &dmae_params);
2044		if (!read_using_dmae) {
2045			dev_data->use_dmae = 0;
2046			DP_VERBOSE(p_hwfn,
2047				   QED_MSG_DEBUG,
2048				   "Failed reading from chip using DMAE, using GRC instead\n");
2049		}
2050	}
2051
2052	if (read_using_dmae)
2053		goto print_log;
2054
2055	/* If not read using DMAE, read using GRC */
2056
2057	/* Set pretend */
2058	if (split_type != dev_data->pretend.split_type ||
2059	    split_id != dev_data->pretend.split_id) {
2060		switch (split_type) {
2061		case SPLIT_TYPE_PORT:
2062			qed_port_pretend(p_hwfn, p_ptt, port_id);
2063			break;
2064		case SPLIT_TYPE_PF:
2065			fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID,
2066					  pf_id);
2067			qed_fid_pretend(p_hwfn, p_ptt, fid);
2068			break;
2069		case SPLIT_TYPE_PORT_PF:
2070			fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID,
2071					  pf_id);
2072			qed_port_fid_pretend(p_hwfn, p_ptt, port_id, fid);
2073			break;
2074		case SPLIT_TYPE_VF:
2075			fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFVALID, 1)
2076			      | FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFID,
2077					  vf_id);
2078			qed_fid_pretend(p_hwfn, p_ptt, fid);
2079			break;
2080		default:
2081			break;
2082		}
2083
2084		dev_data->pretend.split_type = (u8)split_type;
2085		dev_data->pretend.split_id = split_id;
2086	}
2087
2088	/* Read registers using GRC */
2089	qed_read_regs(p_hwfn, p_ptt, dump_buf, addr, len);
2090
2091print_log:
2092	/* Print log */
2093	dev_data->num_regs_read += len;
2094	thresh = s_hw_type_defs[dev_data->hw_type].log_thresh;
2095	if ((dev_data->num_regs_read / thresh) >
2096	    ((dev_data->num_regs_read - len) / thresh))
2097		DP_VERBOSE(p_hwfn,
2098			   QED_MSG_DEBUG,
2099			   "Dumped %d registers...\n", dev_data->num_regs_read);
2100
2101	return len;
2102}
2103
2104/* Dumps GRC registers sequence header. Returns the dumped size in dwords.
2105 * The addr and len arguments are specified in dwords.
2106 */
2107static u32 qed_grc_dump_reg_entry_hdr(u32 *dump_buf,
2108				      bool dump, u32 addr, u32 len)
2109{
2110	if (dump)
2111		*dump_buf = addr | (len << REG_DUMP_LEN_SHIFT);
2112
2113	return 1;
2114}
2115
2116/* Dumps GRC registers sequence. Returns the dumped size in dwords.
2117 * The addr and len arguments are specified in dwords.
2118 */
2119static u32 qed_grc_dump_reg_entry(struct qed_hwfn *p_hwfn,
2120				  struct qed_ptt *p_ptt,
2121				  u32 *dump_buf,
2122				  bool dump, u32 addr, u32 len, bool wide_bus,
2123				  enum init_split_types split_type, u8 split_id)
2124{
2125	u32 offset = 0;
2126
2127	offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, len);
2128	offset += qed_grc_dump_addr_range(p_hwfn,
2129					  p_ptt,
2130					  dump_buf + offset,
2131					  dump, addr, len, wide_bus,
2132					  split_type, split_id);
2133
2134	return offset;
2135}
2136
2137/* Dumps GRC registers sequence with skip cycle.
2138 * Returns the dumped size in dwords.
2139 * - addr:	start GRC address in dwords
2140 * - total_len:	total no. of dwords to dump
2141 * - read_len:	no. consecutive dwords to read
2142 * - skip_len:	no. of dwords to skip (and fill with zeros)
2143 */
2144static u32 qed_grc_dump_reg_entry_skip(struct qed_hwfn *p_hwfn,
2145				       struct qed_ptt *p_ptt,
2146				       u32 *dump_buf,
2147				       bool dump,
2148				       u32 addr,
2149				       u32 total_len,
2150				       u32 read_len, u32 skip_len)
2151{
2152	u32 offset = 0, reg_offset = 0;
2153
2154	offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, total_len);
2155
2156	if (!dump)
2157		return offset + total_len;
2158
2159	while (reg_offset < total_len) {
2160		u32 curr_len = min_t(u32, read_len, total_len - reg_offset);
2161
2162		offset += qed_grc_dump_addr_range(p_hwfn,
2163						  p_ptt,
2164						  dump_buf + offset,
2165						  dump,  addr, curr_len, false,
2166						  SPLIT_TYPE_NONE, 0);
2167		reg_offset += curr_len;
2168		addr += curr_len;
2169
2170		if (reg_offset < total_len) {
2171			curr_len = min_t(u32, skip_len, total_len - skip_len);
2172			memset(dump_buf + offset, 0, DWORDS_TO_BYTES(curr_len));
2173			offset += curr_len;
2174			reg_offset += curr_len;
2175			addr += curr_len;
2176		}
2177	}
2178
2179	return offset;
2180}
2181
2182/* Dumps GRC registers entries. Returns the dumped size in dwords. */
2183static u32 qed_grc_dump_regs_entries(struct qed_hwfn *p_hwfn,
2184				     struct qed_ptt *p_ptt,
2185				     struct virt_mem_desc input_regs_arr,
2186				     u32 *dump_buf,
2187				     bool dump,
2188				     enum init_split_types split_type,
2189				     u8 split_id,
2190				     bool block_enable[MAX_BLOCK_ID],
2191				     u32 *num_dumped_reg_entries)
2192{
2193	u32 i, offset = 0, input_offset = 0;
2194	bool mode_match = true;
2195
2196	*num_dumped_reg_entries = 0;
2197
2198	while (input_offset < BYTES_TO_DWORDS(input_regs_arr.size)) {
2199		const struct dbg_dump_cond_hdr *cond_hdr =
2200		    (const struct dbg_dump_cond_hdr *)
2201		    input_regs_arr.ptr + input_offset++;
2202		u16 modes_buf_offset;
2203		bool eval_mode;
2204
2205		/* Check mode/block */
2206		eval_mode = GET_FIELD(cond_hdr->mode.data,
2207				      DBG_MODE_HDR_EVAL_MODE) > 0;
2208		if (eval_mode) {
2209			modes_buf_offset =
2210				GET_FIELD(cond_hdr->mode.data,
2211					  DBG_MODE_HDR_MODES_BUF_OFFSET);
2212			mode_match = qed_is_mode_match(p_hwfn,
2213						       &modes_buf_offset);
2214		}
2215
2216		if (!mode_match || !block_enable[cond_hdr->block_id]) {
2217			input_offset += cond_hdr->data_size;
2218			continue;
2219		}
2220
2221		for (i = 0; i < cond_hdr->data_size; i++, input_offset++) {
2222			const struct dbg_dump_reg *reg =
2223			    (const struct dbg_dump_reg *)
2224			    input_regs_arr.ptr + input_offset;
2225			u32 addr, len;
2226			bool wide_bus;
2227
2228			addr = GET_FIELD(reg->data, DBG_DUMP_REG_ADDRESS);
2229			len = GET_FIELD(reg->data, DBG_DUMP_REG_LENGTH);
2230			wide_bus = GET_FIELD(reg->data, DBG_DUMP_REG_WIDE_BUS);
2231			offset += qed_grc_dump_reg_entry(p_hwfn,
2232							 p_ptt,
2233							 dump_buf + offset,
2234							 dump,
2235							 addr,
2236							 len,
2237							 wide_bus,
2238							 split_type, split_id);
2239			(*num_dumped_reg_entries)++;
2240		}
2241	}
2242
2243	return offset;
2244}
2245
2246/* Dumps GRC registers entries. Returns the dumped size in dwords. */
2247static u32 qed_grc_dump_split_data(struct qed_hwfn *p_hwfn,
2248				   struct qed_ptt *p_ptt,
2249				   struct virt_mem_desc input_regs_arr,
2250				   u32 *dump_buf,
2251				   bool dump,
2252				   bool block_enable[MAX_BLOCK_ID],
2253				   enum init_split_types split_type,
2254				   u8 split_id, const char *reg_type_name)
2255{
2256	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2257	enum init_split_types hdr_split_type = split_type;
2258	u32 num_dumped_reg_entries, offset;
2259	u8 hdr_split_id = split_id;
2260
2261	/* In PORT_PF split type, print a port split header */
2262	if (split_type == SPLIT_TYPE_PORT_PF) {
2263		hdr_split_type = SPLIT_TYPE_PORT;
2264		hdr_split_id = split_id / dev_data->num_pfs_per_port;
2265	}
2266
2267	/* Calculate register dump header size (and skip it for now) */
2268	offset = qed_grc_dump_regs_hdr(dump_buf,
2269				       false,
2270				       0,
2271				       hdr_split_type,
2272				       hdr_split_id, reg_type_name);
2273
2274	/* Dump registers */
2275	offset += qed_grc_dump_regs_entries(p_hwfn,
2276					    p_ptt,
2277					    input_regs_arr,
2278					    dump_buf + offset,
2279					    dump,
2280					    split_type,
2281					    split_id,
2282					    block_enable,
2283					    &num_dumped_reg_entries);
2284
2285	/* Write register dump header */
2286	if (dump && num_dumped_reg_entries > 0)
2287		qed_grc_dump_regs_hdr(dump_buf,
2288				      dump,
2289				      num_dumped_reg_entries,
2290				      hdr_split_type,
2291				      hdr_split_id, reg_type_name);
2292
2293	return num_dumped_reg_entries > 0 ? offset : 0;
2294}
2295
2296/* Dumps registers according to the input registers array. Returns the dumped
2297 * size in dwords.
2298 */
2299static u32 qed_grc_dump_registers(struct qed_hwfn *p_hwfn,
2300				  struct qed_ptt *p_ptt,
2301				  u32 *dump_buf,
2302				  bool dump,
2303				  bool block_enable[MAX_BLOCK_ID],
2304				  const char *reg_type_name)
2305{
2306	struct virt_mem_desc *dbg_buf =
2307	    &p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG];
2308	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2309	u32 offset = 0, input_offset = 0;
2310
2311	while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) {
2312		const struct dbg_dump_split_hdr *split_hdr;
2313		struct virt_mem_desc curr_input_regs_arr;
2314		enum init_split_types split_type;
2315		u16 split_count = 0;
2316		u32 split_data_size;
2317		u8 split_id;
2318
2319		split_hdr =
2320		    (const struct dbg_dump_split_hdr *)
2321		    dbg_buf->ptr + input_offset++;
2322		split_type =
2323		    GET_FIELD(split_hdr->hdr,
2324			      DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
2325		split_data_size = GET_FIELD(split_hdr->hdr,
2326					    DBG_DUMP_SPLIT_HDR_DATA_SIZE);
2327		curr_input_regs_arr.ptr =
2328		    (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr +
2329		    input_offset;
2330		curr_input_regs_arr.size = DWORDS_TO_BYTES(split_data_size);
2331
2332		switch (split_type) {
2333		case SPLIT_TYPE_NONE:
2334			split_count = 1;
2335			break;
2336		case SPLIT_TYPE_PORT:
2337			split_count = dev_data->num_ports;
2338			break;
2339		case SPLIT_TYPE_PF:
2340		case SPLIT_TYPE_PORT_PF:
2341			split_count = dev_data->num_ports *
2342			    dev_data->num_pfs_per_port;
2343			break;
2344		case SPLIT_TYPE_VF:
2345			split_count = dev_data->num_vfs;
2346			break;
2347		default:
2348			return 0;
2349		}
2350
2351		for (split_id = 0; split_id < split_count; split_id++)
2352			offset += qed_grc_dump_split_data(p_hwfn, p_ptt,
2353							  curr_input_regs_arr,
2354							  dump_buf + offset,
2355							  dump, block_enable,
2356							  split_type,
2357							  split_id,
2358							  reg_type_name);
2359
2360		input_offset += split_data_size;
2361	}
2362
2363	/* Cancel pretends (pretend to original PF) */
2364	if (dump) {
2365		qed_fid_pretend(p_hwfn, p_ptt,
2366				FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID,
2367					    p_hwfn->rel_pf_id));
2368		dev_data->pretend.split_type = SPLIT_TYPE_NONE;
2369		dev_data->pretend.split_id = 0;
2370	}
2371
2372	return offset;
2373}
2374
2375/* Dump reset registers. Returns the dumped size in dwords. */
2376static u32 qed_grc_dump_reset_regs(struct qed_hwfn *p_hwfn,
2377				   struct qed_ptt *p_ptt,
2378				   u32 *dump_buf, bool dump)
2379{
2380	u32 offset = 0, num_regs = 0;
2381	u8 reset_reg_id;
2382
2383	/* Calculate header size */
2384	offset += qed_grc_dump_regs_hdr(dump_buf,
2385					false,
2386					0, SPLIT_TYPE_NONE, 0, "RESET_REGS");
2387
2388	/* Write reset registers */
2389	for (reset_reg_id = 0; reset_reg_id < NUM_DBG_RESET_REGS;
2390	     reset_reg_id++) {
2391		const struct dbg_reset_reg *reset_reg;
2392		u32 reset_reg_addr;
2393
2394		reset_reg = qed_get_dbg_reset_reg(p_hwfn, reset_reg_id);
2395
2396		if (GET_FIELD(reset_reg->data, DBG_RESET_REG_IS_REMOVED))
2397			continue;
2398
2399		reset_reg_addr = GET_FIELD(reset_reg->data, DBG_RESET_REG_ADDR);
2400		offset += qed_grc_dump_reg_entry(p_hwfn,
2401						 p_ptt,
2402						 dump_buf + offset,
2403						 dump,
2404						 reset_reg_addr,
2405						 1, false, SPLIT_TYPE_NONE, 0);
2406		num_regs++;
2407	}
2408
2409	/* Write header */
2410	if (dump)
2411		qed_grc_dump_regs_hdr(dump_buf,
2412				      true, num_regs, SPLIT_TYPE_NONE,
2413				      0, "RESET_REGS");
2414
2415	return offset;
2416}
2417
2418/* Dump registers that are modified during GRC Dump and therefore must be
2419 * dumped first. Returns the dumped size in dwords.
2420 */
2421static u32 qed_grc_dump_modified_regs(struct qed_hwfn *p_hwfn,
2422				      struct qed_ptt *p_ptt,
2423				      u32 *dump_buf, bool dump)
2424{
2425	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2426	u32 block_id, offset = 0, stall_regs_offset;
2427	const struct dbg_attn_reg *attn_reg_arr;
2428	u8 storm_id, reg_idx, num_attn_regs;
2429	u32 num_reg_entries = 0;
2430
2431	/* Write empty header for attention registers */
2432	offset += qed_grc_dump_regs_hdr(dump_buf,
2433					false,
2434					0, SPLIT_TYPE_NONE, 0, "ATTN_REGS");
2435
2436	/* Write parity registers */
2437	for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) {
2438		if (dev_data->block_in_reset[block_id] && dump)
2439			continue;
2440
2441		attn_reg_arr = qed_get_block_attn_regs(p_hwfn,
2442						       (enum block_id)block_id,
2443						       ATTN_TYPE_PARITY,
2444						       &num_attn_regs);
2445
2446		for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
2447			const struct dbg_attn_reg *reg_data =
2448				&attn_reg_arr[reg_idx];
2449			u16 modes_buf_offset;
2450			bool eval_mode;
2451			u32 addr;
2452
2453			/* Check mode */
2454			eval_mode = GET_FIELD(reg_data->mode.data,
2455					      DBG_MODE_HDR_EVAL_MODE) > 0;
2456			modes_buf_offset =
2457				GET_FIELD(reg_data->mode.data,
2458					  DBG_MODE_HDR_MODES_BUF_OFFSET);
2459			if (eval_mode &&
2460			    !qed_is_mode_match(p_hwfn, &modes_buf_offset))
2461				continue;
2462
2463			/* Mode match: read & dump registers */
2464			addr = reg_data->mask_address;
2465			offset += qed_grc_dump_reg_entry(p_hwfn,
2466							 p_ptt,
2467							 dump_buf + offset,
2468							 dump,
2469							 addr,
2470							 1, false,
2471							 SPLIT_TYPE_NONE, 0);
2472			addr = GET_FIELD(reg_data->data,
2473					 DBG_ATTN_REG_STS_ADDRESS);
2474			offset += qed_grc_dump_reg_entry(p_hwfn,
2475							 p_ptt,
2476							 dump_buf + offset,
2477							 dump,
2478							 addr,
2479							 1, false,
2480							 SPLIT_TYPE_NONE, 0);
2481			num_reg_entries += 2;
2482		}
2483	}
2484
2485	/* Overwrite header for attention registers */
2486	if (dump)
2487		qed_grc_dump_regs_hdr(dump_buf,
2488				      true,
2489				      num_reg_entries,
2490				      SPLIT_TYPE_NONE, 0, "ATTN_REGS");
2491
2492	/* Write empty header for stall registers */
2493	stall_regs_offset = offset;
2494	offset += qed_grc_dump_regs_hdr(dump_buf,
2495					false, 0, SPLIT_TYPE_NONE, 0, "REGS");
2496
2497	/* Write Storm stall status registers */
2498	for (storm_id = 0, num_reg_entries = 0; storm_id < MAX_DBG_STORMS;
2499	     storm_id++) {
2500		struct storm_defs *storm = &s_storm_defs[storm_id];
2501		u32 addr;
2502
2503		if (dev_data->block_in_reset[storm->sem_block_id] && dump)
2504			continue;
2505
2506		addr =
2507		    BYTES_TO_DWORDS(storm->sem_fast_mem_addr +
2508				    SEM_FAST_REG_STALLED);
2509		offset += qed_grc_dump_reg_entry(p_hwfn,
2510						 p_ptt,
2511						 dump_buf + offset,
2512						 dump,
2513						 addr,
2514						 1,
2515						 false, SPLIT_TYPE_NONE, 0);
2516		num_reg_entries++;
2517	}
2518
2519	/* Overwrite header for stall registers */
2520	if (dump)
2521		qed_grc_dump_regs_hdr(dump_buf + stall_regs_offset,
2522				      true,
2523				      num_reg_entries,
2524				      SPLIT_TYPE_NONE, 0, "REGS");
2525
2526	return offset;
2527}
2528
2529/* Dumps registers that can't be represented in the debug arrays */
2530static u32 qed_grc_dump_special_regs(struct qed_hwfn *p_hwfn,
2531				     struct qed_ptt *p_ptt,
2532				     u32 *dump_buf, bool dump)
2533{
2534	u32 offset = 0, addr;
2535
2536	offset += qed_grc_dump_regs_hdr(dump_buf,
2537					dump, 2, SPLIT_TYPE_NONE, 0, "REGS");
2538
2539	/* Dump R/TDIF_REG_DEBUG_ERROR_INFO_SIZE (every 8'th register should be
2540	 * skipped).
2541	 */
2542	addr = BYTES_TO_DWORDS(RDIF_REG_DEBUG_ERROR_INFO);
2543	offset += qed_grc_dump_reg_entry_skip(p_hwfn,
2544					      p_ptt,
2545					      dump_buf + offset,
2546					      dump,
2547					      addr,
2548					      RDIF_REG_DEBUG_ERROR_INFO_SIZE,
2549					      7,
2550					      1);
2551	addr = BYTES_TO_DWORDS(TDIF_REG_DEBUG_ERROR_INFO);
2552	offset +=
2553	    qed_grc_dump_reg_entry_skip(p_hwfn,
2554					p_ptt,
2555					dump_buf + offset,
2556					dump,
2557					addr,
2558					TDIF_REG_DEBUG_ERROR_INFO_SIZE,
2559					7,
2560					1);
2561
2562	return offset;
2563}
2564
2565/* Dumps a GRC memory header (section and params). Returns the dumped size in
2566 * dwords. The following parameters are dumped:
2567 * - name:	   dumped only if it's not NULL.
2568 * - addr:	   in dwords, dumped only if name is NULL.
2569 * - len:	   in dwords, always dumped.
2570 * - width:	   dumped if it's not zero.
2571 * - packed:	   dumped only if it's not false.
2572 * - mem_group:	   always dumped.
2573 * - is_storm:	   true only if the memory is related to a Storm.
2574 * - storm_letter: valid only if is_storm is true.
2575 *
2576 */
2577static u32 qed_grc_dump_mem_hdr(struct qed_hwfn *p_hwfn,
2578				u32 *dump_buf,
2579				bool dump,
2580				const char *name,
2581				u32 addr,
2582				u32 len,
2583				u32 bit_width,
2584				bool packed,
2585				const char *mem_group, char storm_letter)
2586{
2587	u8 num_params = 3;
2588	u32 offset = 0;
2589	char buf[64];
2590
2591	if (!len)
2592		DP_NOTICE(p_hwfn,
2593			  "Unexpected GRC Dump error: dumped memory size must be non-zero\n");
2594
2595	if (bit_width)
2596		num_params++;
2597	if (packed)
2598		num_params++;
2599
2600	/* Dump section header */
2601	offset += qed_dump_section_hdr(dump_buf + offset,
2602				       dump, "grc_mem", num_params);
2603
2604	if (name) {
2605		/* Dump name */
2606		if (storm_letter) {
2607			strcpy(buf, "?STORM_");
2608			buf[0] = storm_letter;
2609			strcpy(buf + strlen(buf), name);
2610		} else {
2611			strcpy(buf, name);
2612		}
2613
2614		offset += qed_dump_str_param(dump_buf + offset,
2615					     dump, "name", buf);
2616	} else {
2617		/* Dump address */
2618		u32 addr_in_bytes = DWORDS_TO_BYTES(addr);
2619
2620		offset += qed_dump_num_param(dump_buf + offset,
2621					     dump, "addr", addr_in_bytes);
2622	}
2623
2624	/* Dump len */
2625	offset += qed_dump_num_param(dump_buf + offset, dump, "len", len);
2626
2627	/* Dump bit width */
2628	if (bit_width)
2629		offset += qed_dump_num_param(dump_buf + offset,
2630					     dump, "width", bit_width);
2631
2632	/* Dump packed */
2633	if (packed)
2634		offset += qed_dump_num_param(dump_buf + offset,
2635					     dump, "packed", 1);
2636
2637	/* Dump reg type */
2638	if (storm_letter) {
2639		strcpy(buf, "?STORM_");
2640		buf[0] = storm_letter;
2641		strcpy(buf + strlen(buf), mem_group);
2642	} else {
2643		strcpy(buf, mem_group);
2644	}
2645
2646	offset += qed_dump_str_param(dump_buf + offset, dump, "type", buf);
2647
2648	return offset;
2649}
2650
2651/* Dumps a single GRC memory. If name is NULL, the memory is stored by address.
2652 * Returns the dumped size in dwords.
2653 * The addr and len arguments are specified in dwords.
2654 */
2655static u32 qed_grc_dump_mem(struct qed_hwfn *p_hwfn,
2656			    struct qed_ptt *p_ptt,
2657			    u32 *dump_buf,
2658			    bool dump,
2659			    const char *name,
2660			    u32 addr,
2661			    u32 len,
2662			    bool wide_bus,
2663			    u32 bit_width,
2664			    bool packed,
2665			    const char *mem_group, char storm_letter)
2666{
2667	u32 offset = 0;
2668
2669	offset += qed_grc_dump_mem_hdr(p_hwfn,
2670				       dump_buf + offset,
2671				       dump,
2672				       name,
2673				       addr,
2674				       len,
2675				       bit_width,
2676				       packed, mem_group, storm_letter);
2677	offset += qed_grc_dump_addr_range(p_hwfn,
2678					  p_ptt,
2679					  dump_buf + offset,
2680					  dump, addr, len, wide_bus,
2681					  SPLIT_TYPE_NONE, 0);
2682
2683	return offset;
2684}
2685
2686/* Dumps GRC memories entries. Returns the dumped size in dwords. */
2687static u32 qed_grc_dump_mem_entries(struct qed_hwfn *p_hwfn,
2688				    struct qed_ptt *p_ptt,
2689				    struct virt_mem_desc input_mems_arr,
2690				    u32 *dump_buf, bool dump)
2691{
2692	u32 i, offset = 0, input_offset = 0;
2693	bool mode_match = true;
2694
2695	while (input_offset < BYTES_TO_DWORDS(input_mems_arr.size)) {
2696		const struct dbg_dump_cond_hdr *cond_hdr;
2697		u16 modes_buf_offset;
2698		u32 num_entries;
2699		bool eval_mode;
2700
2701		cond_hdr =
2702		    (const struct dbg_dump_cond_hdr *)input_mems_arr.ptr +
2703		    input_offset++;
2704		num_entries = cond_hdr->data_size / MEM_DUMP_ENTRY_SIZE_DWORDS;
2705
2706		/* Check required mode */
2707		eval_mode = GET_FIELD(cond_hdr->mode.data,
2708				      DBG_MODE_HDR_EVAL_MODE) > 0;
2709		if (eval_mode) {
2710			modes_buf_offset =
2711				GET_FIELD(cond_hdr->mode.data,
2712					  DBG_MODE_HDR_MODES_BUF_OFFSET);
2713			mode_match = qed_is_mode_match(p_hwfn,
2714						       &modes_buf_offset);
2715		}
2716
2717		if (!mode_match) {
2718			input_offset += cond_hdr->data_size;
2719			continue;
2720		}
2721
2722		for (i = 0; i < num_entries;
2723		     i++, input_offset += MEM_DUMP_ENTRY_SIZE_DWORDS) {
2724			const struct dbg_dump_mem *mem =
2725			    (const struct dbg_dump_mem *)((u32 *)
2726							  input_mems_arr.ptr
2727							  + input_offset);
2728			const struct dbg_block *block;
2729			char storm_letter = 0;
2730			u32 mem_addr, mem_len;
2731			bool mem_wide_bus;
2732			u8 mem_group_id;
2733
2734			mem_group_id = GET_FIELD(mem->dword0,
2735						 DBG_DUMP_MEM_MEM_GROUP_ID);
2736			if (mem_group_id >= MEM_GROUPS_NUM) {
2737				DP_NOTICE(p_hwfn, "Invalid mem_group_id\n");
2738				return 0;
2739			}
2740
2741			if (!qed_grc_is_mem_included(p_hwfn,
2742						     (enum block_id)
2743						     cond_hdr->block_id,
2744						     mem_group_id))
2745				continue;
2746
2747			mem_addr = GET_FIELD(mem->dword0, DBG_DUMP_MEM_ADDRESS);
2748			mem_len = GET_FIELD(mem->dword1, DBG_DUMP_MEM_LENGTH);
2749			mem_wide_bus = GET_FIELD(mem->dword1,
2750						 DBG_DUMP_MEM_WIDE_BUS);
2751
2752			block = get_dbg_block(p_hwfn,
2753					      cond_hdr->block_id);
2754
2755			/* If memory is associated with Storm,
2756			 * update storm details
2757			 */
2758			if (block->associated_storm_letter)
2759				storm_letter = block->associated_storm_letter;
2760
2761			/* Dump memory */
2762			offset += qed_grc_dump_mem(p_hwfn,
2763						p_ptt,
2764						dump_buf + offset,
2765						dump,
2766						NULL,
2767						mem_addr,
2768						mem_len,
2769						mem_wide_bus,
2770						0,
2771						false,
2772						s_mem_group_names[mem_group_id],
2773						storm_letter);
2774		}
2775	}
2776
2777	return offset;
2778}
2779
2780/* Dumps GRC memories according to the input array dump_mem.
2781 * Returns the dumped size in dwords.
2782 */
2783static u32 qed_grc_dump_memories(struct qed_hwfn *p_hwfn,
2784				 struct qed_ptt *p_ptt,
2785				 u32 *dump_buf, bool dump)
2786{
2787	struct virt_mem_desc *dbg_buf =
2788	    &p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_MEM];
2789	u32 offset = 0, input_offset = 0;
2790
2791	while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) {
2792		const struct dbg_dump_split_hdr *split_hdr;
2793		struct virt_mem_desc curr_input_mems_arr;
2794		enum init_split_types split_type;
2795		u32 split_data_size;
2796
2797		split_hdr =
2798		    (const struct dbg_dump_split_hdr *)dbg_buf->ptr +
2799		    input_offset++;
2800		split_type = GET_FIELD(split_hdr->hdr,
2801				       DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
2802		split_data_size = GET_FIELD(split_hdr->hdr,
2803					    DBG_DUMP_SPLIT_HDR_DATA_SIZE);
2804		curr_input_mems_arr.ptr = (u32 *)dbg_buf->ptr + input_offset;
2805		curr_input_mems_arr.size = DWORDS_TO_BYTES(split_data_size);
2806
2807		if (split_type == SPLIT_TYPE_NONE)
2808			offset += qed_grc_dump_mem_entries(p_hwfn,
2809							   p_ptt,
2810							   curr_input_mems_arr,
2811							   dump_buf + offset,
2812							   dump);
2813		else
2814			DP_NOTICE(p_hwfn,
2815				  "Dumping split memories is currently not supported\n");
2816
2817		input_offset += split_data_size;
2818	}
2819
2820	return offset;
2821}
2822
2823/* Dumps GRC context data for the specified Storm.
2824 * Returns the dumped size in dwords.
2825 * The lid_size argument is specified in quad-regs.
2826 */
2827static u32 qed_grc_dump_ctx_data(struct qed_hwfn *p_hwfn,
2828				 struct qed_ptt *p_ptt,
2829				 u32 *dump_buf,
2830				 bool dump,
2831				 const char *name,
2832				 u32 num_lids,
2833				 enum cm_ctx_types ctx_type, u8 storm_id)
2834{
2835	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2836	struct storm_defs *storm = &s_storm_defs[storm_id];
2837	u32 i, lid, lid_size, total_size;
2838	u32 rd_reg_addr, offset = 0;
2839
2840	/* Convert quad-regs to dwords */
2841	lid_size = storm->cm_ctx_lid_sizes[dev_data->chip_id][ctx_type] * 4;
2842
2843	if (!lid_size)
2844		return 0;
2845
2846	total_size = num_lids * lid_size;
2847
2848	offset += qed_grc_dump_mem_hdr(p_hwfn,
2849				       dump_buf + offset,
2850				       dump,
2851				       name,
2852				       0,
2853				       total_size,
2854				       lid_size * 32,
2855				       false, name, storm->letter);
2856
2857	if (!dump)
2858		return offset + total_size;
2859
2860	rd_reg_addr = BYTES_TO_DWORDS(storm->cm_ctx_rd_addr[ctx_type]);
2861
2862	/* Dump context data */
2863	for (lid = 0; lid < num_lids; lid++) {
2864		for (i = 0; i < lid_size; i++) {
2865			qed_wr(p_hwfn,
2866			       p_ptt, storm->cm_ctx_wr_addr, (i << 9) | lid);
2867			offset += qed_grc_dump_addr_range(p_hwfn,
2868							  p_ptt,
2869							  dump_buf + offset,
2870							  dump,
2871							  rd_reg_addr,
2872							  1,
2873							  false,
2874							  SPLIT_TYPE_NONE, 0);
2875		}
2876		cond_resched();
2877	}
2878
2879	return offset;
2880}
2881
2882/* Dumps GRC contexts. Returns the dumped size in dwords. */
2883static u32 qed_grc_dump_ctx(struct qed_hwfn *p_hwfn,
2884			    struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
2885{
2886	u32 offset = 0;
2887	u8 storm_id;
2888
2889	for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
2890		if (!qed_grc_is_storm_included(p_hwfn,
2891					       (enum dbg_storms)storm_id))
2892			continue;
2893
2894		/* Dump Conn AG context size */
2895		offset += qed_grc_dump_ctx_data(p_hwfn,
2896						p_ptt,
2897						dump_buf + offset,
2898						dump,
2899						"CONN_AG_CTX",
2900						NUM_OF_LCIDS,
2901						CM_CTX_CONN_AG, storm_id);
2902
2903		/* Dump Conn ST context size */
2904		offset += qed_grc_dump_ctx_data(p_hwfn,
2905						p_ptt,
2906						dump_buf + offset,
2907						dump,
2908						"CONN_ST_CTX",
2909						NUM_OF_LCIDS,
2910						CM_CTX_CONN_ST, storm_id);
2911
2912		/* Dump Task AG context size */
2913		offset += qed_grc_dump_ctx_data(p_hwfn,
2914						p_ptt,
2915						dump_buf + offset,
2916						dump,
2917						"TASK_AG_CTX",
2918						NUM_OF_LTIDS,
2919						CM_CTX_TASK_AG, storm_id);
2920
2921		/* Dump Task ST context size */
2922		offset += qed_grc_dump_ctx_data(p_hwfn,
2923						p_ptt,
2924						dump_buf + offset,
2925						dump,
2926						"TASK_ST_CTX",
2927						NUM_OF_LTIDS,
2928						CM_CTX_TASK_ST, storm_id);
2929	}
2930
2931	return offset;
2932}
2933
2934#define VFC_STATUS_RESP_READY_BIT	0
2935#define VFC_STATUS_BUSY_BIT		1
2936#define VFC_STATUS_SENDING_CMD_BIT	2
2937
2938#define VFC_POLLING_DELAY_MS	1
2939#define VFC_POLLING_COUNT		20
2940
2941/* Reads data from VFC. Returns the number of dwords read (0 on error).
2942 * Sizes are specified in dwords.
2943 */
2944static u32 qed_grc_dump_read_from_vfc(struct qed_hwfn *p_hwfn,
2945				      struct qed_ptt *p_ptt,
2946				      struct storm_defs *storm,
2947				      u32 *cmd_data,
2948				      u32 cmd_size,
2949				      u32 *addr_data,
2950				      u32 addr_size,
2951				      u32 resp_size, u32 *dump_buf)
2952{
2953	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2954	u32 vfc_status, polling_ms, polling_count = 0, i;
2955	u32 reg_addr, sem_base;
2956	bool is_ready = false;
2957
2958	sem_base = storm->sem_fast_mem_addr;
2959	polling_ms = VFC_POLLING_DELAY_MS *
2960	    s_hw_type_defs[dev_data->hw_type].delay_factor;
2961
2962	/* Write VFC command */
2963	ARR_REG_WR(p_hwfn,
2964		   p_ptt,
2965		   sem_base + SEM_FAST_REG_VFC_DATA_WR,
2966		   cmd_data, cmd_size);
2967
2968	/* Write VFC address */
2969	ARR_REG_WR(p_hwfn,
2970		   p_ptt,
2971		   sem_base + SEM_FAST_REG_VFC_ADDR,
2972		   addr_data, addr_size);
2973
2974	/* Read response */
2975	for (i = 0; i < resp_size; i++) {
2976		/* Poll until ready */
2977		do {
2978			reg_addr = sem_base + SEM_FAST_REG_VFC_STATUS;
2979			qed_grc_dump_addr_range(p_hwfn,
2980						p_ptt,
2981						&vfc_status,
2982						true,
2983						BYTES_TO_DWORDS(reg_addr),
2984						1,
2985						false, SPLIT_TYPE_NONE, 0);
2986			is_ready = vfc_status & BIT(VFC_STATUS_RESP_READY_BIT);
2987
2988			if (!is_ready) {
2989				if (polling_count++ == VFC_POLLING_COUNT)
2990					return 0;
2991
2992				msleep(polling_ms);
2993			}
2994		} while (!is_ready);
2995
2996		reg_addr = sem_base + SEM_FAST_REG_VFC_DATA_RD;
2997		qed_grc_dump_addr_range(p_hwfn,
2998					p_ptt,
2999					dump_buf + i,
3000					true,
3001					BYTES_TO_DWORDS(reg_addr),
3002					1, false, SPLIT_TYPE_NONE, 0);
3003	}
3004
3005	return resp_size;
3006}
3007
3008/* Dump VFC CAM. Returns the dumped size in dwords. */
3009static u32 qed_grc_dump_vfc_cam(struct qed_hwfn *p_hwfn,
3010				struct qed_ptt *p_ptt,
3011				u32 *dump_buf, bool dump, u8 storm_id)
3012{
3013	u32 total_size = VFC_CAM_NUM_ROWS * VFC_CAM_RESP_DWORDS;
3014	struct storm_defs *storm = &s_storm_defs[storm_id];
3015	u32 cam_addr[VFC_CAM_ADDR_DWORDS] = { 0 };
3016	u32 cam_cmd[VFC_CAM_CMD_DWORDS] = { 0 };
3017	u32 row, offset = 0;
3018
3019	offset += qed_grc_dump_mem_hdr(p_hwfn,
3020				       dump_buf + offset,
3021				       dump,
3022				       "vfc_cam",
3023				       0,
3024				       total_size,
3025				       256,
3026				       false, "vfc_cam", storm->letter);
3027
3028	if (!dump)
3029		return offset + total_size;
3030
3031	/* Prepare CAM address */
3032	SET_VAR_FIELD(cam_addr, VFC_CAM_ADDR, OP, VFC_OPCODE_CAM_RD);
3033
3034	/* Read VFC CAM data */
3035	for (row = 0; row < VFC_CAM_NUM_ROWS; row++) {
3036		SET_VAR_FIELD(cam_cmd, VFC_CAM_CMD, ROW, row);
3037		offset += qed_grc_dump_read_from_vfc(p_hwfn,
3038						     p_ptt,
3039						     storm,
3040						     cam_cmd,
3041						     VFC_CAM_CMD_DWORDS,
3042						     cam_addr,
3043						     VFC_CAM_ADDR_DWORDS,
3044						     VFC_CAM_RESP_DWORDS,
3045						     dump_buf + offset);
3046	}
3047
3048	return offset;
3049}
3050
3051/* Dump VFC RAM. Returns the dumped size in dwords. */
3052static u32 qed_grc_dump_vfc_ram(struct qed_hwfn *p_hwfn,
3053				struct qed_ptt *p_ptt,
3054				u32 *dump_buf,
3055				bool dump,
3056				u8 storm_id, struct vfc_ram_defs *ram_defs)
3057{
3058	u32 total_size = ram_defs->num_rows * VFC_RAM_RESP_DWORDS;
3059	struct storm_defs *storm = &s_storm_defs[storm_id];
3060	u32 ram_addr[VFC_RAM_ADDR_DWORDS] = { 0 };
3061	u32 ram_cmd[VFC_RAM_CMD_DWORDS] = { 0 };
3062	u32 row, offset = 0;
3063
3064	offset += qed_grc_dump_mem_hdr(p_hwfn,
3065				       dump_buf + offset,
3066				       dump,
3067				       ram_defs->mem_name,
3068				       0,
3069				       total_size,
3070				       256,
3071				       false,
3072				       ram_defs->type_name,
3073				       storm->letter);
3074
3075	if (!dump)
3076		return offset + total_size;
3077
3078	/* Prepare RAM address */
3079	SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, OP, VFC_OPCODE_RAM_RD);
3080
3081	/* Read VFC RAM data */
3082	for (row = ram_defs->base_row;
3083	     row < ram_defs->base_row + ram_defs->num_rows; row++) {
3084		SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, ROW, row);
3085		offset += qed_grc_dump_read_from_vfc(p_hwfn,
3086						     p_ptt,
3087						     storm,
3088						     ram_cmd,
3089						     VFC_RAM_CMD_DWORDS,
3090						     ram_addr,
3091						     VFC_RAM_ADDR_DWORDS,
3092						     VFC_RAM_RESP_DWORDS,
3093						     dump_buf + offset);
3094	}
3095
3096	return offset;
3097}
3098
3099/* Dumps GRC VFC data. Returns the dumped size in dwords. */
3100static u32 qed_grc_dump_vfc(struct qed_hwfn *p_hwfn,
3101			    struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3102{
3103	u8 storm_id, i;
3104	u32 offset = 0;
3105
3106	for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
3107		if (!qed_grc_is_storm_included(p_hwfn,
3108					       (enum dbg_storms)storm_id) ||
3109		    !s_storm_defs[storm_id].has_vfc)
3110			continue;
3111
3112		/* Read CAM */
3113		offset += qed_grc_dump_vfc_cam(p_hwfn,
3114					       p_ptt,
3115					       dump_buf + offset,
3116					       dump, storm_id);
3117
3118		/* Read RAM */
3119		for (i = 0; i < NUM_VFC_RAM_TYPES; i++)
3120			offset += qed_grc_dump_vfc_ram(p_hwfn,
3121						       p_ptt,
3122						       dump_buf + offset,
3123						       dump,
3124						       storm_id,
3125						       &s_vfc_ram_defs[i]);
3126	}
3127
3128	return offset;
3129}
3130
3131/* Dumps GRC RSS data. Returns the dumped size in dwords. */
3132static u32 qed_grc_dump_rss(struct qed_hwfn *p_hwfn,
3133			    struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3134{
3135	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3136	u32 offset = 0;
3137	u8 rss_mem_id;
3138
3139	for (rss_mem_id = 0; rss_mem_id < NUM_RSS_MEM_TYPES; rss_mem_id++) {
3140		u32 rss_addr, num_entries, total_dwords;
3141		struct rss_mem_defs *rss_defs;
3142		u32 addr, num_dwords_to_read;
3143		bool packed;
3144
3145		rss_defs = &s_rss_mem_defs[rss_mem_id];
3146		rss_addr = rss_defs->addr;
3147		num_entries = rss_defs->num_entries[dev_data->chip_id];
3148		total_dwords = (num_entries * rss_defs->entry_width) / 32;
3149		packed = (rss_defs->entry_width == 16);
3150
3151		offset += qed_grc_dump_mem_hdr(p_hwfn,
3152					       dump_buf + offset,
3153					       dump,
3154					       rss_defs->mem_name,
3155					       0,
3156					       total_dwords,
3157					       rss_defs->entry_width,
3158					       packed,
3159					       rss_defs->type_name, 0);
3160
3161		/* Dump RSS data */
3162		if (!dump) {
3163			offset += total_dwords;
3164			continue;
3165		}
3166
3167		addr = BYTES_TO_DWORDS(RSS_REG_RSS_RAM_DATA);
3168		while (total_dwords) {
3169			num_dwords_to_read = min_t(u32,
3170						   RSS_REG_RSS_RAM_DATA_SIZE,
3171						   total_dwords);
3172			qed_wr(p_hwfn, p_ptt, RSS_REG_RSS_RAM_ADDR, rss_addr);
3173			offset += qed_grc_dump_addr_range(p_hwfn,
3174							  p_ptt,
3175							  dump_buf + offset,
3176							  dump,
3177							  addr,
3178							  num_dwords_to_read,
3179							  false,
3180							  SPLIT_TYPE_NONE, 0);
3181			total_dwords -= num_dwords_to_read;
3182			rss_addr++;
3183		}
3184	}
3185
3186	return offset;
3187}
3188
3189/* Dumps GRC Big RAM. Returns the dumped size in dwords. */
3190static u32 qed_grc_dump_big_ram(struct qed_hwfn *p_hwfn,
3191				struct qed_ptt *p_ptt,
3192				u32 *dump_buf, bool dump, u8 big_ram_id)
3193{
3194	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3195	u32 block_size, ram_size, offset = 0, reg_val, i;
3196	char mem_name[12] = "???_BIG_RAM";
3197	char type_name[8] = "???_RAM";
3198	struct big_ram_defs *big_ram;
3199
3200	big_ram = &s_big_ram_defs[big_ram_id];
3201	ram_size = big_ram->ram_size[dev_data->chip_id];
3202
3203	reg_val = qed_rd(p_hwfn, p_ptt, big_ram->is_256b_reg_addr);
3204	block_size = reg_val &
3205		     BIT(big_ram->is_256b_bit_offset[dev_data->chip_id]) ? 256
3206									 : 128;
3207
3208	memcpy(type_name, big_ram->instance_name, BIG_RAM_NAME_LEN);
3209	memcpy(mem_name, big_ram->instance_name, BIG_RAM_NAME_LEN);
3210
3211	/* Dump memory header */
3212	offset += qed_grc_dump_mem_hdr(p_hwfn,
3213				       dump_buf + offset,
3214				       dump,
3215				       mem_name,
3216				       0,
3217				       ram_size,
3218				       block_size * 8,
3219				       false, type_name, 0);
3220
3221	/* Read and dump Big RAM data */
3222	if (!dump)
3223		return offset + ram_size;
3224
3225	/* Dump Big RAM */
3226	for (i = 0; i < DIV_ROUND_UP(ram_size, BRB_REG_BIG_RAM_DATA_SIZE);
3227	     i++) {
3228		u32 addr, len;
3229
3230		qed_wr(p_hwfn, p_ptt, big_ram->addr_reg_addr, i);
3231		addr = BYTES_TO_DWORDS(big_ram->data_reg_addr);
3232		len = BRB_REG_BIG_RAM_DATA_SIZE;
3233		offset += qed_grc_dump_addr_range(p_hwfn,
3234						  p_ptt,
3235						  dump_buf + offset,
3236						  dump,
3237						  addr,
3238						  len,
3239						  false, SPLIT_TYPE_NONE, 0);
3240	}
3241
3242	return offset;
3243}
3244
3245/* Dumps MCP scratchpad. Returns the dumped size in dwords. */
3246static u32 qed_grc_dump_mcp(struct qed_hwfn *p_hwfn,
3247			    struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3248{
3249	bool block_enable[MAX_BLOCK_ID] = { 0 };
3250	u32 offset = 0, addr;
3251	bool halted = false;
3252
3253	/* Halt MCP */
3254	if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {
3255		halted = !qed_mcp_halt(p_hwfn, p_ptt);
3256		if (!halted)
3257			DP_NOTICE(p_hwfn, "MCP halt failed!\n");
3258	}
3259
3260	/* Dump MCP scratchpad */
3261	offset += qed_grc_dump_mem(p_hwfn,
3262				   p_ptt,
3263				   dump_buf + offset,
3264				   dump,
3265				   NULL,
3266				   BYTES_TO_DWORDS(MCP_REG_SCRATCH),
3267				   MCP_REG_SCRATCH_SIZE,
3268				   false, 0, false, "MCP", 0);
3269
3270	/* Dump MCP cpu_reg_file */
3271	offset += qed_grc_dump_mem(p_hwfn,
3272				   p_ptt,
3273				   dump_buf + offset,
3274				   dump,
3275				   NULL,
3276				   BYTES_TO_DWORDS(MCP_REG_CPU_REG_FILE),
3277				   MCP_REG_CPU_REG_FILE_SIZE,
3278				   false, 0, false, "MCP", 0);
3279
3280	/* Dump MCP registers */
3281	block_enable[BLOCK_MCP] = true;
3282	offset += qed_grc_dump_registers(p_hwfn,
3283					 p_ptt,
3284					 dump_buf + offset,
3285					 dump, block_enable, "MCP");
3286
3287	/* Dump required non-MCP registers */
3288	offset += qed_grc_dump_regs_hdr(dump_buf + offset,
3289					dump, 1, SPLIT_TYPE_NONE, 0,
3290					"MCP");
3291	addr = BYTES_TO_DWORDS(MISC_REG_SHARED_MEM_ADDR);
3292	offset += qed_grc_dump_reg_entry(p_hwfn,
3293					 p_ptt,
3294					 dump_buf + offset,
3295					 dump,
3296					 addr,
3297					 1,
3298					 false, SPLIT_TYPE_NONE, 0);
3299
3300	/* Release MCP */
3301	if (halted && qed_mcp_resume(p_hwfn, p_ptt))
3302		DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n");
3303
3304	return offset;
3305}
3306
3307/* Dumps the tbus indirect memory for all PHYs.
3308 * Returns the dumped size in dwords.
3309 */
3310static u32 qed_grc_dump_phy(struct qed_hwfn *p_hwfn,
3311			    struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3312{
3313	u32 offset = 0, tbus_lo_offset, tbus_hi_offset;
3314	char mem_name[32];
3315	u8 phy_id;
3316
3317	for (phy_id = 0; phy_id < ARRAY_SIZE(s_phy_defs); phy_id++) {
3318		u32 addr_lo_addr, addr_hi_addr, data_lo_addr, data_hi_addr;
3319		struct phy_defs *phy_defs;
3320		u8 *bytes_buf;
3321
3322		phy_defs = &s_phy_defs[phy_id];
3323		addr_lo_addr = phy_defs->base_addr +
3324			       phy_defs->tbus_addr_lo_addr;
3325		addr_hi_addr = phy_defs->base_addr +
3326			       phy_defs->tbus_addr_hi_addr;
3327		data_lo_addr = phy_defs->base_addr +
3328			       phy_defs->tbus_data_lo_addr;
3329		data_hi_addr = phy_defs->base_addr +
3330			       phy_defs->tbus_data_hi_addr;
3331
3332		if (snprintf(mem_name, sizeof(mem_name), "tbus_%s",
3333			     phy_defs->phy_name) < 0)
3334			DP_NOTICE(p_hwfn,
3335				  "Unexpected debug error: invalid PHY memory name\n");
3336
3337		offset += qed_grc_dump_mem_hdr(p_hwfn,
3338					       dump_buf + offset,
3339					       dump,
3340					       mem_name,
3341					       0,
3342					       PHY_DUMP_SIZE_DWORDS,
3343					       16, true, mem_name, 0);
3344
3345		if (!dump) {
3346			offset += PHY_DUMP_SIZE_DWORDS;
3347			continue;
3348		}
3349
3350		bytes_buf = (u8 *)(dump_buf + offset);
3351		for (tbus_hi_offset = 0;
3352		     tbus_hi_offset < (NUM_PHY_TBUS_ADDRESSES >> 8);
3353		     tbus_hi_offset++) {
3354			qed_wr(p_hwfn, p_ptt, addr_hi_addr, tbus_hi_offset);
3355			for (tbus_lo_offset = 0; tbus_lo_offset < 256;
3356			     tbus_lo_offset++) {
3357				qed_wr(p_hwfn,
3358				       p_ptt, addr_lo_addr, tbus_lo_offset);
3359				*(bytes_buf++) = (u8)qed_rd(p_hwfn,
3360							    p_ptt,
3361							    data_lo_addr);
3362				*(bytes_buf++) = (u8)qed_rd(p_hwfn,
3363							    p_ptt,
3364							    data_hi_addr);
3365			}
3366		}
3367
3368		offset += PHY_DUMP_SIZE_DWORDS;
3369	}
3370
3371	return offset;
3372}
3373
3374/* Dumps the MCP HW dump from NVRAM. Returns the dumped size in dwords. */
3375static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn,
3376				    struct qed_ptt *p_ptt,
3377				    u32 *dump_buf, bool dump)
3378{
3379	u32 hw_dump_offset_bytes = 0, hw_dump_size_bytes = 0;
3380	u32 hw_dump_size_dwords = 0, offset = 0;
3381	enum dbg_status status;
3382
3383	/* Read HW dump image from NVRAM */
3384	status = qed_find_nvram_image(p_hwfn,
3385				      p_ptt,
3386				      NVM_TYPE_HW_DUMP_OUT,
3387				      &hw_dump_offset_bytes,
3388				      &hw_dump_size_bytes,
3389				      false);
3390	if (status != DBG_STATUS_OK)
3391		return 0;
3392
3393	hw_dump_size_dwords = BYTES_TO_DWORDS(hw_dump_size_bytes);
3394
3395	/* Dump HW dump image section */
3396	offset += qed_dump_section_hdr(dump_buf + offset,
3397				       dump, "mcp_hw_dump", 1);
3398	offset += qed_dump_num_param(dump_buf + offset,
3399				     dump, "size", hw_dump_size_dwords);
3400
3401	/* Read MCP HW dump image into dump buffer */
3402	if (dump && hw_dump_size_dwords) {
3403		status = qed_nvram_read(p_hwfn,
3404					p_ptt,
3405					hw_dump_offset_bytes,
3406					hw_dump_size_bytes,
3407					dump_buf + offset,
3408					false);
3409		if (status != DBG_STATUS_OK) {
3410			DP_NOTICE(p_hwfn,
3411				  "Failed to read MCP HW Dump image from NVRAM\n");
3412			return 0;
3413		}
3414	}
3415	offset += hw_dump_size_dwords;
3416
3417	return offset;
3418}
3419
3420/* Dumps Static Debug data. Returns the dumped size in dwords. */
3421static u32 qed_grc_dump_static_debug(struct qed_hwfn *p_hwfn,
3422				     struct qed_ptt *p_ptt,
3423				     u32 *dump_buf, bool dump)
3424{
3425	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3426	u32 block_id, line_id, offset = 0, addr, len;
3427
3428	/* Don't dump static debug if a debug bus recording is in progress */
3429	if (dump && qed_rd(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON))
3430		return 0;
3431
3432	if (dump) {
3433		/* Disable debug bus in all blocks */
3434		qed_bus_disable_blocks(p_hwfn, p_ptt);
3435
3436		qed_bus_reset_dbg_block(p_hwfn, p_ptt);
3437		qed_wr(p_hwfn,
3438		       p_ptt, DBG_REG_FRAMING_MODE, DBG_BUS_FRAME_MODE_8HW);
3439		qed_wr(p_hwfn,
3440		       p_ptt, DBG_REG_DEBUG_TARGET, DBG_BUS_TARGET_ID_INT_BUF);
3441		qed_wr(p_hwfn, p_ptt, DBG_REG_FULL_MODE, 1);
3442		qed_bus_enable_dbg_block(p_hwfn, p_ptt, true);
3443	}
3444
3445	/* Dump all static debug lines for each relevant block */
3446	for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
3447		const struct dbg_block_chip *block_per_chip;
3448		const struct dbg_block *block;
3449		bool is_removed, has_dbg_bus;
3450		u16 modes_buf_offset;
3451		u32 block_dwords;
3452
3453		block_per_chip =
3454		    qed_get_dbg_block_per_chip(p_hwfn, (enum block_id)block_id);
3455		is_removed = GET_FIELD(block_per_chip->flags,
3456				       DBG_BLOCK_CHIP_IS_REMOVED);
3457		has_dbg_bus = GET_FIELD(block_per_chip->flags,
3458					DBG_BLOCK_CHIP_HAS_DBG_BUS);
3459
3460		if (!is_removed && has_dbg_bus &&
3461		    GET_FIELD(block_per_chip->dbg_bus_mode.data,
3462			      DBG_MODE_HDR_EVAL_MODE) > 0) {
3463			modes_buf_offset =
3464			    GET_FIELD(block_per_chip->dbg_bus_mode.data,
3465				      DBG_MODE_HDR_MODES_BUF_OFFSET);
3466			if (!qed_is_mode_match(p_hwfn, &modes_buf_offset))
3467				has_dbg_bus = false;
3468		}
3469
3470		if (is_removed || !has_dbg_bus)
3471			continue;
3472
3473		block_dwords = NUM_DBG_LINES(block_per_chip) *
3474			       STATIC_DEBUG_LINE_DWORDS;
3475
3476		/* Dump static section params */
3477		block = get_dbg_block(p_hwfn, (enum block_id)block_id);
3478		offset += qed_grc_dump_mem_hdr(p_hwfn,
3479					       dump_buf + offset,
3480					       dump,
3481					       block->name,
3482					       0,
3483					       block_dwords,
3484					       32, false, "STATIC", 0);
3485
3486		if (!dump) {
3487			offset += block_dwords;
3488			continue;
3489		}
3490
3491		/* If all lines are invalid - dump zeros */
3492		if (dev_data->block_in_reset[block_id]) {
3493			memset(dump_buf + offset, 0,
3494			       DWORDS_TO_BYTES(block_dwords));
3495			offset += block_dwords;
3496			continue;
3497		}
3498
3499		/* Enable block's client */
3500		qed_bus_enable_clients(p_hwfn,
3501				       p_ptt,
3502				       BIT(block_per_chip->dbg_client_id));
3503
3504		addr = BYTES_TO_DWORDS(DBG_REG_CALENDAR_OUT_DATA);
3505		len = STATIC_DEBUG_LINE_DWORDS;
3506		for (line_id = 0; line_id < (u32)NUM_DBG_LINES(block_per_chip);
3507		     line_id++) {
3508			/* Configure debug line ID */
3509			qed_bus_config_dbg_line(p_hwfn,
3510						p_ptt,
3511						(enum block_id)block_id,
3512						(u8)line_id, 0xf, 0, 0, 0);
3513
3514			/* Read debug line info */
3515			offset += qed_grc_dump_addr_range(p_hwfn,
3516							  p_ptt,
3517							  dump_buf + offset,
3518							  dump,
3519							  addr,
3520							  len,
3521							  true, SPLIT_TYPE_NONE,
3522							  0);
3523		}
3524
3525		/* Disable block's client and debug output */
3526		qed_bus_enable_clients(p_hwfn, p_ptt, 0);
3527		qed_bus_config_dbg_line(p_hwfn, p_ptt,
3528					(enum block_id)block_id, 0, 0, 0, 0, 0);
3529	}
3530
3531	if (dump) {
3532		qed_bus_enable_dbg_block(p_hwfn, p_ptt, false);
3533		qed_bus_enable_clients(p_hwfn, p_ptt, 0);
3534	}
3535
3536	return offset;
3537}
3538
3539/* Performs GRC Dump to the specified buffer.
3540 * Returns the dumped size in dwords.
3541 */
3542static enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn,
3543				    struct qed_ptt *p_ptt,
3544				    u32 *dump_buf,
3545				    bool dump, u32 *num_dumped_dwords)
3546{
3547	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3548	bool parities_masked = false;
3549	u32 dwords_read, offset = 0;
3550	u8 i;
3551
3552	*num_dumped_dwords = 0;
3553	dev_data->num_regs_read = 0;
3554
3555	/* Update reset state */
3556	if (dump)
3557		qed_update_blocks_reset_state(p_hwfn, p_ptt);
3558
3559	/* Dump global params */
3560	offset += qed_dump_common_global_params(p_hwfn,
3561						p_ptt,
3562						dump_buf + offset, dump, 4);
3563	offset += qed_dump_str_param(dump_buf + offset,
3564				     dump, "dump-type", "grc-dump");
3565	offset += qed_dump_num_param(dump_buf + offset,
3566				     dump,
3567				     "num-lcids",
3568				     NUM_OF_LCIDS);
3569	offset += qed_dump_num_param(dump_buf + offset,
3570				     dump,
3571				     "num-ltids",
3572				     NUM_OF_LTIDS);
3573	offset += qed_dump_num_param(dump_buf + offset,
3574				     dump, "num-ports", dev_data->num_ports);
3575
3576	/* Dump reset registers (dumped before taking blocks out of reset ) */
3577	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
3578		offset += qed_grc_dump_reset_regs(p_hwfn,
3579						  p_ptt,
3580						  dump_buf + offset, dump);
3581
3582	/* Take all blocks out of reset (using reset registers) */
3583	if (dump) {
3584		qed_grc_unreset_blocks(p_hwfn, p_ptt, false);
3585		qed_update_blocks_reset_state(p_hwfn, p_ptt);
3586	}
3587
3588	/* Disable all parities using MFW command */
3589	if (dump &&
3590	    !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {
3591		parities_masked = !qed_mcp_mask_parities(p_hwfn, p_ptt, 1);
3592		if (!parities_masked) {
3593			DP_NOTICE(p_hwfn,
3594				  "Failed to mask parities using MFW\n");
3595			if (qed_grc_get_param
3596			    (p_hwfn, DBG_GRC_PARAM_PARITY_SAFE))
3597				return DBG_STATUS_MCP_COULD_NOT_MASK_PRTY;
3598		}
3599	}
3600
3601	/* Dump modified registers (dumped before modifying them) */
3602	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
3603		offset += qed_grc_dump_modified_regs(p_hwfn,
3604						     p_ptt,
3605						     dump_buf + offset, dump);
3606
3607	/* Stall storms */
3608	if (dump &&
3609	    (qed_grc_is_included(p_hwfn,
3610				 DBG_GRC_PARAM_DUMP_IOR) ||
3611	     qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)))
3612		qed_grc_stall_storms(p_hwfn, p_ptt, true);
3613
3614	/* Dump all regs  */
3615	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS)) {
3616		bool block_enable[MAX_BLOCK_ID];
3617
3618		/* Dump all blocks except MCP */
3619		for (i = 0; i < MAX_BLOCK_ID; i++)
3620			block_enable[i] = true;
3621		block_enable[BLOCK_MCP] = false;
3622		offset += qed_grc_dump_registers(p_hwfn,
3623						 p_ptt,
3624						 dump_buf +
3625						 offset,
3626						 dump,
3627						 block_enable, NULL);
3628
3629		/* Dump special registers */
3630		offset += qed_grc_dump_special_regs(p_hwfn,
3631						    p_ptt,
3632						    dump_buf + offset, dump);
3633	}
3634
3635	/* Dump memories */
3636	offset += qed_grc_dump_memories(p_hwfn, p_ptt, dump_buf + offset, dump);
3637
3638	/* Dump MCP */
3639	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP))
3640		offset += qed_grc_dump_mcp(p_hwfn,
3641					   p_ptt, dump_buf + offset, dump);
3642
3643	/* Dump context */
3644	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX))
3645		offset += qed_grc_dump_ctx(p_hwfn,
3646					   p_ptt, dump_buf + offset, dump);
3647
3648	/* Dump RSS memories */
3649	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RSS))
3650		offset += qed_grc_dump_rss(p_hwfn,
3651					   p_ptt, dump_buf + offset, dump);
3652
3653	/* Dump Big RAM */
3654	for (i = 0; i < NUM_BIG_RAM_TYPES; i++)
3655		if (qed_grc_is_included(p_hwfn, s_big_ram_defs[i].grc_param))
3656			offset += qed_grc_dump_big_ram(p_hwfn,
3657						       p_ptt,
3658						       dump_buf + offset,
3659						       dump, i);
3660
3661	/* Dump VFC */
3662	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)) {
3663		dwords_read = qed_grc_dump_vfc(p_hwfn,
3664					       p_ptt, dump_buf + offset, dump);
3665		offset += dwords_read;
3666		if (!dwords_read)
3667			return DBG_STATUS_VFC_READ_ERROR;
3668	}
3669
3670	/* Dump PHY tbus */
3671	if (qed_grc_is_included(p_hwfn,
3672				DBG_GRC_PARAM_DUMP_PHY) && dev_data->chip_id ==
3673	    CHIP_K2 && dev_data->hw_type == HW_TYPE_ASIC)
3674		offset += qed_grc_dump_phy(p_hwfn,
3675					   p_ptt, dump_buf + offset, dump);
3676
3677	/* Dump MCP HW Dump */
3678	if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP_HW_DUMP) &&
3679	    !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP) && 1)
3680		offset += qed_grc_dump_mcp_hw_dump(p_hwfn,
3681						   p_ptt,
3682						   dump_buf + offset, dump);
3683
3684	/* Dump static debug data (only if not during debug bus recording) */
3685	if (qed_grc_is_included(p_hwfn,
3686				DBG_GRC_PARAM_DUMP_STATIC) &&
3687	    (!dump || dev_data->bus.state == DBG_BUS_STATE_IDLE))
3688		offset += qed_grc_dump_static_debug(p_hwfn,
3689						    p_ptt,
3690						    dump_buf + offset, dump);
3691
3692	/* Dump last section */
3693	offset += qed_dump_last_section(dump_buf, offset, dump);
3694
3695	if (dump) {
3696		/* Unstall storms */
3697		if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_UNSTALL))
3698			qed_grc_stall_storms(p_hwfn, p_ptt, false);
3699
3700		/* Clear parity status */
3701		qed_grc_clear_all_prty(p_hwfn, p_ptt);
3702
3703		/* Enable all parities using MFW command */
3704		if (parities_masked)
3705			qed_mcp_mask_parities(p_hwfn, p_ptt, 0);
3706	}
3707
3708	*num_dumped_dwords = offset;
3709
3710	return DBG_STATUS_OK;
3711}
3712
3713/* Writes the specified failing Idle Check rule to the specified buffer.
3714 * Returns the dumped size in dwords.
3715 */
3716static u32 qed_idle_chk_dump_failure(struct qed_hwfn *p_hwfn,
3717				     struct qed_ptt *p_ptt,
3718				     u32 *dump_buf,
3719				     bool dump,
3720				     u16 rule_id,
3721				     const struct dbg_idle_chk_rule *rule,
3722				     u16 fail_entry_id, u32 *cond_reg_values)
3723{
3724	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3725	const struct dbg_idle_chk_cond_reg *cond_regs;
3726	const struct dbg_idle_chk_info_reg *info_regs;
3727	u32 i, next_reg_offset = 0, offset = 0;
3728	struct dbg_idle_chk_result_hdr *hdr;
3729	const union dbg_idle_chk_reg *regs;
3730	u8 reg_id;
3731
3732	hdr = (struct dbg_idle_chk_result_hdr *)dump_buf;
3733	regs = (const union dbg_idle_chk_reg *)
3734		p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr +
3735		rule->reg_offset;
3736	cond_regs = &regs[0].cond_reg;
3737	info_regs = &regs[rule->num_cond_regs].info_reg;
3738
3739	/* Dump rule data */
3740	if (dump) {
3741		memset(hdr, 0, sizeof(*hdr));
3742		hdr->rule_id = rule_id;
3743		hdr->mem_entry_id = fail_entry_id;
3744		hdr->severity = rule->severity;
3745		hdr->num_dumped_cond_regs = rule->num_cond_regs;
3746	}
3747
3748	offset += IDLE_CHK_RESULT_HDR_DWORDS;
3749
3750	/* Dump condition register values */
3751	for (reg_id = 0; reg_id < rule->num_cond_regs; reg_id++) {
3752		const struct dbg_idle_chk_cond_reg *reg = &cond_regs[reg_id];
3753		struct dbg_idle_chk_result_reg_hdr *reg_hdr;
3754
3755		reg_hdr =
3756		    (struct dbg_idle_chk_result_reg_hdr *)(dump_buf + offset);
3757
3758		/* Write register header */
3759		if (!dump) {
3760			offset += IDLE_CHK_RESULT_REG_HDR_DWORDS +
3761			    reg->entry_size;
3762			continue;
3763		}
3764
3765		offset += IDLE_CHK_RESULT_REG_HDR_DWORDS;
3766		memset(reg_hdr, 0, sizeof(*reg_hdr));
3767		reg_hdr->start_entry = reg->start_entry;
3768		reg_hdr->size = reg->entry_size;
3769		SET_FIELD(reg_hdr->data,
3770			  DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM,
3771			  reg->num_entries > 1 || reg->start_entry > 0 ? 1 : 0);
3772		SET_FIELD(reg_hdr->data,
3773			  DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID, reg_id);
3774
3775		/* Write register values */
3776		for (i = 0; i < reg_hdr->size; i++, next_reg_offset++, offset++)
3777			dump_buf[offset] = cond_reg_values[next_reg_offset];
3778	}
3779
3780	/* Dump info register values */
3781	for (reg_id = 0; reg_id < rule->num_info_regs; reg_id++) {
3782		const struct dbg_idle_chk_info_reg *reg = &info_regs[reg_id];
3783		u32 block_id;
3784
3785		/* Check if register's block is in reset */
3786		if (!dump) {
3787			offset += IDLE_CHK_RESULT_REG_HDR_DWORDS + reg->size;
3788			continue;
3789		}
3790
3791		block_id = GET_FIELD(reg->data, DBG_IDLE_CHK_INFO_REG_BLOCK_ID);
3792		if (block_id >= MAX_BLOCK_ID) {
3793			DP_NOTICE(p_hwfn, "Invalid block_id\n");
3794			return 0;
3795		}
3796
3797		if (!dev_data->block_in_reset[block_id]) {
3798			struct dbg_idle_chk_result_reg_hdr *reg_hdr;
3799			bool wide_bus, eval_mode, mode_match = true;
3800			u16 modes_buf_offset;
3801			u32 addr;
3802
3803			reg_hdr = (struct dbg_idle_chk_result_reg_hdr *)
3804				  (dump_buf + offset);
3805
3806			/* Check mode */
3807			eval_mode = GET_FIELD(reg->mode.data,
3808					      DBG_MODE_HDR_EVAL_MODE) > 0;
3809			if (eval_mode) {
3810				modes_buf_offset =
3811				    GET_FIELD(reg->mode.data,
3812					      DBG_MODE_HDR_MODES_BUF_OFFSET);
3813				mode_match =
3814					qed_is_mode_match(p_hwfn,
3815							  &modes_buf_offset);
3816			}
3817
3818			if (!mode_match)
3819				continue;
3820
3821			addr = GET_FIELD(reg->data,
3822					 DBG_IDLE_CHK_INFO_REG_ADDRESS);
3823			wide_bus = GET_FIELD(reg->data,
3824					     DBG_IDLE_CHK_INFO_REG_WIDE_BUS);
3825
3826			/* Write register header */
3827			offset += IDLE_CHK_RESULT_REG_HDR_DWORDS;
3828			hdr->num_dumped_info_regs++;
3829			memset(reg_hdr, 0, sizeof(*reg_hdr));
3830			reg_hdr->size = reg->size;
3831			SET_FIELD(reg_hdr->data,
3832				  DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID,
3833				  rule->num_cond_regs + reg_id);
3834
3835			/* Write register values */
3836			offset += qed_grc_dump_addr_range(p_hwfn,
3837							  p_ptt,
3838							  dump_buf + offset,
3839							  dump,
3840							  addr,
3841							  reg->size, wide_bus,
3842							  SPLIT_TYPE_NONE, 0);
3843		}
3844	}
3845
3846	return offset;
3847}
3848
3849/* Dumps idle check rule entries. Returns the dumped size in dwords. */
3850static u32
3851qed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
3852			       u32 *dump_buf, bool dump,
3853			       const struct dbg_idle_chk_rule *input_rules,
3854			       u32 num_input_rules, u32 *num_failing_rules)
3855{
3856	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3857	u32 cond_reg_values[IDLE_CHK_MAX_ENTRIES_SIZE];
3858	u32 i, offset = 0;
3859	u16 entry_id;
3860	u8 reg_id;
3861
3862	*num_failing_rules = 0;
3863
3864	for (i = 0; i < num_input_rules; i++) {
3865		const struct dbg_idle_chk_cond_reg *cond_regs;
3866		const struct dbg_idle_chk_rule *rule;
3867		const union dbg_idle_chk_reg *regs;
3868		u16 num_reg_entries = 1;
3869		bool check_rule = true;
3870		const u32 *imm_values;
3871
3872		rule = &input_rules[i];
3873		regs = (const union dbg_idle_chk_reg *)
3874			p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr +
3875			rule->reg_offset;
3876		cond_regs = &regs[0].cond_reg;
3877		imm_values =
3878		    (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr +
3879		    rule->imm_offset;
3880
3881		/* Check if all condition register blocks are out of reset, and
3882		 * find maximal number of entries (all condition registers that
3883		 * are memories must have the same size, which is > 1).
3884		 */
3885		for (reg_id = 0; reg_id < rule->num_cond_regs && check_rule;
3886		     reg_id++) {
3887			u32 block_id =
3888				GET_FIELD(cond_regs[reg_id].data,
3889					  DBG_IDLE_CHK_COND_REG_BLOCK_ID);
3890
3891			if (block_id >= MAX_BLOCK_ID) {
3892				DP_NOTICE(p_hwfn, "Invalid block_id\n");
3893				return 0;
3894			}
3895
3896			check_rule = !dev_data->block_in_reset[block_id];
3897			if (cond_regs[reg_id].num_entries > num_reg_entries)
3898				num_reg_entries = cond_regs[reg_id].num_entries;
3899		}
3900
3901		if (!check_rule && dump)
3902			continue;
3903
3904		if (!dump) {
3905			u32 entry_dump_size =
3906				qed_idle_chk_dump_failure(p_hwfn,
3907							  p_ptt,
3908							  dump_buf + offset,
3909							  false,
3910							  rule->rule_id,
3911							  rule,
3912							  0,
3913							  NULL);
3914
3915			offset += num_reg_entries * entry_dump_size;
3916			(*num_failing_rules) += num_reg_entries;
3917			continue;
3918		}
3919
3920		/* Go over all register entries (number of entries is the same
3921		 * for all condition registers).
3922		 */
3923		for (entry_id = 0; entry_id < num_reg_entries; entry_id++) {
3924			u32 next_reg_offset = 0;
3925
3926			/* Read current entry of all condition registers */
3927			for (reg_id = 0; reg_id < rule->num_cond_regs;
3928			     reg_id++) {
3929				const struct dbg_idle_chk_cond_reg *reg =
3930					&cond_regs[reg_id];
3931				u32 padded_entry_size, addr;
3932				bool wide_bus;
3933
3934				/* Find GRC address (if it's a memory, the
3935				 * address of the specific entry is calculated).
3936				 */
3937				addr = GET_FIELD(reg->data,
3938						 DBG_IDLE_CHK_COND_REG_ADDRESS);
3939				wide_bus =
3940				    GET_FIELD(reg->data,
3941					      DBG_IDLE_CHK_COND_REG_WIDE_BUS);
3942				if (reg->num_entries > 1 ||
3943				    reg->start_entry > 0) {
3944					padded_entry_size =
3945					   reg->entry_size > 1 ?
3946					   roundup_pow_of_two(reg->entry_size) :
3947					   1;
3948					addr += (reg->start_entry + entry_id) *
3949						padded_entry_size;
3950				}
3951
3952				/* Read registers */
3953				if (next_reg_offset + reg->entry_size >=
3954				    IDLE_CHK_MAX_ENTRIES_SIZE) {
3955					DP_NOTICE(p_hwfn,
3956						  "idle check registers entry is too large\n");
3957					return 0;
3958				}
3959
3960				next_reg_offset +=
3961				    qed_grc_dump_addr_range(p_hwfn, p_ptt,
3962							    cond_reg_values +
3963							    next_reg_offset,
3964							    dump, addr,
3965							    reg->entry_size,
3966							    wide_bus,
3967							    SPLIT_TYPE_NONE, 0);
3968			}
3969
3970			/* Call rule condition function.
3971			 * If returns true, it's a failure.
3972			 */
3973			if ((*cond_arr[rule->cond_id]) (cond_reg_values,
3974							imm_values)) {
3975				offset += qed_idle_chk_dump_failure(p_hwfn,
3976							p_ptt,
3977							dump_buf + offset,
3978							dump,
3979							rule->rule_id,
3980							rule,
3981							entry_id,
3982							cond_reg_values);
3983				(*num_failing_rules)++;
3984			}
3985		}
3986	}
3987
3988	return offset;
3989}
3990
3991/* Performs Idle Check Dump to the specified buffer.
3992 * Returns the dumped size in dwords.
3993 */
3994static u32 qed_idle_chk_dump(struct qed_hwfn *p_hwfn,
3995			     struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3996{
3997	struct virt_mem_desc *dbg_buf =
3998	    &p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES];
3999	u32 num_failing_rules_offset, offset = 0,
4000	    input_offset = 0, num_failing_rules = 0;
4001
4002	/* Dump global params  - 1 must match below amount of params */
4003	offset += qed_dump_common_global_params(p_hwfn,
4004						p_ptt,
4005						dump_buf + offset, dump, 1);
4006	offset += qed_dump_str_param(dump_buf + offset,
4007				     dump, "dump-type", "idle-chk");
4008
4009	/* Dump idle check section header with a single parameter */
4010	offset += qed_dump_section_hdr(dump_buf + offset, dump, "idle_chk", 1);
4011	num_failing_rules_offset = offset;
4012	offset += qed_dump_num_param(dump_buf + offset, dump, "num_rules", 0);
4013
4014	while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) {
4015		const struct dbg_idle_chk_cond_hdr *cond_hdr =
4016		    (const struct dbg_idle_chk_cond_hdr *)dbg_buf->ptr +
4017		    input_offset++;
4018		bool eval_mode, mode_match = true;
4019		u32 curr_failing_rules;
4020		u16 modes_buf_offset;
4021
4022		/* Check mode */
4023		eval_mode = GET_FIELD(cond_hdr->mode.data,
4024				      DBG_MODE_HDR_EVAL_MODE) > 0;
4025		if (eval_mode) {
4026			modes_buf_offset =
4027				GET_FIELD(cond_hdr->mode.data,
4028					  DBG_MODE_HDR_MODES_BUF_OFFSET);
4029			mode_match = qed_is_mode_match(p_hwfn,
4030						       &modes_buf_offset);
4031		}
4032
4033		if (mode_match) {
4034			const struct dbg_idle_chk_rule *rule =
4035			    (const struct dbg_idle_chk_rule *)((u32 *)
4036							       dbg_buf->ptr
4037							       + input_offset);
4038			u32 num_input_rules =
4039				cond_hdr->data_size / IDLE_CHK_RULE_SIZE_DWORDS;
4040			offset +=
4041			    qed_idle_chk_dump_rule_entries(p_hwfn,
4042							   p_ptt,
4043							   dump_buf +
4044							   offset,
4045							   dump,
4046							   rule,
4047							   num_input_rules,
4048							   &curr_failing_rules);
4049			num_failing_rules += curr_failing_rules;
4050		}
4051
4052		input_offset += cond_hdr->data_size;
4053	}
4054
4055	/* Overwrite num_rules parameter */
4056	if (dump)
4057		qed_dump_num_param(dump_buf + num_failing_rules_offset,
4058				   dump, "num_rules", num_failing_rules);
4059
4060	/* Dump last section */
4061	offset += qed_dump_last_section(dump_buf, offset, dump);
4062
4063	return offset;
4064}
4065
4066/* Get info on the MCP Trace data in the scratchpad:
4067 * - trace_data_grc_addr (OUT): trace data GRC address in bytes
4068 * - trace_data_size (OUT): trace data size in bytes (without the header)
4069 */
4070static enum dbg_status qed_mcp_trace_get_data_info(struct qed_hwfn *p_hwfn,
4071						   struct qed_ptt *p_ptt,
4072						   u32 *trace_data_grc_addr,
4073						   u32 *trace_data_size)
4074{
4075	u32 spad_trace_offsize, signature;
4076
4077	/* Read trace section offsize structure from MCP scratchpad */
4078	spad_trace_offsize = qed_rd(p_hwfn, p_ptt, MCP_SPAD_TRACE_OFFSIZE_ADDR);
4079
4080	/* Extract trace section address from offsize (in scratchpad) */
4081	*trace_data_grc_addr =
4082		MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize);
4083
4084	/* Read signature from MCP trace section */
4085	signature = qed_rd(p_hwfn, p_ptt,
4086			   *trace_data_grc_addr +
4087			   offsetof(struct mcp_trace, signature));
4088
4089	if (signature != MFW_TRACE_SIGNATURE)
4090		return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4091
4092	/* Read trace size from MCP trace section */
4093	*trace_data_size = qed_rd(p_hwfn,
4094				  p_ptt,
4095				  *trace_data_grc_addr +
4096				  offsetof(struct mcp_trace, size));
4097
4098	return DBG_STATUS_OK;
4099}
4100
4101/* Reads MCP trace meta data image from NVRAM
4102 * - running_bundle_id (OUT): running bundle ID (invalid when loaded from file)
4103 * - trace_meta_offset (OUT): trace meta offset in NVRAM in bytes (invalid when
4104 *			      loaded from file).
4105 * - trace_meta_size (OUT):   size in bytes of the trace meta data.
4106 */
4107static enum dbg_status qed_mcp_trace_get_meta_info(struct qed_hwfn *p_hwfn,
4108						   struct qed_ptt *p_ptt,
4109						   u32 trace_data_size_bytes,
4110						   u32 *running_bundle_id,
4111						   u32 *trace_meta_offset,
4112						   u32 *trace_meta_size)
4113{
4114	u32 spad_trace_offsize, nvram_image_type, running_mfw_addr;
4115
4116	/* Read MCP trace section offsize structure from MCP scratchpad */
4117	spad_trace_offsize = qed_rd(p_hwfn, p_ptt, MCP_SPAD_TRACE_OFFSIZE_ADDR);
4118
4119	/* Find running bundle ID */
4120	running_mfw_addr =
4121		MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize) +
4122		QED_SECTION_SIZE(spad_trace_offsize) + trace_data_size_bytes;
4123	*running_bundle_id = qed_rd(p_hwfn, p_ptt, running_mfw_addr);
4124	if (*running_bundle_id > 1)
4125		return DBG_STATUS_INVALID_NVRAM_BUNDLE;
4126
4127	/* Find image in NVRAM */
4128	nvram_image_type =
4129	    (*running_bundle_id ==
4130	     DIR_ID_1) ? NVM_TYPE_MFW_TRACE1 : NVM_TYPE_MFW_TRACE2;
4131	return qed_find_nvram_image(p_hwfn,
4132				    p_ptt,
4133				    nvram_image_type,
4134				    trace_meta_offset,
4135				    trace_meta_size,
4136				    true);
4137}
4138
4139/* Reads the MCP Trace meta data from NVRAM into the specified buffer */
4140static enum dbg_status qed_mcp_trace_read_meta(struct qed_hwfn *p_hwfn,
4141					       struct qed_ptt *p_ptt,
4142					       u32 nvram_offset_in_bytes,
4143					       u32 size_in_bytes, u32 *buf)
4144{
4145	u8 modules_num, module_len, i, *byte_buf = (u8 *)buf;
4146	enum dbg_status status;
4147	u32 signature;
4148
4149	/* Read meta data from NVRAM */
4150	status = qed_nvram_read(p_hwfn,
4151				p_ptt,
4152				nvram_offset_in_bytes,
4153				size_in_bytes,
4154				buf,
4155				true);
4156	if (status != DBG_STATUS_OK)
4157		return status;
4158
4159	/* Extract and check first signature */
4160	signature = qed_read_unaligned_dword(byte_buf);
4161	byte_buf += sizeof(signature);
4162	if (signature != NVM_MAGIC_VALUE)
4163		return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4164
4165	/* Extract number of modules */
4166	modules_num = *(byte_buf++);
4167
4168	/* Skip all modules */
4169	for (i = 0; i < modules_num; i++) {
4170		module_len = *(byte_buf++);
4171		byte_buf += module_len;
4172	}
4173
4174	/* Extract and check second signature */
4175	signature = qed_read_unaligned_dword(byte_buf);
4176	byte_buf += sizeof(signature);
4177	if (signature != NVM_MAGIC_VALUE)
4178		return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4179
4180	return DBG_STATUS_OK;
4181}
4182
4183/* Dump MCP Trace */
4184static enum dbg_status qed_mcp_trace_dump(struct qed_hwfn *p_hwfn,
4185					  struct qed_ptt *p_ptt,
4186					  u32 *dump_buf,
4187					  bool dump, u32 *num_dumped_dwords)
4188{
4189	u32 trace_data_grc_addr, trace_data_size_bytes, trace_data_size_dwords;
4190	u32 trace_meta_size_dwords = 0, running_bundle_id, offset = 0;
4191	u32 trace_meta_offset_bytes = 0, trace_meta_size_bytes = 0;
4192	enum dbg_status status;
4193	int halted = 0;
4194	bool use_mfw;
4195
4196	*num_dumped_dwords = 0;
4197
4198	use_mfw = !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP);
4199
4200	/* Get trace data info */
4201	status = qed_mcp_trace_get_data_info(p_hwfn,
4202					     p_ptt,
4203					     &trace_data_grc_addr,
4204					     &trace_data_size_bytes);
4205	if (status != DBG_STATUS_OK)
4206		return status;
4207
4208	/* Dump global params */
4209	offset += qed_dump_common_global_params(p_hwfn,
4210						p_ptt,
4211						dump_buf + offset, dump, 1);
4212	offset += qed_dump_str_param(dump_buf + offset,
4213				     dump, "dump-type", "mcp-trace");
4214
4215	/* Halt MCP while reading from scratchpad so the read data will be
4216	 * consistent. if halt fails, MCP trace is taken anyway, with a small
4217	 * risk that it may be corrupt.
4218	 */
4219	if (dump && use_mfw) {
4220		halted = !qed_mcp_halt(p_hwfn, p_ptt);
4221		if (!halted)
4222			DP_NOTICE(p_hwfn, "MCP halt failed!\n");
4223	}
4224
4225	/* Find trace data size */
4226	trace_data_size_dwords =
4227	    DIV_ROUND_UP(trace_data_size_bytes + sizeof(struct mcp_trace),
4228			 BYTES_IN_DWORD);
4229
4230	/* Dump trace data section header and param */
4231	offset += qed_dump_section_hdr(dump_buf + offset,
4232				       dump, "mcp_trace_data", 1);
4233	offset += qed_dump_num_param(dump_buf + offset,
4234				     dump, "size", trace_data_size_dwords);
4235
4236	/* Read trace data from scratchpad into dump buffer */
4237	offset += qed_grc_dump_addr_range(p_hwfn,
4238					  p_ptt,
4239					  dump_buf + offset,
4240					  dump,
4241					  BYTES_TO_DWORDS(trace_data_grc_addr),
4242					  trace_data_size_dwords, false,
4243					  SPLIT_TYPE_NONE, 0);
4244
4245	/* Resume MCP (only if halt succeeded) */
4246	if (halted && qed_mcp_resume(p_hwfn, p_ptt))
4247		DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n");
4248
4249	/* Dump trace meta section header */
4250	offset += qed_dump_section_hdr(dump_buf + offset,
4251				       dump, "mcp_trace_meta", 1);
4252
4253	/* If MCP Trace meta size parameter was set, use it.
4254	 * Otherwise, read trace meta.
4255	 * trace_meta_size_bytes is dword-aligned.
4256	 */
4257	trace_meta_size_bytes =
4258		qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_MCP_TRACE_META_SIZE);
4259	if ((!trace_meta_size_bytes || dump) && use_mfw)
4260		status = qed_mcp_trace_get_meta_info(p_hwfn,
4261						     p_ptt,
4262						     trace_data_size_bytes,
4263						     &running_bundle_id,
4264						     &trace_meta_offset_bytes,
4265						     &trace_meta_size_bytes);
4266	if (status == DBG_STATUS_OK)
4267		trace_meta_size_dwords = BYTES_TO_DWORDS(trace_meta_size_bytes);
4268
4269	/* Dump trace meta size param */
4270	offset += qed_dump_num_param(dump_buf + offset,
4271				     dump, "size", trace_meta_size_dwords);
4272
4273	/* Read trace meta image into dump buffer */
4274	if (dump && trace_meta_size_dwords)
4275		status = qed_mcp_trace_read_meta(p_hwfn,
4276						 p_ptt,
4277						 trace_meta_offset_bytes,
4278						 trace_meta_size_bytes,
4279						 dump_buf + offset);
4280	if (status == DBG_STATUS_OK)
4281		offset += trace_meta_size_dwords;
4282
4283	/* Dump last section */
4284	offset += qed_dump_last_section(dump_buf, offset, dump);
4285
4286	*num_dumped_dwords = offset;
4287
4288	/* If no mcp access, indicate that the dump doesn't contain the meta
4289	 * data from NVRAM.
4290	 */
4291	return use_mfw ? status : DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
4292}
4293
4294/* Dump GRC FIFO */
4295static enum dbg_status qed_reg_fifo_dump(struct qed_hwfn *p_hwfn,
4296					 struct qed_ptt *p_ptt,
4297					 u32 *dump_buf,
4298					 bool dump, u32 *num_dumped_dwords)
4299{
4300	u32 dwords_read, size_param_offset, offset = 0, addr, len;
4301	bool fifo_has_data;
4302
4303	*num_dumped_dwords = 0;
4304
4305	/* Dump global params */
4306	offset += qed_dump_common_global_params(p_hwfn,
4307						p_ptt,
4308						dump_buf + offset, dump, 1);
4309	offset += qed_dump_str_param(dump_buf + offset,
4310				     dump, "dump-type", "reg-fifo");
4311
4312	/* Dump fifo data section header and param. The size param is 0 for
4313	 * now, and is overwritten after reading the FIFO.
4314	 */
4315	offset += qed_dump_section_hdr(dump_buf + offset,
4316				       dump, "reg_fifo_data", 1);
4317	size_param_offset = offset;
4318	offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4319
4320	if (!dump) {
4321		/* FIFO max size is REG_FIFO_DEPTH_DWORDS. There is no way to
4322		 * test how much data is available, except for reading it.
4323		 */
4324		offset += REG_FIFO_DEPTH_DWORDS;
4325		goto out;
4326	}
4327
4328	fifo_has_data = qed_rd(p_hwfn, p_ptt,
4329			       GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
4330
4331	/* Pull available data from fifo. Use DMAE since this is widebus memory
4332	 * and must be accessed atomically. Test for dwords_read not passing
4333	 * buffer size since more entries could be added to the buffer as we are
4334	 * emptying it.
4335	 */
4336	addr = BYTES_TO_DWORDS(GRC_REG_TRACE_FIFO);
4337	len = REG_FIFO_ELEMENT_DWORDS;
4338	for (dwords_read = 0;
4339	     fifo_has_data && dwords_read < REG_FIFO_DEPTH_DWORDS;
4340	     dwords_read += REG_FIFO_ELEMENT_DWORDS) {
4341		offset += qed_grc_dump_addr_range(p_hwfn,
4342						  p_ptt,
4343						  dump_buf + offset,
4344						  true,
4345						  addr,
4346						  len,
4347						  true, SPLIT_TYPE_NONE,
4348						  0);
4349		fifo_has_data = qed_rd(p_hwfn, p_ptt,
4350				       GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
4351	}
4352
4353	qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4354			   dwords_read);
4355out:
4356	/* Dump last section */
4357	offset += qed_dump_last_section(dump_buf, offset, dump);
4358
4359	*num_dumped_dwords = offset;
4360
4361	return DBG_STATUS_OK;
4362}
4363
4364/* Dump IGU FIFO */
4365static enum dbg_status qed_igu_fifo_dump(struct qed_hwfn *p_hwfn,
4366					 struct qed_ptt *p_ptt,
4367					 u32 *dump_buf,
4368					 bool dump, u32 *num_dumped_dwords)
4369{
4370	u32 dwords_read, size_param_offset, offset = 0, addr, len;
4371	bool fifo_has_data;
4372
4373	*num_dumped_dwords = 0;
4374
4375	/* Dump global params */
4376	offset += qed_dump_common_global_params(p_hwfn,
4377						p_ptt,
4378						dump_buf + offset, dump, 1);
4379	offset += qed_dump_str_param(dump_buf + offset,
4380				     dump, "dump-type", "igu-fifo");
4381
4382	/* Dump fifo data section header and param. The size param is 0 for
4383	 * now, and is overwritten after reading the FIFO.
4384	 */
4385	offset += qed_dump_section_hdr(dump_buf + offset,
4386				       dump, "igu_fifo_data", 1);
4387	size_param_offset = offset;
4388	offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4389
4390	if (!dump) {
4391		/* FIFO max size is IGU_FIFO_DEPTH_DWORDS. There is no way to
4392		 * test how much data is available, except for reading it.
4393		 */
4394		offset += IGU_FIFO_DEPTH_DWORDS;
4395		goto out;
4396	}
4397
4398	fifo_has_data = qed_rd(p_hwfn, p_ptt,
4399			       IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
4400
4401	/* Pull available data from fifo. Use DMAE since this is widebus memory
4402	 * and must be accessed atomically. Test for dwords_read not passing
4403	 * buffer size since more entries could be added to the buffer as we are
4404	 * emptying it.
4405	 */
4406	addr = BYTES_TO_DWORDS(IGU_REG_ERROR_HANDLING_MEMORY);
4407	len = IGU_FIFO_ELEMENT_DWORDS;
4408	for (dwords_read = 0;
4409	     fifo_has_data && dwords_read < IGU_FIFO_DEPTH_DWORDS;
4410	     dwords_read += IGU_FIFO_ELEMENT_DWORDS) {
4411		offset += qed_grc_dump_addr_range(p_hwfn,
4412						  p_ptt,
4413						  dump_buf + offset,
4414						  true,
4415						  addr,
4416						  len,
4417						  true, SPLIT_TYPE_NONE,
4418						  0);
4419		fifo_has_data = qed_rd(p_hwfn, p_ptt,
4420				       IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
4421	}
4422
4423	qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4424			   dwords_read);
4425out:
4426	/* Dump last section */
4427	offset += qed_dump_last_section(dump_buf, offset, dump);
4428
4429	*num_dumped_dwords = offset;
4430
4431	return DBG_STATUS_OK;
4432}
4433
4434/* Protection Override dump */
4435static enum dbg_status qed_protection_override_dump(struct qed_hwfn *p_hwfn,
4436						    struct qed_ptt *p_ptt,
4437						    u32 *dump_buf,
4438						    bool dump,
4439						    u32 *num_dumped_dwords)
4440{
4441	u32 size_param_offset, override_window_dwords, offset = 0, addr;
4442
4443	*num_dumped_dwords = 0;
4444
4445	/* Dump global params */
4446	offset += qed_dump_common_global_params(p_hwfn,
4447						p_ptt,
4448						dump_buf + offset, dump, 1);
4449	offset += qed_dump_str_param(dump_buf + offset,
4450				     dump, "dump-type", "protection-override");
4451
4452	/* Dump data section header and param. The size param is 0 for now,
4453	 * and is overwritten after reading the data.
4454	 */
4455	offset += qed_dump_section_hdr(dump_buf + offset,
4456				       dump, "protection_override_data", 1);
4457	size_param_offset = offset;
4458	offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4459
4460	if (!dump) {
4461		offset += PROTECTION_OVERRIDE_DEPTH_DWORDS;
4462		goto out;
4463	}
4464
4465	/* Add override window info to buffer, preventing buffer overflow */
4466	override_window_dwords =
4467		min(qed_rd(p_hwfn, p_ptt, GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW) *
4468		PROTECTION_OVERRIDE_ELEMENT_DWORDS,
4469		PROTECTION_OVERRIDE_DEPTH_DWORDS);
4470	if (override_window_dwords) {
4471		addr = BYTES_TO_DWORDS(GRC_REG_PROTECTION_OVERRIDE_WINDOW);
4472		offset += qed_grc_dump_addr_range(p_hwfn,
4473						  p_ptt,
4474						  dump_buf + offset,
4475						  true,
4476						  addr,
4477						  override_window_dwords,
4478						  true, SPLIT_TYPE_NONE, 0);
4479		qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4480				   override_window_dwords);
4481	}
4482out:
4483	/* Dump last section */
4484	offset += qed_dump_last_section(dump_buf, offset, dump);
4485
4486	*num_dumped_dwords = offset;
4487
4488	return DBG_STATUS_OK;
4489}
4490
4491/* Performs FW Asserts Dump to the specified buffer.
4492 * Returns the dumped size in dwords.
4493 */
4494static u32 qed_fw_asserts_dump(struct qed_hwfn *p_hwfn,
4495			       struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
4496{
4497	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4498	struct fw_asserts_ram_section *asserts;
4499	char storm_letter_str[2] = "?";
4500	struct fw_info fw_info;
4501	u32 offset = 0;
4502	u8 storm_id;
4503
4504	/* Dump global params */
4505	offset += qed_dump_common_global_params(p_hwfn,
4506						p_ptt,
4507						dump_buf + offset, dump, 1);
4508	offset += qed_dump_str_param(dump_buf + offset,
4509				     dump, "dump-type", "fw-asserts");
4510
4511	/* Find Storm dump size */
4512	for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
4513		u32 fw_asserts_section_addr, next_list_idx_addr, next_list_idx;
4514		struct storm_defs *storm = &s_storm_defs[storm_id];
4515		u32 last_list_idx, addr;
4516
4517		if (dev_data->block_in_reset[storm->sem_block_id])
4518			continue;
4519
4520		/* Read FW info for the current Storm */
4521		qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, &fw_info);
4522
4523		asserts = &fw_info.fw_asserts_section;
4524
4525		/* Dump FW Asserts section header and params */
4526		storm_letter_str[0] = storm->letter;
4527		offset += qed_dump_section_hdr(dump_buf + offset,
4528					       dump, "fw_asserts", 2);
4529		offset += qed_dump_str_param(dump_buf + offset,
4530					     dump, "storm", storm_letter_str);
4531		offset += qed_dump_num_param(dump_buf + offset,
4532					     dump,
4533					     "size",
4534					     asserts->list_element_dword_size);
4535
4536		/* Read and dump FW Asserts data */
4537		if (!dump) {
4538			offset += asserts->list_element_dword_size;
4539			continue;
4540		}
4541
4542		addr = le16_to_cpu(asserts->section_ram_line_offset);
4543		fw_asserts_section_addr = storm->sem_fast_mem_addr +
4544					  SEM_FAST_REG_INT_RAM +
4545					  RAM_LINES_TO_BYTES(addr);
4546
4547		next_list_idx_addr = fw_asserts_section_addr +
4548			DWORDS_TO_BYTES(asserts->list_next_index_dword_offset);
4549		next_list_idx = qed_rd(p_hwfn, p_ptt, next_list_idx_addr);
4550		last_list_idx = (next_list_idx > 0 ?
4551				 next_list_idx :
4552				 asserts->list_num_elements) - 1;
4553		addr = BYTES_TO_DWORDS(fw_asserts_section_addr) +
4554		       asserts->list_dword_offset +
4555		       last_list_idx * asserts->list_element_dword_size;
4556		offset +=
4557		    qed_grc_dump_addr_range(p_hwfn, p_ptt,
4558					    dump_buf + offset,
4559					    dump, addr,
4560					    asserts->list_element_dword_size,
4561						  false, SPLIT_TYPE_NONE, 0);
4562	}
4563
4564	/* Dump last section */
4565	offset += qed_dump_last_section(dump_buf, offset, dump);
4566
4567	return offset;
4568}
4569
4570/* Dumps the specified ILT pages to the specified buffer.
4571 * Returns the dumped size in dwords.
4572 */
4573static u32 qed_ilt_dump_pages_range(u32 *dump_buf, u32 *given_offset,
4574				    bool *dump, u32 start_page_id,
4575				    u32 num_pages,
4576				    struct phys_mem_desc *ilt_pages,
4577				    bool dump_page_ids, u32 buf_size_in_dwords,
4578				    u32 *given_actual_dump_size_in_dwords)
4579{
4580	u32 actual_dump_size_in_dwords = *given_actual_dump_size_in_dwords;
4581	u32 page_id, end_page_id, offset = *given_offset;
4582	struct phys_mem_desc *mem_desc = NULL;
4583	bool continue_dump = *dump;
4584	u32 partial_page_size = 0;
4585
4586	if (num_pages == 0)
4587		return offset;
4588
4589	end_page_id = start_page_id + num_pages - 1;
4590
4591	for (page_id = start_page_id; page_id <= end_page_id; page_id++) {
4592		mem_desc = &ilt_pages[page_id];
4593		if (!ilt_pages[page_id].virt_addr)
4594			continue;
4595
4596		if (dump_page_ids) {
4597			/* Copy page ID to dump buffer
4598			 * (if dump is needed and buffer is not full)
4599			 */
4600			if ((continue_dump) &&
4601			    (offset + 1 > buf_size_in_dwords)) {
4602				continue_dump = false;
4603				actual_dump_size_in_dwords = offset;
4604			}
4605			if (continue_dump)
4606				*(dump_buf + offset) = page_id;
4607			offset++;
4608		} else {
4609			/* Copy page memory to dump buffer */
4610			if ((continue_dump) &&
4611			    (offset + BYTES_TO_DWORDS(mem_desc->size) >
4612			     buf_size_in_dwords)) {
4613				if (offset + BYTES_TO_DWORDS(mem_desc->size) >
4614				    buf_size_in_dwords) {
4615					partial_page_size =
4616					    buf_size_in_dwords - offset;
4617					memcpy(dump_buf + offset,
4618					       mem_desc->virt_addr,
4619					       partial_page_size);
4620					continue_dump = false;
4621					actual_dump_size_in_dwords =
4622					    offset + partial_page_size;
4623				}
4624			}
4625
4626			if (continue_dump)
4627				memcpy(dump_buf + offset,
4628				       mem_desc->virt_addr, mem_desc->size);
4629			offset += BYTES_TO_DWORDS(mem_desc->size);
4630		}
4631	}
4632
4633	*dump = continue_dump;
4634	*given_offset = offset;
4635	*given_actual_dump_size_in_dwords = actual_dump_size_in_dwords;
4636
4637	return offset;
4638}
4639
4640/* Dumps a section containing the dumped ILT pages.
4641 * Returns the dumped size in dwords.
4642 */
4643static u32 qed_ilt_dump_pages_section(struct qed_hwfn *p_hwfn,
4644				      u32 *dump_buf,
4645				      u32 *given_offset,
4646				      bool *dump,
4647				      u32 valid_conn_pf_pages,
4648				      u32 valid_conn_vf_pages,
4649				      struct phys_mem_desc *ilt_pages,
4650				      bool dump_page_ids,
4651				      u32 buf_size_in_dwords,
4652				      u32 *given_actual_dump_size_in_dwords)
4653{
4654	struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
4655	u32 pf_start_line, start_page_id, offset = *given_offset;
4656	u32 cdut_pf_init_pages, cdut_vf_init_pages;
4657	u32 cdut_pf_work_pages, cdut_vf_work_pages;
4658	u32 base_data_offset, size_param_offset;
4659	u32 src_pages;
4660	u32 section_header_and_param_size;
4661	u32 cdut_pf_pages, cdut_vf_pages;
4662	u32 actual_dump_size_in_dwords;
4663	bool continue_dump = *dump;
4664	bool update_size = *dump;
4665	const char *section_name;
4666	u32 i;
4667
4668	actual_dump_size_in_dwords = *given_actual_dump_size_in_dwords;
4669	section_name = dump_page_ids ? "ilt_page_ids" : "ilt_page_mem";
4670	cdut_pf_init_pages = qed_get_cdut_num_pf_init_pages(p_hwfn);
4671	cdut_vf_init_pages = qed_get_cdut_num_vf_init_pages(p_hwfn);
4672	cdut_pf_work_pages = qed_get_cdut_num_pf_work_pages(p_hwfn);
4673	cdut_vf_work_pages = qed_get_cdut_num_vf_work_pages(p_hwfn);
4674	cdut_pf_pages = cdut_pf_init_pages + cdut_pf_work_pages;
4675	cdut_vf_pages = cdut_vf_init_pages + cdut_vf_work_pages;
4676	pf_start_line = p_hwfn->p_cxt_mngr->pf_start_line;
4677	section_header_and_param_size = qed_dump_section_hdr(NULL,
4678							     false,
4679							     section_name,
4680							     1) +
4681	qed_dump_num_param(NULL, false, "size", 0);
4682
4683	if ((continue_dump) &&
4684	    (offset + section_header_and_param_size > buf_size_in_dwords)) {
4685		continue_dump = false;
4686		update_size = false;
4687		actual_dump_size_in_dwords = offset;
4688	}
4689
4690	offset += qed_dump_section_hdr(dump_buf + offset,
4691				       continue_dump, section_name, 1);
4692
4693	/* Dump size parameter (0 for now, overwritten with real size later) */
4694	size_param_offset = offset;
4695	offset += qed_dump_num_param(dump_buf + offset,
4696				     continue_dump, "size", 0);
4697	base_data_offset = offset;
4698
4699	/* CDUC pages are ordered as follows:
4700	 * - PF pages - valid section (included in PF connection type mapping)
4701	 * - PF pages - invalid section (not dumped)
4702	 * - For each VF in the PF:
4703	 *   - VF pages - valid section (included in VF connection type mapping)
4704	 *   - VF pages - invalid section (not dumped)
4705	 */
4706	if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUC)) {
4707		/* Dump connection PF pages */
4708		start_page_id = clients[ILT_CLI_CDUC].first.val - pf_start_line;
4709		qed_ilt_dump_pages_range(dump_buf, &offset, &continue_dump,
4710					 start_page_id, valid_conn_pf_pages,
4711					 ilt_pages, dump_page_ids,
4712					 buf_size_in_dwords,
4713					 &actual_dump_size_in_dwords);
4714
4715		/* Dump connection VF pages */
4716		start_page_id += clients[ILT_CLI_CDUC].pf_total_lines;
4717		for (i = 0; i < p_hwfn->p_cxt_mngr->vf_count;
4718		     i++, start_page_id += clients[ILT_CLI_CDUC].vf_total_lines)
4719			qed_ilt_dump_pages_range(dump_buf, &offset,
4720						 &continue_dump, start_page_id,
4721						 valid_conn_vf_pages,
4722						 ilt_pages, dump_page_ids,
4723						 buf_size_in_dwords,
4724						 &actual_dump_size_in_dwords);
4725	}
4726
4727	/* CDUT pages are ordered as follows:
4728	 * - PF init pages (not dumped)
4729	 * - PF work pages
4730	 * - For each VF in the PF:
4731	 *   - VF init pages (not dumped)
4732	 *   - VF work pages
4733	 */
4734	if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUT)) {
4735		/* Dump task PF pages */
4736		start_page_id = clients[ILT_CLI_CDUT].first.val +
4737		    cdut_pf_init_pages - pf_start_line;
4738		qed_ilt_dump_pages_range(dump_buf, &offset, &continue_dump,
4739					 start_page_id, cdut_pf_work_pages,
4740					 ilt_pages, dump_page_ids,
4741					 buf_size_in_dwords,
4742					 &actual_dump_size_in_dwords);
4743
4744		/* Dump task VF pages */
4745		start_page_id = clients[ILT_CLI_CDUT].first.val +
4746		    cdut_pf_pages + cdut_vf_init_pages - pf_start_line;
4747		for (i = 0; i < p_hwfn->p_cxt_mngr->vf_count;
4748		     i++, start_page_id += cdut_vf_pages)
4749			qed_ilt_dump_pages_range(dump_buf, &offset,
4750						 &continue_dump, start_page_id,
4751						 cdut_vf_work_pages, ilt_pages,
4752						 dump_page_ids,
4753						 buf_size_in_dwords,
4754						 &actual_dump_size_in_dwords);
4755	}
4756
4757	/*Dump Searcher pages */
4758	if (clients[ILT_CLI_SRC].active) {
4759		start_page_id = clients[ILT_CLI_SRC].first.val - pf_start_line;
4760		src_pages = clients[ILT_CLI_SRC].last.val -
4761		    clients[ILT_CLI_SRC].first.val + 1;
4762		qed_ilt_dump_pages_range(dump_buf, &offset, &continue_dump,
4763					 start_page_id, src_pages, ilt_pages,
4764					 dump_page_ids, buf_size_in_dwords,
4765					 &actual_dump_size_in_dwords);
4766	}
4767
4768	/* Overwrite size param */
4769	if (update_size) {
4770		u32 section_size = (*dump == continue_dump) ?
4771		    offset - base_data_offset :
4772		    actual_dump_size_in_dwords - base_data_offset;
4773		if (section_size > 0)
4774			qed_dump_num_param(dump_buf + size_param_offset,
4775					   *dump, "size", section_size);
4776		else if ((section_size == 0) && (*dump != continue_dump))
4777			actual_dump_size_in_dwords -=
4778			    section_header_and_param_size;
4779	}
4780
4781	*dump = continue_dump;
4782	*given_offset = offset;
4783	*given_actual_dump_size_in_dwords = actual_dump_size_in_dwords;
4784
4785	return offset;
4786}
4787
4788/* Dumps a section containing the global parameters.
4789 * Part of ilt dump process
4790 * Returns the dumped size in dwords.
4791 */
4792static u32
4793qed_ilt_dump_dump_common_global_params(struct qed_hwfn *p_hwfn,
4794				       struct qed_ptt *p_ptt,
4795				       u32 *dump_buf,
4796				       bool dump,
4797				       u32 cduc_page_size,
4798				       u32 conn_ctx_size,
4799				       u32 cdut_page_size,
4800				       u32 *full_dump_size_param_offset,
4801				       u32 *actual_dump_size_param_offset)
4802{
4803	struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
4804	u32 offset = 0;
4805
4806	offset += qed_dump_common_global_params(p_hwfn, p_ptt,
4807						dump_buf + offset,
4808						dump, 30);
4809	offset += qed_dump_str_param(dump_buf + offset,
4810				     dump,
4811				     "dump-type", "ilt-dump");
4812	offset += qed_dump_num_param(dump_buf + offset,
4813				     dump,
4814				     "cduc-page-size",
4815				     cduc_page_size);
4816	offset += qed_dump_num_param(dump_buf + offset,
4817				     dump,
4818				     "cduc-first-page-id",
4819				     clients[ILT_CLI_CDUC].first.val);
4820	offset += qed_dump_num_param(dump_buf + offset,
4821				     dump,
4822				     "cduc-last-page-id",
4823				     clients[ILT_CLI_CDUC].last.val);
4824	offset += qed_dump_num_param(dump_buf + offset,
4825				     dump,
4826				     "cduc-num-pf-pages",
4827				     clients[ILT_CLI_CDUC].pf_total_lines);
4828	offset += qed_dump_num_param(dump_buf + offset,
4829				     dump,
4830				     "cduc-num-vf-pages",
4831				     clients[ILT_CLI_CDUC].vf_total_lines);
4832	offset += qed_dump_num_param(dump_buf + offset,
4833				     dump,
4834				     "max-conn-ctx-size",
4835				     conn_ctx_size);
4836	offset += qed_dump_num_param(dump_buf + offset,
4837				     dump,
4838				     "cdut-page-size",
4839				     cdut_page_size);
4840	offset += qed_dump_num_param(dump_buf + offset,
4841				     dump,
4842				     "cdut-first-page-id",
4843				     clients[ILT_CLI_CDUT].first.val);
4844	offset += qed_dump_num_param(dump_buf + offset,
4845				     dump,
4846				     "cdut-last-page-id",
4847				     clients[ILT_CLI_CDUT].last.val);
4848	offset += qed_dump_num_param(dump_buf + offset,
4849				     dump,
4850				     "cdut-num-pf-init-pages",
4851				     qed_get_cdut_num_pf_init_pages(p_hwfn));
4852	offset += qed_dump_num_param(dump_buf + offset,
4853				     dump,
4854				     "cdut-num-vf-init-pages",
4855				     qed_get_cdut_num_vf_init_pages(p_hwfn));
4856	offset += qed_dump_num_param(dump_buf + offset,
4857				     dump,
4858				     "cdut-num-pf-work-pages",
4859				     qed_get_cdut_num_pf_work_pages(p_hwfn));
4860	offset += qed_dump_num_param(dump_buf + offset,
4861				     dump,
4862				     "cdut-num-vf-work-pages",
4863				     qed_get_cdut_num_vf_work_pages(p_hwfn));
4864	offset += qed_dump_num_param(dump_buf + offset,
4865				     dump,
4866				     "max-task-ctx-size",
4867				     p_hwfn->p_cxt_mngr->task_ctx_size);
4868	offset += qed_dump_num_param(dump_buf + offset,
4869				     dump,
4870				     "first-vf-id-in-pf",
4871				     p_hwfn->p_cxt_mngr->first_vf_in_pf);
4872	offset += qed_dump_num_param(dump_buf + offset,
4873				     dump,
4874				     "num-vfs-in-pf",
4875				     p_hwfn->p_cxt_mngr->vf_count);
4876	offset += qed_dump_num_param(dump_buf + offset,
4877				     dump,
4878				     "ptr-size-bytes",
4879				     sizeof(void *));
4880	offset += qed_dump_num_param(dump_buf + offset,
4881				     dump,
4882				     "pf-start-line",
4883				     p_hwfn->p_cxt_mngr->pf_start_line);
4884	offset += qed_dump_num_param(dump_buf + offset,
4885				     dump,
4886				     "page-mem-desc-size-dwords",
4887				     PAGE_MEM_DESC_SIZE_DWORDS);
4888	offset += qed_dump_num_param(dump_buf + offset,
4889				     dump,
4890				     "ilt-shadow-size",
4891				     p_hwfn->p_cxt_mngr->ilt_shadow_size);
4892
4893	*full_dump_size_param_offset = offset;
4894
4895	offset += qed_dump_num_param(dump_buf + offset,
4896				     dump, "dump-size-full", 0);
4897
4898	*actual_dump_size_param_offset = offset;
4899
4900	offset += qed_dump_num_param(dump_buf + offset,
4901				     dump,
4902				     "dump-size-actual", 0);
4903	offset += qed_dump_num_param(dump_buf + offset,
4904				     dump,
4905				     "iscsi_task_pages",
4906				     p_hwfn->p_cxt_mngr->iscsi_task_pages);
4907	offset += qed_dump_num_param(dump_buf + offset,
4908				     dump,
4909				     "fcoe_task_pages",
4910				     p_hwfn->p_cxt_mngr->fcoe_task_pages);
4911	offset += qed_dump_num_param(dump_buf + offset,
4912				     dump,
4913				     "roce_task_pages",
4914				     p_hwfn->p_cxt_mngr->roce_task_pages);
4915	offset += qed_dump_num_param(dump_buf + offset,
4916				     dump,
4917				     "eth_task_pages",
4918				     p_hwfn->p_cxt_mngr->eth_task_pages);
4919	offset += qed_dump_num_param(dump_buf + offset,
4920				      dump,
4921				      "src-first-page-id",
4922				      clients[ILT_CLI_SRC].first.val);
4923	offset += qed_dump_num_param(dump_buf + offset,
4924				     dump,
4925				     "src-last-page-id",
4926				     clients[ILT_CLI_SRC].last.val);
4927	offset += qed_dump_num_param(dump_buf + offset,
4928				     dump,
4929				     "src-is-active",
4930				     clients[ILT_CLI_SRC].active);
4931
4932	/* Additional/Less parameters require matching of number in call to
4933	 * dump_common_global_params()
4934	 */
4935
4936	return offset;
4937}
4938
4939/* Dump section containing number of PF CIDs per connection type.
4940 * Part of ilt dump process.
4941 * Returns the dumped size in dwords.
4942 */
4943static u32 qed_ilt_dump_dump_num_pf_cids(struct qed_hwfn *p_hwfn,
4944					 u32 *dump_buf,
4945					 bool dump, u32 *valid_conn_pf_cids)
4946{
4947	u32 num_pf_cids = 0;
4948	u32 offset = 0;
4949	u8 conn_type;
4950
4951	offset += qed_dump_section_hdr(dump_buf + offset,
4952				       dump, "num_pf_cids_per_conn_type", 1);
4953	offset += qed_dump_num_param(dump_buf + offset,
4954				     dump, "size", NUM_OF_CONNECTION_TYPES);
4955	for (conn_type = 0, *valid_conn_pf_cids = 0;
4956	     conn_type < NUM_OF_CONNECTION_TYPES; conn_type++, offset++) {
4957		num_pf_cids = p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cid_count;
4958		if (dump)
4959			*(dump_buf + offset) = num_pf_cids;
4960		*valid_conn_pf_cids += num_pf_cids;
4961	}
4962
4963	return offset;
4964}
4965
4966/* Dump section containing number of VF CIDs per connection type
4967 * Part of ilt dump process.
4968 * Returns the dumped size in dwords.
4969 */
4970static u32 qed_ilt_dump_dump_num_vf_cids(struct qed_hwfn *p_hwfn,
4971					 u32 *dump_buf,
4972					 bool dump, u32 *valid_conn_vf_cids)
4973{
4974	u32 num_vf_cids = 0;
4975	u32 offset = 0;
4976	u8 conn_type;
4977
4978	offset += qed_dump_section_hdr(dump_buf + offset, dump,
4979				       "num_vf_cids_per_conn_type", 1);
4980	offset += qed_dump_num_param(dump_buf + offset,
4981				     dump, "size", NUM_OF_CONNECTION_TYPES);
4982	for (conn_type = 0, *valid_conn_vf_cids = 0;
4983	     conn_type < NUM_OF_CONNECTION_TYPES; conn_type++, offset++) {
4984		num_vf_cids =
4985		    p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cids_per_vf;
4986		if (dump)
4987			*(dump_buf + offset) = num_vf_cids;
4988		*valid_conn_vf_cids += num_vf_cids;
4989	}
4990
4991	return offset;
4992}
4993
4994/* Performs ILT Dump to the specified buffer.
4995 * buf_size_in_dwords - The dumped buffer size.
4996 * Returns the dumped size in dwords.
4997 */
4998static u32 qed_ilt_dump(struct qed_hwfn *p_hwfn,
4999			struct qed_ptt *p_ptt,
5000			u32 *dump_buf, u32 buf_size_in_dwords, bool dump)
5001{
5002#if ((!defined VMWARE) && (!defined UEFI))
5003	struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
5004#endif
5005	u32 valid_conn_vf_cids = 0,
5006	    valid_conn_vf_pages, offset = 0, real_dumped_size = 0;
5007	u32 valid_conn_pf_cids = 0, valid_conn_pf_pages, num_pages;
5008	u32 num_cids_per_page, conn_ctx_size;
5009	u32 cduc_page_size, cdut_page_size;
5010	u32 actual_dump_size_in_dwords = 0;
5011	struct phys_mem_desc *ilt_pages;
5012	u32 actul_dump_off = 0;
5013	u32 last_section_size;
5014	u32 full_dump_off = 0;
5015	u32 section_size = 0;
5016	bool continue_dump;
5017	u32 page_id;
5018
5019	last_section_size = qed_dump_last_section(NULL, 0, false);
5020	cduc_page_size = 1 <<
5021	    (clients[ILT_CLI_CDUC].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN);
5022	cdut_page_size = 1 <<
5023	    (clients[ILT_CLI_CDUT].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN);
5024	conn_ctx_size = p_hwfn->p_cxt_mngr->conn_ctx_size;
5025	num_cids_per_page = (int)(cduc_page_size / conn_ctx_size);
5026	ilt_pages = p_hwfn->p_cxt_mngr->ilt_shadow;
5027	continue_dump = dump;
5028
5029	/* if need to dump then save memory for the last section
5030	 * (last section calculates CRC of dumped data)
5031	 */
5032	if (dump) {
5033		if (buf_size_in_dwords >= last_section_size) {
5034			buf_size_in_dwords -= last_section_size;
5035		} else {
5036			continue_dump = false;
5037			actual_dump_size_in_dwords = offset;
5038		}
5039	}
5040
5041	/* Dump global params */
5042
5043	/* if need to dump then first check that there is enough memory
5044	 * in dumped buffer for this section calculate the size of this
5045	 * section without dumping. if there is not enough memory - then
5046	 * stop the dumping.
5047	 */
5048	if (continue_dump) {
5049		section_size =
5050			qed_ilt_dump_dump_common_global_params(p_hwfn,
5051							       p_ptt,
5052							       NULL,
5053							       false,
5054							       cduc_page_size,
5055							       conn_ctx_size,
5056							       cdut_page_size,
5057							       &full_dump_off,
5058							       &actul_dump_off);
5059		if (offset + section_size > buf_size_in_dwords) {
5060			continue_dump = false;
5061			actual_dump_size_in_dwords = offset;
5062		}
5063	}
5064
5065	offset += qed_ilt_dump_dump_common_global_params(p_hwfn,
5066							 p_ptt,
5067							 dump_buf + offset,
5068							 continue_dump,
5069							 cduc_page_size,
5070							 conn_ctx_size,
5071							 cdut_page_size,
5072							 &full_dump_off,
5073							 &actul_dump_off);
5074
5075	/* Dump section containing number of PF CIDs per connection type
5076	 * If need to dump then first check that there is enough memory in
5077	 * dumped buffer for this section.
5078	 */
5079	if (continue_dump) {
5080		section_size =
5081			qed_ilt_dump_dump_num_pf_cids(p_hwfn,
5082						      NULL,
5083						      false,
5084						      &valid_conn_pf_cids);
5085		if (offset + section_size > buf_size_in_dwords) {
5086			continue_dump = false;
5087			actual_dump_size_in_dwords = offset;
5088		}
5089	}
5090
5091	offset += qed_ilt_dump_dump_num_pf_cids(p_hwfn,
5092						dump_buf + offset,
5093						continue_dump,
5094						&valid_conn_pf_cids);
5095
5096	/* Dump section containing number of VF CIDs per connection type
5097	 * If need to dump then first check that there is enough memory in
5098	 * dumped buffer for this section.
5099	 */
5100	if (continue_dump) {
5101		section_size =
5102			qed_ilt_dump_dump_num_vf_cids(p_hwfn,
5103						      NULL,
5104						      false,
5105						      &valid_conn_vf_cids);
5106		if (offset + section_size > buf_size_in_dwords) {
5107			continue_dump = false;
5108			actual_dump_size_in_dwords = offset;
5109		}
5110	}
5111
5112	offset += qed_ilt_dump_dump_num_vf_cids(p_hwfn,
5113						dump_buf + offset,
5114						continue_dump,
5115						&valid_conn_vf_cids);
5116
5117	/* Dump section containing physical memory descriptors for each
5118	 * ILT page.
5119	 */
5120	num_pages = p_hwfn->p_cxt_mngr->ilt_shadow_size;
5121
5122	/* If need to dump then first check that there is enough memory
5123	 * in dumped buffer for the section header.
5124	 */
5125	if (continue_dump) {
5126		section_size = qed_dump_section_hdr(NULL,
5127						    false,
5128						    "ilt_page_desc",
5129						    1) +
5130		    qed_dump_num_param(NULL,
5131				       false,
5132				       "size",
5133				       num_pages * PAGE_MEM_DESC_SIZE_DWORDS);
5134		if (offset + section_size > buf_size_in_dwords) {
5135			continue_dump = false;
5136			actual_dump_size_in_dwords = offset;
5137		}
5138	}
5139
5140	offset += qed_dump_section_hdr(dump_buf + offset,
5141				       continue_dump, "ilt_page_desc", 1);
5142	offset += qed_dump_num_param(dump_buf + offset,
5143				     continue_dump,
5144				     "size",
5145				     num_pages * PAGE_MEM_DESC_SIZE_DWORDS);
5146
5147	/* Copy memory descriptors to dump buffer
5148	 * If need to dump then dump till the dump buffer size
5149	 */
5150	if (continue_dump) {
5151		for (page_id = 0; page_id < num_pages;
5152		     page_id++, offset += PAGE_MEM_DESC_SIZE_DWORDS) {
5153			if (continue_dump &&
5154			    (offset + PAGE_MEM_DESC_SIZE_DWORDS <=
5155			     buf_size_in_dwords)) {
5156				memcpy(dump_buf + offset,
5157				       &ilt_pages[page_id],
5158				       DWORDS_TO_BYTES
5159				       (PAGE_MEM_DESC_SIZE_DWORDS));
5160			} else {
5161				if (continue_dump) {
5162					continue_dump = false;
5163					actual_dump_size_in_dwords = offset;
5164				}
5165			}
5166		}
5167	} else {
5168		offset += num_pages * PAGE_MEM_DESC_SIZE_DWORDS;
5169	}
5170
5171	valid_conn_pf_pages = DIV_ROUND_UP(valid_conn_pf_cids,
5172					   num_cids_per_page);
5173	valid_conn_vf_pages = DIV_ROUND_UP(valid_conn_vf_cids,
5174					   num_cids_per_page);
5175
5176	/* Dump ILT pages IDs */
5177	qed_ilt_dump_pages_section(p_hwfn, dump_buf, &offset, &continue_dump,
5178				   valid_conn_pf_pages, valid_conn_vf_pages,
5179				   ilt_pages, true, buf_size_in_dwords,
5180				   &actual_dump_size_in_dwords);
5181
5182	/* Dump ILT pages memory */
5183	qed_ilt_dump_pages_section(p_hwfn, dump_buf, &offset, &continue_dump,
5184				   valid_conn_pf_pages, valid_conn_vf_pages,
5185				   ilt_pages, false, buf_size_in_dwords,
5186				   &actual_dump_size_in_dwords);
5187
5188	real_dumped_size =
5189	    (continue_dump == dump) ? offset : actual_dump_size_in_dwords;
5190	qed_dump_num_param(dump_buf + full_dump_off, dump,
5191			   "full-dump-size", offset + last_section_size);
5192	qed_dump_num_param(dump_buf + actul_dump_off,
5193			   dump,
5194			   "actual-dump-size",
5195			   real_dumped_size + last_section_size);
5196
5197	/* Dump last section */
5198	real_dumped_size += qed_dump_last_section(dump_buf,
5199						  real_dumped_size, dump);
5200
5201	return real_dumped_size;
5202}
5203
5204/***************************** Public Functions *******************************/
5205
5206enum dbg_status qed_dbg_set_bin_ptr(struct qed_hwfn *p_hwfn,
5207				    const u8 * const bin_ptr)
5208{
5209	struct bin_buffer_hdr *buf_hdrs = (struct bin_buffer_hdr *)bin_ptr;
5210	u8 buf_id;
5211
5212	/* Convert binary data to debug arrays */
5213	for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++)
5214		qed_set_dbg_bin_buf(p_hwfn,
5215				    buf_id,
5216				    (u32 *)(bin_ptr + buf_hdrs[buf_id].offset),
5217				    buf_hdrs[buf_id].length);
5218
5219	return DBG_STATUS_OK;
5220}
5221
5222static enum dbg_status qed_dbg_set_app_ver(u32 ver)
5223{
5224	if (ver < TOOLS_VERSION)
5225		return DBG_STATUS_UNSUPPORTED_APP_VERSION;
5226
5227	s_app_ver = ver;
5228
5229	return DBG_STATUS_OK;
5230}
5231
5232bool qed_read_fw_info(struct qed_hwfn *p_hwfn,
5233		      struct qed_ptt *p_ptt, struct fw_info *fw_info)
5234{
5235	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5236	u8 storm_id;
5237
5238	for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
5239		struct storm_defs *storm = &s_storm_defs[storm_id];
5240
5241		/* Skip Storm if it's in reset */
5242		if (dev_data->block_in_reset[storm->sem_block_id])
5243			continue;
5244
5245		/* Read FW info for the current Storm */
5246		qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, fw_info);
5247
5248		return true;
5249	}
5250
5251	return false;
5252}
5253
5254enum dbg_status qed_dbg_grc_config(struct qed_hwfn *p_hwfn,
5255				   enum dbg_grc_params grc_param, u32 val)
5256{
5257	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5258	enum dbg_status status;
5259	int i;
5260
5261	DP_VERBOSE(p_hwfn,
5262		   QED_MSG_DEBUG,
5263		   "dbg_grc_config: paramId = %d, val = %d\n", grc_param, val);
5264
5265	status = qed_dbg_dev_init(p_hwfn);
5266	if (status != DBG_STATUS_OK)
5267		return status;
5268
5269	/* Initializes the GRC parameters (if not initialized). Needed in order
5270	 * to set the default parameter values for the first time.
5271	 */
5272	qed_dbg_grc_init_params(p_hwfn);
5273
5274	if (grc_param >= MAX_DBG_GRC_PARAMS)
5275		return DBG_STATUS_INVALID_ARGS;
5276	if (val < s_grc_param_defs[grc_param].min ||
5277	    val > s_grc_param_defs[grc_param].max)
5278		return DBG_STATUS_INVALID_ARGS;
5279
5280	if (s_grc_param_defs[grc_param].is_preset) {
5281		/* Preset param */
5282
5283		/* Disabling a preset is not allowed. Call
5284		 * dbg_grc_set_params_default instead.
5285		 */
5286		if (!val)
5287			return DBG_STATUS_INVALID_ARGS;
5288
5289		/* Update all params with the preset values */
5290		for (i = 0; i < MAX_DBG_GRC_PARAMS; i++) {
5291			struct grc_param_defs *defs = &s_grc_param_defs[i];
5292			u32 preset_val;
5293			/* Skip persistent params */
5294			if (defs->is_persistent)
5295				continue;
5296
5297			/* Find preset value */
5298			if (grc_param == DBG_GRC_PARAM_EXCLUDE_ALL)
5299				preset_val =
5300				    defs->exclude_all_preset_val;
5301			else if (grc_param == DBG_GRC_PARAM_CRASH)
5302				preset_val =
5303				    defs->crash_preset_val[dev_data->chip_id];
5304			else
5305				return DBG_STATUS_INVALID_ARGS;
5306
5307			qed_grc_set_param(p_hwfn, i, preset_val);
5308		}
5309	} else {
5310		/* Regular param - set its value */
5311		qed_grc_set_param(p_hwfn, grc_param, val);
5312	}
5313
5314	return DBG_STATUS_OK;
5315}
5316
5317/* Assign default GRC param values */
5318void qed_dbg_grc_set_params_default(struct qed_hwfn *p_hwfn)
5319{
5320	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5321	u32 i;
5322
5323	for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
5324		if (!s_grc_param_defs[i].is_persistent)
5325			dev_data->grc.param_val[i] =
5326			    s_grc_param_defs[i].default_val[dev_data->chip_id];
5327}
5328
5329enum dbg_status qed_dbg_grc_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5330					      struct qed_ptt *p_ptt,
5331					      u32 *buf_size)
5332{
5333	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5334
5335	*buf_size = 0;
5336
5337	if (status != DBG_STATUS_OK)
5338		return status;
5339
5340	if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
5341	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr ||
5342	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr ||
5343	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||
5344	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)
5345		return DBG_STATUS_DBG_ARRAY_NOT_SET;
5346
5347	return qed_grc_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5348}
5349
5350enum dbg_status qed_dbg_grc_dump(struct qed_hwfn *p_hwfn,
5351				 struct qed_ptt *p_ptt,
5352				 u32 *dump_buf,
5353				 u32 buf_size_in_dwords,
5354				 u32 *num_dumped_dwords)
5355{
5356	u32 needed_buf_size_in_dwords;
5357	enum dbg_status status;
5358
5359	*num_dumped_dwords = 0;
5360
5361	status = qed_dbg_grc_get_dump_buf_size(p_hwfn,
5362					       p_ptt,
5363					       &needed_buf_size_in_dwords);
5364	if (status != DBG_STATUS_OK)
5365		return status;
5366
5367	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5368		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5369
5370	/* Doesn't do anything, needed for compile time asserts */
5371	qed_static_asserts();
5372
5373	/* GRC Dump */
5374	status = qed_grc_dump(p_hwfn, p_ptt, dump_buf, true, num_dumped_dwords);
5375
5376	/* Revert GRC params to their default */
5377	qed_dbg_grc_set_params_default(p_hwfn);
5378
5379	return status;
5380}
5381
5382enum dbg_status qed_dbg_idle_chk_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5383						   struct qed_ptt *p_ptt,
5384						   u32 *buf_size)
5385{
5386	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5387	struct idle_chk_data *idle_chk = &dev_data->idle_chk;
5388	enum dbg_status status;
5389
5390	*buf_size = 0;
5391
5392	status = qed_dbg_dev_init(p_hwfn);
5393	if (status != DBG_STATUS_OK)
5394		return status;
5395
5396	if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
5397	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr ||
5398	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr ||
5399	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr)
5400		return DBG_STATUS_DBG_ARRAY_NOT_SET;
5401
5402	if (!idle_chk->buf_size_set) {
5403		idle_chk->buf_size = qed_idle_chk_dump(p_hwfn,
5404						       p_ptt, NULL, false);
5405		idle_chk->buf_size_set = true;
5406	}
5407
5408	*buf_size = idle_chk->buf_size;
5409
5410	return DBG_STATUS_OK;
5411}
5412
5413enum dbg_status qed_dbg_idle_chk_dump(struct qed_hwfn *p_hwfn,
5414				      struct qed_ptt *p_ptt,
5415				      u32 *dump_buf,
5416				      u32 buf_size_in_dwords,
5417				      u32 *num_dumped_dwords)
5418{
5419	u32 needed_buf_size_in_dwords;
5420	enum dbg_status status;
5421
5422	*num_dumped_dwords = 0;
5423
5424	status = qed_dbg_idle_chk_get_dump_buf_size(p_hwfn,
5425						    p_ptt,
5426						    &needed_buf_size_in_dwords);
5427	if (status != DBG_STATUS_OK)
5428		return status;
5429
5430	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5431		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5432
5433	/* Update reset state */
5434	qed_grc_unreset_blocks(p_hwfn, p_ptt, true);
5435	qed_update_blocks_reset_state(p_hwfn, p_ptt);
5436
5437	/* Idle Check Dump */
5438	*num_dumped_dwords = qed_idle_chk_dump(p_hwfn, p_ptt, dump_buf, true);
5439
5440	/* Revert GRC params to their default */
5441	qed_dbg_grc_set_params_default(p_hwfn);
5442
5443	return DBG_STATUS_OK;
5444}
5445
5446enum dbg_status qed_dbg_mcp_trace_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5447						    struct qed_ptt *p_ptt,
5448						    u32 *buf_size)
5449{
5450	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5451
5452	*buf_size = 0;
5453
5454	if (status != DBG_STATUS_OK)
5455		return status;
5456
5457	return qed_mcp_trace_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5458}
5459
5460enum dbg_status qed_dbg_mcp_trace_dump(struct qed_hwfn *p_hwfn,
5461				       struct qed_ptt *p_ptt,
5462				       u32 *dump_buf,
5463				       u32 buf_size_in_dwords,
5464				       u32 *num_dumped_dwords)
5465{
5466	u32 needed_buf_size_in_dwords;
5467	enum dbg_status status;
5468
5469	status =
5470		qed_dbg_mcp_trace_get_dump_buf_size(p_hwfn,
5471						    p_ptt,
5472						    &needed_buf_size_in_dwords);
5473	if (status != DBG_STATUS_OK && status !=
5474	    DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
5475		return status;
5476
5477	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5478		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5479
5480	/* Update reset state */
5481	qed_update_blocks_reset_state(p_hwfn, p_ptt);
5482
5483	/* Perform dump */
5484	status = qed_mcp_trace_dump(p_hwfn,
5485				    p_ptt, dump_buf, true, num_dumped_dwords);
5486
5487	/* Revert GRC params to their default */
5488	qed_dbg_grc_set_params_default(p_hwfn);
5489
5490	return status;
5491}
5492
5493enum dbg_status qed_dbg_reg_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5494						   struct qed_ptt *p_ptt,
5495						   u32 *buf_size)
5496{
5497	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5498
5499	*buf_size = 0;
5500
5501	if (status != DBG_STATUS_OK)
5502		return status;
5503
5504	return qed_reg_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5505}
5506
5507enum dbg_status qed_dbg_reg_fifo_dump(struct qed_hwfn *p_hwfn,
5508				      struct qed_ptt *p_ptt,
5509				      u32 *dump_buf,
5510				      u32 buf_size_in_dwords,
5511				      u32 *num_dumped_dwords)
5512{
5513	u32 needed_buf_size_in_dwords;
5514	enum dbg_status status;
5515
5516	*num_dumped_dwords = 0;
5517
5518	status = qed_dbg_reg_fifo_get_dump_buf_size(p_hwfn,
5519						    p_ptt,
5520						    &needed_buf_size_in_dwords);
5521	if (status != DBG_STATUS_OK)
5522		return status;
5523
5524	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5525		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5526
5527	/* Update reset state */
5528	qed_update_blocks_reset_state(p_hwfn, p_ptt);
5529
5530	status = qed_reg_fifo_dump(p_hwfn,
5531				   p_ptt, dump_buf, true, num_dumped_dwords);
5532
5533	/* Revert GRC params to their default */
5534	qed_dbg_grc_set_params_default(p_hwfn);
5535
5536	return status;
5537}
5538
5539enum dbg_status qed_dbg_igu_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5540						   struct qed_ptt *p_ptt,
5541						   u32 *buf_size)
5542{
5543	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5544
5545	*buf_size = 0;
5546
5547	if (status != DBG_STATUS_OK)
5548		return status;
5549
5550	return qed_igu_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5551}
5552
5553enum dbg_status qed_dbg_igu_fifo_dump(struct qed_hwfn *p_hwfn,
5554				      struct qed_ptt *p_ptt,
5555				      u32 *dump_buf,
5556				      u32 buf_size_in_dwords,
5557				      u32 *num_dumped_dwords)
5558{
5559	u32 needed_buf_size_in_dwords;
5560	enum dbg_status status;
5561
5562	*num_dumped_dwords = 0;
5563
5564	status = qed_dbg_igu_fifo_get_dump_buf_size(p_hwfn,
5565						    p_ptt,
5566						    &needed_buf_size_in_dwords);
5567	if (status != DBG_STATUS_OK)
5568		return status;
5569
5570	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5571		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5572
5573	/* Update reset state */
5574	qed_update_blocks_reset_state(p_hwfn, p_ptt);
5575
5576	status = qed_igu_fifo_dump(p_hwfn,
5577				   p_ptt, dump_buf, true, num_dumped_dwords);
5578	/* Revert GRC params to their default */
5579	qed_dbg_grc_set_params_default(p_hwfn);
5580
5581	return status;
5582}
5583
5584enum dbg_status
5585qed_dbg_protection_override_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5586					      struct qed_ptt *p_ptt,
5587					      u32 *buf_size)
5588{
5589	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5590
5591	*buf_size = 0;
5592
5593	if (status != DBG_STATUS_OK)
5594		return status;
5595
5596	return qed_protection_override_dump(p_hwfn,
5597					    p_ptt, NULL, false, buf_size);
5598}
5599
5600enum dbg_status qed_dbg_protection_override_dump(struct qed_hwfn *p_hwfn,
5601						 struct qed_ptt *p_ptt,
5602						 u32 *dump_buf,
5603						 u32 buf_size_in_dwords,
5604						 u32 *num_dumped_dwords)
5605{
5606	u32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords;
5607	enum dbg_status status;
5608
5609	*num_dumped_dwords = 0;
5610
5611	status =
5612		qed_dbg_protection_override_get_dump_buf_size(p_hwfn,
5613							      p_ptt,
5614							      p_size);
5615	if (status != DBG_STATUS_OK)
5616		return status;
5617
5618	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5619		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5620
5621	/* Update reset state */
5622	qed_update_blocks_reset_state(p_hwfn, p_ptt);
5623
5624	status = qed_protection_override_dump(p_hwfn,
5625					      p_ptt,
5626					      dump_buf,
5627					      true, num_dumped_dwords);
5628
5629	/* Revert GRC params to their default */
5630	qed_dbg_grc_set_params_default(p_hwfn);
5631
5632	return status;
5633}
5634
5635enum dbg_status qed_dbg_fw_asserts_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5636						     struct qed_ptt *p_ptt,
5637						     u32 *buf_size)
5638{
5639	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5640
5641	*buf_size = 0;
5642
5643	if (status != DBG_STATUS_OK)
5644		return status;
5645
5646	/* Update reset state */
5647	qed_update_blocks_reset_state(p_hwfn, p_ptt);
5648
5649	*buf_size = qed_fw_asserts_dump(p_hwfn, p_ptt, NULL, false);
5650
5651	return DBG_STATUS_OK;
5652}
5653
5654enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn *p_hwfn,
5655					struct qed_ptt *p_ptt,
5656					u32 *dump_buf,
5657					u32 buf_size_in_dwords,
5658					u32 *num_dumped_dwords)
5659{
5660	u32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords;
5661	enum dbg_status status;
5662
5663	*num_dumped_dwords = 0;
5664
5665	status =
5666		qed_dbg_fw_asserts_get_dump_buf_size(p_hwfn,
5667						     p_ptt,
5668						     p_size);
5669	if (status != DBG_STATUS_OK)
5670		return status;
5671
5672	if (buf_size_in_dwords < needed_buf_size_in_dwords)
5673		return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5674
5675	*num_dumped_dwords = qed_fw_asserts_dump(p_hwfn, p_ptt, dump_buf, true);
5676
5677	/* Revert GRC params to their default */
5678	qed_dbg_grc_set_params_default(p_hwfn);
5679
5680	return DBG_STATUS_OK;
5681}
5682
5683static enum dbg_status qed_dbg_ilt_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5684						     struct qed_ptt *p_ptt,
5685						     u32 *buf_size)
5686{
5687	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5688
5689	*buf_size = 0;
5690
5691	if (status != DBG_STATUS_OK)
5692		return status;
5693
5694	*buf_size = qed_ilt_dump(p_hwfn, p_ptt, NULL, 0, false);
5695
5696	return DBG_STATUS_OK;
5697}
5698
5699static enum dbg_status qed_dbg_ilt_dump(struct qed_hwfn *p_hwfn,
5700					struct qed_ptt *p_ptt,
5701					u32 *dump_buf,
5702					u32 buf_size_in_dwords,
5703					u32 *num_dumped_dwords)
5704{
5705	*num_dumped_dwords = qed_ilt_dump(p_hwfn,
5706					  p_ptt,
5707					  dump_buf, buf_size_in_dwords, true);
5708
5709	/* Reveret GRC params to their default */
5710	qed_dbg_grc_set_params_default(p_hwfn);
5711
5712	return DBG_STATUS_OK;
5713}
5714
5715enum dbg_status qed_dbg_read_attn(struct qed_hwfn *p_hwfn,
5716				  struct qed_ptt *p_ptt,
5717				  enum block_id block_id,
5718				  enum dbg_attn_type attn_type,
5719				  bool clear_status,
5720				  struct dbg_attn_block_result *results)
5721{
5722	enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5723	u8 reg_idx, num_attn_regs, num_result_regs = 0;
5724	const struct dbg_attn_reg *attn_reg_arr;
5725
5726	if (status != DBG_STATUS_OK)
5727		return status;
5728
5729	if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
5730	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||
5731	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)
5732		return DBG_STATUS_DBG_ARRAY_NOT_SET;
5733
5734	attn_reg_arr = qed_get_block_attn_regs(p_hwfn,
5735					       block_id,
5736					       attn_type, &num_attn_regs);
5737
5738	for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
5739		const struct dbg_attn_reg *reg_data = &attn_reg_arr[reg_idx];
5740		struct dbg_attn_reg_result *reg_result;
5741		u32 sts_addr, sts_val;
5742		u16 modes_buf_offset;
5743		bool eval_mode;
5744
5745		/* Check mode */
5746		eval_mode = GET_FIELD(reg_data->mode.data,
5747				      DBG_MODE_HDR_EVAL_MODE) > 0;
5748		modes_buf_offset = GET_FIELD(reg_data->mode.data,
5749					     DBG_MODE_HDR_MODES_BUF_OFFSET);
5750		if (eval_mode && !qed_is_mode_match(p_hwfn, &modes_buf_offset))
5751			continue;
5752
5753		/* Mode match - read attention status register */
5754		sts_addr = DWORDS_TO_BYTES(clear_status ?
5755					   reg_data->sts_clr_address :
5756					   GET_FIELD(reg_data->data,
5757						     DBG_ATTN_REG_STS_ADDRESS));
5758		sts_val = qed_rd(p_hwfn, p_ptt, sts_addr);
5759		if (!sts_val)
5760			continue;
5761
5762		/* Non-zero attention status - add to results */
5763		reg_result = &results->reg_results[num_result_regs];
5764		SET_FIELD(reg_result->data,
5765			  DBG_ATTN_REG_RESULT_STS_ADDRESS, sts_addr);
5766		SET_FIELD(reg_result->data,
5767			  DBG_ATTN_REG_RESULT_NUM_REG_ATTN,
5768			  GET_FIELD(reg_data->data, DBG_ATTN_REG_NUM_REG_ATTN));
5769		reg_result->block_attn_offset = reg_data->block_attn_offset;
5770		reg_result->sts_val = sts_val;
5771		reg_result->mask_val = qed_rd(p_hwfn,
5772					      p_ptt,
5773					      DWORDS_TO_BYTES
5774					      (reg_data->mask_address));
5775		num_result_regs++;
5776	}
5777
5778	results->block_id = (u8)block_id;
5779	results->names_offset =
5780	    qed_get_block_attn_data(p_hwfn, block_id, attn_type)->names_offset;
5781	SET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE, attn_type);
5782	SET_FIELD(results->data,
5783		  DBG_ATTN_BLOCK_RESULT_NUM_REGS, num_result_regs);
5784
5785	return DBG_STATUS_OK;
5786}
5787
5788/******************************* Data Types **********************************/
5789
5790/* REG fifo element */
5791struct reg_fifo_element {
5792	u64 data;
5793#define REG_FIFO_ELEMENT_ADDRESS_SHIFT		0
5794#define REG_FIFO_ELEMENT_ADDRESS_MASK		0x7fffff
5795#define REG_FIFO_ELEMENT_ACCESS_SHIFT		23
5796#define REG_FIFO_ELEMENT_ACCESS_MASK		0x1
5797#define REG_FIFO_ELEMENT_PF_SHIFT		24
5798#define REG_FIFO_ELEMENT_PF_MASK		0xf
5799#define REG_FIFO_ELEMENT_VF_SHIFT		28
5800#define REG_FIFO_ELEMENT_VF_MASK		0xff
5801#define REG_FIFO_ELEMENT_PORT_SHIFT		36
5802#define REG_FIFO_ELEMENT_PORT_MASK		0x3
5803#define REG_FIFO_ELEMENT_PRIVILEGE_SHIFT	38
5804#define REG_FIFO_ELEMENT_PRIVILEGE_MASK		0x3
5805#define REG_FIFO_ELEMENT_PROTECTION_SHIFT	40
5806#define REG_FIFO_ELEMENT_PROTECTION_MASK	0x7
5807#define REG_FIFO_ELEMENT_MASTER_SHIFT		43
5808#define REG_FIFO_ELEMENT_MASTER_MASK		0xf
5809#define REG_FIFO_ELEMENT_ERROR_SHIFT		47
5810#define REG_FIFO_ELEMENT_ERROR_MASK		0x1f
5811};
5812
5813/* REG fifo error element */
5814struct reg_fifo_err {
5815	u32 err_code;
5816	const char *err_msg;
5817};
5818
5819/* IGU fifo element */
5820struct igu_fifo_element {
5821	u32 dword0;
5822#define IGU_FIFO_ELEMENT_DWORD0_FID_SHIFT		0
5823#define IGU_FIFO_ELEMENT_DWORD0_FID_MASK		0xff
5824#define IGU_FIFO_ELEMENT_DWORD0_IS_PF_SHIFT		8
5825#define IGU_FIFO_ELEMENT_DWORD0_IS_PF_MASK		0x1
5826#define IGU_FIFO_ELEMENT_DWORD0_SOURCE_SHIFT		9
5827#define IGU_FIFO_ELEMENT_DWORD0_SOURCE_MASK		0xf
5828#define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_SHIFT		13
5829#define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_MASK		0xf
5830#define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_SHIFT		17
5831#define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_MASK		0x7fff
5832	u32 dword1;
5833	u32 dword2;
5834#define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_SHIFT	0
5835#define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_MASK		0x1
5836#define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_SHIFT		1
5837#define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_MASK		0xffffffff
5838	u32 reserved;
5839};
5840
5841struct igu_fifo_wr_data {
5842	u32 data;
5843#define IGU_FIFO_WR_DATA_PROD_CONS_SHIFT		0
5844#define IGU_FIFO_WR_DATA_PROD_CONS_MASK			0xffffff
5845#define IGU_FIFO_WR_DATA_UPDATE_FLAG_SHIFT		24
5846#define IGU_FIFO_WR_DATA_UPDATE_FLAG_MASK		0x1
5847#define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_SHIFT	25
5848#define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_MASK		0x3
5849#define IGU_FIFO_WR_DATA_SEGMENT_SHIFT			27
5850#define IGU_FIFO_WR_DATA_SEGMENT_MASK			0x1
5851#define IGU_FIFO_WR_DATA_TIMER_MASK_SHIFT		28
5852#define IGU_FIFO_WR_DATA_TIMER_MASK_MASK		0x1
5853#define IGU_FIFO_WR_DATA_CMD_TYPE_SHIFT			31
5854#define IGU_FIFO_WR_DATA_CMD_TYPE_MASK			0x1
5855};
5856
5857struct igu_fifo_cleanup_wr_data {
5858	u32 data;
5859#define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_SHIFT		0
5860#define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_MASK		0x7ffffff
5861#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_SHIFT	27
5862#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_MASK	0x1
5863#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_SHIFT	28
5864#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_MASK	0x7
5865#define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_SHIFT		31
5866#define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_MASK		0x1
5867};
5868
5869/* Protection override element */
5870struct protection_override_element {
5871	u64 data;
5872#define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_SHIFT		0
5873#define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_MASK		0x7fffff
5874#define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_SHIFT		23
5875#define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_MASK		0xffffff
5876#define PROTECTION_OVERRIDE_ELEMENT_READ_SHIFT			47
5877#define PROTECTION_OVERRIDE_ELEMENT_READ_MASK			0x1
5878#define PROTECTION_OVERRIDE_ELEMENT_WRITE_SHIFT			48
5879#define PROTECTION_OVERRIDE_ELEMENT_WRITE_MASK			0x1
5880#define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_SHIFT	49
5881#define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_MASK	0x7
5882#define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_SHIFT	52
5883#define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_MASK	0x7
5884};
5885
5886enum igu_fifo_sources {
5887	IGU_SRC_PXP0,
5888	IGU_SRC_PXP1,
5889	IGU_SRC_PXP2,
5890	IGU_SRC_PXP3,
5891	IGU_SRC_PXP4,
5892	IGU_SRC_PXP5,
5893	IGU_SRC_PXP6,
5894	IGU_SRC_PXP7,
5895	IGU_SRC_CAU,
5896	IGU_SRC_ATTN,
5897	IGU_SRC_GRC
5898};
5899
5900enum igu_fifo_addr_types {
5901	IGU_ADDR_TYPE_MSIX_MEM,
5902	IGU_ADDR_TYPE_WRITE_PBA,
5903	IGU_ADDR_TYPE_WRITE_INT_ACK,
5904	IGU_ADDR_TYPE_WRITE_ATTN_BITS,
5905	IGU_ADDR_TYPE_READ_INT,
5906	IGU_ADDR_TYPE_WRITE_PROD_UPDATE,
5907	IGU_ADDR_TYPE_RESERVED
5908};
5909
5910struct igu_fifo_addr_data {
5911	u16 start_addr;
5912	u16 end_addr;
5913	char *desc;
5914	char *vf_desc;
5915	enum igu_fifo_addr_types type;
5916};
5917
5918/******************************** Constants **********************************/
5919
5920#define MAX_MSG_LEN				1024
5921
5922#define MCP_TRACE_MAX_MODULE_LEN		8
5923#define MCP_TRACE_FORMAT_MAX_PARAMS		3
5924#define MCP_TRACE_FORMAT_PARAM_WIDTH \
5925	(MCP_TRACE_FORMAT_P2_SIZE_OFFSET - MCP_TRACE_FORMAT_P1_SIZE_OFFSET)
5926
5927#define REG_FIFO_ELEMENT_ADDR_FACTOR		4
5928#define REG_FIFO_ELEMENT_IS_PF_VF_VAL		127
5929
5930#define PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR	4
5931
5932/***************************** Constant Arrays *******************************/
5933
5934/* Status string array */
5935static const char * const s_status_str[] = {
5936	/* DBG_STATUS_OK */
5937	"Operation completed successfully",
5938
5939	/* DBG_STATUS_APP_VERSION_NOT_SET */
5940	"Debug application version wasn't set",
5941
5942	/* DBG_STATUS_UNSUPPORTED_APP_VERSION */
5943	"Unsupported debug application version",
5944
5945	/* DBG_STATUS_DBG_BLOCK_NOT_RESET */
5946	"The debug block wasn't reset since the last recording",
5947
5948	/* DBG_STATUS_INVALID_ARGS */
5949	"Invalid arguments",
5950
5951	/* DBG_STATUS_OUTPUT_ALREADY_SET */
5952	"The debug output was already set",
5953
5954	/* DBG_STATUS_INVALID_PCI_BUF_SIZE */
5955	"Invalid PCI buffer size",
5956
5957	/* DBG_STATUS_PCI_BUF_ALLOC_FAILED */
5958	"PCI buffer allocation failed",
5959
5960	/* DBG_STATUS_PCI_BUF_NOT_ALLOCATED */
5961	"A PCI buffer wasn't allocated",
5962
5963	/* DBG_STATUS_INVALID_FILTER_TRIGGER_DWORDS */
5964	"The filter/trigger constraint dword offsets are not enabled for recording",
5965	/* DBG_STATUS_NO_MATCHING_FRAMING_MODE */
5966	"No matching framing mode",
5967
5968	/* DBG_STATUS_VFC_READ_ERROR */
5969	"Error reading from VFC",
5970
5971	/* DBG_STATUS_STORM_ALREADY_ENABLED */
5972	"The Storm was already enabled",
5973
5974	/* DBG_STATUS_STORM_NOT_ENABLED */
5975	"The specified Storm wasn't enabled",
5976
5977	/* DBG_STATUS_BLOCK_ALREADY_ENABLED */
5978	"The block was already enabled",
5979
5980	/* DBG_STATUS_BLOCK_NOT_ENABLED */
5981	"The specified block wasn't enabled",
5982
5983	/* DBG_STATUS_NO_INPUT_ENABLED */
5984	"No input was enabled for recording",
5985
5986	/* DBG_STATUS_NO_FILTER_TRIGGER_256B */
5987	"Filters and triggers are not allowed in E4 256-bit mode",
5988
5989	/* DBG_STATUS_FILTER_ALREADY_ENABLED */
5990	"The filter was already enabled",
5991
5992	/* DBG_STATUS_TRIGGER_ALREADY_ENABLED */
5993	"The trigger was already enabled",
5994
5995	/* DBG_STATUS_TRIGGER_NOT_ENABLED */
5996	"The trigger wasn't enabled",
5997
5998	/* DBG_STATUS_CANT_ADD_CONSTRAINT */
5999	"A constraint can be added only after a filter was enabled or a trigger state was added",
6000
6001	/* DBG_STATUS_TOO_MANY_TRIGGER_STATES */
6002	"Cannot add more than 3 trigger states",
6003
6004	/* DBG_STATUS_TOO_MANY_CONSTRAINTS */
6005	"Cannot add more than 4 constraints per filter or trigger state",
6006
6007	/* DBG_STATUS_RECORDING_NOT_STARTED */
6008	"The recording wasn't started",
6009
6010	/* DBG_STATUS_DATA_DIDNT_TRIGGER */
6011	"A trigger was configured, but it didn't trigger",
6012
6013	/* DBG_STATUS_NO_DATA_RECORDED */
6014	"No data was recorded",
6015
6016	/* DBG_STATUS_DUMP_BUF_TOO_SMALL */
6017	"Dump buffer is too small",
6018
6019	/* DBG_STATUS_DUMP_NOT_CHUNK_ALIGNED */
6020	"Dumped data is not aligned to chunks",
6021
6022	/* DBG_STATUS_UNKNOWN_CHIP */
6023	"Unknown chip",
6024
6025	/* DBG_STATUS_VIRT_MEM_ALLOC_FAILED */
6026	"Failed allocating virtual memory",
6027
6028	/* DBG_STATUS_BLOCK_IN_RESET */
6029	"The input block is in reset",
6030
6031	/* DBG_STATUS_INVALID_TRACE_SIGNATURE */
6032	"Invalid MCP trace signature found in NVRAM",
6033
6034	/* DBG_STATUS_INVALID_NVRAM_BUNDLE */
6035	"Invalid bundle ID found in NVRAM",
6036
6037	/* DBG_STATUS_NVRAM_GET_IMAGE_FAILED */
6038	"Failed getting NVRAM image",
6039
6040	/* DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE */
6041	"NVRAM image is not dword-aligned",
6042
6043	/* DBG_STATUS_NVRAM_READ_FAILED */
6044	"Failed reading from NVRAM",
6045
6046	/* DBG_STATUS_IDLE_CHK_PARSE_FAILED */
6047	"Idle check parsing failed",
6048
6049	/* DBG_STATUS_MCP_TRACE_BAD_DATA */
6050	"MCP Trace data is corrupt",
6051
6052	/* DBG_STATUS_MCP_TRACE_NO_META */
6053	"Dump doesn't contain meta data - it must be provided in image file",
6054
6055	/* DBG_STATUS_MCP_COULD_NOT_HALT */
6056	"Failed to halt MCP",
6057
6058	/* DBG_STATUS_MCP_COULD_NOT_RESUME */
6059	"Failed to resume MCP after halt",
6060
6061	/* DBG_STATUS_RESERVED0 */
6062	"",
6063
6064	/* DBG_STATUS_SEMI_FIFO_NOT_EMPTY */
6065	"Failed to empty SEMI sync FIFO",
6066
6067	/* DBG_STATUS_IGU_FIFO_BAD_DATA */
6068	"IGU FIFO data is corrupt",
6069
6070	/* DBG_STATUS_MCP_COULD_NOT_MASK_PRTY */
6071	"MCP failed to mask parities",
6072
6073	/* DBG_STATUS_FW_ASSERTS_PARSE_FAILED */
6074	"FW Asserts parsing failed",
6075
6076	/* DBG_STATUS_REG_FIFO_BAD_DATA */
6077	"GRC FIFO data is corrupt",
6078
6079	/* DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA */
6080	"Protection Override data is corrupt",
6081
6082	/* DBG_STATUS_DBG_ARRAY_NOT_SET */
6083	"Debug arrays were not set (when using binary files, dbg_set_bin_ptr must be called)",
6084
6085	/* DBG_STATUS_RESERVED1 */
6086	"",
6087
6088	/* DBG_STATUS_NON_MATCHING_LINES */
6089	"Non-matching debug lines - in E4, all lines must be of the same type (either 128b or 256b)",
6090
6091	/* DBG_STATUS_INSUFFICIENT_HW_IDS */
6092	"Insufficient HW IDs. Try to record less Storms/blocks",
6093
6094	/* DBG_STATUS_DBG_BUS_IN_USE */
6095	"The debug bus is in use",
6096
6097	/* DBG_STATUS_INVALID_STORM_DBG_MODE */
6098	"The storm debug mode is not supported in the current chip",
6099
6100	/* DBG_STATUS_OTHER_ENGINE_BB_ONLY */
6101	"Other engine is supported only in BB",
6102
6103	/* DBG_STATUS_FILTER_SINGLE_HW_ID */
6104	"The configured filter mode requires a single Storm/block input",
6105
6106	/* DBG_STATUS_TRIGGER_SINGLE_HW_ID */
6107	"The configured filter mode requires that all the constraints of a single trigger state will be defined on a single Storm/block input",
6108
6109	/* DBG_STATUS_MISSING_TRIGGER_STATE_STORM */
6110	"When triggering on Storm data, the Storm to trigger on must be specified",
6111
6112	/* DBG_STATUS_MDUMP2_FAILED_TO_REQUEST_OFFSIZE */
6113	"Failed to request MDUMP2 Offsize",
6114
6115	/* DBG_STATUS_MDUMP2_FAILED_VALIDATION_OF_DATA_CRC */
6116	"Expected CRC (part of the MDUMP2 data) is different than the calculated CRC over that data",
6117
6118	/* DBG_STATUS_MDUMP2_INVALID_SIGNATURE */
6119	"Invalid Signature found at start of MDUMP2",
6120
6121	/* DBG_STATUS_MDUMP2_INVALID_LOG_SIZE */
6122	"Invalid Log Size of MDUMP2",
6123
6124	/* DBG_STATUS_MDUMP2_INVALID_LOG_HDR */
6125	"Invalid Log Header of MDUMP2",
6126
6127	/* DBG_STATUS_MDUMP2_INVALID_LOG_DATA */
6128	"Invalid Log Data of MDUMP2",
6129
6130	/* DBG_STATUS_MDUMP2_ERROR_EXTRACTING_NUM_PORTS */
6131	"Could not extract number of ports from regval buf of MDUMP2",
6132
6133	/* DBG_STATUS_MDUMP2_ERROR_EXTRACTING_MFW_STATUS */
6134	"Could not extract MFW (link) status from regval buf of MDUMP2",
6135
6136	/* DBG_STATUS_MDUMP2_ERROR_DISPLAYING_LINKDUMP */
6137	"Could not display linkdump of MDUMP2",
6138
6139	/* DBG_STATUS_MDUMP2_ERROR_READING_PHY_CFG */
6140	"Could not read PHY CFG of MDUMP2",
6141
6142	/* DBG_STATUS_MDUMP2_ERROR_READING_PLL_MODE */
6143	"Could not read PLL Mode of MDUMP2",
6144
6145	/* DBG_STATUS_MDUMP2_ERROR_READING_LANE_REGS */
6146	"Could not read TSCF/TSCE Lane Regs of MDUMP2",
6147
6148	/* DBG_STATUS_MDUMP2_ERROR_ALLOCATING_BUF */
6149	"Could not allocate MDUMP2 reg-val internal buffer"
6150};
6151
6152/* Idle check severity names array */
6153static const char * const s_idle_chk_severity_str[] = {
6154	"Error",
6155	"Error if no traffic",
6156	"Warning"
6157};
6158
6159/* MCP Trace level names array */
6160static const char * const s_mcp_trace_level_str[] = {
6161	"ERROR",
6162	"TRACE",
6163	"DEBUG"
6164};
6165
6166/* Access type names array */
6167static const char * const s_access_strs[] = {
6168	"read",
6169	"write"
6170};
6171
6172/* Privilege type names array */
6173static const char * const s_privilege_strs[] = {
6174	"VF",
6175	"PDA",
6176	"HV",
6177	"UA"
6178};
6179
6180/* Protection type names array */
6181static const char * const s_protection_strs[] = {
6182	"(default)",
6183	"(default)",
6184	"(default)",
6185	"(default)",
6186	"override VF",
6187	"override PDA",
6188	"override HV",
6189	"override UA"
6190};
6191
6192/* Master type names array */
6193static const char * const s_master_strs[] = {
6194	"???",
6195	"pxp",
6196	"mcp",
6197	"msdm",
6198	"psdm",
6199	"ysdm",
6200	"usdm",
6201	"tsdm",
6202	"xsdm",
6203	"dbu",
6204	"dmae",
6205	"jdap",
6206	"???",
6207	"???",
6208	"???",
6209	"???"
6210};
6211
6212/* REG FIFO error messages array */
6213static struct reg_fifo_err s_reg_fifo_errors[] = {
6214	{1, "grc timeout"},
6215	{2, "address doesn't belong to any block"},
6216	{4, "reserved address in block or write to read-only address"},
6217	{8, "privilege/protection mismatch"},
6218	{16, "path isolation error"},
6219	{17, "RSL error"}
6220};
6221
6222/* IGU FIFO sources array */
6223static const char * const s_igu_fifo_source_strs[] = {
6224	"TSTORM",
6225	"MSTORM",
6226	"USTORM",
6227	"XSTORM",
6228	"YSTORM",
6229	"PSTORM",
6230	"PCIE",
6231	"NIG_QM_PBF",
6232	"CAU",
6233	"ATTN",
6234	"GRC",
6235};
6236
6237/* IGU FIFO error messages */
6238static const char * const s_igu_fifo_error_strs[] = {
6239	"no error",
6240	"length error",
6241	"function disabled",
6242	"VF sent command to attention address",
6243	"host sent prod update command",
6244	"read of during interrupt register while in MIMD mode",
6245	"access to PXP BAR reserved address",
6246	"producer update command to attention index",
6247	"unknown error",
6248	"SB index not valid",
6249	"SB relative index and FID not found",
6250	"FID not match",
6251	"command with error flag asserted (PCI error or CAU discard)",
6252	"VF sent cleanup and RF cleanup is disabled",
6253	"cleanup command on type bigger than 4"
6254};
6255
6256/* IGU FIFO address data */
6257static const struct igu_fifo_addr_data s_igu_fifo_addr_data[] = {
6258	{0x0, 0x101, "MSI-X Memory", NULL,
6259	 IGU_ADDR_TYPE_MSIX_MEM},
6260	{0x102, 0x1ff, "reserved", NULL,
6261	 IGU_ADDR_TYPE_RESERVED},
6262	{0x200, 0x200, "Write PBA[0:63]", NULL,
6263	 IGU_ADDR_TYPE_WRITE_PBA},
6264	{0x201, 0x201, "Write PBA[64:127]", "reserved",
6265	 IGU_ADDR_TYPE_WRITE_PBA},
6266	{0x202, 0x202, "Write PBA[128]", "reserved",
6267	 IGU_ADDR_TYPE_WRITE_PBA},
6268	{0x203, 0x3ff, "reserved", NULL,
6269	 IGU_ADDR_TYPE_RESERVED},
6270	{0x400, 0x5ef, "Write interrupt acknowledgment", NULL,
6271	 IGU_ADDR_TYPE_WRITE_INT_ACK},
6272	{0x5f0, 0x5f0, "Attention bits update", NULL,
6273	 IGU_ADDR_TYPE_WRITE_ATTN_BITS},
6274	{0x5f1, 0x5f1, "Attention bits set", NULL,
6275	 IGU_ADDR_TYPE_WRITE_ATTN_BITS},
6276	{0x5f2, 0x5f2, "Attention bits clear", NULL,
6277	 IGU_ADDR_TYPE_WRITE_ATTN_BITS},
6278	{0x5f3, 0x5f3, "Read interrupt 0:63 with mask", NULL,
6279	 IGU_ADDR_TYPE_READ_INT},
6280	{0x5f4, 0x5f4, "Read interrupt 0:31 with mask", NULL,
6281	 IGU_ADDR_TYPE_READ_INT},
6282	{0x5f5, 0x5f5, "Read interrupt 32:63 with mask", NULL,
6283	 IGU_ADDR_TYPE_READ_INT},
6284	{0x5f6, 0x5f6, "Read interrupt 0:63 without mask", NULL,
6285	 IGU_ADDR_TYPE_READ_INT},
6286	{0x5f7, 0x5ff, "reserved", NULL,
6287	 IGU_ADDR_TYPE_RESERVED},
6288	{0x600, 0x7ff, "Producer update", NULL,
6289	 IGU_ADDR_TYPE_WRITE_PROD_UPDATE}
6290};
6291
6292/******************************** Variables **********************************/
6293
6294/* Temporary buffer, used for print size calculations */
6295static char s_temp_buf[MAX_MSG_LEN];
6296
6297/**************************** Private Functions ******************************/
6298
6299static void qed_user_static_asserts(void)
6300{
6301}
6302
6303static u32 qed_cyclic_add(u32 a, u32 b, u32 size)
6304{
6305	return (a + b) % size;
6306}
6307
6308static u32 qed_cyclic_sub(u32 a, u32 b, u32 size)
6309{
6310	return (size + a - b) % size;
6311}
6312
6313/* Reads the specified number of bytes from the specified cyclic buffer (up to 4
6314 * bytes) and returns them as a dword value. the specified buffer offset is
6315 * updated.
6316 */
6317static u32 qed_read_from_cyclic_buf(void *buf,
6318				    u32 *offset,
6319				    u32 buf_size, u8 num_bytes_to_read)
6320{
6321	u8 i, *val_ptr, *bytes_buf = (u8 *)buf;
6322	u32 val = 0;
6323
6324	val_ptr = (u8 *)&val;
6325
6326	/* Assume running on a LITTLE ENDIAN and the buffer is network order
6327	 * (BIG ENDIAN), as high order bytes are placed in lower memory address.
6328	 */
6329	for (i = 0; i < num_bytes_to_read; i++) {
6330		val_ptr[i] = bytes_buf[*offset];
6331		*offset = qed_cyclic_add(*offset, 1, buf_size);
6332	}
6333
6334	return val;
6335}
6336
6337/* Reads and returns the next byte from the specified buffer.
6338 * The specified buffer offset is updated.
6339 */
6340static u8 qed_read_byte_from_buf(void *buf, u32 *offset)
6341{
6342	return ((u8 *)buf)[(*offset)++];
6343}
6344
6345/* Reads and returns the next dword from the specified buffer.
6346 * The specified buffer offset is updated.
6347 */
6348static u32 qed_read_dword_from_buf(void *buf, u32 *offset)
6349{
6350	u32 dword_val = *(u32 *)&((u8 *)buf)[*offset];
6351
6352	*offset += 4;
6353
6354	return dword_val;
6355}
6356
6357/* Reads the next string from the specified buffer, and copies it to the
6358 * specified pointer. The specified buffer offset is updated.
6359 */
6360static void qed_read_str_from_buf(void *buf, u32 *offset, u32 size, char *dest)
6361{
6362	const char *source_str = &((const char *)buf)[*offset];
6363
6364	strscpy(dest, source_str, size);
6365	*offset += size;
6366}
6367
6368/* Returns a pointer to the specified offset (in bytes) of the specified buffer.
6369 * If the specified buffer in NULL, a temporary buffer pointer is returned.
6370 */
6371static char *qed_get_buf_ptr(void *buf, u32 offset)
6372{
6373	return buf ? (char *)buf + offset : s_temp_buf;
6374}
6375
6376/* Reads a param from the specified buffer. Returns the number of dwords read.
6377 * If the returned str_param is NULL, the param is numeric and its value is
6378 * returned in num_param.
6379 * Otheriwise, the param is a string and its pointer is returned in str_param.
6380 */
6381static u32 qed_read_param(u32 *dump_buf,
6382			  const char **param_name,
6383			  const char **param_str_val, u32 *param_num_val)
6384{
6385	char *char_buf = (char *)dump_buf;
6386	size_t offset = 0;
6387
6388	/* Extract param name */
6389	*param_name = char_buf;
6390	offset += strlen(*param_name) + 1;
6391
6392	/* Check param type */
6393	if (*(char_buf + offset++)) {
6394		/* String param */
6395		*param_str_val = char_buf + offset;
6396		*param_num_val = 0;
6397		offset += strlen(*param_str_val) + 1;
6398		if (offset & 0x3)
6399			offset += (4 - (offset & 0x3));
6400	} else {
6401		/* Numeric param */
6402		*param_str_val = NULL;
6403		if (offset & 0x3)
6404			offset += (4 - (offset & 0x3));
6405		*param_num_val = *(u32 *)(char_buf + offset);
6406		offset += 4;
6407	}
6408
6409	return (u32)offset / 4;
6410}
6411
6412/* Reads a section header from the specified buffer.
6413 * Returns the number of dwords read.
6414 */
6415static u32 qed_read_section_hdr(u32 *dump_buf,
6416				const char **section_name,
6417				u32 *num_section_params)
6418{
6419	const char *param_str_val;
6420
6421	return qed_read_param(dump_buf,
6422			      section_name, &param_str_val, num_section_params);
6423}
6424
6425/* Reads section params from the specified buffer and prints them to the results
6426 * buffer. Returns the number of dwords read.
6427 */
6428static u32 qed_print_section_params(u32 *dump_buf,
6429				    u32 num_section_params,
6430				    char *results_buf, u32 *num_chars_printed)
6431{
6432	u32 i, dump_offset = 0, results_offset = 0;
6433
6434	for (i = 0; i < num_section_params; i++) {
6435		const char *param_name, *param_str_val;
6436		u32 param_num_val = 0;
6437
6438		dump_offset += qed_read_param(dump_buf + dump_offset,
6439					      &param_name,
6440					      &param_str_val, &param_num_val);
6441
6442		if (param_str_val)
6443			results_offset +=
6444				sprintf(qed_get_buf_ptr(results_buf,
6445							results_offset),
6446					"%s: %s\n", param_name, param_str_val);
6447		else if (strcmp(param_name, "fw-timestamp"))
6448			results_offset +=
6449				sprintf(qed_get_buf_ptr(results_buf,
6450							results_offset),
6451					"%s: %d\n", param_name, param_num_val);
6452	}
6453
6454	results_offset += sprintf(qed_get_buf_ptr(results_buf, results_offset),
6455				  "\n");
6456
6457	*num_chars_printed = results_offset;
6458
6459	return dump_offset;
6460}
6461
6462/* Returns the block name that matches the specified block ID,
6463 * or NULL if not found.
6464 */
6465static const char *qed_dbg_get_block_name(struct qed_hwfn *p_hwfn,
6466					  enum block_id block_id)
6467{
6468	const struct dbg_block_user *block =
6469	    (const struct dbg_block_user *)
6470	    p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS_USER_DATA].ptr + block_id;
6471
6472	return (const char *)block->name;
6473}
6474
6475static struct dbg_tools_user_data *qed_dbg_get_user_data(struct qed_hwfn
6476							 *p_hwfn)
6477{
6478	return (struct dbg_tools_user_data *)p_hwfn->dbg_user_info;
6479}
6480
6481/* Parses the idle check rules and returns the number of characters printed.
6482 * In case of parsing error, returns 0.
6483 */
6484static u32 qed_parse_idle_chk_dump_rules(struct qed_hwfn *p_hwfn,
6485					 u32 *dump_buf,
6486					 u32 *dump_buf_end,
6487					 u32 num_rules,
6488					 bool print_fw_idle_chk,
6489					 char *results_buf,
6490					 u32 *num_errors, u32 *num_warnings)
6491{
6492	/* Offset in results_buf in bytes */
6493	u32 results_offset = 0;
6494
6495	u32 rule_idx;
6496	u16 i, j;
6497
6498	*num_errors = 0;
6499	*num_warnings = 0;
6500
6501	/* Go over dumped results */
6502	for (rule_idx = 0; rule_idx < num_rules && dump_buf < dump_buf_end;
6503	     rule_idx++) {
6504		const struct dbg_idle_chk_rule_parsing_data *rule_parsing_data;
6505		struct dbg_idle_chk_result_hdr *hdr;
6506		const char *parsing_str, *lsi_msg;
6507		u32 parsing_str_offset;
6508		bool has_fw_msg;
6509		u8 curr_reg_id;
6510
6511		hdr = (struct dbg_idle_chk_result_hdr *)dump_buf;
6512		rule_parsing_data =
6513		    (const struct dbg_idle_chk_rule_parsing_data *)
6514		    p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr +
6515		    hdr->rule_id;
6516		parsing_str_offset =
6517		    GET_FIELD(rule_parsing_data->data,
6518			      DBG_IDLE_CHK_RULE_PARSING_DATA_STR_OFFSET);
6519		has_fw_msg =
6520		    GET_FIELD(rule_parsing_data->data,
6521			      DBG_IDLE_CHK_RULE_PARSING_DATA_HAS_FW_MSG) > 0;
6522		parsing_str = (const char *)
6523		    p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr +
6524		    parsing_str_offset;
6525		lsi_msg = parsing_str;
6526		curr_reg_id = 0;
6527
6528		if (hdr->severity >= MAX_DBG_IDLE_CHK_SEVERITY_TYPES)
6529			return 0;
6530
6531		/* Skip rule header */
6532		dump_buf += BYTES_TO_DWORDS(sizeof(*hdr));
6533
6534		/* Update errors/warnings count */
6535		if (hdr->severity == IDLE_CHK_SEVERITY_ERROR ||
6536		    hdr->severity == IDLE_CHK_SEVERITY_ERROR_NO_TRAFFIC)
6537			(*num_errors)++;
6538		else
6539			(*num_warnings)++;
6540
6541		/* Print rule severity */
6542		results_offset +=
6543		    sprintf(qed_get_buf_ptr(results_buf,
6544					    results_offset), "%s: ",
6545			    s_idle_chk_severity_str[hdr->severity]);
6546
6547		/* Print rule message */
6548		if (has_fw_msg)
6549			parsing_str += strlen(parsing_str) + 1;
6550		results_offset +=
6551		    sprintf(qed_get_buf_ptr(results_buf,
6552					    results_offset), "%s.",
6553			    has_fw_msg &&
6554			    print_fw_idle_chk ? parsing_str : lsi_msg);
6555		parsing_str += strlen(parsing_str) + 1;
6556
6557		/* Print register values */
6558		results_offset +=
6559		    sprintf(qed_get_buf_ptr(results_buf,
6560					    results_offset), " Registers:");
6561		for (i = 0;
6562		     i < hdr->num_dumped_cond_regs + hdr->num_dumped_info_regs;
6563		     i++) {
6564			struct dbg_idle_chk_result_reg_hdr *reg_hdr;
6565			bool is_mem;
6566			u8 reg_id;
6567
6568			reg_hdr =
6569				(struct dbg_idle_chk_result_reg_hdr *)dump_buf;
6570			is_mem = GET_FIELD(reg_hdr->data,
6571					   DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM);
6572			reg_id = GET_FIELD(reg_hdr->data,
6573					   DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID);
6574
6575			/* Skip reg header */
6576			dump_buf += BYTES_TO_DWORDS(sizeof(*reg_hdr));
6577
6578			/* Skip register names until the required reg_id is
6579			 * reached.
6580			 */
6581			for (; reg_id > curr_reg_id; curr_reg_id++)
6582				parsing_str += strlen(parsing_str) + 1;
6583
6584			results_offset +=
6585			    sprintf(qed_get_buf_ptr(results_buf,
6586						    results_offset), " %s",
6587				    parsing_str);
6588			if (i < hdr->num_dumped_cond_regs && is_mem)
6589				results_offset +=
6590				    sprintf(qed_get_buf_ptr(results_buf,
6591							    results_offset),
6592					    "[%d]", hdr->mem_entry_id +
6593					    reg_hdr->start_entry);
6594			results_offset +=
6595			    sprintf(qed_get_buf_ptr(results_buf,
6596						    results_offset), "=");
6597			for (j = 0; j < reg_hdr->size; j++, dump_buf++) {
6598				results_offset +=
6599				    sprintf(qed_get_buf_ptr(results_buf,
6600							    results_offset),
6601					    "0x%x", *dump_buf);
6602				if (j < reg_hdr->size - 1)
6603					results_offset +=
6604					    sprintf(qed_get_buf_ptr
6605						    (results_buf,
6606						     results_offset), ",");
6607			}
6608		}
6609
6610		results_offset +=
6611		    sprintf(qed_get_buf_ptr(results_buf, results_offset), "\n");
6612	}
6613
6614	/* Check if end of dump buffer was exceeded */
6615	if (dump_buf > dump_buf_end)
6616		return 0;
6617
6618	return results_offset;
6619}
6620
6621/* Parses an idle check dump buffer.
6622 * If result_buf is not NULL, the idle check results are printed to it.
6623 * In any case, the required results buffer size is assigned to
6624 * parsed_results_bytes.
6625 * The parsing status is returned.
6626 */
6627static enum dbg_status qed_parse_idle_chk_dump(struct qed_hwfn *p_hwfn,
6628					       u32 *dump_buf,
6629					       u32 num_dumped_dwords,
6630					       char *results_buf,
6631					       u32 *parsed_results_bytes,
6632					       u32 *num_errors,
6633					       u32 *num_warnings)
6634{
6635	u32 num_section_params = 0, num_rules, num_rules_not_dumped;
6636	const char *section_name, *param_name, *param_str_val;
6637	u32 *dump_buf_end = dump_buf + num_dumped_dwords;
6638
6639	/* Offset in results_buf in bytes */
6640	u32 results_offset = 0;
6641
6642	*parsed_results_bytes = 0;
6643	*num_errors = 0;
6644	*num_warnings = 0;
6645
6646	if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr ||
6647	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr)
6648		return DBG_STATUS_DBG_ARRAY_NOT_SET;
6649
6650	/* Read global_params section */
6651	dump_buf += qed_read_section_hdr(dump_buf,
6652					 &section_name, &num_section_params);
6653	if (strcmp(section_name, "global_params"))
6654		return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6655
6656	/* Print global params */
6657	dump_buf += qed_print_section_params(dump_buf,
6658					     num_section_params,
6659					     results_buf, &results_offset);
6660
6661	/* Read idle_chk section
6662	 * There may be 1 or 2 idle_chk section parameters:
6663	 * - 1st is "num_rules"
6664	 * - 2nd is "num_rules_not_dumped" (optional)
6665	 */
6666
6667	dump_buf += qed_read_section_hdr(dump_buf,
6668					 &section_name, &num_section_params);
6669	if (strcmp(section_name, "idle_chk") ||
6670	    (num_section_params != 2 && num_section_params != 1))
6671		return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6672	dump_buf += qed_read_param(dump_buf,
6673				   &param_name, &param_str_val, &num_rules);
6674	if (strcmp(param_name, "num_rules"))
6675		return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6676	if (num_section_params > 1) {
6677		dump_buf += qed_read_param(dump_buf,
6678					   &param_name,
6679					   &param_str_val,
6680					   &num_rules_not_dumped);
6681		if (strcmp(param_name, "num_rules_not_dumped"))
6682			return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6683	} else {
6684		num_rules_not_dumped = 0;
6685	}
6686
6687	if (num_rules) {
6688		u32 rules_print_size;
6689
6690		/* Print FW output */
6691		results_offset +=
6692		    sprintf(qed_get_buf_ptr(results_buf,
6693					    results_offset),
6694			    "FW_IDLE_CHECK:\n");
6695		rules_print_size =
6696			qed_parse_idle_chk_dump_rules(p_hwfn,
6697						      dump_buf,
6698						      dump_buf_end,
6699						      num_rules,
6700						      true,
6701						      results_buf ?
6702						      results_buf +
6703						      results_offset :
6704						      NULL,
6705						      num_errors,
6706						      num_warnings);
6707		results_offset += rules_print_size;
6708		if (!rules_print_size)
6709			return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6710
6711		/* Print LSI output */
6712		results_offset +=
6713		    sprintf(qed_get_buf_ptr(results_buf,
6714					    results_offset),
6715			    "\nLSI_IDLE_CHECK:\n");
6716		rules_print_size =
6717			qed_parse_idle_chk_dump_rules(p_hwfn,
6718						      dump_buf,
6719						      dump_buf_end,
6720						      num_rules,
6721						      false,
6722						      results_buf ?
6723						      results_buf +
6724						      results_offset :
6725						      NULL,
6726						      num_errors,
6727						      num_warnings);
6728		results_offset += rules_print_size;
6729		if (!rules_print_size)
6730			return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6731	}
6732
6733	/* Print errors/warnings count */
6734	if (*num_errors)
6735		results_offset +=
6736		    sprintf(qed_get_buf_ptr(results_buf,
6737					    results_offset),
6738			    "\nIdle Check failed!!! (with %d errors and %d warnings)\n",
6739			    *num_errors, *num_warnings);
6740	else if (*num_warnings)
6741		results_offset +=
6742		    sprintf(qed_get_buf_ptr(results_buf,
6743					    results_offset),
6744			    "\nIdle Check completed successfully (with %d warnings)\n",
6745			    *num_warnings);
6746	else
6747		results_offset +=
6748		    sprintf(qed_get_buf_ptr(results_buf,
6749					    results_offset),
6750			    "\nIdle Check completed successfully\n");
6751
6752	if (num_rules_not_dumped)
6753		results_offset +=
6754		    sprintf(qed_get_buf_ptr(results_buf,
6755					    results_offset),
6756			    "\nIdle Check Partially dumped : num_rules_not_dumped = %d\n",
6757			    num_rules_not_dumped);
6758
6759	/* Add 1 for string NULL termination */
6760	*parsed_results_bytes = results_offset + 1;
6761
6762	return DBG_STATUS_OK;
6763}
6764
6765/* Allocates and fills MCP Trace meta data based on the specified meta data
6766 * dump buffer.
6767 * Returns debug status code.
6768 */
6769static enum dbg_status
6770qed_mcp_trace_alloc_meta_data(struct qed_hwfn *p_hwfn,
6771			      const u32 *meta_buf)
6772{
6773	struct dbg_tools_user_data *dev_user_data;
6774	u32 offset = 0, signature, i;
6775	struct mcp_trace_meta *meta;
6776	u8 *meta_buf_bytes;
6777
6778	dev_user_data = qed_dbg_get_user_data(p_hwfn);
6779	meta = &dev_user_data->mcp_trace_meta;
6780	meta_buf_bytes = (u8 *)meta_buf;
6781
6782	/* Free the previous meta before loading a new one. */
6783	if (meta->is_allocated)
6784		qed_mcp_trace_free_meta_data(p_hwfn);
6785
6786	memset(meta, 0, sizeof(*meta));
6787
6788	/* Read first signature */
6789	signature = qed_read_dword_from_buf(meta_buf_bytes, &offset);
6790	if (signature != NVM_MAGIC_VALUE)
6791		return DBG_STATUS_INVALID_TRACE_SIGNATURE;
6792
6793	/* Read no. of modules and allocate memory for their pointers */
6794	meta->modules_num = qed_read_byte_from_buf(meta_buf_bytes, &offset);
6795	meta->modules = kcalloc(meta->modules_num, sizeof(char *),
6796				GFP_KERNEL);
6797	if (!meta->modules)
6798		return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6799
6800	/* Allocate and read all module strings */
6801	for (i = 0; i < meta->modules_num; i++) {
6802		u8 module_len = qed_read_byte_from_buf(meta_buf_bytes, &offset);
6803
6804		*(meta->modules + i) = kzalloc(module_len, GFP_KERNEL);
6805		if (!(*(meta->modules + i))) {
6806			/* Update number of modules to be released */
6807			meta->modules_num = i ? i - 1 : 0;
6808			return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6809		}
6810
6811		qed_read_str_from_buf(meta_buf_bytes, &offset, module_len,
6812				      *(meta->modules + i));
6813		if (module_len > MCP_TRACE_MAX_MODULE_LEN)
6814			(*(meta->modules + i))[MCP_TRACE_MAX_MODULE_LEN] = '\0';
6815	}
6816
6817	/* Read second signature */
6818	signature = qed_read_dword_from_buf(meta_buf_bytes, &offset);
6819	if (signature != NVM_MAGIC_VALUE)
6820		return DBG_STATUS_INVALID_TRACE_SIGNATURE;
6821
6822	/* Read number of formats and allocate memory for all formats */
6823	meta->formats_num = qed_read_dword_from_buf(meta_buf_bytes, &offset);
6824	meta->formats = kcalloc(meta->formats_num,
6825				sizeof(struct mcp_trace_format),
6826				GFP_KERNEL);
6827	if (!meta->formats)
6828		return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6829
6830	/* Allocate and read all strings */
6831	for (i = 0; i < meta->formats_num; i++) {
6832		struct mcp_trace_format *format_ptr = &meta->formats[i];
6833		u8 format_len;
6834
6835		format_ptr->data = qed_read_dword_from_buf(meta_buf_bytes,
6836							   &offset);
6837		format_len = GET_MFW_FIELD(format_ptr->data,
6838					   MCP_TRACE_FORMAT_LEN);
6839		format_ptr->format_str = kzalloc(format_len, GFP_KERNEL);
6840		if (!format_ptr->format_str) {
6841			/* Update number of modules to be released */
6842			meta->formats_num = i ? i - 1 : 0;
6843			return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6844		}
6845
6846		qed_read_str_from_buf(meta_buf_bytes,
6847				      &offset,
6848				      format_len, format_ptr->format_str);
6849	}
6850
6851	meta->is_allocated = true;
6852	return DBG_STATUS_OK;
6853}
6854
6855/* Parses an MCP trace buffer. If result_buf is not NULL, the MCP Trace results
6856 * are printed to it. The parsing status is returned.
6857 * Arguments:
6858 * trace_buf - MCP trace cyclic buffer
6859 * trace_buf_size - MCP trace cyclic buffer size in bytes
6860 * data_offset - offset in bytes of the data to parse in the MCP trace cyclic
6861 *		 buffer.
6862 * data_size - size in bytes of data to parse.
6863 * parsed_buf - destination buffer for parsed data.
6864 * parsed_results_bytes - size of parsed data in bytes.
6865 */
6866static enum dbg_status qed_parse_mcp_trace_buf(struct qed_hwfn *p_hwfn,
6867					       u8 *trace_buf,
6868					       u32 trace_buf_size,
6869					       u32 data_offset,
6870					       u32 data_size,
6871					       char *parsed_buf,
6872					       u32 *parsed_results_bytes)
6873{
6874	struct dbg_tools_user_data *dev_user_data;
6875	struct mcp_trace_meta *meta;
6876	u32 param_mask, param_shift;
6877	enum dbg_status status;
6878
6879	dev_user_data = qed_dbg_get_user_data(p_hwfn);
6880	meta = &dev_user_data->mcp_trace_meta;
6881	*parsed_results_bytes = 0;
6882
6883	if (!meta->is_allocated)
6884		return DBG_STATUS_MCP_TRACE_BAD_DATA;
6885
6886	status = DBG_STATUS_OK;
6887
6888	while (data_size) {
6889		struct mcp_trace_format *format_ptr;
6890		u8 format_level, format_module;
6891		u32 params[3] = { 0, 0, 0 };
6892		u32 header, format_idx, i;
6893
6894		if (data_size < MFW_TRACE_ENTRY_SIZE)
6895			return DBG_STATUS_MCP_TRACE_BAD_DATA;
6896
6897		header = qed_read_from_cyclic_buf(trace_buf,
6898						  &data_offset,
6899						  trace_buf_size,
6900						  MFW_TRACE_ENTRY_SIZE);
6901		data_size -= MFW_TRACE_ENTRY_SIZE;
6902		format_idx = header & MFW_TRACE_EVENTID_MASK;
6903
6904		/* Skip message if its index doesn't exist in the meta data */
6905		if (format_idx >= meta->formats_num) {
6906			u8 format_size = (u8)GET_MFW_FIELD(header,
6907							   MFW_TRACE_PRM_SIZE);
6908
6909			if (data_size < format_size)
6910				return DBG_STATUS_MCP_TRACE_BAD_DATA;
6911
6912			data_offset = qed_cyclic_add(data_offset,
6913						     format_size,
6914						     trace_buf_size);
6915			data_size -= format_size;
6916			continue;
6917		}
6918
6919		format_ptr = &meta->formats[format_idx];
6920
6921		for (i = 0,
6922		     param_mask = MCP_TRACE_FORMAT_P1_SIZE_MASK, param_shift =
6923		     MCP_TRACE_FORMAT_P1_SIZE_OFFSET;
6924		     i < MCP_TRACE_FORMAT_MAX_PARAMS;
6925		     i++, param_mask <<= MCP_TRACE_FORMAT_PARAM_WIDTH,
6926		     param_shift += MCP_TRACE_FORMAT_PARAM_WIDTH) {
6927			/* Extract param size (0..3) */
6928			u8 param_size = (u8)((format_ptr->data & param_mask) >>
6929					     param_shift);
6930
6931			/* If the param size is zero, there are no other
6932			 * parameters.
6933			 */
6934			if (!param_size)
6935				break;
6936
6937			/* Size is encoded using 2 bits, where 3 is used to
6938			 * encode 4.
6939			 */
6940			if (param_size == 3)
6941				param_size = 4;
6942
6943			if (data_size < param_size)
6944				return DBG_STATUS_MCP_TRACE_BAD_DATA;
6945
6946			params[i] = qed_read_from_cyclic_buf(trace_buf,
6947							     &data_offset,
6948							     trace_buf_size,
6949							     param_size);
6950			data_size -= param_size;
6951		}
6952
6953		format_level = (u8)GET_MFW_FIELD(format_ptr->data,
6954						 MCP_TRACE_FORMAT_LEVEL);
6955		format_module = (u8)GET_MFW_FIELD(format_ptr->data,
6956						  MCP_TRACE_FORMAT_MODULE);
6957		if (format_level >= ARRAY_SIZE(s_mcp_trace_level_str))
6958			return DBG_STATUS_MCP_TRACE_BAD_DATA;
6959
6960		/* Print current message to results buffer */
6961		*parsed_results_bytes +=
6962			sprintf(qed_get_buf_ptr(parsed_buf,
6963						*parsed_results_bytes),
6964				"%s %-8s: ",
6965				s_mcp_trace_level_str[format_level],
6966				meta->modules[format_module]);
6967		*parsed_results_bytes +=
6968		    sprintf(qed_get_buf_ptr(parsed_buf, *parsed_results_bytes),
6969			    format_ptr->format_str,
6970			    params[0], params[1], params[2]);
6971	}
6972
6973	/* Add string NULL terminator */
6974	(*parsed_results_bytes)++;
6975
6976	return status;
6977}
6978
6979/* Parses an MCP Trace dump buffer.
6980 * If result_buf is not NULL, the MCP Trace results are printed to it.
6981 * In any case, the required results buffer size is assigned to
6982 * parsed_results_bytes.
6983 * The parsing status is returned.
6984 */
6985static enum dbg_status qed_parse_mcp_trace_dump(struct qed_hwfn *p_hwfn,
6986						u32 *dump_buf,
6987						char *results_buf,
6988						u32 *parsed_results_bytes,
6989						bool free_meta_data)
6990{
6991	const char *section_name, *param_name, *param_str_val;
6992	u32 data_size, trace_data_dwords, trace_meta_dwords;
6993	u32 offset, results_offset, results_buf_bytes;
6994	u32 param_num_val, num_section_params;
6995	struct mcp_trace *trace;
6996	enum dbg_status status;
6997	const u32 *meta_buf;
6998	u8 *trace_buf;
6999
7000	*parsed_results_bytes = 0;
7001
7002	/* Read global_params section */
7003	dump_buf += qed_read_section_hdr(dump_buf,
7004					 &section_name, &num_section_params);
7005	if (strcmp(section_name, "global_params"))
7006		return DBG_STATUS_MCP_TRACE_BAD_DATA;
7007
7008	/* Print global params */
7009	dump_buf += qed_print_section_params(dump_buf,
7010					     num_section_params,
7011					     results_buf, &results_offset);
7012
7013	/* Read trace_data section */
7014	dump_buf += qed_read_section_hdr(dump_buf,
7015					 &section_name, &num_section_params);
7016	if (strcmp(section_name, "mcp_trace_data") || num_section_params != 1)
7017		return DBG_STATUS_MCP_TRACE_BAD_DATA;
7018	dump_buf += qed_read_param(dump_buf,
7019				   &param_name, &param_str_val, &param_num_val);
7020	if (strcmp(param_name, "size"))
7021		return DBG_STATUS_MCP_TRACE_BAD_DATA;
7022	trace_data_dwords = param_num_val;
7023
7024	/* Prepare trace info */
7025	trace = (struct mcp_trace *)dump_buf;
7026	if (trace->signature != MFW_TRACE_SIGNATURE || !trace->size)
7027		return DBG_STATUS_MCP_TRACE_BAD_DATA;
7028
7029	trace_buf = (u8 *)dump_buf + sizeof(*trace);
7030	offset = trace->trace_oldest;
7031	data_size = qed_cyclic_sub(trace->trace_prod, offset, trace->size);
7032	dump_buf += trace_data_dwords;
7033
7034	/* Read meta_data section */
7035	dump_buf += qed_read_section_hdr(dump_buf,
7036					 &section_name, &num_section_params);
7037	if (strcmp(section_name, "mcp_trace_meta"))
7038		return DBG_STATUS_MCP_TRACE_BAD_DATA;
7039	dump_buf += qed_read_param(dump_buf,
7040				   &param_name, &param_str_val, &param_num_val);
7041	if (strcmp(param_name, "size"))
7042		return DBG_STATUS_MCP_TRACE_BAD_DATA;
7043	trace_meta_dwords = param_num_val;
7044
7045	/* Choose meta data buffer */
7046	if (!trace_meta_dwords) {
7047		/* Dump doesn't include meta data */
7048		struct dbg_tools_user_data *dev_user_data =
7049			qed_dbg_get_user_data(p_hwfn);
7050
7051		if (!dev_user_data->mcp_trace_user_meta_buf)
7052			return DBG_STATUS_MCP_TRACE_NO_META;
7053
7054		meta_buf = dev_user_data->mcp_trace_user_meta_buf;
7055	} else {
7056		/* Dump includes meta data */
7057		meta_buf = dump_buf;
7058	}
7059
7060	/* Allocate meta data memory */
7061	status = qed_mcp_trace_alloc_meta_data(p_hwfn, meta_buf);
7062	if (status != DBG_STATUS_OK)
7063		return status;
7064
7065	status = qed_parse_mcp_trace_buf(p_hwfn,
7066					 trace_buf,
7067					 trace->size,
7068					 offset,
7069					 data_size,
7070					 results_buf ?
7071					 results_buf + results_offset :
7072					 NULL,
7073					 &results_buf_bytes);
7074	if (status != DBG_STATUS_OK)
7075		return status;
7076
7077	if (free_meta_data)
7078		qed_mcp_trace_free_meta_data(p_hwfn);
7079
7080	*parsed_results_bytes = results_offset + results_buf_bytes;
7081
7082	return DBG_STATUS_OK;
7083}
7084
7085/* Parses a Reg FIFO dump buffer.
7086 * If result_buf is not NULL, the Reg FIFO results are printed to it.
7087 * In any case, the required results buffer size is assigned to
7088 * parsed_results_bytes.
7089 * The parsing status is returned.
7090 */
7091static enum dbg_status qed_parse_reg_fifo_dump(u32 *dump_buf,
7092					       char *results_buf,
7093					       u32 *parsed_results_bytes)
7094{
7095	const char *section_name, *param_name, *param_str_val;
7096	u32 param_num_val, num_section_params, num_elements;
7097	struct reg_fifo_element *elements;
7098	u8 i, j, err_code, vf_val;
7099	u32 results_offset = 0;
7100	char vf_str[4];
7101
7102	/* Read global_params section */
7103	dump_buf += qed_read_section_hdr(dump_buf,
7104					 &section_name, &num_section_params);
7105	if (strcmp(section_name, "global_params"))
7106		return DBG_STATUS_REG_FIFO_BAD_DATA;
7107
7108	/* Print global params */
7109	dump_buf += qed_print_section_params(dump_buf,
7110					     num_section_params,
7111					     results_buf, &results_offset);
7112
7113	/* Read reg_fifo_data section */
7114	dump_buf += qed_read_section_hdr(dump_buf,
7115					 &section_name, &num_section_params);
7116	if (strcmp(section_name, "reg_fifo_data"))
7117		return DBG_STATUS_REG_FIFO_BAD_DATA;
7118	dump_buf += qed_read_param(dump_buf,
7119				   &param_name, &param_str_val, &param_num_val);
7120	if (strcmp(param_name, "size"))
7121		return DBG_STATUS_REG_FIFO_BAD_DATA;
7122	if (param_num_val % REG_FIFO_ELEMENT_DWORDS)
7123		return DBG_STATUS_REG_FIFO_BAD_DATA;
7124	num_elements = param_num_val / REG_FIFO_ELEMENT_DWORDS;
7125	elements = (struct reg_fifo_element *)dump_buf;
7126
7127	/* Decode elements */
7128	for (i = 0; i < num_elements; i++) {
7129		const char *err_msg = NULL;
7130
7131		/* Discover if element belongs to a VF or a PF */
7132		vf_val = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_VF);
7133		if (vf_val == REG_FIFO_ELEMENT_IS_PF_VF_VAL)
7134			sprintf(vf_str, "%s", "N/A");
7135		else
7136			sprintf(vf_str, "%d", vf_val);
7137
7138		/* Find error message */
7139		err_code = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_ERROR);
7140		for (j = 0; j < ARRAY_SIZE(s_reg_fifo_errors) && !err_msg; j++)
7141			if (err_code == s_reg_fifo_errors[j].err_code)
7142				err_msg = s_reg_fifo_errors[j].err_msg;
7143
7144		/* Add parsed element to parsed buffer */
7145		results_offset +=
7146		    sprintf(qed_get_buf_ptr(results_buf,
7147					    results_offset),
7148			    "raw: 0x%016llx, address: 0x%07x, access: %-5s, pf: %2d, vf: %s, port: %d, privilege: %-3s, protection: %-12s, master: %-4s, error: %s\n",
7149			    elements[i].data,
7150			    (u32)GET_FIELD(elements[i].data,
7151					   REG_FIFO_ELEMENT_ADDRESS) *
7152			    REG_FIFO_ELEMENT_ADDR_FACTOR,
7153			    s_access_strs[GET_FIELD(elements[i].data,
7154						    REG_FIFO_ELEMENT_ACCESS)],
7155			    (u32)GET_FIELD(elements[i].data,
7156					   REG_FIFO_ELEMENT_PF),
7157			    vf_str,
7158			    (u32)GET_FIELD(elements[i].data,
7159					   REG_FIFO_ELEMENT_PORT),
7160			    s_privilege_strs[GET_FIELD(elements[i].data,
7161						REG_FIFO_ELEMENT_PRIVILEGE)],
7162			    s_protection_strs[GET_FIELD(elements[i].data,
7163						REG_FIFO_ELEMENT_PROTECTION)],
7164			    s_master_strs[GET_FIELD(elements[i].data,
7165						    REG_FIFO_ELEMENT_MASTER)],
7166			    err_msg ? err_msg : "unknown error code");
7167	}
7168
7169	results_offset += sprintf(qed_get_buf_ptr(results_buf,
7170						  results_offset),
7171				  "fifo contained %d elements", num_elements);
7172
7173	/* Add 1 for string NULL termination */
7174	*parsed_results_bytes = results_offset + 1;
7175
7176	return DBG_STATUS_OK;
7177}
7178
7179static enum dbg_status qed_parse_igu_fifo_element(struct igu_fifo_element
7180						  *element, char
7181						  *results_buf,
7182						  u32 *results_offset)
7183{
7184	const struct igu_fifo_addr_data *found_addr = NULL;
7185	u8 source, err_type, i, is_cleanup;
7186	char parsed_addr_data[32];
7187	char parsed_wr_data[256];
7188	u32 wr_data, prod_cons;
7189	bool is_wr_cmd, is_pf;
7190	u16 cmd_addr;
7191	u64 dword12;
7192
7193	/* Dword12 (dword index 1 and 2) contains bits 32..95 of the
7194	 * FIFO element.
7195	 */
7196	dword12 = ((u64)element->dword2 << 32) | element->dword1;
7197	is_wr_cmd = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD);
7198	is_pf = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_IS_PF);
7199	cmd_addr = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR);
7200	source = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_SOURCE);
7201	err_type = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE);
7202
7203	if (source >= ARRAY_SIZE(s_igu_fifo_source_strs))
7204		return DBG_STATUS_IGU_FIFO_BAD_DATA;
7205	if (err_type >= ARRAY_SIZE(s_igu_fifo_error_strs))
7206		return DBG_STATUS_IGU_FIFO_BAD_DATA;
7207
7208	/* Find address data */
7209	for (i = 0; i < ARRAY_SIZE(s_igu_fifo_addr_data) && !found_addr; i++) {
7210		const struct igu_fifo_addr_data *curr_addr =
7211			&s_igu_fifo_addr_data[i];
7212
7213		if (cmd_addr >= curr_addr->start_addr && cmd_addr <=
7214		    curr_addr->end_addr)
7215			found_addr = curr_addr;
7216	}
7217
7218	if (!found_addr)
7219		return DBG_STATUS_IGU_FIFO_BAD_DATA;
7220
7221	/* Prepare parsed address data */
7222	switch (found_addr->type) {
7223	case IGU_ADDR_TYPE_MSIX_MEM:
7224		sprintf(parsed_addr_data, " vector_num = 0x%x", cmd_addr / 2);
7225		break;
7226	case IGU_ADDR_TYPE_WRITE_INT_ACK:
7227	case IGU_ADDR_TYPE_WRITE_PROD_UPDATE:
7228		sprintf(parsed_addr_data,
7229			" SB = 0x%x", cmd_addr - found_addr->start_addr);
7230		break;
7231	default:
7232		parsed_addr_data[0] = '\0';
7233	}
7234
7235	if (!is_wr_cmd) {
7236		parsed_wr_data[0] = '\0';
7237		goto out;
7238	}
7239
7240	/* Prepare parsed write data */
7241	wr_data = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_WR_DATA);
7242	prod_cons = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_PROD_CONS);
7243	is_cleanup = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_CMD_TYPE);
7244
7245	if (source == IGU_SRC_ATTN) {
7246		sprintf(parsed_wr_data, "prod: 0x%x, ", prod_cons);
7247	} else {
7248		if (is_cleanup) {
7249			u8 cleanup_val, cleanup_type;
7250
7251			cleanup_val =
7252				GET_FIELD(wr_data,
7253					  IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL);
7254			cleanup_type =
7255			    GET_FIELD(wr_data,
7256				      IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE);
7257
7258			sprintf(parsed_wr_data,
7259				"cmd_type: cleanup, cleanup_val: %s, cleanup_type : %d, ",
7260				cleanup_val ? "set" : "clear",
7261				cleanup_type);
7262		} else {
7263			u8 update_flag, en_dis_int_for_sb, segment;
7264			u8 timer_mask;
7265
7266			update_flag = GET_FIELD(wr_data,
7267						IGU_FIFO_WR_DATA_UPDATE_FLAG);
7268			en_dis_int_for_sb =
7269				GET_FIELD(wr_data,
7270					  IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB);
7271			segment = GET_FIELD(wr_data,
7272					    IGU_FIFO_WR_DATA_SEGMENT);
7273			timer_mask = GET_FIELD(wr_data,
7274					       IGU_FIFO_WR_DATA_TIMER_MASK);
7275
7276			sprintf(parsed_wr_data,
7277				"cmd_type: prod/cons update, prod/cons: 0x%x, update_flag: %s, en_dis_int_for_sb : %s, segment : %s, timer_mask = %d, ",
7278				prod_cons,
7279				update_flag ? "update" : "nop",
7280				en_dis_int_for_sb ?
7281				(en_dis_int_for_sb == 1 ? "disable" : "nop") :
7282				"enable",
7283				segment ? "attn" : "regular",
7284				timer_mask);
7285		}
7286	}
7287out:
7288	/* Add parsed element to parsed buffer */
7289	*results_offset += sprintf(qed_get_buf_ptr(results_buf,
7290						   *results_offset),
7291				   "raw: 0x%01x%08x%08x, %s: %d, source : %s, type : %s, cmd_addr : 0x%x(%s%s), %serror: %s\n",
7292				   element->dword2, element->dword1,
7293				   element->dword0,
7294				   is_pf ? "pf" : "vf",
7295				   GET_FIELD(element->dword0,
7296					     IGU_FIFO_ELEMENT_DWORD0_FID),
7297				   s_igu_fifo_source_strs[source],
7298				   is_wr_cmd ? "wr" : "rd",
7299				   cmd_addr,
7300				   (!is_pf && found_addr->vf_desc)
7301				   ? found_addr->vf_desc
7302				   : found_addr->desc,
7303				   parsed_addr_data,
7304				   parsed_wr_data,
7305				   s_igu_fifo_error_strs[err_type]);
7306
7307	return DBG_STATUS_OK;
7308}
7309
7310/* Parses an IGU FIFO dump buffer.
7311 * If result_buf is not NULL, the IGU FIFO results are printed to it.
7312 * In any case, the required results buffer size is assigned to
7313 * parsed_results_bytes.
7314 * The parsing status is returned.
7315 */
7316static enum dbg_status qed_parse_igu_fifo_dump(u32 *dump_buf,
7317					       char *results_buf,
7318					       u32 *parsed_results_bytes)
7319{
7320	const char *section_name, *param_name, *param_str_val;
7321	u32 param_num_val, num_section_params, num_elements;
7322	struct igu_fifo_element *elements;
7323	enum dbg_status status;
7324	u32 results_offset = 0;
7325	u8 i;
7326
7327	/* Read global_params section */
7328	dump_buf += qed_read_section_hdr(dump_buf,
7329					 &section_name, &num_section_params);
7330	if (strcmp(section_name, "global_params"))
7331		return DBG_STATUS_IGU_FIFO_BAD_DATA;
7332
7333	/* Print global params */
7334	dump_buf += qed_print_section_params(dump_buf,
7335					     num_section_params,
7336					     results_buf, &results_offset);
7337
7338	/* Read igu_fifo_data section */
7339	dump_buf += qed_read_section_hdr(dump_buf,
7340					 &section_name, &num_section_params);
7341	if (strcmp(section_name, "igu_fifo_data"))
7342		return DBG_STATUS_IGU_FIFO_BAD_DATA;
7343	dump_buf += qed_read_param(dump_buf,
7344				   &param_name, &param_str_val, &param_num_val);
7345	if (strcmp(param_name, "size"))
7346		return DBG_STATUS_IGU_FIFO_BAD_DATA;
7347	if (param_num_val % IGU_FIFO_ELEMENT_DWORDS)
7348		return DBG_STATUS_IGU_FIFO_BAD_DATA;
7349	num_elements = param_num_val / IGU_FIFO_ELEMENT_DWORDS;
7350	elements = (struct igu_fifo_element *)dump_buf;
7351
7352	/* Decode elements */
7353	for (i = 0; i < num_elements; i++) {
7354		status = qed_parse_igu_fifo_element(&elements[i],
7355						    results_buf,
7356						    &results_offset);
7357		if (status != DBG_STATUS_OK)
7358			return status;
7359	}
7360
7361	results_offset += sprintf(qed_get_buf_ptr(results_buf,
7362						  results_offset),
7363				  "fifo contained %d elements", num_elements);
7364
7365	/* Add 1 for string NULL termination */
7366	*parsed_results_bytes = results_offset + 1;
7367
7368	return DBG_STATUS_OK;
7369}
7370
7371static enum dbg_status
7372qed_parse_protection_override_dump(u32 *dump_buf,
7373				   char *results_buf,
7374				   u32 *parsed_results_bytes)
7375{
7376	const char *section_name, *param_name, *param_str_val;
7377	u32 param_num_val, num_section_params, num_elements;
7378	struct protection_override_element *elements;
7379	u32 results_offset = 0;
7380	u8 i;
7381
7382	/* Read global_params section */
7383	dump_buf += qed_read_section_hdr(dump_buf,
7384					 &section_name, &num_section_params);
7385	if (strcmp(section_name, "global_params"))
7386		return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7387
7388	/* Print global params */
7389	dump_buf += qed_print_section_params(dump_buf,
7390					     num_section_params,
7391					     results_buf, &results_offset);
7392
7393	/* Read protection_override_data section */
7394	dump_buf += qed_read_section_hdr(dump_buf,
7395					 &section_name, &num_section_params);
7396	if (strcmp(section_name, "protection_override_data"))
7397		return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7398	dump_buf += qed_read_param(dump_buf,
7399				   &param_name, &param_str_val, &param_num_val);
7400	if (strcmp(param_name, "size"))
7401		return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7402	if (param_num_val % PROTECTION_OVERRIDE_ELEMENT_DWORDS)
7403		return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7404	num_elements = param_num_val / PROTECTION_OVERRIDE_ELEMENT_DWORDS;
7405	elements = (struct protection_override_element *)dump_buf;
7406
7407	/* Decode elements */
7408	for (i = 0; i < num_elements; i++) {
7409		u32 address = GET_FIELD(elements[i].data,
7410					PROTECTION_OVERRIDE_ELEMENT_ADDRESS) *
7411			      PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR;
7412
7413		results_offset +=
7414		    sprintf(qed_get_buf_ptr(results_buf,
7415					    results_offset),
7416			    "window %2d, address: 0x%07x, size: %7d regs, read: %d, write: %d, read protection: %-12s, write protection: %-12s\n",
7417			    i, address,
7418			    (u32)GET_FIELD(elements[i].data,
7419				      PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE),
7420			    (u32)GET_FIELD(elements[i].data,
7421				      PROTECTION_OVERRIDE_ELEMENT_READ),
7422			    (u32)GET_FIELD(elements[i].data,
7423				      PROTECTION_OVERRIDE_ELEMENT_WRITE),
7424			    s_protection_strs[GET_FIELD(elements[i].data,
7425				PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION)],
7426			    s_protection_strs[GET_FIELD(elements[i].data,
7427				PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION)]);
7428	}
7429
7430	results_offset += sprintf(qed_get_buf_ptr(results_buf,
7431						  results_offset),
7432				  "protection override contained %d elements",
7433				  num_elements);
7434
7435	/* Add 1 for string NULL termination */
7436	*parsed_results_bytes = results_offset + 1;
7437
7438	return DBG_STATUS_OK;
7439}
7440
7441/* Parses a FW Asserts dump buffer.
7442 * If result_buf is not NULL, the FW Asserts results are printed to it.
7443 * In any case, the required results buffer size is assigned to
7444 * parsed_results_bytes.
7445 * The parsing status is returned.
7446 */
7447static enum dbg_status qed_parse_fw_asserts_dump(u32 *dump_buf,
7448						 char *results_buf,
7449						 u32 *parsed_results_bytes)
7450{
7451	u32 num_section_params, param_num_val, i, results_offset = 0;
7452	const char *param_name, *param_str_val, *section_name;
7453	bool last_section_found = false;
7454
7455	*parsed_results_bytes = 0;
7456
7457	/* Read global_params section */
7458	dump_buf += qed_read_section_hdr(dump_buf,
7459					 &section_name, &num_section_params);
7460	if (strcmp(section_name, "global_params"))
7461		return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7462
7463	/* Print global params */
7464	dump_buf += qed_print_section_params(dump_buf,
7465					     num_section_params,
7466					     results_buf, &results_offset);
7467
7468	while (!last_section_found) {
7469		dump_buf += qed_read_section_hdr(dump_buf,
7470						 &section_name,
7471						 &num_section_params);
7472		if (!strcmp(section_name, "fw_asserts")) {
7473			/* Extract params */
7474			const char *storm_letter = NULL;
7475			u32 storm_dump_size = 0;
7476
7477			for (i = 0; i < num_section_params; i++) {
7478				dump_buf += qed_read_param(dump_buf,
7479							   &param_name,
7480							   &param_str_val,
7481							   &param_num_val);
7482				if (!strcmp(param_name, "storm"))
7483					storm_letter = param_str_val;
7484				else if (!strcmp(param_name, "size"))
7485					storm_dump_size = param_num_val;
7486				else
7487					return
7488					    DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7489			}
7490
7491			if (!storm_letter || !storm_dump_size)
7492				return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7493
7494			/* Print data */
7495			results_offset +=
7496			    sprintf(qed_get_buf_ptr(results_buf,
7497						    results_offset),
7498				    "\n%sSTORM_ASSERT: size=%d\n",
7499				    storm_letter, storm_dump_size);
7500			for (i = 0; i < storm_dump_size; i++, dump_buf++)
7501				results_offset +=
7502				    sprintf(qed_get_buf_ptr(results_buf,
7503							    results_offset),
7504					    "%08x\n", *dump_buf);
7505		} else if (!strcmp(section_name, "last")) {
7506			last_section_found = true;
7507		} else {
7508			return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7509		}
7510	}
7511
7512	/* Add 1 for string NULL termination */
7513	*parsed_results_bytes = results_offset + 1;
7514
7515	return DBG_STATUS_OK;
7516}
7517
7518/***************************** Public Functions *******************************/
7519
7520enum dbg_status qed_dbg_user_set_bin_ptr(struct qed_hwfn *p_hwfn,
7521					 const u8 * const bin_ptr)
7522{
7523	struct bin_buffer_hdr *buf_hdrs = (struct bin_buffer_hdr *)bin_ptr;
7524	u8 buf_id;
7525
7526	/* Convert binary data to debug arrays */
7527	for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++)
7528		qed_set_dbg_bin_buf(p_hwfn,
7529				    (enum bin_dbg_buffer_type)buf_id,
7530				    (u32 *)(bin_ptr + buf_hdrs[buf_id].offset),
7531				    buf_hdrs[buf_id].length);
7532
7533	return DBG_STATUS_OK;
7534}
7535
7536enum dbg_status qed_dbg_alloc_user_data(struct qed_hwfn *p_hwfn,
7537					void **user_data_ptr)
7538{
7539	*user_data_ptr = kzalloc(sizeof(struct dbg_tools_user_data),
7540				 GFP_KERNEL);
7541	if (!(*user_data_ptr))
7542		return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
7543
7544	return DBG_STATUS_OK;
7545}
7546
7547const char *qed_dbg_get_status_str(enum dbg_status status)
7548{
7549	return (status <
7550		MAX_DBG_STATUS) ? s_status_str[status] : "Invalid debug status";
7551}
7552
7553enum dbg_status qed_get_idle_chk_results_buf_size(struct qed_hwfn *p_hwfn,
7554						  u32 *dump_buf,
7555						  u32 num_dumped_dwords,
7556						  u32 *results_buf_size)
7557{
7558	u32 num_errors, num_warnings;
7559
7560	return qed_parse_idle_chk_dump(p_hwfn,
7561				       dump_buf,
7562				       num_dumped_dwords,
7563				       NULL,
7564				       results_buf_size,
7565				       &num_errors, &num_warnings);
7566}
7567
7568enum dbg_status qed_print_idle_chk_results(struct qed_hwfn *p_hwfn,
7569					   u32 *dump_buf,
7570					   u32 num_dumped_dwords,
7571					   char *results_buf,
7572					   u32 *num_errors,
7573					   u32 *num_warnings)
7574{
7575	u32 parsed_buf_size;
7576
7577	return qed_parse_idle_chk_dump(p_hwfn,
7578				       dump_buf,
7579				       num_dumped_dwords,
7580				       results_buf,
7581				       &parsed_buf_size,
7582				       num_errors, num_warnings);
7583}
7584
7585void qed_dbg_mcp_trace_set_meta_data(struct qed_hwfn *p_hwfn,
7586				     const u32 *meta_buf)
7587{
7588	struct dbg_tools_user_data *dev_user_data =
7589		qed_dbg_get_user_data(p_hwfn);
7590
7591	dev_user_data->mcp_trace_user_meta_buf = meta_buf;
7592}
7593
7594enum dbg_status qed_get_mcp_trace_results_buf_size(struct qed_hwfn *p_hwfn,
7595						   u32 *dump_buf,
7596						   u32 num_dumped_dwords,
7597						   u32 *results_buf_size)
7598{
7599	return qed_parse_mcp_trace_dump(p_hwfn,
7600					dump_buf, NULL, results_buf_size, true);
7601}
7602
7603enum dbg_status qed_print_mcp_trace_results(struct qed_hwfn *p_hwfn,
7604					    u32 *dump_buf,
7605					    u32 num_dumped_dwords,
7606					    char *results_buf)
7607{
7608	u32 parsed_buf_size;
7609
7610	/* Doesn't do anything, needed for compile time asserts */
7611	qed_user_static_asserts();
7612
7613	return qed_parse_mcp_trace_dump(p_hwfn,
7614					dump_buf,
7615					results_buf, &parsed_buf_size, true);
7616}
7617
7618/* Frees the specified MCP Trace meta data */
7619void qed_mcp_trace_free_meta_data(struct qed_hwfn *p_hwfn)
7620{
7621	struct dbg_tools_user_data *dev_user_data;
7622	struct mcp_trace_meta *meta;
7623	u32 i;
7624
7625	dev_user_data = qed_dbg_get_user_data(p_hwfn);
7626	meta = &dev_user_data->mcp_trace_meta;
7627	if (!meta->is_allocated)
7628		return;
7629
7630	/* Release modules */
7631	if (meta->modules) {
7632		for (i = 0; i < meta->modules_num; i++)
7633			kfree(meta->modules[i]);
7634		kfree(meta->modules);
7635	}
7636
7637	/* Release formats */
7638	if (meta->formats) {
7639		for (i = 0; i < meta->formats_num; i++)
7640			kfree(meta->formats[i].format_str);
7641		kfree(meta->formats);
7642	}
7643
7644	meta->is_allocated = false;
7645}
7646
7647enum dbg_status qed_get_reg_fifo_results_buf_size(struct qed_hwfn *p_hwfn,
7648						  u32 *dump_buf,
7649						  u32 num_dumped_dwords,
7650						  u32 *results_buf_size)
7651{
7652	return qed_parse_reg_fifo_dump(dump_buf, NULL, results_buf_size);
7653}
7654
7655enum dbg_status qed_print_reg_fifo_results(struct qed_hwfn *p_hwfn,
7656					   u32 *dump_buf,
7657					   u32 num_dumped_dwords,
7658					   char *results_buf)
7659{
7660	u32 parsed_buf_size;
7661
7662	return qed_parse_reg_fifo_dump(dump_buf, results_buf, &parsed_buf_size);
7663}
7664
7665enum dbg_status qed_get_igu_fifo_results_buf_size(struct qed_hwfn *p_hwfn,
7666						  u32 *dump_buf,
7667						  u32 num_dumped_dwords,
7668						  u32 *results_buf_size)
7669{
7670	return qed_parse_igu_fifo_dump(dump_buf, NULL, results_buf_size);
7671}
7672
7673enum dbg_status qed_print_igu_fifo_results(struct qed_hwfn *p_hwfn,
7674					   u32 *dump_buf,
7675					   u32 num_dumped_dwords,
7676					   char *results_buf)
7677{
7678	u32 parsed_buf_size;
7679
7680	return qed_parse_igu_fifo_dump(dump_buf, results_buf, &parsed_buf_size);
7681}
7682
7683enum dbg_status
7684qed_get_protection_override_results_buf_size(struct qed_hwfn *p_hwfn,
7685					     u32 *dump_buf,
7686					     u32 num_dumped_dwords,
7687					     u32 *results_buf_size)
7688{
7689	return qed_parse_protection_override_dump(dump_buf,
7690						  NULL, results_buf_size);
7691}
7692
7693enum dbg_status qed_print_protection_override_results(struct qed_hwfn *p_hwfn,
7694						      u32 *dump_buf,
7695						      u32 num_dumped_dwords,
7696						      char *results_buf)
7697{
7698	u32 parsed_buf_size;
7699
7700	return qed_parse_protection_override_dump(dump_buf,
7701						  results_buf,
7702						  &parsed_buf_size);
7703}
7704
7705enum dbg_status qed_get_fw_asserts_results_buf_size(struct qed_hwfn *p_hwfn,
7706						    u32 *dump_buf,
7707						    u32 num_dumped_dwords,
7708						    u32 *results_buf_size)
7709{
7710	return qed_parse_fw_asserts_dump(dump_buf, NULL, results_buf_size);
7711}
7712
7713enum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn,
7714					     u32 *dump_buf,
7715					     u32 num_dumped_dwords,
7716					     char *results_buf)
7717{
7718	u32 parsed_buf_size;
7719
7720	return qed_parse_fw_asserts_dump(dump_buf,
7721					 results_buf, &parsed_buf_size);
7722}
7723
7724enum dbg_status qed_dbg_parse_attn(struct qed_hwfn *p_hwfn,
7725				   struct dbg_attn_block_result *results)
7726{
7727	const u32 *block_attn_name_offsets;
7728	const char *attn_name_base;
7729	const char *block_name;
7730	enum dbg_attn_type attn_type;
7731	u8 num_regs, i, j;
7732
7733	num_regs = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_NUM_REGS);
7734	attn_type = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE);
7735	block_name = qed_dbg_get_block_name(p_hwfn, results->block_id);
7736	if (!block_name)
7737		return DBG_STATUS_INVALID_ARGS;
7738
7739	if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr ||
7740	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr ||
7741	    !p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr)
7742		return DBG_STATUS_DBG_ARRAY_NOT_SET;
7743
7744	block_attn_name_offsets =
7745	    (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr +
7746	    results->names_offset;
7747
7748	attn_name_base = p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr;
7749
7750	/* Go over registers with a non-zero attention status */
7751	for (i = 0; i < num_regs; i++) {
7752		struct dbg_attn_bit_mapping *bit_mapping;
7753		struct dbg_attn_reg_result *reg_result;
7754		u8 num_reg_attn, bit_idx = 0;
7755
7756		reg_result = &results->reg_results[i];
7757		num_reg_attn = GET_FIELD(reg_result->data,
7758					 DBG_ATTN_REG_RESULT_NUM_REG_ATTN);
7759		bit_mapping = (struct dbg_attn_bit_mapping *)
7760		    p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr +
7761		    reg_result->block_attn_offset;
7762
7763		/* Go over attention status bits */
7764		for (j = 0; j < num_reg_attn; j++) {
7765			u16 attn_idx_val = GET_FIELD(bit_mapping[j].data,
7766						     DBG_ATTN_BIT_MAPPING_VAL);
7767			const char *attn_name, *attn_type_str, *masked_str;
7768			u32 attn_name_offset;
7769			u32 sts_addr;
7770
7771			/* Check if bit mask should be advanced (due to unused
7772			 * bits).
7773			 */
7774			if (GET_FIELD(bit_mapping[j].data,
7775				      DBG_ATTN_BIT_MAPPING_IS_UNUSED_BIT_CNT)) {
7776				bit_idx += (u8)attn_idx_val;
7777				continue;
7778			}
7779
7780			/* Check current bit index */
7781			if (reg_result->sts_val & BIT(bit_idx)) {
7782				/* An attention bit with value=1 was found
7783				 * Find attention name
7784				 */
7785				attn_name_offset =
7786					block_attn_name_offsets[attn_idx_val];
7787				attn_name = attn_name_base + attn_name_offset;
7788				attn_type_str =
7789					(attn_type ==
7790					 ATTN_TYPE_INTERRUPT ? "Interrupt" :
7791					 "Parity");
7792				masked_str = reg_result->mask_val &
7793					     BIT(bit_idx) ?
7794					     " [masked]" : "";
7795				sts_addr =
7796				GET_FIELD(reg_result->data,
7797					  DBG_ATTN_REG_RESULT_STS_ADDRESS);
7798				DP_NOTICE(p_hwfn,
7799					  "%s (%s) : %s [address 0x%08x, bit %d]%s\n",
7800					  block_name, attn_type_str, attn_name,
7801					  sts_addr * 4, bit_idx, masked_str);
7802			}
7803
7804			bit_idx++;
7805		}
7806	}
7807
7808	return DBG_STATUS_OK;
7809}
7810
7811/* Wrapper for unifying the idle_chk and mcp_trace api */
7812static enum dbg_status
7813qed_print_idle_chk_results_wrapper(struct qed_hwfn *p_hwfn,
7814				   u32 *dump_buf,
7815				   u32 num_dumped_dwords,
7816				   char *results_buf)
7817{
7818	u32 num_errors, num_warnnings;
7819
7820	return qed_print_idle_chk_results(p_hwfn, dump_buf, num_dumped_dwords,
7821					  results_buf, &num_errors,
7822					  &num_warnnings);
7823}
7824
7825static DEFINE_MUTEX(qed_dbg_lock);
7826
7827#define MAX_PHY_RESULT_BUFFER 9000
7828
7829/******************************** Feature Meta data section ******************/
7830
7831#define GRC_NUM_STR_FUNCS 2
7832#define IDLE_CHK_NUM_STR_FUNCS 1
7833#define MCP_TRACE_NUM_STR_FUNCS 1
7834#define REG_FIFO_NUM_STR_FUNCS 1
7835#define IGU_FIFO_NUM_STR_FUNCS 1
7836#define PROTECTION_OVERRIDE_NUM_STR_FUNCS 1
7837#define FW_ASSERTS_NUM_STR_FUNCS 1
7838#define ILT_NUM_STR_FUNCS 1
7839#define PHY_NUM_STR_FUNCS 20
7840
7841/* Feature meta data lookup table */
7842static struct {
7843	char *name;
7844	u32 num_funcs;
7845	enum dbg_status (*get_size)(struct qed_hwfn *p_hwfn,
7846				    struct qed_ptt *p_ptt, u32 *size);
7847	enum dbg_status (*perform_dump)(struct qed_hwfn *p_hwfn,
7848					struct qed_ptt *p_ptt, u32 *dump_buf,
7849					u32 buf_size, u32 *dumped_dwords);
7850	enum dbg_status (*print_results)(struct qed_hwfn *p_hwfn,
7851					 u32 *dump_buf, u32 num_dumped_dwords,
7852					 char *results_buf);
7853	enum dbg_status (*results_buf_size)(struct qed_hwfn *p_hwfn,
7854					    u32 *dump_buf,
7855					    u32 num_dumped_dwords,
7856					    u32 *results_buf_size);
7857	const struct qed_func_lookup *hsi_func_lookup;
7858} qed_features_lookup[] = {
7859	{
7860	"grc", GRC_NUM_STR_FUNCS, qed_dbg_grc_get_dump_buf_size,
7861		    qed_dbg_grc_dump, NULL, NULL, NULL}, {
7862	"idle_chk", IDLE_CHK_NUM_STR_FUNCS,
7863		    qed_dbg_idle_chk_get_dump_buf_size,
7864		    qed_dbg_idle_chk_dump,
7865		    qed_print_idle_chk_results_wrapper,
7866		    qed_get_idle_chk_results_buf_size,
7867		    NULL}, {
7868	"mcp_trace", MCP_TRACE_NUM_STR_FUNCS,
7869		    qed_dbg_mcp_trace_get_dump_buf_size,
7870		    qed_dbg_mcp_trace_dump, qed_print_mcp_trace_results,
7871		    qed_get_mcp_trace_results_buf_size,
7872		    NULL}, {
7873	"reg_fifo", REG_FIFO_NUM_STR_FUNCS,
7874		    qed_dbg_reg_fifo_get_dump_buf_size,
7875		    qed_dbg_reg_fifo_dump, qed_print_reg_fifo_results,
7876		    qed_get_reg_fifo_results_buf_size,
7877		    NULL}, {
7878	"igu_fifo", IGU_FIFO_NUM_STR_FUNCS,
7879		    qed_dbg_igu_fifo_get_dump_buf_size,
7880		    qed_dbg_igu_fifo_dump, qed_print_igu_fifo_results,
7881		    qed_get_igu_fifo_results_buf_size,
7882		    NULL}, {
7883	"protection_override", PROTECTION_OVERRIDE_NUM_STR_FUNCS,
7884		    qed_dbg_protection_override_get_dump_buf_size,
7885		    qed_dbg_protection_override_dump,
7886		    qed_print_protection_override_results,
7887		    qed_get_protection_override_results_buf_size,
7888		    NULL}, {
7889	"fw_asserts", FW_ASSERTS_NUM_STR_FUNCS,
7890		    qed_dbg_fw_asserts_get_dump_buf_size,
7891		    qed_dbg_fw_asserts_dump,
7892		    qed_print_fw_asserts_results,
7893		    qed_get_fw_asserts_results_buf_size,
7894		    NULL}, {
7895	"ilt", ILT_NUM_STR_FUNCS, qed_dbg_ilt_get_dump_buf_size,
7896		    qed_dbg_ilt_dump, NULL, NULL, NULL},};
7897
7898static void qed_dbg_print_feature(u8 *p_text_buf, u32 text_size)
7899{
7900	u32 i, precision = 80;
7901
7902	if (!p_text_buf)
7903		return;
7904
7905	pr_notice("\n%.*s", precision, p_text_buf);
7906	for (i = precision; i < text_size; i += precision)
7907		pr_cont("%.*s", precision, p_text_buf + i);
7908	pr_cont("\n");
7909}
7910
7911#define QED_RESULTS_BUF_MIN_SIZE 16
7912/* Generic function for decoding debug feature info */
7913static enum dbg_status format_feature(struct qed_hwfn *p_hwfn,
7914				      enum qed_dbg_features feature_idx)
7915{
7916	struct qed_dbg_feature *feature =
7917	    &p_hwfn->cdev->dbg_features[feature_idx];
7918	u32 txt_size_bytes, null_char_pos, i;
7919	u32 *dbuf, dwords;
7920	enum dbg_status rc;
7921	char *text_buf;
7922
7923	/* Check if feature supports formatting capability */
7924	if (!qed_features_lookup[feature_idx].results_buf_size)
7925		return DBG_STATUS_OK;
7926
7927	dbuf = (u32 *)feature->dump_buf;
7928	dwords = feature->dumped_dwords;
7929
7930	/* Obtain size of formatted output */
7931	rc = qed_features_lookup[feature_idx].results_buf_size(p_hwfn,
7932							       dbuf,
7933							       dwords,
7934							       &txt_size_bytes);
7935	if (rc != DBG_STATUS_OK)
7936		return rc;
7937
7938	/* Make sure that the allocated size is a multiple of dword
7939	 * (4 bytes).
7940	 */
7941	null_char_pos = txt_size_bytes - 1;
7942	txt_size_bytes = (txt_size_bytes + 3) & ~0x3;
7943
7944	if (txt_size_bytes < QED_RESULTS_BUF_MIN_SIZE) {
7945		DP_NOTICE(p_hwfn->cdev,
7946			  "formatted size of feature was too small %d. Aborting\n",
7947			  txt_size_bytes);
7948		return DBG_STATUS_INVALID_ARGS;
7949	}
7950
7951	/* allocate temp text buf */
7952	text_buf = vzalloc(txt_size_bytes);
7953	if (!text_buf) {
7954		DP_NOTICE(p_hwfn->cdev,
7955			  "failed to allocate text buffer. Aborting\n");
7956		return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
7957	}
7958
7959	/* Decode feature opcodes to string on temp buf */
7960	rc = qed_features_lookup[feature_idx].print_results(p_hwfn,
7961							    dbuf,
7962							    dwords,
7963							    text_buf);
7964	if (rc != DBG_STATUS_OK) {
7965		vfree(text_buf);
7966		return rc;
7967	}
7968
7969	/* Replace the original null character with a '\n' character.
7970	 * The bytes that were added as a result of the dword alignment are also
7971	 * padded with '\n' characters.
7972	 */
7973	for (i = null_char_pos; i < txt_size_bytes; i++)
7974		text_buf[i] = '\n';
7975
7976	/* Dump printable feature to log */
7977	if (p_hwfn->cdev->print_dbg_data)
7978		qed_dbg_print_feature(text_buf, txt_size_bytes);
7979
7980	/* Dump binary data as is to the output file */
7981	if (p_hwfn->cdev->dbg_bin_dump) {
7982		vfree(text_buf);
7983		return rc;
7984	}
7985
7986	/* Free the old dump_buf and point the dump_buf to the newly allocated
7987	 * and formatted text buffer.
7988	 */
7989	vfree(feature->dump_buf);
7990	feature->dump_buf = text_buf;
7991	feature->buf_size = txt_size_bytes;
7992	feature->dumped_dwords = txt_size_bytes / 4;
7993
7994	return rc;
7995}
7996
7997#define MAX_DBG_FEATURE_SIZE_DWORDS	0x3FFFFFFF
7998
7999/* Generic function for performing the dump of a debug feature. */
8000static enum dbg_status qed_dbg_dump(struct qed_hwfn *p_hwfn,
8001				    struct qed_ptt *p_ptt,
8002				    enum qed_dbg_features feature_idx)
8003{
8004	struct qed_dbg_feature *feature =
8005	    &p_hwfn->cdev->dbg_features[feature_idx];
8006	u32 buf_size_dwords, *dbuf, *dwords;
8007	enum dbg_status rc;
8008
8009	DP_NOTICE(p_hwfn->cdev, "Collecting a debug feature [\"%s\"]\n",
8010		  qed_features_lookup[feature_idx].name);
8011
8012	/* Dump_buf was already allocated need to free (this can happen if dump
8013	 * was called but file was never read).
8014	 * We can't use the buffer as is since size may have changed.
8015	 */
8016	if (feature->dump_buf) {
8017		vfree(feature->dump_buf);
8018		feature->dump_buf = NULL;
8019	}
8020
8021	/* Get buffer size from hsi, allocate accordingly, and perform the
8022	 * dump.
8023	 */
8024	rc = qed_features_lookup[feature_idx].get_size(p_hwfn, p_ptt,
8025						       &buf_size_dwords);
8026	if (rc != DBG_STATUS_OK && rc != DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
8027		return rc;
8028
8029	if (buf_size_dwords > MAX_DBG_FEATURE_SIZE_DWORDS) {
8030		feature->buf_size = 0;
8031		DP_NOTICE(p_hwfn->cdev,
8032			  "Debug feature [\"%s\"] size (0x%x dwords) exceeds maximum size (0x%x dwords)\n",
8033			  qed_features_lookup[feature_idx].name,
8034			  buf_size_dwords, MAX_DBG_FEATURE_SIZE_DWORDS);
8035
8036		return DBG_STATUS_OK;
8037	}
8038
8039	feature->buf_size = buf_size_dwords * sizeof(u32);
8040	feature->dump_buf = vmalloc(feature->buf_size);
8041	if (!feature->dump_buf)
8042		return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
8043
8044	dbuf = (u32 *)feature->dump_buf;
8045	dwords = &feature->dumped_dwords;
8046	rc = qed_features_lookup[feature_idx].perform_dump(p_hwfn, p_ptt,
8047							   dbuf,
8048							   feature->buf_size /
8049							   sizeof(u32),
8050							   dwords);
8051
8052	/* If mcp is stuck we get DBG_STATUS_NVRAM_GET_IMAGE_FAILED error.
8053	 * In this case the buffer holds valid binary data, but we won't able
8054	 * to parse it (since parsing relies on data in NVRAM which is only
8055	 * accessible when MFW is responsive). skip the formatting but return
8056	 * success so that binary data is provided.
8057	 */
8058	if (rc == DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
8059		return DBG_STATUS_OK;
8060
8061	if (rc != DBG_STATUS_OK)
8062		return rc;
8063
8064	/* Format output */
8065	rc = format_feature(p_hwfn, feature_idx);
8066	return rc;
8067}
8068
8069int qed_dbg_grc(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
8070{
8071	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_GRC, num_dumped_bytes);
8072}
8073
8074int qed_dbg_grc_size(struct qed_dev *cdev)
8075{
8076	return qed_dbg_feature_size(cdev, DBG_FEATURE_GRC);
8077}
8078
8079int qed_dbg_idle_chk(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
8080{
8081	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IDLE_CHK,
8082			       num_dumped_bytes);
8083}
8084
8085int qed_dbg_idle_chk_size(struct qed_dev *cdev)
8086{
8087	return qed_dbg_feature_size(cdev, DBG_FEATURE_IDLE_CHK);
8088}
8089
8090int qed_dbg_reg_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
8091{
8092	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_REG_FIFO,
8093			       num_dumped_bytes);
8094}
8095
8096int qed_dbg_reg_fifo_size(struct qed_dev *cdev)
8097{
8098	return qed_dbg_feature_size(cdev, DBG_FEATURE_REG_FIFO);
8099}
8100
8101int qed_dbg_igu_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
8102{
8103	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IGU_FIFO,
8104			       num_dumped_bytes);
8105}
8106
8107int qed_dbg_igu_fifo_size(struct qed_dev *cdev)
8108{
8109	return qed_dbg_feature_size(cdev, DBG_FEATURE_IGU_FIFO);
8110}
8111
8112static int qed_dbg_nvm_image_length(struct qed_hwfn *p_hwfn,
8113				    enum qed_nvm_images image_id, u32 *length)
8114{
8115	struct qed_nvm_image_att image_att;
8116	int rc;
8117
8118	*length = 0;
8119	rc = qed_mcp_get_nvm_image_att(p_hwfn, image_id, &image_att);
8120	if (rc)
8121		return rc;
8122
8123	*length = image_att.length;
8124
8125	return rc;
8126}
8127
8128static int qed_dbg_nvm_image(struct qed_dev *cdev, void *buffer,
8129			     u32 *num_dumped_bytes,
8130			     enum qed_nvm_images image_id)
8131{
8132	struct qed_hwfn *p_hwfn =
8133		&cdev->hwfns[cdev->engine_for_debug];
8134	u32 len_rounded;
8135	int rc;
8136
8137	*num_dumped_bytes = 0;
8138	rc = qed_dbg_nvm_image_length(p_hwfn, image_id, &len_rounded);
8139	if (rc)
8140		return rc;
8141
8142	DP_NOTICE(p_hwfn->cdev,
8143		  "Collecting a debug feature [\"nvram image %d\"]\n",
8144		  image_id);
8145
8146	len_rounded = roundup(len_rounded, sizeof(u32));
8147	rc = qed_mcp_get_nvm_image(p_hwfn, image_id, buffer, len_rounded);
8148	if (rc)
8149		return rc;
8150
8151	/* QED_NVM_IMAGE_NVM_META image is not swapped like other images */
8152	if (image_id != QED_NVM_IMAGE_NVM_META)
8153		cpu_to_be32_array((__force __be32 *)buffer,
8154				  (const u32 *)buffer,
8155				  len_rounded / sizeof(u32));
8156
8157	*num_dumped_bytes = len_rounded;
8158
8159	return rc;
8160}
8161
8162int qed_dbg_protection_override(struct qed_dev *cdev, void *buffer,
8163				u32 *num_dumped_bytes)
8164{
8165	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_PROTECTION_OVERRIDE,
8166			       num_dumped_bytes);
8167}
8168
8169int qed_dbg_protection_override_size(struct qed_dev *cdev)
8170{
8171	return qed_dbg_feature_size(cdev, DBG_FEATURE_PROTECTION_OVERRIDE);
8172}
8173
8174int qed_dbg_fw_asserts(struct qed_dev *cdev, void *buffer,
8175		       u32 *num_dumped_bytes)
8176{
8177	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_FW_ASSERTS,
8178			       num_dumped_bytes);
8179}
8180
8181int qed_dbg_fw_asserts_size(struct qed_dev *cdev)
8182{
8183	return qed_dbg_feature_size(cdev, DBG_FEATURE_FW_ASSERTS);
8184}
8185
8186int qed_dbg_ilt(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
8187{
8188	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_ILT, num_dumped_bytes);
8189}
8190
8191int qed_dbg_ilt_size(struct qed_dev *cdev)
8192{
8193	return qed_dbg_feature_size(cdev, DBG_FEATURE_ILT);
8194}
8195
8196int qed_dbg_mcp_trace(struct qed_dev *cdev, void *buffer,
8197		      u32 *num_dumped_bytes)
8198{
8199	return qed_dbg_feature(cdev, buffer, DBG_FEATURE_MCP_TRACE,
8200			       num_dumped_bytes);
8201}
8202
8203int qed_dbg_mcp_trace_size(struct qed_dev *cdev)
8204{
8205	return qed_dbg_feature_size(cdev, DBG_FEATURE_MCP_TRACE);
8206}
8207
8208/* Defines the amount of bytes allocated for recording the length of debugfs
8209 * feature buffer.
8210 */
8211#define REGDUMP_HEADER_SIZE			sizeof(u32)
8212#define REGDUMP_HEADER_SIZE_SHIFT		0
8213#define REGDUMP_HEADER_SIZE_MASK		0xffffff
8214#define REGDUMP_HEADER_FEATURE_SHIFT		24
8215#define REGDUMP_HEADER_FEATURE_MASK		0x1f
8216#define REGDUMP_HEADER_BIN_DUMP_SHIFT		29
8217#define REGDUMP_HEADER_BIN_DUMP_MASK		0x1
8218#define REGDUMP_HEADER_OMIT_ENGINE_SHIFT	30
8219#define REGDUMP_HEADER_OMIT_ENGINE_MASK		0x1
8220#define REGDUMP_HEADER_ENGINE_SHIFT		31
8221#define REGDUMP_HEADER_ENGINE_MASK		0x1
8222#define REGDUMP_MAX_SIZE			0x1000000
8223#define ILT_DUMP_MAX_SIZE			(1024 * 1024 * 15)
8224
8225enum debug_print_features {
8226	OLD_MODE = 0,
8227	IDLE_CHK = 1,
8228	GRC_DUMP = 2,
8229	MCP_TRACE = 3,
8230	REG_FIFO = 4,
8231	PROTECTION_OVERRIDE = 5,
8232	IGU_FIFO = 6,
8233	PHY = 7,
8234	FW_ASSERTS = 8,
8235	NVM_CFG1 = 9,
8236	DEFAULT_CFG = 10,
8237	NVM_META = 11,
8238	MDUMP = 12,
8239	ILT_DUMP = 13,
8240};
8241
8242static u32 qed_calc_regdump_header(struct qed_dev *cdev,
8243				   enum debug_print_features feature,
8244				   int engine, u32 feature_size,
8245				   u8 omit_engine, u8 dbg_bin_dump)
8246{
8247	u32 res = 0;
8248
8249	SET_FIELD(res, REGDUMP_HEADER_SIZE, feature_size);
8250	if (res != feature_size)
8251		DP_NOTICE(cdev,
8252			  "Feature %d is too large (size 0x%x) and will corrupt the dump\n",
8253			  feature, feature_size);
8254
8255	SET_FIELD(res, REGDUMP_HEADER_FEATURE, feature);
8256	SET_FIELD(res, REGDUMP_HEADER_BIN_DUMP, dbg_bin_dump);
8257	SET_FIELD(res, REGDUMP_HEADER_OMIT_ENGINE, omit_engine);
8258	SET_FIELD(res, REGDUMP_HEADER_ENGINE, engine);
8259
8260	return res;
8261}
8262
8263int qed_dbg_all_data(struct qed_dev *cdev, void *buffer)
8264{
8265	u8 cur_engine, omit_engine = 0, org_engine;
8266	struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug];
8267	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
8268	int grc_params[MAX_DBG_GRC_PARAMS], rc, i;
8269	u32 offset = 0, feature_size;
8270
8271	for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
8272		grc_params[i] = dev_data->grc.param_val[i];
8273
8274	if (!QED_IS_CMT(cdev))
8275		omit_engine = 1;
8276
8277	cdev->dbg_bin_dump = 1;
8278	mutex_lock(&qed_dbg_lock);
8279
8280	org_engine = qed_get_debug_engine(cdev);
8281	for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
8282		/* Collect idle_chks and grcDump for each hw function */
8283		DP_VERBOSE(cdev, QED_MSG_DEBUG,
8284			   "obtaining idle_chk and grcdump for current engine\n");
8285		qed_set_debug_engine(cdev, cur_engine);
8286
8287		/* First idle_chk */
8288		rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset +
8289				      REGDUMP_HEADER_SIZE, &feature_size);
8290		if (!rc) {
8291			*(u32 *)((u8 *)buffer + offset) =
8292			    qed_calc_regdump_header(cdev, IDLE_CHK,
8293						    cur_engine,
8294						    feature_size,
8295						    omit_engine,
8296						    cdev->dbg_bin_dump);
8297			offset += (feature_size + REGDUMP_HEADER_SIZE);
8298		} else {
8299			DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
8300		}
8301
8302		/* Second idle_chk */
8303		rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset +
8304				      REGDUMP_HEADER_SIZE, &feature_size);
8305		if (!rc) {
8306			*(u32 *)((u8 *)buffer + offset) =
8307			    qed_calc_regdump_header(cdev, IDLE_CHK,
8308						    cur_engine,
8309						    feature_size,
8310						    omit_engine,
8311						    cdev->dbg_bin_dump);
8312			offset += (feature_size + REGDUMP_HEADER_SIZE);
8313		} else {
8314			DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
8315		}
8316
8317		/* reg_fifo dump */
8318		rc = qed_dbg_reg_fifo(cdev, (u8 *)buffer + offset +
8319				      REGDUMP_HEADER_SIZE, &feature_size);
8320		if (!rc) {
8321			*(u32 *)((u8 *)buffer + offset) =
8322			    qed_calc_regdump_header(cdev, REG_FIFO,
8323						    cur_engine,
8324						    feature_size,
8325						    omit_engine,
8326						    cdev->dbg_bin_dump);
8327			offset += (feature_size + REGDUMP_HEADER_SIZE);
8328		} else {
8329			DP_ERR(cdev, "qed_dbg_reg_fifo failed. rc = %d\n", rc);
8330		}
8331
8332		/* igu_fifo dump */
8333		rc = qed_dbg_igu_fifo(cdev, (u8 *)buffer + offset +
8334				      REGDUMP_HEADER_SIZE, &feature_size);
8335		if (!rc) {
8336			*(u32 *)((u8 *)buffer + offset) =
8337			    qed_calc_regdump_header(cdev, IGU_FIFO,
8338						    cur_engine,
8339						    feature_size,
8340						    omit_engine,
8341						    cdev->dbg_bin_dump);
8342			offset += (feature_size + REGDUMP_HEADER_SIZE);
8343		} else {
8344			DP_ERR(cdev, "qed_dbg_igu_fifo failed. rc = %d", rc);
8345		}
8346
8347		/* protection_override dump */
8348		rc = qed_dbg_protection_override(cdev, (u8 *)buffer + offset +
8349						 REGDUMP_HEADER_SIZE,
8350						 &feature_size);
8351		if (!rc) {
8352			*(u32 *)((u8 *)buffer + offset) =
8353			    qed_calc_regdump_header(cdev,
8354						    PROTECTION_OVERRIDE,
8355						    cur_engine,
8356						    feature_size,
8357						    omit_engine,
8358						    cdev->dbg_bin_dump);
8359			offset += (feature_size + REGDUMP_HEADER_SIZE);
8360		} else {
8361			DP_ERR(cdev,
8362			       "qed_dbg_protection_override failed. rc = %d\n",
8363			       rc);
8364		}
8365
8366		/* fw_asserts dump */
8367		rc = qed_dbg_fw_asserts(cdev, (u8 *)buffer + offset +
8368					REGDUMP_HEADER_SIZE, &feature_size);
8369		if (!rc) {
8370			*(u32 *)((u8 *)buffer + offset) =
8371			    qed_calc_regdump_header(cdev, FW_ASSERTS,
8372						    cur_engine,
8373						    feature_size,
8374						    omit_engine,
8375						    cdev->dbg_bin_dump);
8376			offset += (feature_size + REGDUMP_HEADER_SIZE);
8377		} else {
8378			DP_ERR(cdev, "qed_dbg_fw_asserts failed. rc = %d\n",
8379			       rc);
8380		}
8381
8382		feature_size = qed_dbg_ilt_size(cdev);
8383		if (!cdev->disable_ilt_dump && feature_size <
8384		    ILT_DUMP_MAX_SIZE) {
8385			rc = qed_dbg_ilt(cdev, (u8 *)buffer + offset +
8386					 REGDUMP_HEADER_SIZE, &feature_size);
8387			if (!rc) {
8388				*(u32 *)((u8 *)buffer + offset) =
8389				    qed_calc_regdump_header(cdev, ILT_DUMP,
8390							    cur_engine,
8391							    feature_size,
8392							    omit_engine,
8393							    cdev->dbg_bin_dump);
8394				offset += (feature_size + REGDUMP_HEADER_SIZE);
8395			} else {
8396				DP_ERR(cdev, "qed_dbg_ilt failed. rc = %d\n",
8397				       rc);
8398			}
8399		}
8400
8401		/* Grc dump - must be last because when mcp stuck it will
8402		 * clutter idle_chk, reg_fifo, ...
8403		 */
8404		for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
8405			dev_data->grc.param_val[i] = grc_params[i];
8406
8407		rc = qed_dbg_grc(cdev, (u8 *)buffer + offset +
8408				 REGDUMP_HEADER_SIZE, &feature_size);
8409		if (!rc) {
8410			*(u32 *)((u8 *)buffer + offset) =
8411			    qed_calc_regdump_header(cdev, GRC_DUMP,
8412						    cur_engine,
8413						    feature_size,
8414						    omit_engine,
8415						    cdev->dbg_bin_dump);
8416			offset += (feature_size + REGDUMP_HEADER_SIZE);
8417		} else {
8418			DP_ERR(cdev, "qed_dbg_grc failed. rc = %d", rc);
8419		}
8420	}
8421
8422	qed_set_debug_engine(cdev, org_engine);
8423
8424	/* mcp_trace */
8425	rc = qed_dbg_mcp_trace(cdev, (u8 *)buffer + offset +
8426			       REGDUMP_HEADER_SIZE, &feature_size);
8427	if (!rc) {
8428		*(u32 *)((u8 *)buffer + offset) =
8429		    qed_calc_regdump_header(cdev, MCP_TRACE, cur_engine,
8430					    feature_size, omit_engine,
8431					    cdev->dbg_bin_dump);
8432		offset += (feature_size + REGDUMP_HEADER_SIZE);
8433	} else {
8434		DP_ERR(cdev, "qed_dbg_mcp_trace failed. rc = %d\n", rc);
8435	}
8436
8437	/* nvm cfg1 */
8438	rc = qed_dbg_nvm_image(cdev,
8439			       (u8 *)buffer + offset +
8440			       REGDUMP_HEADER_SIZE, &feature_size,
8441			       QED_NVM_IMAGE_NVM_CFG1);
8442	if (!rc) {
8443		*(u32 *)((u8 *)buffer + offset) =
8444		    qed_calc_regdump_header(cdev, NVM_CFG1, cur_engine,
8445					    feature_size, omit_engine,
8446					    cdev->dbg_bin_dump);
8447		offset += (feature_size + REGDUMP_HEADER_SIZE);
8448	} else if (rc != -ENOENT) {
8449		DP_ERR(cdev,
8450		       "qed_dbg_nvm_image failed for image  %d (%s), rc = %d\n",
8451		       QED_NVM_IMAGE_NVM_CFG1, "QED_NVM_IMAGE_NVM_CFG1",
8452		       rc);
8453	}
8454
8455		/* nvm default */
8456	rc = qed_dbg_nvm_image(cdev,
8457			       (u8 *)buffer + offset +
8458			       REGDUMP_HEADER_SIZE, &feature_size,
8459			       QED_NVM_IMAGE_DEFAULT_CFG);
8460	if (!rc) {
8461		*(u32 *)((u8 *)buffer + offset) =
8462		    qed_calc_regdump_header(cdev, DEFAULT_CFG,
8463					    cur_engine, feature_size,
8464					    omit_engine,
8465					    cdev->dbg_bin_dump);
8466		offset += (feature_size + REGDUMP_HEADER_SIZE);
8467	} else if (rc != -ENOENT) {
8468		DP_ERR(cdev,
8469		       "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
8470		       QED_NVM_IMAGE_DEFAULT_CFG,
8471		       "QED_NVM_IMAGE_DEFAULT_CFG", rc);
8472	}
8473
8474	/* nvm meta */
8475	rc = qed_dbg_nvm_image(cdev,
8476			       (u8 *)buffer + offset +
8477			       REGDUMP_HEADER_SIZE, &feature_size,
8478			       QED_NVM_IMAGE_NVM_META);
8479	if (!rc) {
8480		*(u32 *)((u8 *)buffer + offset) =
8481		    qed_calc_regdump_header(cdev, NVM_META, cur_engine,
8482					    feature_size, omit_engine,
8483					    cdev->dbg_bin_dump);
8484		offset += (feature_size + REGDUMP_HEADER_SIZE);
8485	} else if (rc != -ENOENT) {
8486		DP_ERR(cdev,
8487		       "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
8488		       QED_NVM_IMAGE_NVM_META, "QED_NVM_IMAGE_NVM_META",
8489		       rc);
8490	}
8491
8492	/* nvm mdump */
8493	rc = qed_dbg_nvm_image(cdev, (u8 *)buffer + offset +
8494			       REGDUMP_HEADER_SIZE, &feature_size,
8495			       QED_NVM_IMAGE_MDUMP);
8496	if (!rc) {
8497		*(u32 *)((u8 *)buffer + offset) =
8498		    qed_calc_regdump_header(cdev, MDUMP, cur_engine,
8499					    feature_size, omit_engine,
8500					    cdev->dbg_bin_dump);
8501		offset += (feature_size + REGDUMP_HEADER_SIZE);
8502	} else if (rc != -ENOENT) {
8503		DP_ERR(cdev,
8504		       "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
8505		       QED_NVM_IMAGE_MDUMP, "QED_NVM_IMAGE_MDUMP", rc);
8506	}
8507
8508	mutex_unlock(&qed_dbg_lock);
8509	cdev->dbg_bin_dump = 0;
8510
8511	return 0;
8512}
8513
8514int qed_dbg_all_data_size(struct qed_dev *cdev)
8515{
8516	u32 regs_len = 0, image_len = 0, ilt_len = 0, total_ilt_len = 0;
8517	struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug];
8518	u8 cur_engine, org_engine;
8519
8520	cdev->disable_ilt_dump = false;
8521	org_engine = qed_get_debug_engine(cdev);
8522	for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
8523		/* Engine specific */
8524		DP_VERBOSE(cdev, QED_MSG_DEBUG,
8525			   "calculating idle_chk and grcdump register length for current engine\n");
8526		qed_set_debug_engine(cdev, cur_engine);
8527		regs_len += REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
8528		    REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
8529		    REGDUMP_HEADER_SIZE + qed_dbg_grc_size(cdev) +
8530		    REGDUMP_HEADER_SIZE + qed_dbg_reg_fifo_size(cdev) +
8531		    REGDUMP_HEADER_SIZE + qed_dbg_igu_fifo_size(cdev) +
8532		    REGDUMP_HEADER_SIZE +
8533		    qed_dbg_protection_override_size(cdev) +
8534		    REGDUMP_HEADER_SIZE + qed_dbg_fw_asserts_size(cdev);
8535		ilt_len = REGDUMP_HEADER_SIZE + qed_dbg_ilt_size(cdev);
8536		if (ilt_len < ILT_DUMP_MAX_SIZE) {
8537			total_ilt_len += ilt_len;
8538			regs_len += ilt_len;
8539		}
8540	}
8541
8542	qed_set_debug_engine(cdev, org_engine);
8543
8544	/* Engine common */
8545	regs_len += REGDUMP_HEADER_SIZE + qed_dbg_mcp_trace_size(cdev) +
8546	    REGDUMP_HEADER_SIZE + qed_dbg_phy_size(cdev);
8547	qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_CFG1, &image_len);
8548	if (image_len)
8549		regs_len += REGDUMP_HEADER_SIZE + image_len;
8550	qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_DEFAULT_CFG, &image_len);
8551	if (image_len)
8552		regs_len += REGDUMP_HEADER_SIZE + image_len;
8553	qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_META, &image_len);
8554	if (image_len)
8555		regs_len += REGDUMP_HEADER_SIZE + image_len;
8556	qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_MDUMP, &image_len);
8557	if (image_len)
8558		regs_len += REGDUMP_HEADER_SIZE + image_len;
8559
8560	if (regs_len > REGDUMP_MAX_SIZE) {
8561		DP_VERBOSE(cdev, QED_MSG_DEBUG,
8562			   "Dump exceeds max size 0x%x, disable ILT dump\n",
8563			   REGDUMP_MAX_SIZE);
8564		cdev->disable_ilt_dump = true;
8565		regs_len -= total_ilt_len;
8566	}
8567
8568	return regs_len;
8569}
8570
8571int qed_dbg_feature(struct qed_dev *cdev, void *buffer,
8572		    enum qed_dbg_features feature, u32 *num_dumped_bytes)
8573{
8574	struct qed_dbg_feature *qed_feature = &cdev->dbg_features[feature];
8575	struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug];
8576	enum dbg_status dbg_rc;
8577	struct qed_ptt *p_ptt;
8578	int rc = 0;
8579
8580	/* Acquire ptt */
8581	p_ptt = qed_ptt_acquire(p_hwfn);
8582	if (!p_ptt)
8583		return -EINVAL;
8584
8585	/* Get dump */
8586	dbg_rc = qed_dbg_dump(p_hwfn, p_ptt, feature);
8587	if (dbg_rc != DBG_STATUS_OK) {
8588		DP_VERBOSE(cdev, QED_MSG_DEBUG, "%s\n",
8589			   qed_dbg_get_status_str(dbg_rc));
8590		*num_dumped_bytes = 0;
8591		rc = -EINVAL;
8592		goto out;
8593	}
8594
8595	DP_VERBOSE(cdev, QED_MSG_DEBUG,
8596		   "copying debugfs feature to external buffer\n");
8597	memcpy(buffer, qed_feature->dump_buf, qed_feature->buf_size);
8598	*num_dumped_bytes = cdev->dbg_features[feature].dumped_dwords *
8599			    4;
8600
8601out:
8602	qed_ptt_release(p_hwfn, p_ptt);
8603	return rc;
8604}
8605
8606int qed_dbg_feature_size(struct qed_dev *cdev, enum qed_dbg_features feature)
8607{
8608	struct qed_dbg_feature *qed_feature = &cdev->dbg_features[feature];
8609	struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug];
8610	struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
8611	u32 buf_size_dwords;
8612	enum dbg_status rc;
8613
8614	if (!p_ptt)
8615		return -EINVAL;
8616
8617	rc = qed_features_lookup[feature].get_size(p_hwfn, p_ptt,
8618						   &buf_size_dwords);
8619	if (rc != DBG_STATUS_OK)
8620		buf_size_dwords = 0;
8621
8622	/* Feature will not be dumped if it exceeds maximum size */
8623	if (buf_size_dwords > MAX_DBG_FEATURE_SIZE_DWORDS)
8624		buf_size_dwords = 0;
8625
8626	qed_ptt_release(p_hwfn, p_ptt);
8627	qed_feature->buf_size = buf_size_dwords * sizeof(u32);
8628	return qed_feature->buf_size;
8629}
8630
8631int qed_dbg_phy_size(struct qed_dev *cdev)
8632{
8633	/* return max size of phy info and
8634	 * phy mac_stat multiplied by the number of ports
8635	 */
8636	return MAX_PHY_RESULT_BUFFER * (1 + qed_device_num_ports(cdev));
8637}
8638
8639u8 qed_get_debug_engine(struct qed_dev *cdev)
8640{
8641	return cdev->engine_for_debug;
8642}
8643
8644void qed_set_debug_engine(struct qed_dev *cdev, int engine_number)
8645{
8646	DP_VERBOSE(cdev, QED_MSG_DEBUG, "set debug engine to %d\n",
8647		   engine_number);
8648	cdev->engine_for_debug = engine_number;
8649}
8650
8651void qed_dbg_pf_init(struct qed_dev *cdev)
8652{
8653	const u8 *dbg_values = NULL;
8654	int i;
8655
8656	/* Sync ver with debugbus qed code */
8657	qed_dbg_set_app_ver(TOOLS_VERSION);
8658
8659	/* Debug values are after init values.
8660	 * The offset is the first dword of the file.
8661	 */
8662	dbg_values = cdev->firmware->data + *(u32 *)cdev->firmware->data;
8663
8664	for_each_hwfn(cdev, i) {
8665		qed_dbg_set_bin_ptr(&cdev->hwfns[i], dbg_values);
8666		qed_dbg_user_set_bin_ptr(&cdev->hwfns[i], dbg_values);
8667	}
8668
8669	/* Set the hwfn to be 0 as default */
8670	cdev->engine_for_debug = 0;
8671}
8672
8673void qed_dbg_pf_exit(struct qed_dev *cdev)
8674{
8675	struct qed_dbg_feature *feature = NULL;
8676	enum qed_dbg_features feature_idx;
8677
8678	/* debug features' buffers may be allocated if debug feature was used
8679	 * but dump wasn't called
8680	 */
8681	for (feature_idx = 0; feature_idx < DBG_FEATURE_NUM; feature_idx++) {
8682		feature = &cdev->dbg_features[feature_idx];
8683		if (feature->dump_buf) {
8684			vfree(feature->dump_buf);
8685			feature->dump_buf = NULL;
8686		}
8687	}
8688}
~/ Read-only file preview.