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