Linux Audio

Check our new training course

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