Linux Audio

Check our new training course

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