blob: 483241b4b05db2add64ff928ccc9419fe733355a [file] [log] [blame]
Tomer Tayarc965db42016-09-07 16:36:24 +03001/* QLogic qed NIC Driver
2 * Copyright (c) 2015 QLogic Corporation
3 *
4 * This software is available under the terms of the GNU General Public License
5 * (GPL) Version 2, available from the file COPYING in the main directory of
6 * this source tree.
7 */
8
9#include <linux/module.h>
10#include <linux/vmalloc.h>
11#include <linux/crc32.h>
12#include "qed.h"
13#include "qed_hsi.h"
14#include "qed_hw.h"
15#include "qed_mcp.h"
16#include "qed_reg_addr.h"
17
18/* Chip IDs enum */
19enum chip_ids {
Tomer Tayarc965db42016-09-07 16:36:24 +030020 CHIP_BB_B0,
21 CHIP_K2,
22 MAX_CHIP_IDS
23};
24
25/* Memory groups enum */
26enum mem_groups {
27 MEM_GROUP_PXP_MEM,
28 MEM_GROUP_DMAE_MEM,
29 MEM_GROUP_CM_MEM,
30 MEM_GROUP_QM_MEM,
31 MEM_GROUP_TM_MEM,
32 MEM_GROUP_BRB_RAM,
33 MEM_GROUP_BRB_MEM,
34 MEM_GROUP_PRS_MEM,
35 MEM_GROUP_SDM_MEM,
36 MEM_GROUP_PBUF,
37 MEM_GROUP_IOR,
38 MEM_GROUP_RAM,
39 MEM_GROUP_BTB_RAM,
40 MEM_GROUP_RDIF_CTX,
41 MEM_GROUP_TDIF_CTX,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +020042 MEM_GROUP_CFC_MEM,
Tomer Tayarc965db42016-09-07 16:36:24 +030043 MEM_GROUP_CONN_CFC_MEM,
44 MEM_GROUP_TASK_CFC_MEM,
45 MEM_GROUP_CAU_PI,
46 MEM_GROUP_CAU_MEM,
47 MEM_GROUP_PXP_ILT,
48 MEM_GROUP_MULD_MEM,
49 MEM_GROUP_BTB_MEM,
50 MEM_GROUP_IGU_MEM,
51 MEM_GROUP_IGU_MSIX,
52 MEM_GROUP_CAU_SB,
53 MEM_GROUP_BMB_RAM,
54 MEM_GROUP_BMB_MEM,
55 MEM_GROUPS_NUM
56};
57
58/* Memory groups names */
59static const char * const s_mem_group_names[] = {
60 "PXP_MEM",
61 "DMAE_MEM",
62 "CM_MEM",
63 "QM_MEM",
64 "TM_MEM",
65 "BRB_RAM",
66 "BRB_MEM",
67 "PRS_MEM",
68 "SDM_MEM",
69 "PBUF",
70 "IOR",
71 "RAM",
72 "BTB_RAM",
73 "RDIF_CTX",
74 "TDIF_CTX",
Mintz, Yuvalbe086e72017-03-11 18:39:18 +020075 "CFC_MEM",
Tomer Tayarc965db42016-09-07 16:36:24 +030076 "CONN_CFC_MEM",
77 "TASK_CFC_MEM",
78 "CAU_PI",
79 "CAU_MEM",
80 "PXP_ILT",
81 "MULD_MEM",
82 "BTB_MEM",
83 "IGU_MEM",
84 "IGU_MSIX",
85 "CAU_SB",
86 "BMB_RAM",
87 "BMB_MEM",
88};
89
90/* Idle check conditions */
91static u32 cond4(const u32 *r, const u32 *imm)
92{
93 return ((r[0] & imm[0]) != imm[1]) && ((r[1] & imm[2]) != imm[3]);
94}
95
96static u32 cond6(const u32 *r, const u32 *imm)
97{
98 return ((r[0] >> imm[0]) & imm[1]) != imm[2];
99}
100
101static u32 cond5(const u32 *r, const u32 *imm)
102{
103 return (r[0] & imm[0]) != imm[1];
104}
105
106static u32 cond8(const u32 *r, const u32 *imm)
107{
108 return ((r[0] & imm[0]) >> imm[1]) !=
109 (((r[0] & imm[2]) >> imm[3]) | ((r[1] & imm[4]) << imm[5]));
110}
111
112static u32 cond9(const u32 *r, const u32 *imm)
113{
114 return ((r[0] & imm[0]) >> imm[1]) != (r[0] & imm[2]);
115}
116
117static u32 cond1(const u32 *r, const u32 *imm)
118{
119 return (r[0] & ~imm[0]) != imm[1];
120}
121
122static u32 cond0(const u32 *r, const u32 *imm)
123{
124 return r[0] != imm[0];
125}
126
127static u32 cond10(const u32 *r, const u32 *imm)
128{
129 return r[0] != r[1] && r[2] == imm[0];
130}
131
132static u32 cond11(const u32 *r, const u32 *imm)
133{
134 return r[0] != r[1] && r[2] > imm[0];
135}
136
137static u32 cond3(const u32 *r, const u32 *imm)
138{
139 return r[0] != r[1];
140}
141
142static u32 cond12(const u32 *r, const u32 *imm)
143{
144 return r[0] & imm[0];
145}
146
147static u32 cond7(const u32 *r, const u32 *imm)
148{
149 return r[0] < (r[1] - imm[0]);
150}
151
152static u32 cond2(const u32 *r, const u32 *imm)
153{
154 return r[0] > imm[0];
155}
156
157/* Array of Idle Check conditions */
158static u32(*cond_arr[]) (const u32 *r, const u32 *imm) = {
159 cond0,
160 cond1,
161 cond2,
162 cond3,
163 cond4,
164 cond5,
165 cond6,
166 cond7,
167 cond8,
168 cond9,
169 cond10,
170 cond11,
171 cond12,
172};
173
174/******************************* Data Types **********************************/
175
176enum platform_ids {
177 PLATFORM_ASIC,
178 PLATFORM_RESERVED,
179 PLATFORM_RESERVED2,
180 PLATFORM_RESERVED3,
181 MAX_PLATFORM_IDS
182};
183
184struct dbg_array {
185 const u32 *ptr;
186 u32 size_in_dwords;
187};
188
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200189struct chip_platform_defs {
190 u8 num_ports;
191 u8 num_pfs;
192 u8 num_vfs;
193};
194
Tomer Tayarc965db42016-09-07 16:36:24 +0300195/* Chip constant definitions */
196struct chip_defs {
197 const char *name;
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200198 struct chip_platform_defs per_platform[MAX_PLATFORM_IDS];
Tomer Tayarc965db42016-09-07 16:36:24 +0300199};
200
201/* Platform constant definitions */
202struct platform_defs {
203 const char *name;
204 u32 delay_factor;
205};
206
207/* Storm constant definitions */
208struct storm_defs {
209 char letter;
210 enum block_id block_id;
211 enum dbg_bus_clients dbg_client_id[MAX_CHIP_IDS];
212 bool has_vfc;
213 u32 sem_fast_mem_addr;
214 u32 sem_frame_mode_addr;
215 u32 sem_slow_enable_addr;
216 u32 sem_slow_mode_addr;
217 u32 sem_slow_mode1_conf_addr;
218 u32 sem_sync_dbg_empty_addr;
219 u32 sem_slow_dbg_empty_addr;
220 u32 cm_ctx_wr_addr;
221 u32 cm_conn_ag_ctx_lid_size; /* In quad-regs */
222 u32 cm_conn_ag_ctx_rd_addr;
223 u32 cm_conn_st_ctx_lid_size; /* In quad-regs */
224 u32 cm_conn_st_ctx_rd_addr;
225 u32 cm_task_ag_ctx_lid_size; /* In quad-regs */
226 u32 cm_task_ag_ctx_rd_addr;
227 u32 cm_task_st_ctx_lid_size; /* In quad-regs */
228 u32 cm_task_st_ctx_rd_addr;
229};
230
231/* Block constant definitions */
232struct block_defs {
233 const char *name;
234 bool has_dbg_bus[MAX_CHIP_IDS];
235 bool associated_to_storm;
236 u32 storm_id; /* Valid only if associated_to_storm is true */
237 enum dbg_bus_clients dbg_client_id[MAX_CHIP_IDS];
238 u32 dbg_select_addr;
239 u32 dbg_cycle_enable_addr;
240 u32 dbg_shift_addr;
241 u32 dbg_force_valid_addr;
242 u32 dbg_force_frame_addr;
243 bool has_reset_bit;
244 bool unreset; /* If true, the block is taken out of reset before dump */
245 enum dbg_reset_regs reset_reg;
246 u8 reset_bit_offset; /* Bit offset in reset register */
247};
248
249/* Reset register definitions */
250struct reset_reg_defs {
251 u32 addr;
252 u32 unreset_val;
253 bool exists[MAX_CHIP_IDS];
254};
255
256struct grc_param_defs {
257 u32 default_val[MAX_CHIP_IDS];
258 u32 min;
259 u32 max;
260 bool is_preset;
261 u32 exclude_all_preset_val;
262 u32 crash_preset_val;
263};
264
265struct rss_mem_defs {
266 const char *mem_name;
267 const char *type_name;
268 u32 addr; /* In 128b units */
269 u32 num_entries[MAX_CHIP_IDS];
270 u32 entry_width[MAX_CHIP_IDS]; /* In bits */
271};
272
273struct vfc_ram_defs {
274 const char *mem_name;
275 const char *type_name;
276 u32 base_row;
277 u32 num_rows;
278};
279
280struct big_ram_defs {
281 const char *instance_name;
282 enum mem_groups mem_group_id;
283 enum mem_groups ram_mem_group_id;
284 enum dbg_grc_params grc_param;
285 u32 addr_reg_addr;
286 u32 data_reg_addr;
287 u32 num_of_blocks[MAX_CHIP_IDS];
288};
289
290struct phy_defs {
291 const char *phy_name;
292 u32 base_addr;
293 u32 tbus_addr_lo_addr;
294 u32 tbus_addr_hi_addr;
295 u32 tbus_data_lo_addr;
296 u32 tbus_data_hi_addr;
297};
298
299/******************************** Constants **********************************/
300
301#define MAX_LCIDS 320
302#define MAX_LTIDS 320
303#define NUM_IOR_SETS 2
304#define IORS_PER_SET 176
305#define IOR_SET_OFFSET(set_id) ((set_id) * 256)
306#define BYTES_IN_DWORD sizeof(u32)
307
308/* In the macros below, size and offset are specified in bits */
309#define CEIL_DWORDS(size) DIV_ROUND_UP(size, 32)
310#define FIELD_BIT_OFFSET(type, field) type ## _ ## field ## _ ## OFFSET
311#define FIELD_BIT_SIZE(type, field) type ## _ ## field ## _ ## SIZE
312#define FIELD_DWORD_OFFSET(type, field) \
313 (int)(FIELD_BIT_OFFSET(type, field) / 32)
314#define FIELD_DWORD_SHIFT(type, field) (FIELD_BIT_OFFSET(type, field) % 32)
315#define FIELD_BIT_MASK(type, field) \
316 (((1 << FIELD_BIT_SIZE(type, field)) - 1) << \
317 FIELD_DWORD_SHIFT(type, field))
318#define SET_VAR_FIELD(var, type, field, val) \
319 do { \
320 var[FIELD_DWORD_OFFSET(type, field)] &= \
321 (~FIELD_BIT_MASK(type, field)); \
322 var[FIELD_DWORD_OFFSET(type, field)] |= \
323 (val) << FIELD_DWORD_SHIFT(type, field); \
324 } while (0)
325#define ARR_REG_WR(dev, ptt, addr, arr, arr_size) \
326 do { \
327 for (i = 0; i < (arr_size); i++) \
328 qed_wr(dev, ptt, addr, (arr)[i]); \
329 } while (0)
330#define ARR_REG_RD(dev, ptt, addr, arr, arr_size) \
331 do { \
332 for (i = 0; i < (arr_size); i++) \
333 (arr)[i] = qed_rd(dev, ptt, addr); \
334 } while (0)
335
336#define DWORDS_TO_BYTES(dwords) ((dwords) * BYTES_IN_DWORD)
337#define BYTES_TO_DWORDS(bytes) ((bytes) / BYTES_IN_DWORD)
338#define RAM_LINES_TO_DWORDS(lines) ((lines) * 2)
339#define RAM_LINES_TO_BYTES(lines) \
340 DWORDS_TO_BYTES(RAM_LINES_TO_DWORDS(lines))
341#define REG_DUMP_LEN_SHIFT 24
342#define MEM_DUMP_ENTRY_SIZE_DWORDS \
343 BYTES_TO_DWORDS(sizeof(struct dbg_dump_mem))
344#define IDLE_CHK_RULE_SIZE_DWORDS \
345 BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_rule))
346#define IDLE_CHK_RESULT_HDR_DWORDS \
347 BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_hdr))
348#define IDLE_CHK_RESULT_REG_HDR_DWORDS \
349 BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_reg_hdr))
350#define IDLE_CHK_MAX_ENTRIES_SIZE 32
351
352/* The sizes and offsets below are specified in bits */
353#define VFC_CAM_CMD_STRUCT_SIZE 64
354#define VFC_CAM_CMD_ROW_OFFSET 48
355#define VFC_CAM_CMD_ROW_SIZE 9
356#define VFC_CAM_ADDR_STRUCT_SIZE 16
357#define VFC_CAM_ADDR_OP_OFFSET 0
358#define VFC_CAM_ADDR_OP_SIZE 4
359#define VFC_CAM_RESP_STRUCT_SIZE 256
360#define VFC_RAM_ADDR_STRUCT_SIZE 16
361#define VFC_RAM_ADDR_OP_OFFSET 0
362#define VFC_RAM_ADDR_OP_SIZE 2
363#define VFC_RAM_ADDR_ROW_OFFSET 2
364#define VFC_RAM_ADDR_ROW_SIZE 10
365#define VFC_RAM_RESP_STRUCT_SIZE 256
366#define VFC_CAM_CMD_DWORDS CEIL_DWORDS(VFC_CAM_CMD_STRUCT_SIZE)
367#define VFC_CAM_ADDR_DWORDS CEIL_DWORDS(VFC_CAM_ADDR_STRUCT_SIZE)
368#define VFC_CAM_RESP_DWORDS CEIL_DWORDS(VFC_CAM_RESP_STRUCT_SIZE)
369#define VFC_RAM_CMD_DWORDS VFC_CAM_CMD_DWORDS
370#define VFC_RAM_ADDR_DWORDS CEIL_DWORDS(VFC_RAM_ADDR_STRUCT_SIZE)
371#define VFC_RAM_RESP_DWORDS CEIL_DWORDS(VFC_RAM_RESP_STRUCT_SIZE)
372#define NUM_VFC_RAM_TYPES 4
373#define VFC_CAM_NUM_ROWS 512
374#define VFC_OPCODE_CAM_RD 14
375#define VFC_OPCODE_RAM_RD 0
376#define NUM_RSS_MEM_TYPES 5
377#define NUM_BIG_RAM_TYPES 3
378#define BIG_RAM_BLOCK_SIZE_BYTES 128
379#define BIG_RAM_BLOCK_SIZE_DWORDS \
380 BYTES_TO_DWORDS(BIG_RAM_BLOCK_SIZE_BYTES)
381#define NUM_PHY_TBUS_ADDRESSES 2048
382#define PHY_DUMP_SIZE_DWORDS (NUM_PHY_TBUS_ADDRESSES / 2)
383#define RESET_REG_UNRESET_OFFSET 4
384#define STALL_DELAY_MS 500
385#define STATIC_DEBUG_LINE_DWORDS 9
386#define NUM_DBG_BUS_LINES 256
387#define NUM_COMMON_GLOBAL_PARAMS 8
388#define FW_IMG_MAIN 1
389#define REG_FIFO_DEPTH_ELEMENTS 32
390#define REG_FIFO_ELEMENT_DWORDS 2
391#define REG_FIFO_DEPTH_DWORDS \
392 (REG_FIFO_ELEMENT_DWORDS * REG_FIFO_DEPTH_ELEMENTS)
393#define IGU_FIFO_DEPTH_ELEMENTS 64
394#define IGU_FIFO_ELEMENT_DWORDS 4
395#define IGU_FIFO_DEPTH_DWORDS \
396 (IGU_FIFO_ELEMENT_DWORDS * IGU_FIFO_DEPTH_ELEMENTS)
397#define PROTECTION_OVERRIDE_DEPTH_ELEMENTS 20
398#define PROTECTION_OVERRIDE_ELEMENT_DWORDS 2
399#define PROTECTION_OVERRIDE_DEPTH_DWORDS \
400 (PROTECTION_OVERRIDE_DEPTH_ELEMENTS * \
401 PROTECTION_OVERRIDE_ELEMENT_DWORDS)
402#define MCP_SPAD_TRACE_OFFSIZE_ADDR \
403 (MCP_REG_SCRATCH + \
404 offsetof(struct static_init, sections[SPAD_SECTION_TRACE]))
405#define MCP_TRACE_META_IMAGE_SIGNATURE 0x669955aa
406#define EMPTY_FW_VERSION_STR "???_???_???_???"
407#define EMPTY_FW_IMAGE_STR "???????????????"
408
409/***************************** Constant Arrays *******************************/
410
411/* Debug arrays */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200412static struct dbg_array s_dbg_arrays[MAX_BIN_DBG_BUFFER_TYPE] = { {0} };
Tomer Tayarc965db42016-09-07 16:36:24 +0300413
414/* Chip constant definitions array */
415static struct chip_defs s_chip_defs[MAX_CHIP_IDS] = {
Tomer Tayarc965db42016-09-07 16:36:24 +0300416 { "bb_b0",
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200417 { {MAX_NUM_PORTS_BB, MAX_NUM_PFS_BB, MAX_NUM_VFS_BB}, {0, 0, 0},
418 {0, 0, 0}, {0, 0, 0} } },
419 { "k2",
420 { {MAX_NUM_PORTS_K2, MAX_NUM_PFS_K2, MAX_NUM_VFS_K2}, {0, 0, 0},
421 {0, 0, 0}, {0, 0, 0} } }
Tomer Tayarc965db42016-09-07 16:36:24 +0300422};
423
424/* Storm constant definitions array */
425static struct storm_defs s_storm_defs[] = {
426 /* Tstorm */
427 {'T', BLOCK_TSEM,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200428 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT}, true,
Tomer Tayarc965db42016-09-07 16:36:24 +0300429 TSEM_REG_FAST_MEMORY,
430 TSEM_REG_DBG_FRAME_MODE, TSEM_REG_SLOW_DBG_ACTIVE,
431 TSEM_REG_SLOW_DBG_MODE, TSEM_REG_DBG_MODE1_CFG,
432 TSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_SLOW_DBG_EMPTY,
433 TCM_REG_CTX_RBC_ACCS,
434 4, TCM_REG_AGG_CON_CTX,
435 16, TCM_REG_SM_CON_CTX,
436 2, TCM_REG_AGG_TASK_CTX,
437 4, TCM_REG_SM_TASK_CTX},
438 /* Mstorm */
439 {'M', BLOCK_MSEM,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200440 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM}, false,
Tomer Tayarc965db42016-09-07 16:36:24 +0300441 MSEM_REG_FAST_MEMORY,
442 MSEM_REG_DBG_FRAME_MODE, MSEM_REG_SLOW_DBG_ACTIVE,
443 MSEM_REG_SLOW_DBG_MODE, MSEM_REG_DBG_MODE1_CFG,
444 MSEM_REG_SYNC_DBG_EMPTY, MSEM_REG_SLOW_DBG_EMPTY,
445 MCM_REG_CTX_RBC_ACCS,
446 1, MCM_REG_AGG_CON_CTX,
447 10, MCM_REG_SM_CON_CTX,
448 2, MCM_REG_AGG_TASK_CTX,
449 7, MCM_REG_SM_TASK_CTX},
450 /* Ustorm */
451 {'U', BLOCK_USEM,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200452 {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU}, false,
Tomer Tayarc965db42016-09-07 16:36:24 +0300453 USEM_REG_FAST_MEMORY,
454 USEM_REG_DBG_FRAME_MODE, USEM_REG_SLOW_DBG_ACTIVE,
455 USEM_REG_SLOW_DBG_MODE, USEM_REG_DBG_MODE1_CFG,
456 USEM_REG_SYNC_DBG_EMPTY, USEM_REG_SLOW_DBG_EMPTY,
457 UCM_REG_CTX_RBC_ACCS,
458 2, UCM_REG_AGG_CON_CTX,
459 13, UCM_REG_SM_CON_CTX,
460 3, UCM_REG_AGG_TASK_CTX,
461 3, UCM_REG_SM_TASK_CTX},
462 /* Xstorm */
463 {'X', BLOCK_XSEM,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200464 {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX}, false,
Tomer Tayarc965db42016-09-07 16:36:24 +0300465 XSEM_REG_FAST_MEMORY,
466 XSEM_REG_DBG_FRAME_MODE, XSEM_REG_SLOW_DBG_ACTIVE,
467 XSEM_REG_SLOW_DBG_MODE, XSEM_REG_DBG_MODE1_CFG,
468 XSEM_REG_SYNC_DBG_EMPTY, XSEM_REG_SLOW_DBG_EMPTY,
469 XCM_REG_CTX_RBC_ACCS,
470 9, XCM_REG_AGG_CON_CTX,
471 15, XCM_REG_SM_CON_CTX,
472 0, 0,
473 0, 0},
474 /* Ystorm */
475 {'Y', BLOCK_YSEM,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200476 {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY}, false,
Tomer Tayarc965db42016-09-07 16:36:24 +0300477 YSEM_REG_FAST_MEMORY,
478 YSEM_REG_DBG_FRAME_MODE, YSEM_REG_SLOW_DBG_ACTIVE,
479 YSEM_REG_SLOW_DBG_MODE, YSEM_REG_DBG_MODE1_CFG,
480 YSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_SLOW_DBG_EMPTY,
481 YCM_REG_CTX_RBC_ACCS,
482 2, YCM_REG_AGG_CON_CTX,
483 3, YCM_REG_SM_CON_CTX,
484 2, YCM_REG_AGG_TASK_CTX,
485 12, YCM_REG_SM_TASK_CTX},
486 /* Pstorm */
487 {'P', BLOCK_PSEM,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200488 {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS}, true,
Tomer Tayarc965db42016-09-07 16:36:24 +0300489 PSEM_REG_FAST_MEMORY,
490 PSEM_REG_DBG_FRAME_MODE, PSEM_REG_SLOW_DBG_ACTIVE,
491 PSEM_REG_SLOW_DBG_MODE, PSEM_REG_DBG_MODE1_CFG,
492 PSEM_REG_SYNC_DBG_EMPTY, PSEM_REG_SLOW_DBG_EMPTY,
493 PCM_REG_CTX_RBC_ACCS,
494 0, 0,
495 10, PCM_REG_SM_CON_CTX,
496 0, 0,
497 0, 0}
498};
499
500/* Block definitions array */
501static struct block_defs block_grc_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200502 "grc",
503 {true, true}, false, 0,
504 {DBG_BUS_CLIENT_RBCN, DBG_BUS_CLIENT_RBCN},
Tomer Tayarc965db42016-09-07 16:36:24 +0300505 GRC_REG_DBG_SELECT, GRC_REG_DBG_DWORD_ENABLE,
506 GRC_REG_DBG_SHIFT, GRC_REG_DBG_FORCE_VALID,
507 GRC_REG_DBG_FORCE_FRAME,
508 true, false, DBG_RESET_REG_MISC_PL_UA, 1
509};
510
511static struct block_defs block_miscs_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200512 "miscs", {false, false}, false, 0,
513 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +0300514 0, 0, 0, 0, 0,
515 false, false, MAX_DBG_RESET_REGS, 0
516};
517
518static struct block_defs block_misc_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200519 "misc", {false, false}, false, 0,
520 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +0300521 0, 0, 0, 0, 0,
522 false, false, MAX_DBG_RESET_REGS, 0
523};
524
525static struct block_defs block_dbu_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200526 "dbu", {false, false}, false, 0,
527 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +0300528 0, 0, 0, 0, 0,
529 false, false, MAX_DBG_RESET_REGS, 0
530};
531
532static struct block_defs block_pglue_b_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200533 "pglue_b",
534 {true, true}, false, 0,
535 {DBG_BUS_CLIENT_RBCH, DBG_BUS_CLIENT_RBCH},
Tomer Tayarc965db42016-09-07 16:36:24 +0300536 PGLUE_B_REG_DBG_SELECT, PGLUE_B_REG_DBG_DWORD_ENABLE,
537 PGLUE_B_REG_DBG_SHIFT, PGLUE_B_REG_DBG_FORCE_VALID,
538 PGLUE_B_REG_DBG_FORCE_FRAME,
539 true, false, DBG_RESET_REG_MISCS_PL_HV, 1
540};
541
542static struct block_defs block_cnig_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200543 "cnig",
544 {false, true}, false, 0,
545 {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCW},
Tomer Tayarc965db42016-09-07 16:36:24 +0300546 CNIG_REG_DBG_SELECT_K2, CNIG_REG_DBG_DWORD_ENABLE_K2,
547 CNIG_REG_DBG_SHIFT_K2, CNIG_REG_DBG_FORCE_VALID_K2,
548 CNIG_REG_DBG_FORCE_FRAME_K2,
549 true, false, DBG_RESET_REG_MISCS_PL_HV, 0
550};
551
552static struct block_defs block_cpmu_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200553 "cpmu", {false, false}, false, 0,
554 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +0300555 0, 0, 0, 0, 0,
556 true, false, DBG_RESET_REG_MISCS_PL_HV, 8
557};
558
559static struct block_defs block_ncsi_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200560 "ncsi",
561 {true, true}, false, 0,
562 {DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCZ},
Tomer Tayarc965db42016-09-07 16:36:24 +0300563 NCSI_REG_DBG_SELECT, NCSI_REG_DBG_DWORD_ENABLE,
564 NCSI_REG_DBG_SHIFT, NCSI_REG_DBG_FORCE_VALID,
565 NCSI_REG_DBG_FORCE_FRAME,
566 true, false, DBG_RESET_REG_MISCS_PL_HV, 5
567};
568
569static struct block_defs block_opte_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200570 "opte", {false, false}, false, 0,
571 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +0300572 0, 0, 0, 0, 0,
573 true, false, DBG_RESET_REG_MISCS_PL_HV, 4
574};
575
576static struct block_defs block_bmb_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200577 "bmb",
578 {true, true}, false, 0,
579 {DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCB},
Tomer Tayarc965db42016-09-07 16:36:24 +0300580 BMB_REG_DBG_SELECT, BMB_REG_DBG_DWORD_ENABLE,
581 BMB_REG_DBG_SHIFT, BMB_REG_DBG_FORCE_VALID,
582 BMB_REG_DBG_FORCE_FRAME,
583 true, false, DBG_RESET_REG_MISCS_PL_UA, 7
584};
585
586static struct block_defs block_pcie_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200587 "pcie",
588 {false, true}, false, 0,
589 {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH},
Tomer Tayarc965db42016-09-07 16:36:24 +0300590 PCIE_REG_DBG_COMMON_SELECT, PCIE_REG_DBG_COMMON_DWORD_ENABLE,
591 PCIE_REG_DBG_COMMON_SHIFT, PCIE_REG_DBG_COMMON_FORCE_VALID,
592 PCIE_REG_DBG_COMMON_FORCE_FRAME,
593 false, false, MAX_DBG_RESET_REGS, 0
594};
595
596static struct block_defs block_mcp_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200597 "mcp", {false, false}, false, 0,
598 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +0300599 0, 0, 0, 0, 0,
600 false, false, MAX_DBG_RESET_REGS, 0
601};
602
603static struct block_defs block_mcp2_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200604 "mcp2",
605 {true, true}, false, 0,
606 {DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCZ},
Tomer Tayarc965db42016-09-07 16:36:24 +0300607 MCP2_REG_DBG_SELECT, MCP2_REG_DBG_DWORD_ENABLE,
608 MCP2_REG_DBG_SHIFT, MCP2_REG_DBG_FORCE_VALID,
609 MCP2_REG_DBG_FORCE_FRAME,
610 false, false, MAX_DBG_RESET_REGS, 0
611};
612
613static struct block_defs block_pswhst_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200614 "pswhst",
615 {true, true}, false, 0,
616 {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
Tomer Tayarc965db42016-09-07 16:36:24 +0300617 PSWHST_REG_DBG_SELECT, PSWHST_REG_DBG_DWORD_ENABLE,
618 PSWHST_REG_DBG_SHIFT, PSWHST_REG_DBG_FORCE_VALID,
619 PSWHST_REG_DBG_FORCE_FRAME,
620 true, false, DBG_RESET_REG_MISC_PL_HV, 0
621};
622
623static struct block_defs block_pswhst2_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200624 "pswhst2",
625 {true, true}, false, 0,
626 {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
Tomer Tayarc965db42016-09-07 16:36:24 +0300627 PSWHST2_REG_DBG_SELECT, PSWHST2_REG_DBG_DWORD_ENABLE,
628 PSWHST2_REG_DBG_SHIFT, PSWHST2_REG_DBG_FORCE_VALID,
629 PSWHST2_REG_DBG_FORCE_FRAME,
630 true, false, DBG_RESET_REG_MISC_PL_HV, 0
631};
632
633static struct block_defs block_pswrd_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200634 "pswrd",
635 {true, true}, false, 0,
636 {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
Tomer Tayarc965db42016-09-07 16:36:24 +0300637 PSWRD_REG_DBG_SELECT, PSWRD_REG_DBG_DWORD_ENABLE,
638 PSWRD_REG_DBG_SHIFT, PSWRD_REG_DBG_FORCE_VALID,
639 PSWRD_REG_DBG_FORCE_FRAME,
640 true, false, DBG_RESET_REG_MISC_PL_HV, 2
641};
642
643static struct block_defs block_pswrd2_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200644 "pswrd2",
645 {true, true}, false, 0,
646 {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
Tomer Tayarc965db42016-09-07 16:36:24 +0300647 PSWRD2_REG_DBG_SELECT, PSWRD2_REG_DBG_DWORD_ENABLE,
648 PSWRD2_REG_DBG_SHIFT, PSWRD2_REG_DBG_FORCE_VALID,
649 PSWRD2_REG_DBG_FORCE_FRAME,
650 true, false, DBG_RESET_REG_MISC_PL_HV, 2
651};
652
653static struct block_defs block_pswwr_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200654 "pswwr",
655 {true, true}, false, 0,
656 {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
Tomer Tayarc965db42016-09-07 16:36:24 +0300657 PSWWR_REG_DBG_SELECT, PSWWR_REG_DBG_DWORD_ENABLE,
658 PSWWR_REG_DBG_SHIFT, PSWWR_REG_DBG_FORCE_VALID,
659 PSWWR_REG_DBG_FORCE_FRAME,
660 true, false, DBG_RESET_REG_MISC_PL_HV, 3
661};
662
663static struct block_defs block_pswwr2_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200664 "pswwr2", {false, false}, false, 0,
665 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +0300666 0, 0, 0, 0, 0,
667 true, false, DBG_RESET_REG_MISC_PL_HV, 3
668};
669
670static struct block_defs block_pswrq_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200671 "pswrq",
672 {true, true}, false, 0,
673 {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
Tomer Tayarc965db42016-09-07 16:36:24 +0300674 PSWRQ_REG_DBG_SELECT, PSWRQ_REG_DBG_DWORD_ENABLE,
675 PSWRQ_REG_DBG_SHIFT, PSWRQ_REG_DBG_FORCE_VALID,
676 PSWRQ_REG_DBG_FORCE_FRAME,
677 true, false, DBG_RESET_REG_MISC_PL_HV, 1
678};
679
680static struct block_defs block_pswrq2_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200681 "pswrq2",
682 {true, true}, false, 0,
683 {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
Tomer Tayarc965db42016-09-07 16:36:24 +0300684 PSWRQ2_REG_DBG_SELECT, PSWRQ2_REG_DBG_DWORD_ENABLE,
685 PSWRQ2_REG_DBG_SHIFT, PSWRQ2_REG_DBG_FORCE_VALID,
686 PSWRQ2_REG_DBG_FORCE_FRAME,
687 true, false, DBG_RESET_REG_MISC_PL_HV, 1
688};
689
690static struct block_defs block_pglcs_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200691 "pglcs",
692 {false, true}, false, 0,
693 {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH},
Tomer Tayarc965db42016-09-07 16:36:24 +0300694 PGLCS_REG_DBG_SELECT, PGLCS_REG_DBG_DWORD_ENABLE,
695 PGLCS_REG_DBG_SHIFT, PGLCS_REG_DBG_FORCE_VALID,
696 PGLCS_REG_DBG_FORCE_FRAME,
697 true, false, DBG_RESET_REG_MISCS_PL_HV, 2
698};
699
700static struct block_defs block_ptu_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200701 "ptu",
702 {true, true}, false, 0,
703 {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
Tomer Tayarc965db42016-09-07 16:36:24 +0300704 PTU_REG_DBG_SELECT, PTU_REG_DBG_DWORD_ENABLE,
705 PTU_REG_DBG_SHIFT, PTU_REG_DBG_FORCE_VALID,
706 PTU_REG_DBG_FORCE_FRAME,
707 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 20
708};
709
710static struct block_defs block_dmae_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200711 "dmae",
712 {true, true}, false, 0,
713 {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
Tomer Tayarc965db42016-09-07 16:36:24 +0300714 DMAE_REG_DBG_SELECT, DMAE_REG_DBG_DWORD_ENABLE,
715 DMAE_REG_DBG_SHIFT, DMAE_REG_DBG_FORCE_VALID,
716 DMAE_REG_DBG_FORCE_FRAME,
717 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 28
718};
719
720static struct block_defs block_tcm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200721 "tcm",
722 {true, true}, true, DBG_TSTORM_ID,
723 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
Tomer Tayarc965db42016-09-07 16:36:24 +0300724 TCM_REG_DBG_SELECT, TCM_REG_DBG_DWORD_ENABLE,
725 TCM_REG_DBG_SHIFT, TCM_REG_DBG_FORCE_VALID,
726 TCM_REG_DBG_FORCE_FRAME,
727 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 5
728};
729
730static struct block_defs block_mcm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200731 "mcm",
732 {true, true}, true, DBG_MSTORM_ID,
733 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
Tomer Tayarc965db42016-09-07 16:36:24 +0300734 MCM_REG_DBG_SELECT, MCM_REG_DBG_DWORD_ENABLE,
735 MCM_REG_DBG_SHIFT, MCM_REG_DBG_FORCE_VALID,
736 MCM_REG_DBG_FORCE_FRAME,
737 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 3
738};
739
740static struct block_defs block_ucm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200741 "ucm",
742 {true, true}, true, DBG_USTORM_ID,
743 {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
Tomer Tayarc965db42016-09-07 16:36:24 +0300744 UCM_REG_DBG_SELECT, UCM_REG_DBG_DWORD_ENABLE,
745 UCM_REG_DBG_SHIFT, UCM_REG_DBG_FORCE_VALID,
746 UCM_REG_DBG_FORCE_FRAME,
747 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 8
748};
749
750static struct block_defs block_xcm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200751 "xcm",
752 {true, true}, true, DBG_XSTORM_ID,
753 {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
Tomer Tayarc965db42016-09-07 16:36:24 +0300754 XCM_REG_DBG_SELECT, XCM_REG_DBG_DWORD_ENABLE,
755 XCM_REG_DBG_SHIFT, XCM_REG_DBG_FORCE_VALID,
756 XCM_REG_DBG_FORCE_FRAME,
757 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 19
758};
759
760static struct block_defs block_ycm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200761 "ycm",
762 {true, true}, true, DBG_YSTORM_ID,
763 {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY},
Tomer Tayarc965db42016-09-07 16:36:24 +0300764 YCM_REG_DBG_SELECT, YCM_REG_DBG_DWORD_ENABLE,
765 YCM_REG_DBG_SHIFT, YCM_REG_DBG_FORCE_VALID,
766 YCM_REG_DBG_FORCE_FRAME,
767 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 5
768};
769
770static struct block_defs block_pcm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200771 "pcm",
772 {true, true}, true, DBG_PSTORM_ID,
773 {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
Tomer Tayarc965db42016-09-07 16:36:24 +0300774 PCM_REG_DBG_SELECT, PCM_REG_DBG_DWORD_ENABLE,
775 PCM_REG_DBG_SHIFT, PCM_REG_DBG_FORCE_VALID,
776 PCM_REG_DBG_FORCE_FRAME,
777 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 4
778};
779
780static struct block_defs block_qm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200781 "qm",
782 {true, true}, false, 0,
783 {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCQ},
Tomer Tayarc965db42016-09-07 16:36:24 +0300784 QM_REG_DBG_SELECT, QM_REG_DBG_DWORD_ENABLE,
785 QM_REG_DBG_SHIFT, QM_REG_DBG_FORCE_VALID,
786 QM_REG_DBG_FORCE_FRAME,
787 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 16
788};
789
790static struct block_defs block_tm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200791 "tm",
792 {true, true}, false, 0,
793 {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
Tomer Tayarc965db42016-09-07 16:36:24 +0300794 TM_REG_DBG_SELECT, TM_REG_DBG_DWORD_ENABLE,
795 TM_REG_DBG_SHIFT, TM_REG_DBG_FORCE_VALID,
796 TM_REG_DBG_FORCE_FRAME,
797 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 17
798};
799
800static struct block_defs block_dorq_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200801 "dorq",
802 {true, true}, false, 0,
803 {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY},
Tomer Tayarc965db42016-09-07 16:36:24 +0300804 DORQ_REG_DBG_SELECT, DORQ_REG_DBG_DWORD_ENABLE,
805 DORQ_REG_DBG_SHIFT, DORQ_REG_DBG_FORCE_VALID,
806 DORQ_REG_DBG_FORCE_FRAME,
807 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 18
808};
809
810static struct block_defs block_brb_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200811 "brb",
812 {true, true}, false, 0,
813 {DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCR},
Tomer Tayarc965db42016-09-07 16:36:24 +0300814 BRB_REG_DBG_SELECT, BRB_REG_DBG_DWORD_ENABLE,
815 BRB_REG_DBG_SHIFT, BRB_REG_DBG_FORCE_VALID,
816 BRB_REG_DBG_FORCE_FRAME,
817 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 0
818};
819
820static struct block_defs block_src_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200821 "src",
822 {true, true}, false, 0,
823 {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF},
Tomer Tayarc965db42016-09-07 16:36:24 +0300824 SRC_REG_DBG_SELECT, SRC_REG_DBG_DWORD_ENABLE,
825 SRC_REG_DBG_SHIFT, SRC_REG_DBG_FORCE_VALID,
826 SRC_REG_DBG_FORCE_FRAME,
827 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 2
828};
829
830static struct block_defs block_prs_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200831 "prs",
832 {true, true}, false, 0,
833 {DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCR},
Tomer Tayarc965db42016-09-07 16:36:24 +0300834 PRS_REG_DBG_SELECT, PRS_REG_DBG_DWORD_ENABLE,
835 PRS_REG_DBG_SHIFT, PRS_REG_DBG_FORCE_VALID,
836 PRS_REG_DBG_FORCE_FRAME,
837 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 1
838};
839
840static struct block_defs block_tsdm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200841 "tsdm",
842 {true, true}, true, DBG_TSTORM_ID,
843 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
Tomer Tayarc965db42016-09-07 16:36:24 +0300844 TSDM_REG_DBG_SELECT, TSDM_REG_DBG_DWORD_ENABLE,
845 TSDM_REG_DBG_SHIFT, TSDM_REG_DBG_FORCE_VALID,
846 TSDM_REG_DBG_FORCE_FRAME,
847 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 3
848};
849
850static struct block_defs block_msdm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200851 "msdm",
852 {true, true}, true, DBG_MSTORM_ID,
853 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
Tomer Tayarc965db42016-09-07 16:36:24 +0300854 MSDM_REG_DBG_SELECT, MSDM_REG_DBG_DWORD_ENABLE,
855 MSDM_REG_DBG_SHIFT, MSDM_REG_DBG_FORCE_VALID,
856 MSDM_REG_DBG_FORCE_FRAME,
857 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 6
858};
859
860static struct block_defs block_usdm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200861 "usdm",
862 {true, true}, true, DBG_USTORM_ID,
863 {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
Tomer Tayarc965db42016-09-07 16:36:24 +0300864 USDM_REG_DBG_SELECT, USDM_REG_DBG_DWORD_ENABLE,
865 USDM_REG_DBG_SHIFT, USDM_REG_DBG_FORCE_VALID,
866 USDM_REG_DBG_FORCE_FRAME,
867 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 7
868};
869
870static struct block_defs block_xsdm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200871 "xsdm",
872 {true, true}, true, DBG_XSTORM_ID,
873 {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
Tomer Tayarc965db42016-09-07 16:36:24 +0300874 XSDM_REG_DBG_SELECT, XSDM_REG_DBG_DWORD_ENABLE,
875 XSDM_REG_DBG_SHIFT, XSDM_REG_DBG_FORCE_VALID,
876 XSDM_REG_DBG_FORCE_FRAME,
877 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 20
878};
879
880static struct block_defs block_ysdm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200881 "ysdm",
882 {true, true}, true, DBG_YSTORM_ID,
883 {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY},
Tomer Tayarc965db42016-09-07 16:36:24 +0300884 YSDM_REG_DBG_SELECT, YSDM_REG_DBG_DWORD_ENABLE,
885 YSDM_REG_DBG_SHIFT, YSDM_REG_DBG_FORCE_VALID,
886 YSDM_REG_DBG_FORCE_FRAME,
887 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 8
888};
889
890static struct block_defs block_psdm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200891 "psdm",
892 {true, true}, true, DBG_PSTORM_ID,
893 {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
Tomer Tayarc965db42016-09-07 16:36:24 +0300894 PSDM_REG_DBG_SELECT, PSDM_REG_DBG_DWORD_ENABLE,
895 PSDM_REG_DBG_SHIFT, PSDM_REG_DBG_FORCE_VALID,
896 PSDM_REG_DBG_FORCE_FRAME,
897 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 7
898};
899
900static struct block_defs block_tsem_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200901 "tsem",
902 {true, true}, true, DBG_TSTORM_ID,
903 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
Tomer Tayarc965db42016-09-07 16:36:24 +0300904 TSEM_REG_DBG_SELECT, TSEM_REG_DBG_DWORD_ENABLE,
905 TSEM_REG_DBG_SHIFT, TSEM_REG_DBG_FORCE_VALID,
906 TSEM_REG_DBG_FORCE_FRAME,
907 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 4
908};
909
910static struct block_defs block_msem_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200911 "msem",
912 {true, true}, true, DBG_MSTORM_ID,
913 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
Tomer Tayarc965db42016-09-07 16:36:24 +0300914 MSEM_REG_DBG_SELECT, MSEM_REG_DBG_DWORD_ENABLE,
915 MSEM_REG_DBG_SHIFT, MSEM_REG_DBG_FORCE_VALID,
916 MSEM_REG_DBG_FORCE_FRAME,
917 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 9
918};
919
920static struct block_defs block_usem_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200921 "usem",
922 {true, true}, true, DBG_USTORM_ID,
923 {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
Tomer Tayarc965db42016-09-07 16:36:24 +0300924 USEM_REG_DBG_SELECT, USEM_REG_DBG_DWORD_ENABLE,
925 USEM_REG_DBG_SHIFT, USEM_REG_DBG_FORCE_VALID,
926 USEM_REG_DBG_FORCE_FRAME,
927 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 9
928};
929
930static struct block_defs block_xsem_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200931 "xsem",
932 {true, true}, true, DBG_XSTORM_ID,
933 {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
Tomer Tayarc965db42016-09-07 16:36:24 +0300934 XSEM_REG_DBG_SELECT, XSEM_REG_DBG_DWORD_ENABLE,
935 XSEM_REG_DBG_SHIFT, XSEM_REG_DBG_FORCE_VALID,
936 XSEM_REG_DBG_FORCE_FRAME,
937 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 21
938};
939
940static struct block_defs block_ysem_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200941 "ysem",
942 {true, true}, true, DBG_YSTORM_ID,
943 {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY},
Tomer Tayarc965db42016-09-07 16:36:24 +0300944 YSEM_REG_DBG_SELECT, YSEM_REG_DBG_DWORD_ENABLE,
945 YSEM_REG_DBG_SHIFT, YSEM_REG_DBG_FORCE_VALID,
946 YSEM_REG_DBG_FORCE_FRAME,
947 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 11
948};
949
950static struct block_defs block_psem_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200951 "psem",
952 {true, true}, true, DBG_PSTORM_ID,
953 {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
Tomer Tayarc965db42016-09-07 16:36:24 +0300954 PSEM_REG_DBG_SELECT, PSEM_REG_DBG_DWORD_ENABLE,
955 PSEM_REG_DBG_SHIFT, PSEM_REG_DBG_FORCE_VALID,
956 PSEM_REG_DBG_FORCE_FRAME,
957 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 10
958};
959
960static struct block_defs block_rss_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200961 "rss",
962 {true, true}, false, 0,
963 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
Tomer Tayarc965db42016-09-07 16:36:24 +0300964 RSS_REG_DBG_SELECT, RSS_REG_DBG_DWORD_ENABLE,
965 RSS_REG_DBG_SHIFT, RSS_REG_DBG_FORCE_VALID,
966 RSS_REG_DBG_FORCE_FRAME,
967 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 18
968};
969
970static struct block_defs block_tmld_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200971 "tmld",
972 {true, true}, false, 0,
973 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
Tomer Tayarc965db42016-09-07 16:36:24 +0300974 TMLD_REG_DBG_SELECT, TMLD_REG_DBG_DWORD_ENABLE,
975 TMLD_REG_DBG_SHIFT, TMLD_REG_DBG_FORCE_VALID,
976 TMLD_REG_DBG_FORCE_FRAME,
977 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 13
978};
979
980static struct block_defs block_muld_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200981 "muld",
982 {true, true}, false, 0,
983 {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
Tomer Tayarc965db42016-09-07 16:36:24 +0300984 MULD_REG_DBG_SELECT, MULD_REG_DBG_DWORD_ENABLE,
985 MULD_REG_DBG_SHIFT, MULD_REG_DBG_FORCE_VALID,
986 MULD_REG_DBG_FORCE_FRAME,
987 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 14
988};
989
990static struct block_defs block_yuld_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +0200991 "yuld",
992 {true, true}, false, 0,
993 {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
Tomer Tayarc965db42016-09-07 16:36:24 +0300994 YULD_REG_DBG_SELECT, YULD_REG_DBG_DWORD_ENABLE,
995 YULD_REG_DBG_SHIFT, YULD_REG_DBG_FORCE_VALID,
996 YULD_REG_DBG_FORCE_FRAME,
997 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 15
998};
999
1000static struct block_defs block_xyld_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001001 "xyld",
1002 {true, true}, false, 0,
1003 {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
Tomer Tayarc965db42016-09-07 16:36:24 +03001004 XYLD_REG_DBG_SELECT, XYLD_REG_DBG_DWORD_ENABLE,
1005 XYLD_REG_DBG_SHIFT, XYLD_REG_DBG_FORCE_VALID,
1006 XYLD_REG_DBG_FORCE_FRAME,
1007 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 12
1008};
1009
1010static struct block_defs block_prm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001011 "prm",
1012 {true, true}, false, 0,
1013 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
Tomer Tayarc965db42016-09-07 16:36:24 +03001014 PRM_REG_DBG_SELECT, PRM_REG_DBG_DWORD_ENABLE,
1015 PRM_REG_DBG_SHIFT, PRM_REG_DBG_FORCE_VALID,
1016 PRM_REG_DBG_FORCE_FRAME,
1017 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 21
1018};
1019
1020static struct block_defs block_pbf_pb1_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001021 "pbf_pb1",
1022 {true, true}, false, 0,
1023 {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCV},
Tomer Tayarc965db42016-09-07 16:36:24 +03001024 PBF_PB1_REG_DBG_SELECT, PBF_PB1_REG_DBG_DWORD_ENABLE,
1025 PBF_PB1_REG_DBG_SHIFT, PBF_PB1_REG_DBG_FORCE_VALID,
1026 PBF_PB1_REG_DBG_FORCE_FRAME,
1027 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1,
1028 11
1029};
1030
1031static struct block_defs block_pbf_pb2_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001032 "pbf_pb2",
1033 {true, true}, false, 0,
1034 {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCV},
Tomer Tayarc965db42016-09-07 16:36:24 +03001035 PBF_PB2_REG_DBG_SELECT, PBF_PB2_REG_DBG_DWORD_ENABLE,
1036 PBF_PB2_REG_DBG_SHIFT, PBF_PB2_REG_DBG_FORCE_VALID,
1037 PBF_PB2_REG_DBG_FORCE_FRAME,
1038 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1,
1039 12
1040};
1041
1042static struct block_defs block_rpb_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001043 "rpb",
1044 {true, true}, false, 0,
1045 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
Tomer Tayarc965db42016-09-07 16:36:24 +03001046 RPB_REG_DBG_SELECT, RPB_REG_DBG_DWORD_ENABLE,
1047 RPB_REG_DBG_SHIFT, RPB_REG_DBG_FORCE_VALID,
1048 RPB_REG_DBG_FORCE_FRAME,
1049 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 13
1050};
1051
1052static struct block_defs block_btb_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001053 "btb",
1054 {true, true}, false, 0,
1055 {DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCV},
Tomer Tayarc965db42016-09-07 16:36:24 +03001056 BTB_REG_DBG_SELECT, BTB_REG_DBG_DWORD_ENABLE,
1057 BTB_REG_DBG_SHIFT, BTB_REG_DBG_FORCE_VALID,
1058 BTB_REG_DBG_FORCE_FRAME,
1059 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 10
1060};
1061
1062static struct block_defs block_pbf_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001063 "pbf",
1064 {true, true}, false, 0,
1065 {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCV},
Tomer Tayarc965db42016-09-07 16:36:24 +03001066 PBF_REG_DBG_SELECT, PBF_REG_DBG_DWORD_ENABLE,
1067 PBF_REG_DBG_SHIFT, PBF_REG_DBG_FORCE_VALID,
1068 PBF_REG_DBG_FORCE_FRAME,
1069 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 15
1070};
1071
1072static struct block_defs block_rdif_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001073 "rdif",
1074 {true, true}, false, 0,
1075 {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
Tomer Tayarc965db42016-09-07 16:36:24 +03001076 RDIF_REG_DBG_SELECT, RDIF_REG_DBG_DWORD_ENABLE,
1077 RDIF_REG_DBG_SHIFT, RDIF_REG_DBG_FORCE_VALID,
1078 RDIF_REG_DBG_FORCE_FRAME,
1079 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 16
1080};
1081
1082static struct block_defs block_tdif_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001083 "tdif",
1084 {true, true}, false, 0,
1085 {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
Tomer Tayarc965db42016-09-07 16:36:24 +03001086 TDIF_REG_DBG_SELECT, TDIF_REG_DBG_DWORD_ENABLE,
1087 TDIF_REG_DBG_SHIFT, TDIF_REG_DBG_FORCE_VALID,
1088 TDIF_REG_DBG_FORCE_FRAME,
1089 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 17
1090};
1091
1092static struct block_defs block_cdu_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001093 "cdu",
1094 {true, true}, false, 0,
1095 {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF},
Tomer Tayarc965db42016-09-07 16:36:24 +03001096 CDU_REG_DBG_SELECT, CDU_REG_DBG_DWORD_ENABLE,
1097 CDU_REG_DBG_SHIFT, CDU_REG_DBG_FORCE_VALID,
1098 CDU_REG_DBG_FORCE_FRAME,
1099 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 23
1100};
1101
1102static struct block_defs block_ccfc_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001103 "ccfc",
1104 {true, true}, false, 0,
1105 {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF},
Tomer Tayarc965db42016-09-07 16:36:24 +03001106 CCFC_REG_DBG_SELECT, CCFC_REG_DBG_DWORD_ENABLE,
1107 CCFC_REG_DBG_SHIFT, CCFC_REG_DBG_FORCE_VALID,
1108 CCFC_REG_DBG_FORCE_FRAME,
1109 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 24
1110};
1111
1112static struct block_defs block_tcfc_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001113 "tcfc",
1114 {true, true}, false, 0,
1115 {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF},
Tomer Tayarc965db42016-09-07 16:36:24 +03001116 TCFC_REG_DBG_SELECT, TCFC_REG_DBG_DWORD_ENABLE,
1117 TCFC_REG_DBG_SHIFT, TCFC_REG_DBG_FORCE_VALID,
1118 TCFC_REG_DBG_FORCE_FRAME,
1119 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 25
1120};
1121
1122static struct block_defs block_igu_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001123 "igu",
1124 {true, true}, false, 0,
1125 {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
Tomer Tayarc965db42016-09-07 16:36:24 +03001126 IGU_REG_DBG_SELECT, IGU_REG_DBG_DWORD_ENABLE,
1127 IGU_REG_DBG_SHIFT, IGU_REG_DBG_FORCE_VALID,
1128 IGU_REG_DBG_FORCE_FRAME,
1129 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 27
1130};
1131
1132static struct block_defs block_cau_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001133 "cau",
1134 {true, true}, false, 0,
1135 {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
Tomer Tayarc965db42016-09-07 16:36:24 +03001136 CAU_REG_DBG_SELECT, CAU_REG_DBG_DWORD_ENABLE,
1137 CAU_REG_DBG_SHIFT, CAU_REG_DBG_FORCE_VALID,
1138 CAU_REG_DBG_FORCE_FRAME,
1139 true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 19
1140};
1141
1142static struct block_defs block_umac_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001143 "umac",
1144 {false, true}, false, 0,
1145 {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCZ},
Tomer Tayarc965db42016-09-07 16:36:24 +03001146 UMAC_REG_DBG_SELECT, UMAC_REG_DBG_DWORD_ENABLE,
1147 UMAC_REG_DBG_SHIFT, UMAC_REG_DBG_FORCE_VALID,
1148 UMAC_REG_DBG_FORCE_FRAME,
1149 true, false, DBG_RESET_REG_MISCS_PL_HV, 6
1150};
1151
1152static struct block_defs block_xmac_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001153 "xmac", {false, false}, false, 0,
1154 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +03001155 0, 0, 0, 0, 0,
1156 false, false, MAX_DBG_RESET_REGS, 0
1157};
1158
1159static struct block_defs block_dbg_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001160 "dbg", {false, false}, false, 0,
1161 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +03001162 0, 0, 0, 0, 0,
1163 true, true, DBG_RESET_REG_MISC_PL_PDA_VAUX, 3
1164};
1165
1166static struct block_defs block_nig_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001167 "nig",
1168 {true, true}, false, 0,
1169 {DBG_BUS_CLIENT_RBCN, DBG_BUS_CLIENT_RBCN},
Tomer Tayarc965db42016-09-07 16:36:24 +03001170 NIG_REG_DBG_SELECT, NIG_REG_DBG_DWORD_ENABLE,
1171 NIG_REG_DBG_SHIFT, NIG_REG_DBG_FORCE_VALID,
1172 NIG_REG_DBG_FORCE_FRAME,
1173 true, true, DBG_RESET_REG_MISC_PL_PDA_VAUX, 0
1174};
1175
1176static struct block_defs block_wol_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001177 "wol",
1178 {false, true}, false, 0,
1179 {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCZ},
Tomer Tayarc965db42016-09-07 16:36:24 +03001180 WOL_REG_DBG_SELECT, WOL_REG_DBG_DWORD_ENABLE,
1181 WOL_REG_DBG_SHIFT, WOL_REG_DBG_FORCE_VALID,
1182 WOL_REG_DBG_FORCE_FRAME,
1183 true, true, DBG_RESET_REG_MISC_PL_PDA_VAUX, 7
1184};
1185
1186static struct block_defs block_bmbn_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001187 "bmbn",
1188 {false, true}, false, 0,
1189 {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCB},
Tomer Tayarc965db42016-09-07 16:36:24 +03001190 BMBN_REG_DBG_SELECT, BMBN_REG_DBG_DWORD_ENABLE,
1191 BMBN_REG_DBG_SHIFT, BMBN_REG_DBG_FORCE_VALID,
1192 BMBN_REG_DBG_FORCE_FRAME,
1193 false, false, MAX_DBG_RESET_REGS, 0
1194};
1195
1196static struct block_defs block_ipc_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001197 "ipc", {false, false}, false, 0,
1198 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +03001199 0, 0, 0, 0, 0,
1200 true, false, DBG_RESET_REG_MISCS_PL_UA, 8
1201};
1202
1203static struct block_defs block_nwm_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001204 "nwm",
1205 {false, true}, false, 0,
1206 {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCW},
Tomer Tayarc965db42016-09-07 16:36:24 +03001207 NWM_REG_DBG_SELECT, NWM_REG_DBG_DWORD_ENABLE,
1208 NWM_REG_DBG_SHIFT, NWM_REG_DBG_FORCE_VALID,
1209 NWM_REG_DBG_FORCE_FRAME,
1210 true, false, DBG_RESET_REG_MISCS_PL_HV_2, 0
1211};
1212
1213static struct block_defs block_nws_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001214 "nws",
1215 {false, true}, false, 0,
1216 {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCW},
1217 NWS_REG_DBG_SELECT, NWS_REG_DBG_DWORD_ENABLE,
1218 NWS_REG_DBG_SHIFT, NWS_REG_DBG_FORCE_VALID,
1219 NWS_REG_DBG_FORCE_FRAME,
Tomer Tayarc965db42016-09-07 16:36:24 +03001220 true, false, DBG_RESET_REG_MISCS_PL_HV, 12
1221};
1222
1223static struct block_defs block_ms_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001224 "ms",
1225 {false, true}, false, 0,
1226 {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCZ},
1227 MS_REG_DBG_SELECT, MS_REG_DBG_DWORD_ENABLE,
1228 MS_REG_DBG_SHIFT, MS_REG_DBG_FORCE_VALID,
1229 MS_REG_DBG_FORCE_FRAME,
Tomer Tayarc965db42016-09-07 16:36:24 +03001230 true, false, DBG_RESET_REG_MISCS_PL_HV, 13
1231};
1232
1233static struct block_defs block_phy_pcie_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001234 "phy_pcie",
1235 {false, true}, false, 0,
1236 {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH},
Tomer Tayarc965db42016-09-07 16:36:24 +03001237 PCIE_REG_DBG_COMMON_SELECT, PCIE_REG_DBG_COMMON_DWORD_ENABLE,
1238 PCIE_REG_DBG_COMMON_SHIFT, PCIE_REG_DBG_COMMON_FORCE_VALID,
1239 PCIE_REG_DBG_COMMON_FORCE_FRAME,
1240 false, false, MAX_DBG_RESET_REGS, 0
1241};
1242
1243static struct block_defs block_led_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001244 "led", {false, false}, false, 0,
1245 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +03001246 0, 0, 0, 0, 0,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001247 true, false, DBG_RESET_REG_MISCS_PL_HV, 14
1248};
1249
1250static struct block_defs block_avs_wrap_defs = {
1251 "avs_wrap", {false, false}, false, 0,
1252 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1253 0, 0, 0, 0, 0,
1254 true, false, DBG_RESET_REG_MISCS_PL_UA, 11
1255};
1256
1257static struct block_defs block_rgfs_defs = {
1258 "rgfs", {false, false}, false, 0,
1259 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1260 0, 0, 0, 0, 0,
1261 false, false, MAX_DBG_RESET_REGS, 0
1262};
1263
1264static struct block_defs block_tgfs_defs = {
1265 "tgfs", {false, false}, false, 0,
1266 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1267 0, 0, 0, 0, 0,
1268 false, false, MAX_DBG_RESET_REGS, 0
1269};
1270
1271static struct block_defs block_ptld_defs = {
1272 "ptld", {false, false}, false, 0,
1273 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1274 0, 0, 0, 0, 0,
1275 false, false, MAX_DBG_RESET_REGS, 0
1276};
1277
1278static struct block_defs block_ypld_defs = {
1279 "ypld", {false, false}, false, 0,
1280 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1281 0, 0, 0, 0, 0,
1282 false, false, MAX_DBG_RESET_REGS, 0
Tomer Tayarc965db42016-09-07 16:36:24 +03001283};
1284
1285static struct block_defs block_misc_aeu_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001286 "misc_aeu", {false, false}, false, 0,
1287 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +03001288 0, 0, 0, 0, 0,
1289 false, false, MAX_DBG_RESET_REGS, 0
1290};
1291
1292static struct block_defs block_bar0_map_defs = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001293 "bar0_map", {false, false}, false, 0,
1294 {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
Tomer Tayarc965db42016-09-07 16:36:24 +03001295 0, 0, 0, 0, 0,
1296 false, false, MAX_DBG_RESET_REGS, 0
1297};
1298
1299static struct block_defs *s_block_defs[MAX_BLOCK_ID] = {
1300 &block_grc_defs,
1301 &block_miscs_defs,
1302 &block_misc_defs,
1303 &block_dbu_defs,
1304 &block_pglue_b_defs,
1305 &block_cnig_defs,
1306 &block_cpmu_defs,
1307 &block_ncsi_defs,
1308 &block_opte_defs,
1309 &block_bmb_defs,
1310 &block_pcie_defs,
1311 &block_mcp_defs,
1312 &block_mcp2_defs,
1313 &block_pswhst_defs,
1314 &block_pswhst2_defs,
1315 &block_pswrd_defs,
1316 &block_pswrd2_defs,
1317 &block_pswwr_defs,
1318 &block_pswwr2_defs,
1319 &block_pswrq_defs,
1320 &block_pswrq2_defs,
1321 &block_pglcs_defs,
1322 &block_dmae_defs,
1323 &block_ptu_defs,
1324 &block_tcm_defs,
1325 &block_mcm_defs,
1326 &block_ucm_defs,
1327 &block_xcm_defs,
1328 &block_ycm_defs,
1329 &block_pcm_defs,
1330 &block_qm_defs,
1331 &block_tm_defs,
1332 &block_dorq_defs,
1333 &block_brb_defs,
1334 &block_src_defs,
1335 &block_prs_defs,
1336 &block_tsdm_defs,
1337 &block_msdm_defs,
1338 &block_usdm_defs,
1339 &block_xsdm_defs,
1340 &block_ysdm_defs,
1341 &block_psdm_defs,
1342 &block_tsem_defs,
1343 &block_msem_defs,
1344 &block_usem_defs,
1345 &block_xsem_defs,
1346 &block_ysem_defs,
1347 &block_psem_defs,
1348 &block_rss_defs,
1349 &block_tmld_defs,
1350 &block_muld_defs,
1351 &block_yuld_defs,
1352 &block_xyld_defs,
1353 &block_prm_defs,
1354 &block_pbf_pb1_defs,
1355 &block_pbf_pb2_defs,
1356 &block_rpb_defs,
1357 &block_btb_defs,
1358 &block_pbf_defs,
1359 &block_rdif_defs,
1360 &block_tdif_defs,
1361 &block_cdu_defs,
1362 &block_ccfc_defs,
1363 &block_tcfc_defs,
1364 &block_igu_defs,
1365 &block_cau_defs,
1366 &block_umac_defs,
1367 &block_xmac_defs,
1368 &block_dbg_defs,
1369 &block_nig_defs,
1370 &block_wol_defs,
1371 &block_bmbn_defs,
1372 &block_ipc_defs,
1373 &block_nwm_defs,
1374 &block_nws_defs,
1375 &block_ms_defs,
1376 &block_phy_pcie_defs,
1377 &block_led_defs,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001378 &block_avs_wrap_defs,
1379 &block_rgfs_defs,
1380 &block_tgfs_defs,
1381 &block_ptld_defs,
1382 &block_ypld_defs,
Tomer Tayarc965db42016-09-07 16:36:24 +03001383 &block_misc_aeu_defs,
1384 &block_bar0_map_defs,
1385};
1386
1387static struct platform_defs s_platform_defs[] = {
1388 {"asic", 1},
1389 {"reserved", 0},
1390 {"reserved2", 0},
1391 {"reserved3", 0}
1392};
1393
1394static struct grc_param_defs s_grc_param_defs[] = {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001395 {{1, 1}, 0, 1, false, 1, 1}, /* DBG_GRC_PARAM_DUMP_TSTORM */
1396 {{1, 1}, 0, 1, false, 1, 1}, /* DBG_GRC_PARAM_DUMP_MSTORM */
1397 {{1, 1}, 0, 1, false, 1, 1}, /* DBG_GRC_PARAM_DUMP_USTORM */
1398 {{1, 1}, 0, 1, false, 1, 1}, /* DBG_GRC_PARAM_DUMP_XSTORM */
1399 {{1, 1}, 0, 1, false, 1, 1}, /* DBG_GRC_PARAM_DUMP_YSTORM */
1400 {{1, 1}, 0, 1, false, 1, 1}, /* DBG_GRC_PARAM_DUMP_PSTORM */
1401 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_REGS */
1402 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_RAM */
1403 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_PBUF */
1404 {{0, 0}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_IOR */
1405 {{0, 0}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_VFC */
1406 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_CM_CTX */
1407 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_ILT */
1408 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_RSS */
1409 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_CAU */
1410 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_QM */
1411 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_MCP */
1412 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_RESERVED */
1413 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_CFC */
1414 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_IGU */
1415 {{0, 0}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_BRB */
1416 {{0, 0}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_BTB */
1417 {{0, 0}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_BMB */
1418 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_NIG */
1419 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_MULD */
1420 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_PRS */
1421 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_DMAE */
1422 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_TM */
1423 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_SDM */
1424 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_DIF */
1425 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_STATIC */
1426 {{0, 0}, 0, 1, false, 0, 0}, /* DBG_GRC_PARAM_UNSTALL */
1427 {{MAX_LCIDS, MAX_LCIDS}, 1, MAX_LCIDS, false, MAX_LCIDS,
Tomer Tayarc965db42016-09-07 16:36:24 +03001428 MAX_LCIDS}, /* DBG_GRC_PARAM_NUM_LCIDS */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001429 {{MAX_LTIDS, MAX_LTIDS}, 1, MAX_LTIDS, false, MAX_LTIDS,
Tomer Tayarc965db42016-09-07 16:36:24 +03001430 MAX_LTIDS}, /* DBG_GRC_PARAM_NUM_LTIDS */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001431 {{0, 0}, 0, 1, true, 0, 0}, /* DBG_GRC_PARAM_EXCLUDE_ALL */
1432 {{0, 0}, 0, 1, true, 0, 0}, /* DBG_GRC_PARAM_CRASH */
1433 {{0, 0}, 0, 1, false, 1, 0}, /* DBG_GRC_PARAM_PARITY_SAFE */
1434 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_CM */
1435 {{1, 1}, 0, 1, false, 0, 1}, /* DBG_GRC_PARAM_DUMP_PHY */
1436 {{0, 0}, 0, 1, false, 0, 0}, /* DBG_GRC_PARAM_NO_MCP */
1437 {{0, 0}, 0, 1, false, 0, 0} /* DBG_GRC_PARAM_NO_FW_VER */
Tomer Tayarc965db42016-09-07 16:36:24 +03001438};
1439
1440static struct rss_mem_defs s_rss_mem_defs[] = {
1441 { "rss_mem_cid", "rss_cid", 0,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001442 {256, 320},
1443 {32, 32} },
Tomer Tayarc965db42016-09-07 16:36:24 +03001444 { "rss_mem_key_msb", "rss_key", 1024,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001445 {128, 208},
1446 {256, 256} },
Tomer Tayarc965db42016-09-07 16:36:24 +03001447 { "rss_mem_key_lsb", "rss_key", 2048,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001448 {128, 208},
1449 {64, 64} },
Tomer Tayarc965db42016-09-07 16:36:24 +03001450 { "rss_mem_info", "rss_info", 3072,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001451 {128, 208},
1452 {16, 16} },
Tomer Tayarc965db42016-09-07 16:36:24 +03001453 { "rss_mem_ind", "rss_ind", 4096,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001454 {(128 * 128), (128 * 208)},
1455 {16, 16} }
Tomer Tayarc965db42016-09-07 16:36:24 +03001456};
1457
1458static struct vfc_ram_defs s_vfc_ram_defs[] = {
1459 {"vfc_ram_tt1", "vfc_ram", 0, 512},
1460 {"vfc_ram_mtt2", "vfc_ram", 512, 128},
1461 {"vfc_ram_stt2", "vfc_ram", 640, 32},
1462 {"vfc_ram_ro_vect", "vfc_ram", 672, 32}
1463};
1464
1465static struct big_ram_defs s_big_ram_defs[] = {
1466 { "BRB", MEM_GROUP_BRB_MEM, MEM_GROUP_BRB_RAM, DBG_GRC_PARAM_DUMP_BRB,
1467 BRB_REG_BIG_RAM_ADDRESS, BRB_REG_BIG_RAM_DATA,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001468 {4800, 5632} },
Tomer Tayarc965db42016-09-07 16:36:24 +03001469 { "BTB", MEM_GROUP_BTB_MEM, MEM_GROUP_BTB_RAM, DBG_GRC_PARAM_DUMP_BTB,
1470 BTB_REG_BIG_RAM_ADDRESS, BTB_REG_BIG_RAM_DATA,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001471 {2880, 3680} },
Tomer Tayarc965db42016-09-07 16:36:24 +03001472 { "BMB", MEM_GROUP_BMB_MEM, MEM_GROUP_BMB_RAM, DBG_GRC_PARAM_DUMP_BMB,
1473 BMB_REG_BIG_RAM_ADDRESS, BMB_REG_BIG_RAM_DATA,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001474 {1152, 1152} }
Tomer Tayarc965db42016-09-07 16:36:24 +03001475};
1476
1477static struct reset_reg_defs s_reset_regs_defs[] = {
1478 { MISCS_REG_RESET_PL_UA, 0x0,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001479 {true, true} }, /* DBG_RESET_REG_MISCS_PL_UA */
Tomer Tayarc965db42016-09-07 16:36:24 +03001480 { MISCS_REG_RESET_PL_HV, 0x0,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001481 {true, true} }, /* DBG_RESET_REG_MISCS_PL_HV */
Tomer Tayarc965db42016-09-07 16:36:24 +03001482 { MISCS_REG_RESET_PL_HV_2, 0x0,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001483 {false, true} }, /* DBG_RESET_REG_MISCS_PL_HV_2 */
Tomer Tayarc965db42016-09-07 16:36:24 +03001484 { MISC_REG_RESET_PL_UA, 0x0,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001485 {true, true} }, /* DBG_RESET_REG_MISC_PL_UA */
Tomer Tayarc965db42016-09-07 16:36:24 +03001486 { MISC_REG_RESET_PL_HV, 0x0,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001487 {true, true} }, /* DBG_RESET_REG_MISC_PL_HV */
Tomer Tayarc965db42016-09-07 16:36:24 +03001488 { MISC_REG_RESET_PL_PDA_VMAIN_1, 0x4404040,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001489 {true, true} }, /* DBG_RESET_REG_MISC_PL_PDA_VMAIN_1 */
Tomer Tayarc965db42016-09-07 16:36:24 +03001490 { MISC_REG_RESET_PL_PDA_VMAIN_2, 0x7c00007,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001491 {true, true} }, /* DBG_RESET_REG_MISC_PL_PDA_VMAIN_2 */
Tomer Tayarc965db42016-09-07 16:36:24 +03001492 { MISC_REG_RESET_PL_PDA_VAUX, 0x2,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001493 {true, true} }, /* DBG_RESET_REG_MISC_PL_PDA_VAUX */
Tomer Tayarc965db42016-09-07 16:36:24 +03001494};
1495
1496static struct phy_defs s_phy_defs[] = {
1497 {"nw_phy", NWS_REG_NWS_CMU, PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_7_0,
1498 PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_15_8,
1499 PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_7_0,
1500 PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_11_8},
1501 {"sgmii_phy", MS_REG_MS_CMU, PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X132,
1502 PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X133,
1503 PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X130,
1504 PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X131},
1505 {"pcie_phy0", PHY_PCIE_REG_PHY0, PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132,
1506 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133,
1507 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130,
1508 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131},
1509 {"pcie_phy1", PHY_PCIE_REG_PHY1, PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132,
1510 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133,
1511 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130,
1512 PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131},
1513};
1514
1515/**************************** Private Functions ******************************/
1516
1517/* Reads and returns a single dword from the specified unaligned buffer */
1518static u32 qed_read_unaligned_dword(u8 *buf)
1519{
1520 u32 dword;
1521
1522 memcpy((u8 *)&dword, buf, sizeof(dword));
1523 return dword;
1524}
1525
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001526/* Returns the value of the specified GRC param */
1527static u32 qed_grc_get_param(struct qed_hwfn *p_hwfn,
1528 enum dbg_grc_params grc_param)
1529{
1530 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1531
1532 return dev_data->grc.param_val[grc_param];
1533}
1534
1535/* Initializes the GRC parameters */
1536static void qed_dbg_grc_init_params(struct qed_hwfn *p_hwfn)
1537{
1538 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1539
1540 if (!dev_data->grc.params_initialized) {
1541 qed_dbg_grc_set_params_default(p_hwfn);
1542 dev_data->grc.params_initialized = 1;
1543 }
1544}
1545
Tomer Tayarc965db42016-09-07 16:36:24 +03001546/* Initializes debug data for the specified device */
1547static enum dbg_status qed_dbg_dev_init(struct qed_hwfn *p_hwfn,
1548 struct qed_ptt *p_ptt)
1549{
1550 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1551
1552 if (dev_data->initialized)
1553 return DBG_STATUS_OK;
1554
1555 if (QED_IS_K2(p_hwfn->cdev)) {
1556 dev_data->chip_id = CHIP_K2;
1557 dev_data->mode_enable[MODE_K2] = 1;
1558 } else if (QED_IS_BB_B0(p_hwfn->cdev)) {
1559 dev_data->chip_id = CHIP_BB_B0;
Mintz, Yuval9c79dda2017-03-14 16:23:54 +02001560 dev_data->mode_enable[MODE_BB] = 1;
Tomer Tayarc965db42016-09-07 16:36:24 +03001561 } else {
1562 return DBG_STATUS_UNKNOWN_CHIP;
1563 }
1564
1565 dev_data->platform_id = PLATFORM_ASIC;
1566 dev_data->mode_enable[MODE_ASIC] = 1;
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001567
1568 /* Initializes the GRC parameters */
1569 qed_dbg_grc_init_params(p_hwfn);
1570
Tomer Tayarc965db42016-09-07 16:36:24 +03001571 dev_data->initialized = true;
1572 return DBG_STATUS_OK;
1573}
1574
1575/* Reads the FW info structure for the specified Storm from the chip,
1576 * and writes it to the specified fw_info pointer.
1577 */
1578static void qed_read_fw_info(struct qed_hwfn *p_hwfn,
1579 struct qed_ptt *p_ptt,
1580 u8 storm_id, struct fw_info *fw_info)
1581{
1582 /* Read first the address that points to fw_info location.
1583 * The address is located in the last line of the Storm RAM.
1584 */
1585 u32 addr = s_storm_defs[storm_id].sem_fast_mem_addr +
1586 SEM_FAST_REG_INT_RAM +
1587 DWORDS_TO_BYTES(SEM_FAST_REG_INT_RAM_SIZE) -
1588 sizeof(struct fw_info_location);
1589 struct fw_info_location fw_info_location;
1590 u32 *dest = (u32 *)&fw_info_location;
1591 u32 i;
1592
1593 memset(&fw_info_location, 0, sizeof(fw_info_location));
1594 memset(fw_info, 0, sizeof(*fw_info));
1595 for (i = 0; i < BYTES_TO_DWORDS(sizeof(fw_info_location));
1596 i++, addr += BYTES_IN_DWORD)
1597 dest[i] = qed_rd(p_hwfn, p_ptt, addr);
1598 if (fw_info_location.size > 0 && fw_info_location.size <=
1599 sizeof(*fw_info)) {
1600 /* Read FW version info from Storm RAM */
1601 addr = fw_info_location.grc_addr;
1602 dest = (u32 *)fw_info;
1603 for (i = 0; i < BYTES_TO_DWORDS(fw_info_location.size);
1604 i++, addr += BYTES_IN_DWORD)
1605 dest[i] = qed_rd(p_hwfn, p_ptt, addr);
1606 }
1607}
1608
1609/* Dumps the specified string to the specified buffer. Returns the dumped size
1610 * in bytes (actual length + 1 for the null character termination).
1611 */
1612static u32 qed_dump_str(char *dump_buf, bool dump, const char *str)
1613{
1614 if (dump)
1615 strcpy(dump_buf, str);
1616 return (u32)strlen(str) + 1;
1617}
1618
1619/* Dumps zeros to align the specified buffer to dwords. Returns the dumped size
1620 * in bytes.
1621 */
1622static u32 qed_dump_align(char *dump_buf, bool dump, u32 byte_offset)
1623{
1624 u8 offset_in_dword = (u8)(byte_offset & 0x3), align_size;
1625
1626 align_size = offset_in_dword ? BYTES_IN_DWORD - offset_in_dword : 0;
1627
1628 if (dump && align_size)
1629 memset(dump_buf, 0, align_size);
1630 return align_size;
1631}
1632
1633/* Writes the specified string param to the specified buffer.
1634 * Returns the dumped size in dwords.
1635 */
1636static u32 qed_dump_str_param(u32 *dump_buf,
1637 bool dump,
1638 const char *param_name, const char *param_val)
1639{
1640 char *char_buf = (char *)dump_buf;
1641 u32 offset = 0;
1642
1643 /* Dump param name */
1644 offset += qed_dump_str(char_buf + offset, dump, param_name);
1645
1646 /* Indicate a string param value */
1647 if (dump)
1648 *(char_buf + offset) = 1;
1649 offset++;
1650
1651 /* Dump param value */
1652 offset += qed_dump_str(char_buf + offset, dump, param_val);
1653
1654 /* Align buffer to next dword */
1655 offset += qed_dump_align(char_buf + offset, dump, offset);
1656 return BYTES_TO_DWORDS(offset);
1657}
1658
1659/* Writes the specified numeric param to the specified buffer.
1660 * Returns the dumped size in dwords.
1661 */
1662static u32 qed_dump_num_param(u32 *dump_buf,
1663 bool dump, const char *param_name, u32 param_val)
1664{
1665 char *char_buf = (char *)dump_buf;
1666 u32 offset = 0;
1667
1668 /* Dump param name */
1669 offset += qed_dump_str(char_buf + offset, dump, param_name);
1670
1671 /* Indicate a numeric param value */
1672 if (dump)
1673 *(char_buf + offset) = 0;
1674 offset++;
1675
1676 /* Align buffer to next dword */
1677 offset += qed_dump_align(char_buf + offset, dump, offset);
1678
1679 /* Dump param value (and change offset from bytes to dwords) */
1680 offset = BYTES_TO_DWORDS(offset);
1681 if (dump)
1682 *(dump_buf + offset) = param_val;
1683 offset++;
1684 return offset;
1685}
1686
1687/* Reads the FW version and writes it as a param to the specified buffer.
1688 * Returns the dumped size in dwords.
1689 */
1690static u32 qed_dump_fw_ver_param(struct qed_hwfn *p_hwfn,
1691 struct qed_ptt *p_ptt,
1692 u32 *dump_buf, bool dump)
1693{
1694 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1695 char fw_ver_str[16] = EMPTY_FW_VERSION_STR;
1696 char fw_img_str[16] = EMPTY_FW_IMAGE_STR;
1697 struct fw_info fw_info = { {0}, {0} };
1698 int printed_chars;
1699 u32 offset = 0;
1700
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001701 if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {
Tomer Tayarc965db42016-09-07 16:36:24 +03001702 /* Read FW image/version from PRAM in a non-reset SEMI */
1703 bool found = false;
1704 u8 storm_id;
1705
1706 for (storm_id = 0; storm_id < MAX_DBG_STORMS && !found;
1707 storm_id++) {
1708 /* Read FW version/image */
1709 if (!dev_data->block_in_reset
1710 [s_storm_defs[storm_id].block_id]) {
1711 /* read FW info for the current Storm */
1712 qed_read_fw_info(p_hwfn,
1713 p_ptt, storm_id, &fw_info);
1714
1715 /* Create FW version/image strings */
1716 printed_chars =
1717 snprintf(fw_ver_str,
1718 sizeof(fw_ver_str),
1719 "%d_%d_%d_%d",
1720 fw_info.ver.num.major,
1721 fw_info.ver.num.minor,
1722 fw_info.ver.num.rev,
1723 fw_info.ver.num.eng);
1724 if (printed_chars < 0 || printed_chars >=
1725 sizeof(fw_ver_str))
1726 DP_NOTICE(p_hwfn,
1727 "Unexpected debug error: invalid FW version string\n");
1728 switch (fw_info.ver.image_id) {
1729 case FW_IMG_MAIN:
1730 strcpy(fw_img_str, "main");
1731 break;
1732 default:
1733 strcpy(fw_img_str, "unknown");
1734 break;
1735 }
1736
1737 found = true;
1738 }
1739 }
1740 }
1741
1742 /* Dump FW version, image and timestamp */
1743 offset += qed_dump_str_param(dump_buf + offset,
1744 dump, "fw-version", fw_ver_str);
1745 offset += qed_dump_str_param(dump_buf + offset,
1746 dump, "fw-image", fw_img_str);
1747 offset += qed_dump_num_param(dump_buf + offset,
1748 dump,
1749 "fw-timestamp", fw_info.ver.timestamp);
1750 return offset;
1751}
1752
1753/* Reads the MFW version and writes it as a param to the specified buffer.
1754 * Returns the dumped size in dwords.
1755 */
1756static u32 qed_dump_mfw_ver_param(struct qed_hwfn *p_hwfn,
1757 struct qed_ptt *p_ptt,
1758 u32 *dump_buf, bool dump)
1759{
1760 char mfw_ver_str[16] = EMPTY_FW_VERSION_STR;
1761
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001762 if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {
Tomer Tayarc965db42016-09-07 16:36:24 +03001763 u32 global_section_offsize, global_section_addr, mfw_ver;
1764 u32 public_data_addr, global_section_offsize_addr;
1765 int printed_chars;
1766
1767 /* Find MCP public data GRC address.
1768 * Needs to be ORed with MCP_REG_SCRATCH due to a HW bug.
1769 */
1770 public_data_addr = qed_rd(p_hwfn, p_ptt,
1771 MISC_REG_SHARED_MEM_ADDR) |
1772 MCP_REG_SCRATCH;
1773
1774 /* Find MCP public global section offset */
1775 global_section_offsize_addr = public_data_addr +
1776 offsetof(struct mcp_public_data,
1777 sections) +
1778 sizeof(offsize_t) * PUBLIC_GLOBAL;
1779 global_section_offsize = qed_rd(p_hwfn, p_ptt,
1780 global_section_offsize_addr);
1781 global_section_addr = MCP_REG_SCRATCH +
1782 (global_section_offsize &
1783 OFFSIZE_OFFSET_MASK) * 4;
1784
1785 /* Read MFW version from MCP public global section */
1786 mfw_ver = qed_rd(p_hwfn, p_ptt,
1787 global_section_addr +
1788 offsetof(struct public_global, mfw_ver));
1789
1790 /* Dump MFW version param */
1791 printed_chars = snprintf(mfw_ver_str, sizeof(mfw_ver_str),
1792 "%d_%d_%d_%d",
1793 (u8) (mfw_ver >> 24),
1794 (u8) (mfw_ver >> 16),
1795 (u8) (mfw_ver >> 8),
1796 (u8) mfw_ver);
1797 if (printed_chars < 0 || printed_chars >= sizeof(mfw_ver_str))
1798 DP_NOTICE(p_hwfn,
1799 "Unexpected debug error: invalid MFW version string\n");
1800 }
1801
1802 return qed_dump_str_param(dump_buf, dump, "mfw-version", mfw_ver_str);
1803}
1804
1805/* Writes a section header to the specified buffer.
1806 * Returns the dumped size in dwords.
1807 */
1808static u32 qed_dump_section_hdr(u32 *dump_buf,
1809 bool dump, const char *name, u32 num_params)
1810{
1811 return qed_dump_num_param(dump_buf, dump, name, num_params);
1812}
1813
1814/* Writes the common global params to the specified buffer.
1815 * Returns the dumped size in dwords.
1816 */
1817static u32 qed_dump_common_global_params(struct qed_hwfn *p_hwfn,
1818 struct qed_ptt *p_ptt,
1819 u32 *dump_buf,
1820 bool dump,
1821 u8 num_specific_global_params)
1822{
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001823 u8 num_params = NUM_COMMON_GLOBAL_PARAMS + num_specific_global_params;
Tomer Tayarc965db42016-09-07 16:36:24 +03001824 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1825 u32 offset = 0;
1826
1827 /* Find platform string and dump global params section header */
1828 offset += qed_dump_section_hdr(dump_buf + offset,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02001829 dump, "global_params", num_params);
Tomer Tayarc965db42016-09-07 16:36:24 +03001830
1831 /* Store params */
1832 offset += qed_dump_fw_ver_param(p_hwfn, p_ptt, dump_buf + offset, dump);
1833 offset += qed_dump_mfw_ver_param(p_hwfn,
1834 p_ptt, dump_buf + offset, dump);
1835 offset += qed_dump_num_param(dump_buf + offset,
1836 dump, "tools-version", TOOLS_VERSION);
1837 offset += qed_dump_str_param(dump_buf + offset,
1838 dump,
1839 "chip",
1840 s_chip_defs[dev_data->chip_id].name);
1841 offset += qed_dump_str_param(dump_buf + offset,
1842 dump,
1843 "platform",
1844 s_platform_defs[dev_data->platform_id].
1845 name);
1846 offset +=
1847 qed_dump_num_param(dump_buf + offset, dump, "pci-func",
1848 p_hwfn->abs_pf_id);
1849 return offset;
1850}
1851
1852/* Writes the last section to the specified buffer at the given offset.
1853 * Returns the dumped size in dwords.
1854 */
1855static u32 qed_dump_last_section(u32 *dump_buf, u32 offset, bool dump)
1856{
1857 u32 start_offset = offset, crc = ~0;
1858
1859 /* Dump CRC section header */
1860 offset += qed_dump_section_hdr(dump_buf + offset, dump, "last", 0);
1861
1862 /* Calculate CRC32 and add it to the dword following the "last" section.
1863 */
1864 if (dump)
1865 *(dump_buf + offset) = ~crc32(crc, (u8 *)dump_buf,
1866 DWORDS_TO_BYTES(offset));
1867 offset++;
1868 return offset - start_offset;
1869}
1870
1871/* Update blocks reset state */
1872static void qed_update_blocks_reset_state(struct qed_hwfn *p_hwfn,
1873 struct qed_ptt *p_ptt)
1874{
1875 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1876 u32 reg_val[MAX_DBG_RESET_REGS] = { 0 };
1877 u32 i;
1878
1879 /* Read reset registers */
1880 for (i = 0; i < MAX_DBG_RESET_REGS; i++)
1881 if (s_reset_regs_defs[i].exists[dev_data->chip_id])
1882 reg_val[i] = qed_rd(p_hwfn,
1883 p_ptt, s_reset_regs_defs[i].addr);
1884
1885 /* Check if blocks are in reset */
1886 for (i = 0; i < MAX_BLOCK_ID; i++)
1887 dev_data->block_in_reset[i] =
1888 s_block_defs[i]->has_reset_bit &&
1889 !(reg_val[s_block_defs[i]->reset_reg] &
1890 BIT(s_block_defs[i]->reset_bit_offset));
1891}
1892
1893/* Enable / disable the Debug block */
1894static void qed_bus_enable_dbg_block(struct qed_hwfn *p_hwfn,
1895 struct qed_ptt *p_ptt, bool enable)
1896{
1897 qed_wr(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON, enable ? 1 : 0);
1898}
1899
1900/* Resets the Debug block */
1901static void qed_bus_reset_dbg_block(struct qed_hwfn *p_hwfn,
1902 struct qed_ptt *p_ptt)
1903{
1904 u32 dbg_reset_reg_addr, old_reset_reg_val, new_reset_reg_val;
1905
1906 dbg_reset_reg_addr =
1907 s_reset_regs_defs[s_block_defs[BLOCK_DBG]->reset_reg].addr;
1908 old_reset_reg_val = qed_rd(p_hwfn, p_ptt, dbg_reset_reg_addr);
1909 new_reset_reg_val = old_reset_reg_val &
1910 ~BIT(s_block_defs[BLOCK_DBG]->reset_bit_offset);
1911
1912 qed_wr(p_hwfn, p_ptt, dbg_reset_reg_addr, new_reset_reg_val);
1913 qed_wr(p_hwfn, p_ptt, dbg_reset_reg_addr, old_reset_reg_val);
1914}
1915
1916static void qed_bus_set_framing_mode(struct qed_hwfn *p_hwfn,
1917 struct qed_ptt *p_ptt,
1918 enum dbg_bus_frame_modes mode)
1919{
1920 qed_wr(p_hwfn, p_ptt, DBG_REG_FRAMING_MODE, (u8)mode);
1921}
1922
1923/* Enable / disable Debug Bus clients according to the specified mask.
1924 * (1 = enable, 0 = disable)
1925 */
1926static void qed_bus_enable_clients(struct qed_hwfn *p_hwfn,
1927 struct qed_ptt *p_ptt, u32 client_mask)
1928{
1929 qed_wr(p_hwfn, p_ptt, DBG_REG_CLIENT_ENABLE, client_mask);
1930}
1931
1932static bool qed_is_mode_match(struct qed_hwfn *p_hwfn, u16 *modes_buf_offset)
1933{
1934 const u32 *ptr = s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr;
1935 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1936 u8 tree_val = ((u8 *)ptr)[(*modes_buf_offset)++];
1937 bool arg1, arg2;
1938
1939 switch (tree_val) {
1940 case INIT_MODE_OP_NOT:
1941 return !qed_is_mode_match(p_hwfn, modes_buf_offset);
1942 case INIT_MODE_OP_OR:
1943 case INIT_MODE_OP_AND:
1944 arg1 = qed_is_mode_match(p_hwfn, modes_buf_offset);
1945 arg2 = qed_is_mode_match(p_hwfn, modes_buf_offset);
1946 return (tree_val == INIT_MODE_OP_OR) ? (arg1 ||
1947 arg2) : (arg1 && arg2);
1948 default:
1949 return dev_data->mode_enable[tree_val - MAX_INIT_MODE_OPS] > 0;
1950 }
1951}
1952
Tomer Tayarc965db42016-09-07 16:36:24 +03001953/* Returns true if the specified entity (indicated by GRC param) should be
1954 * included in the dump, false otherwise.
1955 */
1956static bool qed_grc_is_included(struct qed_hwfn *p_hwfn,
1957 enum dbg_grc_params grc_param)
1958{
1959 return qed_grc_get_param(p_hwfn, grc_param) > 0;
1960}
1961
1962/* Returns true of the specified Storm should be included in the dump, false
1963 * otherwise.
1964 */
1965static bool qed_grc_is_storm_included(struct qed_hwfn *p_hwfn,
1966 enum dbg_storms storm)
1967{
1968 return qed_grc_get_param(p_hwfn, (enum dbg_grc_params)storm) > 0;
1969}
1970
1971/* Returns true if the specified memory should be included in the dump, false
1972 * otherwise.
1973 */
1974static bool qed_grc_is_mem_included(struct qed_hwfn *p_hwfn,
1975 enum block_id block_id, u8 mem_group_id)
1976{
1977 u8 i;
1978
1979 /* Check Storm match */
1980 if (s_block_defs[block_id]->associated_to_storm &&
1981 !qed_grc_is_storm_included(p_hwfn,
1982 (enum dbg_storms)s_block_defs[block_id]->storm_id))
1983 return false;
1984
1985 for (i = 0; i < NUM_BIG_RAM_TYPES; i++)
1986 if (mem_group_id == s_big_ram_defs[i].mem_group_id ||
1987 mem_group_id == s_big_ram_defs[i].ram_mem_group_id)
1988 return qed_grc_is_included(p_hwfn,
1989 s_big_ram_defs[i].grc_param);
1990 if (mem_group_id == MEM_GROUP_PXP_ILT || mem_group_id ==
1991 MEM_GROUP_PXP_MEM)
1992 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PXP);
1993 if (mem_group_id == MEM_GROUP_RAM)
1994 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RAM);
1995 if (mem_group_id == MEM_GROUP_PBUF)
1996 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PBUF);
1997 if (mem_group_id == MEM_GROUP_CAU_MEM ||
1998 mem_group_id == MEM_GROUP_CAU_SB ||
1999 mem_group_id == MEM_GROUP_CAU_PI)
2000 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU);
2001 if (mem_group_id == MEM_GROUP_QM_MEM)
2002 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_QM);
2003 if (mem_group_id == MEM_GROUP_CONN_CFC_MEM ||
2004 mem_group_id == MEM_GROUP_TASK_CFC_MEM)
2005 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CFC);
2006 if (mem_group_id == MEM_GROUP_IGU_MEM || mem_group_id ==
2007 MEM_GROUP_IGU_MSIX)
2008 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IGU);
2009 if (mem_group_id == MEM_GROUP_MULD_MEM)
2010 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MULD);
2011 if (mem_group_id == MEM_GROUP_PRS_MEM)
2012 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PRS);
2013 if (mem_group_id == MEM_GROUP_DMAE_MEM)
2014 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DMAE);
2015 if (mem_group_id == MEM_GROUP_TM_MEM)
2016 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_TM);
2017 if (mem_group_id == MEM_GROUP_SDM_MEM)
2018 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_SDM);
2019 if (mem_group_id == MEM_GROUP_TDIF_CTX || mem_group_id ==
2020 MEM_GROUP_RDIF_CTX)
2021 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DIF);
2022 if (mem_group_id == MEM_GROUP_CM_MEM)
2023 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM);
2024 if (mem_group_id == MEM_GROUP_IOR)
2025 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IOR);
2026
2027 return true;
2028}
2029
2030/* Stalls all Storms */
2031static void qed_grc_stall_storms(struct qed_hwfn *p_hwfn,
2032 struct qed_ptt *p_ptt, bool stall)
2033{
2034 u8 reg_val = stall ? 1 : 0;
2035 u8 storm_id;
2036
2037 for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
2038 if (qed_grc_is_storm_included(p_hwfn,
2039 (enum dbg_storms)storm_id)) {
2040 u32 reg_addr =
2041 s_storm_defs[storm_id].sem_fast_mem_addr +
2042 SEM_FAST_REG_STALL_0;
2043
2044 qed_wr(p_hwfn, p_ptt, reg_addr, reg_val);
2045 }
2046 }
2047
2048 msleep(STALL_DELAY_MS);
2049}
2050
2051/* Takes all blocks out of reset */
2052static void qed_grc_unreset_blocks(struct qed_hwfn *p_hwfn,
2053 struct qed_ptt *p_ptt)
2054{
2055 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2056 u32 reg_val[MAX_DBG_RESET_REGS] = { 0 };
2057 u32 i;
2058
2059 /* Fill reset regs values */
2060 for (i = 0; i < MAX_BLOCK_ID; i++)
2061 if (s_block_defs[i]->has_reset_bit && s_block_defs[i]->unreset)
2062 reg_val[s_block_defs[i]->reset_reg] |=
2063 BIT(s_block_defs[i]->reset_bit_offset);
2064
2065 /* Write reset registers */
2066 for (i = 0; i < MAX_DBG_RESET_REGS; i++) {
2067 if (s_reset_regs_defs[i].exists[dev_data->chip_id]) {
2068 reg_val[i] |= s_reset_regs_defs[i].unreset_val;
2069 if (reg_val[i])
2070 qed_wr(p_hwfn,
2071 p_ptt,
2072 s_reset_regs_defs[i].addr +
2073 RESET_REG_UNRESET_OFFSET, reg_val[i]);
2074 }
2075 }
2076}
2077
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002078/* Returns the attention block data of the specified block */
Tomer Tayarc965db42016-09-07 16:36:24 +03002079static const struct dbg_attn_block_type_data *
2080qed_get_block_attn_data(enum block_id block_id, enum dbg_attn_type attn_type)
2081{
2082 const struct dbg_attn_block *base_attn_block_arr =
2083 (const struct dbg_attn_block *)
2084 s_dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr;
2085
2086 return &base_attn_block_arr[block_id].per_type_data[attn_type];
2087}
2088
2089/* Returns the attention registers of the specified block */
2090static const struct dbg_attn_reg *
2091qed_get_block_attn_regs(enum block_id block_id, enum dbg_attn_type attn_type,
2092 u8 *num_attn_regs)
2093{
2094 const struct dbg_attn_block_type_data *block_type_data =
2095 qed_get_block_attn_data(block_id, attn_type);
2096
2097 *num_attn_regs = block_type_data->num_regs;
2098 return &((const struct dbg_attn_reg *)
2099 s_dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)[block_type_data->
2100 regs_offset];
2101}
2102
2103/* For each block, clear the status of all parities */
2104static void qed_grc_clear_all_prty(struct qed_hwfn *p_hwfn,
2105 struct qed_ptt *p_ptt)
2106{
2107 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2108 u8 reg_idx, num_attn_regs;
2109 u32 block_id;
2110
2111 for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
2112 const struct dbg_attn_reg *attn_reg_arr;
2113
2114 if (dev_data->block_in_reset[block_id])
2115 continue;
2116
2117 attn_reg_arr = qed_get_block_attn_regs((enum block_id)block_id,
2118 ATTN_TYPE_PARITY,
2119 &num_attn_regs);
2120 for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
2121 const struct dbg_attn_reg *reg_data =
2122 &attn_reg_arr[reg_idx];
2123
2124 /* Check mode */
2125 bool eval_mode = GET_FIELD(reg_data->mode.data,
2126 DBG_MODE_HDR_EVAL_MODE) > 0;
2127 u16 modes_buf_offset =
2128 GET_FIELD(reg_data->mode.data,
2129 DBG_MODE_HDR_MODES_BUF_OFFSET);
2130
2131 if (!eval_mode ||
2132 qed_is_mode_match(p_hwfn, &modes_buf_offset))
2133 /* Mode match - read parity status read-clear
2134 * register.
2135 */
2136 qed_rd(p_hwfn, p_ptt,
2137 DWORDS_TO_BYTES(reg_data->
2138 sts_clr_address));
2139 }
2140 }
2141}
2142
2143/* Dumps GRC registers section header. Returns the dumped size in dwords.
2144 * The following parameters are dumped:
2145 * - 'count' = num_dumped_entries
2146 * - 'split' = split_type
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002147 * - 'id' = split_id (dumped only if split_id >= 0)
Tomer Tayarc965db42016-09-07 16:36:24 +03002148 * - 'param_name' = param_val (user param, dumped only if param_name != NULL and
2149 * param_val != NULL)
2150 */
2151static u32 qed_grc_dump_regs_hdr(u32 *dump_buf,
2152 bool dump,
2153 u32 num_reg_entries,
2154 const char *split_type,
2155 int split_id,
2156 const char *param_name, const char *param_val)
2157{
2158 u8 num_params = 2 + (split_id >= 0 ? 1 : 0) + (param_name ? 1 : 0);
2159 u32 offset = 0;
2160
2161 offset += qed_dump_section_hdr(dump_buf + offset,
2162 dump, "grc_regs", num_params);
2163 offset += qed_dump_num_param(dump_buf + offset,
2164 dump, "count", num_reg_entries);
2165 offset += qed_dump_str_param(dump_buf + offset,
2166 dump, "split", split_type);
2167 if (split_id >= 0)
2168 offset += qed_dump_num_param(dump_buf + offset,
2169 dump, "id", split_id);
2170 if (param_name && param_val)
2171 offset += qed_dump_str_param(dump_buf + offset,
2172 dump, param_name, param_val);
2173 return offset;
2174}
2175
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002176/* Dumps the GRC registers in the specified address range.
2177 * Returns the dumped size in dwords.
2178 */
2179static u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn,
2180 struct qed_ptt *p_ptt, u32 *dump_buf,
2181 bool dump, u32 addr, u32 len)
2182{
2183 u32 byte_addr = DWORDS_TO_BYTES(addr), offset = 0, i;
2184
2185 if (dump)
2186 for (i = 0; i < len; i++, byte_addr += BYTES_IN_DWORD, offset++)
2187 *(dump_buf + offset) = qed_rd(p_hwfn, p_ptt, byte_addr);
2188 else
2189 offset += len;
2190 return offset;
2191}
2192
2193/* Dumps GRC registers sequence header. Returns the dumped size in dwords. */
2194static u32 qed_grc_dump_reg_entry_hdr(u32 *dump_buf, bool dump, u32 addr,
2195 u32 len)
2196{
2197 if (dump)
2198 *dump_buf = addr | (len << REG_DUMP_LEN_SHIFT);
2199 return 1;
2200}
2201
2202/* Dumps GRC registers sequence. Returns the dumped size in dwords. */
Tomer Tayarc965db42016-09-07 16:36:24 +03002203static u32 qed_grc_dump_reg_entry(struct qed_hwfn *p_hwfn,
2204 struct qed_ptt *p_ptt, u32 *dump_buf,
2205 bool dump, u32 addr, u32 len)
2206{
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002207 u32 offset = 0;
Tomer Tayarc965db42016-09-07 16:36:24 +03002208
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002209 offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, len);
2210 offset += qed_grc_dump_addr_range(p_hwfn,
2211 p_ptt,
2212 dump_buf + offset, dump, addr, len);
2213 return offset;
2214}
2215
2216/* Dumps GRC registers sequence with skip cycle.
2217 * Returns the dumped size in dwords.
2218 */
2219static u32 qed_grc_dump_reg_entry_skip(struct qed_hwfn *p_hwfn,
2220 struct qed_ptt *p_ptt, u32 *dump_buf,
2221 bool dump, u32 addr, u32 total_len,
2222 u32 read_len, u32 skip_len)
2223{
2224 u32 offset = 0, reg_offset = 0;
2225
2226 offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, total_len);
Tomer Tayarc965db42016-09-07 16:36:24 +03002227 if (dump) {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002228 while (reg_offset < total_len) {
2229 u32 curr_len = min_t(u32,
2230 read_len,
2231 total_len - reg_offset);
2232 offset += qed_grc_dump_addr_range(p_hwfn,
2233 p_ptt,
2234 dump_buf + offset,
2235 dump, addr, curr_len);
2236 reg_offset += curr_len;
2237 addr += curr_len;
2238 if (reg_offset < total_len) {
2239 curr_len = min_t(u32,
2240 skip_len,
2241 total_len - skip_len);
2242 memset(dump_buf + offset, 0,
2243 DWORDS_TO_BYTES(curr_len));
2244 offset += curr_len;
2245 reg_offset += curr_len;
2246 addr += curr_len;
2247 }
2248 }
Tomer Tayarc965db42016-09-07 16:36:24 +03002249 } else {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002250 offset += total_len;
Tomer Tayarc965db42016-09-07 16:36:24 +03002251 }
2252
2253 return offset;
2254}
2255
2256/* Dumps GRC registers entries. Returns the dumped size in dwords. */
2257static u32 qed_grc_dump_regs_entries(struct qed_hwfn *p_hwfn,
2258 struct qed_ptt *p_ptt,
2259 struct dbg_array input_regs_arr,
2260 u32 *dump_buf,
2261 bool dump,
2262 bool block_enable[MAX_BLOCK_ID],
2263 u32 *num_dumped_reg_entries)
2264{
2265 u32 i, offset = 0, input_offset = 0;
2266 bool mode_match = true;
2267
2268 *num_dumped_reg_entries = 0;
2269 while (input_offset < input_regs_arr.size_in_dwords) {
2270 const struct dbg_dump_cond_hdr *cond_hdr =
2271 (const struct dbg_dump_cond_hdr *)
2272 &input_regs_arr.ptr[input_offset++];
2273 bool eval_mode = GET_FIELD(cond_hdr->mode.data,
2274 DBG_MODE_HDR_EVAL_MODE) > 0;
2275
2276 /* Check mode/block */
2277 if (eval_mode) {
2278 u16 modes_buf_offset =
2279 GET_FIELD(cond_hdr->mode.data,
2280 DBG_MODE_HDR_MODES_BUF_OFFSET);
2281 mode_match = qed_is_mode_match(p_hwfn,
2282 &modes_buf_offset);
2283 }
2284
2285 if (mode_match && block_enable[cond_hdr->block_id]) {
2286 for (i = 0; i < cond_hdr->data_size;
2287 i++, input_offset++) {
2288 const struct dbg_dump_reg *reg =
2289 (const struct dbg_dump_reg *)
2290 &input_regs_arr.ptr[input_offset];
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002291 u32 addr, len;
Tomer Tayarc965db42016-09-07 16:36:24 +03002292
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002293 addr = GET_FIELD(reg->data,
2294 DBG_DUMP_REG_ADDRESS);
2295 len = GET_FIELD(reg->data, DBG_DUMP_REG_LENGTH);
Tomer Tayarc965db42016-09-07 16:36:24 +03002296 offset +=
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002297 qed_grc_dump_reg_entry(p_hwfn, p_ptt,
2298 dump_buf + offset,
2299 dump,
2300 addr,
2301 len);
Tomer Tayarc965db42016-09-07 16:36:24 +03002302 (*num_dumped_reg_entries)++;
2303 }
2304 } else {
2305 input_offset += cond_hdr->data_size;
2306 }
2307 }
2308
2309 return offset;
2310}
2311
2312/* Dumps GRC registers entries. Returns the dumped size in dwords. */
2313static u32 qed_grc_dump_split_data(struct qed_hwfn *p_hwfn,
2314 struct qed_ptt *p_ptt,
2315 struct dbg_array input_regs_arr,
2316 u32 *dump_buf,
2317 bool dump,
2318 bool block_enable[MAX_BLOCK_ID],
2319 const char *split_type_name,
2320 u32 split_id,
2321 const char *param_name,
2322 const char *param_val)
2323{
2324 u32 num_dumped_reg_entries, offset;
2325
2326 /* Calculate register dump header size (and skip it for now) */
2327 offset = qed_grc_dump_regs_hdr(dump_buf,
2328 false,
2329 0,
2330 split_type_name,
2331 split_id, param_name, param_val);
2332
2333 /* Dump registers */
2334 offset += qed_grc_dump_regs_entries(p_hwfn,
2335 p_ptt,
2336 input_regs_arr,
2337 dump_buf + offset,
2338 dump,
2339 block_enable,
2340 &num_dumped_reg_entries);
2341
2342 /* Write register dump header */
2343 if (dump && num_dumped_reg_entries > 0)
2344 qed_grc_dump_regs_hdr(dump_buf,
2345 dump,
2346 num_dumped_reg_entries,
2347 split_type_name,
2348 split_id, param_name, param_val);
2349
2350 return num_dumped_reg_entries > 0 ? offset : 0;
2351}
2352
2353/* Dumps registers according to the input registers array.
2354 * Returns the dumped size in dwords.
2355 */
2356static u32 qed_grc_dump_registers(struct qed_hwfn *p_hwfn,
2357 struct qed_ptt *p_ptt,
2358 u32 *dump_buf,
2359 bool dump,
2360 bool block_enable[MAX_BLOCK_ID],
2361 const char *param_name, const char *param_val)
2362{
2363 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002364 struct chip_platform_defs *p_platform_defs;
Tomer Tayarc965db42016-09-07 16:36:24 +03002365 u32 offset = 0, input_offset = 0;
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002366 struct chip_defs *p_chip_defs;
2367 u8 port_id, pf_id, vf_id;
2368 u16 fid;
2369
2370 p_chip_defs = &s_chip_defs[dev_data->chip_id];
2371 p_platform_defs = &p_chip_defs->per_platform[dev_data->platform_id];
Tomer Tayarc965db42016-09-07 16:36:24 +03002372
2373 if (dump)
2374 DP_VERBOSE(p_hwfn, QED_MSG_DEBUG, "Dumping registers...\n");
2375 while (input_offset <
2376 s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].size_in_dwords) {
2377 const struct dbg_dump_split_hdr *split_hdr =
2378 (const struct dbg_dump_split_hdr *)
2379 &s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr[input_offset++];
2380 u8 split_type_id = GET_FIELD(split_hdr->hdr,
2381 DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
2382 u32 split_data_size = GET_FIELD(split_hdr->hdr,
2383 DBG_DUMP_SPLIT_HDR_DATA_SIZE);
2384 struct dbg_array curr_input_regs_arr = {
2385 &s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr[input_offset],
2386 split_data_size};
2387
2388 switch (split_type_id) {
2389 case SPLIT_TYPE_NONE:
Tomer Tayarc965db42016-09-07 16:36:24 +03002390 offset += qed_grc_dump_split_data(p_hwfn,
2391 p_ptt,
2392 curr_input_regs_arr,
2393 dump_buf + offset,
2394 dump,
2395 block_enable,
2396 "eng",
2397 (u32)(-1),
2398 param_name,
2399 param_val);
2400 break;
2401 case SPLIT_TYPE_PORT:
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002402 for (port_id = 0; port_id < p_platform_defs->num_ports;
Tomer Tayarc965db42016-09-07 16:36:24 +03002403 port_id++) {
2404 if (dump)
2405 qed_port_pretend(p_hwfn, p_ptt,
2406 port_id);
2407 offset +=
2408 qed_grc_dump_split_data(p_hwfn, p_ptt,
2409 curr_input_regs_arr,
2410 dump_buf + offset,
2411 dump, block_enable,
2412 "port", port_id,
2413 param_name,
2414 param_val);
2415 }
2416 break;
2417 case SPLIT_TYPE_PF:
2418 case SPLIT_TYPE_PORT_PF:
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002419 for (pf_id = 0; pf_id < p_platform_defs->num_pfs;
Tomer Tayarc965db42016-09-07 16:36:24 +03002420 pf_id++) {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002421 u8 pfid_shift =
2422 PXP_PRETEND_CONCRETE_FID_PFID_SHIFT;
2423
2424 if (dump) {
2425 fid = pf_id << pfid_shift;
2426 qed_fid_pretend(p_hwfn, p_ptt, fid);
2427 }
2428
2429 offset +=
2430 qed_grc_dump_split_data(p_hwfn, p_ptt,
2431 curr_input_regs_arr,
2432 dump_buf + offset,
2433 dump, block_enable,
2434 "pf", pf_id,
2435 param_name,
2436 param_val);
2437 }
2438 break;
2439 case SPLIT_TYPE_VF:
2440 for (vf_id = 0; vf_id < p_platform_defs->num_vfs;
2441 vf_id++) {
2442 u8 vfvalid_shift =
2443 PXP_PRETEND_CONCRETE_FID_VFVALID_SHIFT;
2444 u8 vfid_shift =
2445 PXP_PRETEND_CONCRETE_FID_VFID_SHIFT;
2446
2447 if (dump) {
2448 fid = BIT(vfvalid_shift) |
2449 (vf_id << vfid_shift);
2450 qed_fid_pretend(p_hwfn, p_ptt, fid);
2451 }
2452
2453 offset +=
2454 qed_grc_dump_split_data(p_hwfn, p_ptt,
2455 curr_input_regs_arr,
2456 dump_buf + offset,
2457 dump, block_enable,
2458 "vf", vf_id,
2459 param_name,
2460 param_val);
Tomer Tayarc965db42016-09-07 16:36:24 +03002461 }
2462 break;
2463 default:
2464 break;
2465 }
2466
2467 input_offset += split_data_size;
2468 }
2469
2470 /* Pretend to original PF */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002471 if (dump) {
2472 fid = p_hwfn->rel_pf_id << PXP_PRETEND_CONCRETE_FID_PFID_SHIFT;
2473 qed_fid_pretend(p_hwfn, p_ptt, fid);
2474 }
2475
Tomer Tayarc965db42016-09-07 16:36:24 +03002476 return offset;
2477}
2478
2479/* Dump reset registers. Returns the dumped size in dwords. */
2480static u32 qed_grc_dump_reset_regs(struct qed_hwfn *p_hwfn,
2481 struct qed_ptt *p_ptt,
2482 u32 *dump_buf, bool dump)
2483{
2484 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2485 u32 i, offset = 0, num_regs = 0;
2486
2487 /* Calculate header size */
2488 offset += qed_grc_dump_regs_hdr(dump_buf,
2489 false, 0, "eng", -1, NULL, NULL);
2490
2491 /* Write reset registers */
2492 for (i = 0; i < MAX_DBG_RESET_REGS; i++) {
2493 if (s_reset_regs_defs[i].exists[dev_data->chip_id]) {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002494 u32 addr = BYTES_TO_DWORDS(s_reset_regs_defs[i].addr);
2495
Tomer Tayarc965db42016-09-07 16:36:24 +03002496 offset += qed_grc_dump_reg_entry(p_hwfn,
2497 p_ptt,
2498 dump_buf + offset,
2499 dump,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002500 addr,
2501 1);
Tomer Tayarc965db42016-09-07 16:36:24 +03002502 num_regs++;
2503 }
2504 }
2505
2506 /* Write header */
2507 if (dump)
2508 qed_grc_dump_regs_hdr(dump_buf,
2509 true, num_regs, "eng", -1, NULL, NULL);
2510 return offset;
2511}
2512
2513/* Dump registers that are modified during GRC Dump and therefore must be dumped
2514 * first. Returns the dumped size in dwords.
2515 */
2516static u32 qed_grc_dump_modified_regs(struct qed_hwfn *p_hwfn,
2517 struct qed_ptt *p_ptt,
2518 u32 *dump_buf, bool dump)
2519{
2520 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2521 u32 offset = 0, num_reg_entries = 0, block_id;
2522 u8 storm_id, reg_idx, num_attn_regs;
2523
2524 /* Calculate header size */
2525 offset += qed_grc_dump_regs_hdr(dump_buf,
2526 false, 0, "eng", -1, NULL, NULL);
2527
2528 /* Write parity registers */
2529 for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
2530 const struct dbg_attn_reg *attn_reg_arr;
2531
2532 if (dev_data->block_in_reset[block_id] && dump)
2533 continue;
2534
2535 attn_reg_arr = qed_get_block_attn_regs((enum block_id)block_id,
2536 ATTN_TYPE_PARITY,
2537 &num_attn_regs);
2538 for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
2539 const struct dbg_attn_reg *reg_data =
2540 &attn_reg_arr[reg_idx];
2541 u16 modes_buf_offset;
2542 bool eval_mode;
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002543 u32 addr;
Tomer Tayarc965db42016-09-07 16:36:24 +03002544
2545 /* Check mode */
2546 eval_mode = GET_FIELD(reg_data->mode.data,
2547 DBG_MODE_HDR_EVAL_MODE) > 0;
2548 modes_buf_offset =
2549 GET_FIELD(reg_data->mode.data,
2550 DBG_MODE_HDR_MODES_BUF_OFFSET);
2551 if (!eval_mode ||
2552 qed_is_mode_match(p_hwfn, &modes_buf_offset)) {
2553 /* Mode match - read and dump registers */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002554 addr = reg_data->mask_address;
2555 offset +=
2556 qed_grc_dump_reg_entry(p_hwfn,
2557 p_ptt,
2558 dump_buf + offset,
2559 dump,
2560 addr,
2561 1);
2562 addr = GET_FIELD(reg_data->data,
2563 DBG_ATTN_REG_STS_ADDRESS);
2564 offset +=
2565 qed_grc_dump_reg_entry(p_hwfn,
2566 p_ptt,
2567 dump_buf + offset,
2568 dump,
2569 addr,
2570 1);
Tomer Tayarc965db42016-09-07 16:36:24 +03002571 num_reg_entries += 2;
2572 }
2573 }
2574 }
2575
2576 /* Write storm stall status registers */
2577 for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002578 u32 addr;
2579
Tomer Tayarc965db42016-09-07 16:36:24 +03002580 if (dev_data->block_in_reset[s_storm_defs[storm_id].block_id] &&
2581 dump)
2582 continue;
2583
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002584 addr =
2585 BYTES_TO_DWORDS(s_storm_defs[storm_id].sem_fast_mem_addr +
2586 SEM_FAST_REG_STALLED);
Tomer Tayarc965db42016-09-07 16:36:24 +03002587 offset += qed_grc_dump_reg_entry(p_hwfn,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002588 p_ptt,
2589 dump_buf + offset,
2590 dump,
2591 addr,
2592 1);
Tomer Tayarc965db42016-09-07 16:36:24 +03002593 num_reg_entries++;
2594 }
2595
2596 /* Write header */
2597 if (dump)
2598 qed_grc_dump_regs_hdr(dump_buf,
2599 true,
2600 num_reg_entries, "eng", -1, NULL, NULL);
2601 return offset;
2602}
2603
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002604/* Dumps registers that can't be represented in the debug arrays */
2605static u32 qed_grc_dump_special_regs(struct qed_hwfn *p_hwfn,
2606 struct qed_ptt *p_ptt,
2607 u32 *dump_buf, bool dump)
2608{
2609 u32 offset = 0, addr;
2610
2611 offset += qed_grc_dump_regs_hdr(dump_buf,
2612 dump, 2, "eng", -1, NULL, NULL);
2613
2614 /* Dump R/TDIF_REG_DEBUG_ERROR_INFO_SIZE (every 8'th register should be
2615 * skipped).
2616 */
2617 addr = BYTES_TO_DWORDS(RDIF_REG_DEBUG_ERROR_INFO);
2618 offset += qed_grc_dump_reg_entry_skip(p_hwfn,
2619 p_ptt,
2620 dump_buf + offset,
2621 dump,
2622 addr,
2623 RDIF_REG_DEBUG_ERROR_INFO_SIZE,
2624 7,
2625 1);
2626 addr = BYTES_TO_DWORDS(TDIF_REG_DEBUG_ERROR_INFO);
2627 offset +=
2628 qed_grc_dump_reg_entry_skip(p_hwfn,
2629 p_ptt,
2630 dump_buf + offset,
2631 dump,
2632 addr,
2633 TDIF_REG_DEBUG_ERROR_INFO_SIZE,
2634 7,
2635 1);
2636
2637 return offset;
2638}
2639
Tomer Tayarc965db42016-09-07 16:36:24 +03002640/* Dumps a GRC memory header (section and params).
2641 * The following parameters are dumped:
2642 * name - name is dumped only if it's not NULL.
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002643 * addr - addr is dumped only if name is NULL.
2644 * len - len is always dumped.
Tomer Tayarc965db42016-09-07 16:36:24 +03002645 * width - bit_width is dumped if it's not zero.
2646 * packed - packed=1 is dumped if it's not false.
2647 * mem_group - mem_group is always dumped.
2648 * is_storm - true only if the memory is related to a Storm.
2649 * storm_letter - storm letter (valid only if is_storm is true).
2650 * Returns the dumped size in dwords.
2651 */
2652static u32 qed_grc_dump_mem_hdr(struct qed_hwfn *p_hwfn,
2653 u32 *dump_buf,
2654 bool dump,
2655 const char *name,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002656 u32 addr,
2657 u32 len,
Tomer Tayarc965db42016-09-07 16:36:24 +03002658 u32 bit_width,
2659 bool packed,
2660 const char *mem_group,
2661 bool is_storm, char storm_letter)
2662{
2663 u8 num_params = 3;
2664 u32 offset = 0;
2665 char buf[64];
2666
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002667 if (!len)
Tomer Tayarc965db42016-09-07 16:36:24 +03002668 DP_NOTICE(p_hwfn,
2669 "Unexpected GRC Dump error: dumped memory size must be non-zero\n");
2670 if (bit_width)
2671 num_params++;
2672 if (packed)
2673 num_params++;
2674
2675 /* Dump section header */
2676 offset += qed_dump_section_hdr(dump_buf + offset,
2677 dump, "grc_mem", num_params);
2678 if (name) {
2679 /* Dump name */
2680 if (is_storm) {
2681 strcpy(buf, "?STORM_");
2682 buf[0] = storm_letter;
2683 strcpy(buf + strlen(buf), name);
2684 } else {
2685 strcpy(buf, name);
2686 }
2687
2688 offset += qed_dump_str_param(dump_buf + offset,
2689 dump, "name", buf);
2690 if (dump)
2691 DP_VERBOSE(p_hwfn,
2692 QED_MSG_DEBUG,
2693 "Dumping %d registers from %s...\n",
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002694 len, buf);
Tomer Tayarc965db42016-09-07 16:36:24 +03002695 } else {
2696 /* Dump address */
2697 offset += qed_dump_num_param(dump_buf + offset,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002698 dump, "addr",
2699 DWORDS_TO_BYTES(addr));
2700 if (dump && len > 64)
Tomer Tayarc965db42016-09-07 16:36:24 +03002701 DP_VERBOSE(p_hwfn,
2702 QED_MSG_DEBUG,
2703 "Dumping %d registers from address 0x%x...\n",
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002704 len, (u32)DWORDS_TO_BYTES(addr));
Tomer Tayarc965db42016-09-07 16:36:24 +03002705 }
2706
2707 /* Dump len */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002708 offset += qed_dump_num_param(dump_buf + offset, dump, "len", len);
Tomer Tayarc965db42016-09-07 16:36:24 +03002709
2710 /* Dump bit width */
2711 if (bit_width)
2712 offset += qed_dump_num_param(dump_buf + offset,
2713 dump, "width", bit_width);
2714
2715 /* Dump packed */
2716 if (packed)
2717 offset += qed_dump_num_param(dump_buf + offset,
2718 dump, "packed", 1);
2719
2720 /* Dump reg type */
2721 if (is_storm) {
2722 strcpy(buf, "?STORM_");
2723 buf[0] = storm_letter;
2724 strcpy(buf + strlen(buf), mem_group);
2725 } else {
2726 strcpy(buf, mem_group);
2727 }
2728
2729 offset += qed_dump_str_param(dump_buf + offset, dump, "type", buf);
2730 return offset;
2731}
2732
2733/* Dumps a single GRC memory. If name is NULL, the memory is stored by address.
2734 * Returns the dumped size in dwords.
2735 */
2736static u32 qed_grc_dump_mem(struct qed_hwfn *p_hwfn,
2737 struct qed_ptt *p_ptt,
2738 u32 *dump_buf,
2739 bool dump,
2740 const char *name,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002741 u32 addr,
2742 u32 len,
Tomer Tayarc965db42016-09-07 16:36:24 +03002743 u32 bit_width,
2744 bool packed,
2745 const char *mem_group,
2746 bool is_storm, char storm_letter)
2747{
2748 u32 offset = 0;
2749
2750 offset += qed_grc_dump_mem_hdr(p_hwfn,
2751 dump_buf + offset,
2752 dump,
2753 name,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002754 addr,
2755 len,
Tomer Tayarc965db42016-09-07 16:36:24 +03002756 bit_width,
2757 packed,
2758 mem_group, is_storm, storm_letter);
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002759 offset += qed_grc_dump_addr_range(p_hwfn,
2760 p_ptt,
2761 dump_buf + offset, dump, addr, len);
Tomer Tayarc965db42016-09-07 16:36:24 +03002762 return offset;
2763}
2764
2765/* Dumps GRC memories entries. Returns the dumped size in dwords. */
2766static u32 qed_grc_dump_mem_entries(struct qed_hwfn *p_hwfn,
2767 struct qed_ptt *p_ptt,
2768 struct dbg_array input_mems_arr,
2769 u32 *dump_buf, bool dump)
2770{
2771 u32 i, offset = 0, input_offset = 0;
2772 bool mode_match = true;
2773
2774 while (input_offset < input_mems_arr.size_in_dwords) {
2775 const struct dbg_dump_cond_hdr *cond_hdr;
2776 u32 num_entries;
2777 bool eval_mode;
2778
2779 cond_hdr = (const struct dbg_dump_cond_hdr *)
2780 &input_mems_arr.ptr[input_offset++];
2781 eval_mode = GET_FIELD(cond_hdr->mode.data,
2782 DBG_MODE_HDR_EVAL_MODE) > 0;
2783
2784 /* Check required mode */
2785 if (eval_mode) {
2786 u16 modes_buf_offset =
2787 GET_FIELD(cond_hdr->mode.data,
2788 DBG_MODE_HDR_MODES_BUF_OFFSET);
2789
2790 mode_match = qed_is_mode_match(p_hwfn,
2791 &modes_buf_offset);
2792 }
2793
2794 if (!mode_match) {
2795 input_offset += cond_hdr->data_size;
2796 continue;
2797 }
2798
2799 num_entries = cond_hdr->data_size / MEM_DUMP_ENTRY_SIZE_DWORDS;
2800 for (i = 0; i < num_entries;
2801 i++, input_offset += MEM_DUMP_ENTRY_SIZE_DWORDS) {
2802 const struct dbg_dump_mem *mem =
2803 (const struct dbg_dump_mem *)
2804 &input_mems_arr.ptr[input_offset];
2805 u8 mem_group_id;
2806
2807 mem_group_id = GET_FIELD(mem->dword0,
2808 DBG_DUMP_MEM_MEM_GROUP_ID);
2809 if (mem_group_id >= MEM_GROUPS_NUM) {
2810 DP_NOTICE(p_hwfn, "Invalid mem_group_id\n");
2811 return 0;
2812 }
2813
2814 if (qed_grc_is_mem_included(p_hwfn,
2815 (enum block_id)cond_hdr->block_id,
2816 mem_group_id)) {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002817 u32 mem_addr = GET_FIELD(mem->dword0,
2818 DBG_DUMP_MEM_ADDRESS);
Tomer Tayarc965db42016-09-07 16:36:24 +03002819 u32 mem_len = GET_FIELD(mem->dword1,
2820 DBG_DUMP_MEM_LENGTH);
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002821 enum dbg_grc_params grc_param;
Tomer Tayarc965db42016-09-07 16:36:24 +03002822 char storm_letter = 'a';
2823 bool is_storm = false;
2824
2825 /* Update memory length for CCFC/TCFC memories
2826 * according to number of LCIDs/LTIDs.
2827 */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002828 if (mem_group_id == MEM_GROUP_CONN_CFC_MEM) {
2829 if (mem_len % MAX_LCIDS != 0) {
2830 DP_NOTICE(p_hwfn,
2831 "Invalid CCFC connection memory size\n");
2832 return 0;
2833 }
2834
2835 grc_param = DBG_GRC_PARAM_NUM_LCIDS;
Tomer Tayarc965db42016-09-07 16:36:24 +03002836 mem_len = qed_grc_get_param(p_hwfn,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002837 grc_param) *
2838 (mem_len / MAX_LCIDS);
2839 } else if (mem_group_id ==
2840 MEM_GROUP_TASK_CFC_MEM) {
2841 if (mem_len % MAX_LTIDS != 0) {
2842 DP_NOTICE(p_hwfn,
2843 "Invalid TCFC task memory size\n");
2844 return 0;
2845 }
2846
2847 grc_param = DBG_GRC_PARAM_NUM_LTIDS;
Tomer Tayarc965db42016-09-07 16:36:24 +03002848 mem_len = qed_grc_get_param(p_hwfn,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002849 grc_param) *
2850 (mem_len / MAX_LTIDS);
2851 }
Tomer Tayarc965db42016-09-07 16:36:24 +03002852
2853 /* If memory is associated with Storm, update
2854 * Storm details.
2855 */
2856 if (s_block_defs[cond_hdr->block_id]->
2857 associated_to_storm) {
2858 is_storm = true;
2859 storm_letter =
2860 s_storm_defs[s_block_defs[
2861 cond_hdr->block_id]->
2862 storm_id].letter;
2863 }
2864
2865 /* Dump memory */
2866 offset += qed_grc_dump_mem(p_hwfn, p_ptt,
2867 dump_buf + offset, dump, NULL,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02002868 mem_addr, mem_len, 0,
Tomer Tayarc965db42016-09-07 16:36:24 +03002869 false,
2870 s_mem_group_names[mem_group_id],
2871 is_storm, storm_letter);
2872 }
2873 }
2874 }
2875
2876 return offset;
2877}
2878
2879/* Dumps GRC memories according to the input array dump_mem.
2880 * Returns the dumped size in dwords.
2881 */
2882static u32 qed_grc_dump_memories(struct qed_hwfn *p_hwfn,
2883 struct qed_ptt *p_ptt,
2884 u32 *dump_buf, bool dump)
2885{
2886 u32 offset = 0, input_offset = 0;
2887
2888 while (input_offset <
2889 s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].size_in_dwords) {
2890 const struct dbg_dump_split_hdr *split_hdr =
2891 (const struct dbg_dump_split_hdr *)
2892 &s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr[input_offset++];
2893 u8 split_type_id = GET_FIELD(split_hdr->hdr,
2894 DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
2895 u32 split_data_size = GET_FIELD(split_hdr->hdr,
2896 DBG_DUMP_SPLIT_HDR_DATA_SIZE);
2897 struct dbg_array curr_input_mems_arr = {
2898 &s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr[input_offset],
2899 split_data_size};
2900
2901 switch (split_type_id) {
2902 case SPLIT_TYPE_NONE:
2903 offset += qed_grc_dump_mem_entries(p_hwfn,
2904 p_ptt,
2905 curr_input_mems_arr,
2906 dump_buf + offset,
2907 dump);
2908 break;
2909 default:
2910 DP_NOTICE(p_hwfn,
2911 "Dumping split memories is currently not supported\n");
2912 break;
2913 }
2914
2915 input_offset += split_data_size;
2916 }
2917
2918 return offset;
2919}
2920
2921/* Dumps GRC context data for the specified Storm.
2922 * Returns the dumped size in dwords.
2923 */
2924static u32 qed_grc_dump_ctx_data(struct qed_hwfn *p_hwfn,
2925 struct qed_ptt *p_ptt,
2926 u32 *dump_buf,
2927 bool dump,
2928 const char *name,
2929 u32 num_lids,
2930 u32 lid_size,
2931 u32 rd_reg_addr,
2932 u8 storm_id)
2933{
2934 u32 i, lid, total_size;
2935 u32 offset = 0;
2936
2937 if (!lid_size)
2938 return 0;
2939 lid_size *= BYTES_IN_DWORD;
2940 total_size = num_lids * lid_size;
2941 offset += qed_grc_dump_mem_hdr(p_hwfn,
2942 dump_buf + offset,
2943 dump,
2944 name,
2945 0,
2946 total_size,
2947 lid_size * 32,
2948 false,
2949 name,
2950 true, s_storm_defs[storm_id].letter);
2951
2952 /* Dump context data */
2953 if (dump) {
2954 for (lid = 0; lid < num_lids; lid++) {
2955 for (i = 0; i < lid_size; i++, offset++) {
2956 qed_wr(p_hwfn,
2957 p_ptt,
2958 s_storm_defs[storm_id].cm_ctx_wr_addr,
2959 BIT(9) | lid);
2960 *(dump_buf + offset) = qed_rd(p_hwfn,
2961 p_ptt,
2962 rd_reg_addr);
2963 }
2964 }
2965 } else {
2966 offset += total_size;
2967 }
2968
2969 return offset;
2970}
2971
2972/* Dumps GRC contexts. Returns the dumped size in dwords. */
2973static u32 qed_grc_dump_ctx(struct qed_hwfn *p_hwfn,
2974 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
2975{
2976 u32 offset = 0;
2977 u8 storm_id;
2978
2979 for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
2980 if (!qed_grc_is_storm_included(p_hwfn,
2981 (enum dbg_storms)storm_id))
2982 continue;
2983
2984 /* Dump Conn AG context size */
2985 offset +=
2986 qed_grc_dump_ctx_data(p_hwfn,
2987 p_ptt,
2988 dump_buf + offset,
2989 dump,
2990 "CONN_AG_CTX",
2991 qed_grc_get_param(p_hwfn,
2992 DBG_GRC_PARAM_NUM_LCIDS),
2993 s_storm_defs[storm_id].
2994 cm_conn_ag_ctx_lid_size,
2995 s_storm_defs[storm_id].
2996 cm_conn_ag_ctx_rd_addr,
2997 storm_id);
2998
2999 /* Dump Conn ST context size */
3000 offset +=
3001 qed_grc_dump_ctx_data(p_hwfn,
3002 p_ptt,
3003 dump_buf + offset,
3004 dump,
3005 "CONN_ST_CTX",
3006 qed_grc_get_param(p_hwfn,
3007 DBG_GRC_PARAM_NUM_LCIDS),
3008 s_storm_defs[storm_id].
3009 cm_conn_st_ctx_lid_size,
3010 s_storm_defs[storm_id].
3011 cm_conn_st_ctx_rd_addr,
3012 storm_id);
3013
3014 /* Dump Task AG context size */
3015 offset +=
3016 qed_grc_dump_ctx_data(p_hwfn,
3017 p_ptt,
3018 dump_buf + offset,
3019 dump,
3020 "TASK_AG_CTX",
3021 qed_grc_get_param(p_hwfn,
3022 DBG_GRC_PARAM_NUM_LTIDS),
3023 s_storm_defs[storm_id].
3024 cm_task_ag_ctx_lid_size,
3025 s_storm_defs[storm_id].
3026 cm_task_ag_ctx_rd_addr,
3027 storm_id);
3028
3029 /* Dump Task ST context size */
3030 offset +=
3031 qed_grc_dump_ctx_data(p_hwfn,
3032 p_ptt,
3033 dump_buf + offset,
3034 dump,
3035 "TASK_ST_CTX",
3036 qed_grc_get_param(p_hwfn,
3037 DBG_GRC_PARAM_NUM_LTIDS),
3038 s_storm_defs[storm_id].
3039 cm_task_st_ctx_lid_size,
3040 s_storm_defs[storm_id].
3041 cm_task_st_ctx_rd_addr,
3042 storm_id);
3043 }
3044
3045 return offset;
3046}
3047
3048/* Dumps GRC IORs data. Returns the dumped size in dwords. */
3049static u32 qed_grc_dump_iors(struct qed_hwfn *p_hwfn,
3050 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3051{
3052 char buf[10] = "IOR_SET_?";
3053 u8 storm_id, set_id;
3054 u32 offset = 0;
3055
3056 for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003057 struct storm_defs *storm = &s_storm_defs[storm_id];
Tomer Tayarc965db42016-09-07 16:36:24 +03003058
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003059 if (!qed_grc_is_storm_included(p_hwfn,
3060 (enum dbg_storms)storm_id))
3061 continue;
3062
3063 for (set_id = 0; set_id < NUM_IOR_SETS; set_id++) {
3064 u32 dwords, addr;
3065
3066 dwords = storm->sem_fast_mem_addr +
3067 SEM_FAST_REG_STORM_REG_FILE;
3068 addr = BYTES_TO_DWORDS(dwords) + IOR_SET_OFFSET(set_id);
3069 buf[strlen(buf) - 1] = '0' + set_id;
3070 offset += qed_grc_dump_mem(p_hwfn,
3071 p_ptt,
3072 dump_buf + offset,
3073 dump,
3074 buf,
3075 addr,
3076 IORS_PER_SET,
3077 32,
3078 false,
3079 "ior",
3080 true,
3081 storm->letter);
Tomer Tayarc965db42016-09-07 16:36:24 +03003082 }
3083 }
3084
3085 return offset;
3086}
3087
3088/* Dump VFC CAM. Returns the dumped size in dwords. */
3089static u32 qed_grc_dump_vfc_cam(struct qed_hwfn *p_hwfn,
3090 struct qed_ptt *p_ptt,
3091 u32 *dump_buf, bool dump, u8 storm_id)
3092{
3093 u32 total_size = VFC_CAM_NUM_ROWS * VFC_CAM_RESP_DWORDS;
3094 u32 cam_addr[VFC_CAM_ADDR_DWORDS] = { 0 };
3095 u32 cam_cmd[VFC_CAM_CMD_DWORDS] = { 0 };
3096 u32 offset = 0;
3097 u32 row, i;
3098
3099 offset += qed_grc_dump_mem_hdr(p_hwfn,
3100 dump_buf + offset,
3101 dump,
3102 "vfc_cam",
3103 0,
3104 total_size,
3105 256,
3106 false,
3107 "vfc_cam",
3108 true, s_storm_defs[storm_id].letter);
3109 if (dump) {
3110 /* Prepare CAM address */
3111 SET_VAR_FIELD(cam_addr, VFC_CAM_ADDR, OP, VFC_OPCODE_CAM_RD);
3112 for (row = 0; row < VFC_CAM_NUM_ROWS;
3113 row++, offset += VFC_CAM_RESP_DWORDS) {
3114 /* Write VFC CAM command */
3115 SET_VAR_FIELD(cam_cmd, VFC_CAM_CMD, ROW, row);
3116 ARR_REG_WR(p_hwfn,
3117 p_ptt,
3118 s_storm_defs[storm_id].sem_fast_mem_addr +
3119 SEM_FAST_REG_VFC_DATA_WR,
3120 cam_cmd, VFC_CAM_CMD_DWORDS);
3121
3122 /* Write VFC CAM address */
3123 ARR_REG_WR(p_hwfn,
3124 p_ptt,
3125 s_storm_defs[storm_id].sem_fast_mem_addr +
3126 SEM_FAST_REG_VFC_ADDR,
3127 cam_addr, VFC_CAM_ADDR_DWORDS);
3128
3129 /* Read VFC CAM read response */
3130 ARR_REG_RD(p_hwfn,
3131 p_ptt,
3132 s_storm_defs[storm_id].sem_fast_mem_addr +
3133 SEM_FAST_REG_VFC_DATA_RD,
3134 dump_buf + offset, VFC_CAM_RESP_DWORDS);
3135 }
3136 } else {
3137 offset += total_size;
3138 }
3139
3140 return offset;
3141}
3142
3143/* Dump VFC RAM. Returns the dumped size in dwords. */
3144static u32 qed_grc_dump_vfc_ram(struct qed_hwfn *p_hwfn,
3145 struct qed_ptt *p_ptt,
3146 u32 *dump_buf,
3147 bool dump,
3148 u8 storm_id, struct vfc_ram_defs *ram_defs)
3149{
3150 u32 total_size = ram_defs->num_rows * VFC_RAM_RESP_DWORDS;
3151 u32 ram_addr[VFC_RAM_ADDR_DWORDS] = { 0 };
3152 u32 ram_cmd[VFC_RAM_CMD_DWORDS] = { 0 };
3153 u32 offset = 0;
3154 u32 row, i;
3155
3156 offset += qed_grc_dump_mem_hdr(p_hwfn,
3157 dump_buf + offset,
3158 dump,
3159 ram_defs->mem_name,
3160 0,
3161 total_size,
3162 256,
3163 false,
3164 ram_defs->type_name,
3165 true, s_storm_defs[storm_id].letter);
3166
3167 /* Prepare RAM address */
3168 SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, OP, VFC_OPCODE_RAM_RD);
3169
3170 if (!dump)
3171 return offset + total_size;
3172
3173 for (row = ram_defs->base_row;
3174 row < ram_defs->base_row + ram_defs->num_rows;
3175 row++, offset += VFC_RAM_RESP_DWORDS) {
3176 /* Write VFC RAM command */
3177 ARR_REG_WR(p_hwfn,
3178 p_ptt,
3179 s_storm_defs[storm_id].sem_fast_mem_addr +
3180 SEM_FAST_REG_VFC_DATA_WR,
3181 ram_cmd, VFC_RAM_CMD_DWORDS);
3182
3183 /* Write VFC RAM address */
3184 SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, ROW, row);
3185 ARR_REG_WR(p_hwfn,
3186 p_ptt,
3187 s_storm_defs[storm_id].sem_fast_mem_addr +
3188 SEM_FAST_REG_VFC_ADDR,
3189 ram_addr, VFC_RAM_ADDR_DWORDS);
3190
3191 /* Read VFC RAM read response */
3192 ARR_REG_RD(p_hwfn,
3193 p_ptt,
3194 s_storm_defs[storm_id].sem_fast_mem_addr +
3195 SEM_FAST_REG_VFC_DATA_RD,
3196 dump_buf + offset, VFC_RAM_RESP_DWORDS);
3197 }
3198
3199 return offset;
3200}
3201
3202/* Dumps GRC VFC data. Returns the dumped size in dwords. */
3203static u32 qed_grc_dump_vfc(struct qed_hwfn *p_hwfn,
3204 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3205{
3206 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3207 u8 storm_id, i;
3208 u32 offset = 0;
3209
3210 for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
3211 if (qed_grc_is_storm_included(p_hwfn,
3212 (enum dbg_storms)storm_id) &&
3213 s_storm_defs[storm_id].has_vfc &&
3214 (storm_id != DBG_PSTORM_ID ||
3215 dev_data->platform_id == PLATFORM_ASIC)) {
3216 /* Read CAM */
3217 offset += qed_grc_dump_vfc_cam(p_hwfn,
3218 p_ptt,
3219 dump_buf + offset,
3220 dump, storm_id);
3221
3222 /* Read RAM */
3223 for (i = 0; i < NUM_VFC_RAM_TYPES; i++)
3224 offset += qed_grc_dump_vfc_ram(p_hwfn,
3225 p_ptt,
3226 dump_buf +
3227 offset,
3228 dump,
3229 storm_id,
3230 &s_vfc_ram_defs
3231 [i]);
3232 }
3233 }
3234
3235 return offset;
3236}
3237
3238/* Dumps GRC RSS data. Returns the dumped size in dwords. */
3239static u32 qed_grc_dump_rss(struct qed_hwfn *p_hwfn,
3240 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3241{
3242 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3243 u32 offset = 0;
3244 u8 rss_mem_id;
3245
3246 for (rss_mem_id = 0; rss_mem_id < NUM_RSS_MEM_TYPES; rss_mem_id++) {
3247 struct rss_mem_defs *rss_defs = &s_rss_mem_defs[rss_mem_id];
3248 u32 num_entries = rss_defs->num_entries[dev_data->chip_id];
3249 u32 entry_width = rss_defs->entry_width[dev_data->chip_id];
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003250 u32 total_dwords = (num_entries * entry_width) / 32;
3251 u32 size = RSS_REG_RSS_RAM_DATA_SIZE;
Tomer Tayarc965db42016-09-07 16:36:24 +03003252 bool packed = (entry_width == 16);
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003253 u32 rss_addr = rss_defs->addr;
3254 u32 i, addr;
Tomer Tayarc965db42016-09-07 16:36:24 +03003255
3256 offset += qed_grc_dump_mem_hdr(p_hwfn,
3257 dump_buf + offset,
3258 dump,
3259 rss_defs->mem_name,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003260 0,
3261 total_dwords,
Tomer Tayarc965db42016-09-07 16:36:24 +03003262 entry_width,
3263 packed,
3264 rss_defs->type_name, false, 0);
3265
3266 if (!dump) {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003267 offset += total_dwords;
Tomer Tayarc965db42016-09-07 16:36:24 +03003268 continue;
3269 }
3270
3271 /* Dump RSS data */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003272 for (i = 0; i < total_dwords;
3273 i += RSS_REG_RSS_RAM_DATA_SIZE, rss_addr++) {
3274 addr = BYTES_TO_DWORDS(RSS_REG_RSS_RAM_DATA);
3275 qed_wr(p_hwfn, p_ptt, RSS_REG_RSS_RAM_ADDR, rss_addr);
3276 offset += qed_grc_dump_addr_range(p_hwfn,
3277 p_ptt,
3278 dump_buf +
3279 offset,
3280 dump,
3281 addr,
3282 size);
Tomer Tayarc965db42016-09-07 16:36:24 +03003283 }
3284 }
3285
3286 return offset;
3287}
3288
3289/* Dumps GRC Big RAM. Returns the dumped size in dwords. */
3290static u32 qed_grc_dump_big_ram(struct qed_hwfn *p_hwfn,
3291 struct qed_ptt *p_ptt,
3292 u32 *dump_buf, bool dump, u8 big_ram_id)
3293{
3294 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003295 u32 total_blocks, ram_size, offset = 0, i;
Tomer Tayarc965db42016-09-07 16:36:24 +03003296 char mem_name[12] = "???_BIG_RAM";
3297 char type_name[8] = "???_RAM";
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003298 struct big_ram_defs *big_ram;
Tomer Tayarc965db42016-09-07 16:36:24 +03003299
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003300 big_ram = &s_big_ram_defs[big_ram_id];
3301 total_blocks = big_ram->num_of_blocks[dev_data->chip_id];
Tomer Tayarc965db42016-09-07 16:36:24 +03003302 ram_size = total_blocks * BIG_RAM_BLOCK_SIZE_DWORDS;
3303
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003304 strncpy(type_name, big_ram->instance_name,
3305 strlen(big_ram->instance_name));
3306 strncpy(mem_name, big_ram->instance_name,
3307 strlen(big_ram->instance_name));
Tomer Tayarc965db42016-09-07 16:36:24 +03003308
3309 /* Dump memory header */
3310 offset += qed_grc_dump_mem_hdr(p_hwfn,
3311 dump_buf + offset,
3312 dump,
3313 mem_name,
3314 0,
3315 ram_size,
3316 BIG_RAM_BLOCK_SIZE_BYTES * 8,
3317 false, type_name, false, 0);
3318
3319 if (!dump)
3320 return offset + ram_size;
3321
3322 /* Read and dump Big RAM data */
3323 for (i = 0; i < total_blocks / 2; i++) {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003324 u32 addr, len;
3325
3326 qed_wr(p_hwfn, p_ptt, big_ram->addr_reg_addr, i);
3327 addr = BYTES_TO_DWORDS(big_ram->data_reg_addr);
3328 len = 2 * BIG_RAM_BLOCK_SIZE_DWORDS;
3329 offset += qed_grc_dump_addr_range(p_hwfn,
3330 p_ptt,
3331 dump_buf + offset,
3332 dump,
3333 addr,
3334 len);
Tomer Tayarc965db42016-09-07 16:36:24 +03003335 }
3336
3337 return offset;
3338}
3339
3340static u32 qed_grc_dump_mcp(struct qed_hwfn *p_hwfn,
3341 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3342{
3343 bool block_enable[MAX_BLOCK_ID] = { 0 };
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003344 u32 offset = 0, addr;
Tomer Tayarc965db42016-09-07 16:36:24 +03003345 bool halted = false;
Tomer Tayarc965db42016-09-07 16:36:24 +03003346
3347 /* Halt MCP */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003348 if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {
Tomer Tayarc965db42016-09-07 16:36:24 +03003349 halted = !qed_mcp_halt(p_hwfn, p_ptt);
3350 if (!halted)
3351 DP_NOTICE(p_hwfn, "MCP halt failed!\n");
3352 }
3353
3354 /* Dump MCP scratchpad */
3355 offset += qed_grc_dump_mem(p_hwfn,
3356 p_ptt,
3357 dump_buf + offset,
3358 dump,
3359 NULL,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003360 BYTES_TO_DWORDS(MCP_REG_SCRATCH),
Tomer Tayarc965db42016-09-07 16:36:24 +03003361 MCP_REG_SCRATCH_SIZE,
3362 0, false, "MCP", false, 0);
3363
3364 /* Dump MCP cpu_reg_file */
3365 offset += qed_grc_dump_mem(p_hwfn,
3366 p_ptt,
3367 dump_buf + offset,
3368 dump,
3369 NULL,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003370 BYTES_TO_DWORDS(MCP_REG_CPU_REG_FILE),
Tomer Tayarc965db42016-09-07 16:36:24 +03003371 MCP_REG_CPU_REG_FILE_SIZE,
3372 0, false, "MCP", false, 0);
3373
3374 /* Dump MCP registers */
3375 block_enable[BLOCK_MCP] = true;
3376 offset += qed_grc_dump_registers(p_hwfn,
3377 p_ptt,
3378 dump_buf + offset,
3379 dump, block_enable, "block", "MCP");
3380
3381 /* Dump required non-MCP registers */
3382 offset += qed_grc_dump_regs_hdr(dump_buf + offset,
3383 dump, 1, "eng", -1, "block", "MCP");
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003384 addr = BYTES_TO_DWORDS(MISC_REG_SHARED_MEM_ADDR);
Tomer Tayarc965db42016-09-07 16:36:24 +03003385 offset += qed_grc_dump_reg_entry(p_hwfn,
3386 p_ptt,
3387 dump_buf + offset,
3388 dump,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003389 addr,
3390 1);
Tomer Tayarc965db42016-09-07 16:36:24 +03003391
3392 /* Release MCP */
3393 if (halted && qed_mcp_resume(p_hwfn, p_ptt))
3394 DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n");
3395 return offset;
3396}
3397
3398/* Dumps the tbus indirect memory for all PHYs. */
3399static u32 qed_grc_dump_phy(struct qed_hwfn *p_hwfn,
3400 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3401{
3402 u32 offset = 0, tbus_lo_offset, tbus_hi_offset;
3403 char mem_name[32];
3404 u8 phy_id;
3405
3406 for (phy_id = 0; phy_id < ARRAY_SIZE(s_phy_defs); phy_id++) {
3407 struct phy_defs *phy_defs = &s_phy_defs[phy_id];
3408 int printed_chars;
3409
3410 printed_chars = snprintf(mem_name, sizeof(mem_name), "tbus_%s",
3411 phy_defs->phy_name);
3412 if (printed_chars < 0 || printed_chars >= sizeof(mem_name))
3413 DP_NOTICE(p_hwfn,
3414 "Unexpected debug error: invalid PHY memory name\n");
3415 offset += qed_grc_dump_mem_hdr(p_hwfn,
3416 dump_buf + offset,
3417 dump,
3418 mem_name,
3419 0,
3420 PHY_DUMP_SIZE_DWORDS,
3421 16, true, mem_name, false, 0);
3422 if (dump) {
3423 u32 addr_lo_addr = phy_defs->base_addr +
3424 phy_defs->tbus_addr_lo_addr;
3425 u32 addr_hi_addr = phy_defs->base_addr +
3426 phy_defs->tbus_addr_hi_addr;
3427 u32 data_lo_addr = phy_defs->base_addr +
3428 phy_defs->tbus_data_lo_addr;
3429 u32 data_hi_addr = phy_defs->base_addr +
3430 phy_defs->tbus_data_hi_addr;
3431 u8 *bytes_buf = (u8 *)(dump_buf + offset);
3432
3433 for (tbus_hi_offset = 0;
3434 tbus_hi_offset < (NUM_PHY_TBUS_ADDRESSES >> 8);
3435 tbus_hi_offset++) {
3436 qed_wr(p_hwfn,
3437 p_ptt, addr_hi_addr, tbus_hi_offset);
3438 for (tbus_lo_offset = 0; tbus_lo_offset < 256;
3439 tbus_lo_offset++) {
3440 qed_wr(p_hwfn,
3441 p_ptt,
3442 addr_lo_addr, tbus_lo_offset);
3443 *(bytes_buf++) =
3444 (u8)qed_rd(p_hwfn, p_ptt,
3445 data_lo_addr);
3446 *(bytes_buf++) =
3447 (u8)qed_rd(p_hwfn, p_ptt,
3448 data_hi_addr);
3449 }
3450 }
3451 }
3452
3453 offset += PHY_DUMP_SIZE_DWORDS;
3454 }
3455
3456 return offset;
3457}
3458
3459static void qed_config_dbg_line(struct qed_hwfn *p_hwfn,
3460 struct qed_ptt *p_ptt,
3461 enum block_id block_id,
3462 u8 line_id,
3463 u8 cycle_en,
3464 u8 right_shift, u8 force_valid, u8 force_frame)
3465{
3466 struct block_defs *p_block_defs = s_block_defs[block_id];
3467
3468 qed_wr(p_hwfn, p_ptt, p_block_defs->dbg_select_addr, line_id);
3469 qed_wr(p_hwfn, p_ptt, p_block_defs->dbg_cycle_enable_addr, cycle_en);
3470 qed_wr(p_hwfn, p_ptt, p_block_defs->dbg_shift_addr, right_shift);
3471 qed_wr(p_hwfn, p_ptt, p_block_defs->dbg_force_valid_addr, force_valid);
3472 qed_wr(p_hwfn, p_ptt, p_block_defs->dbg_force_frame_addr, force_frame);
3473}
3474
3475/* Dumps Static Debug data. Returns the dumped size in dwords. */
3476static u32 qed_grc_dump_static_debug(struct qed_hwfn *p_hwfn,
3477 struct qed_ptt *p_ptt,
3478 u32 *dump_buf, bool dump)
3479{
3480 u32 block_dwords = NUM_DBG_BUS_LINES * STATIC_DEBUG_LINE_DWORDS;
3481 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003482 u32 offset = 0, block_id, line_id;
Tomer Tayarc965db42016-09-07 16:36:24 +03003483 struct block_defs *p_block_defs;
3484
3485 if (dump) {
3486 DP_VERBOSE(p_hwfn,
3487 QED_MSG_DEBUG, "Dumping static debug data...\n");
3488
3489 /* Disable all blocks debug output */
3490 for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
3491 p_block_defs = s_block_defs[block_id];
3492
3493 if (p_block_defs->has_dbg_bus[dev_data->chip_id])
3494 qed_wr(p_hwfn, p_ptt,
3495 p_block_defs->dbg_cycle_enable_addr, 0);
3496 }
3497
3498 qed_bus_reset_dbg_block(p_hwfn, p_ptt);
3499 qed_bus_set_framing_mode(p_hwfn,
3500 p_ptt, DBG_BUS_FRAME_MODE_8HW_0ST);
3501 qed_wr(p_hwfn,
3502 p_ptt, DBG_REG_DEBUG_TARGET, DBG_BUS_TARGET_ID_INT_BUF);
3503 qed_wr(p_hwfn, p_ptt, DBG_REG_FULL_MODE, 1);
3504 qed_bus_enable_dbg_block(p_hwfn, p_ptt, true);
3505 }
3506
3507 /* Dump all static debug lines for each relevant block */
3508 for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
3509 p_block_defs = s_block_defs[block_id];
3510
3511 if (!p_block_defs->has_dbg_bus[dev_data->chip_id])
3512 continue;
3513
3514 /* Dump static section params */
3515 offset += qed_grc_dump_mem_hdr(p_hwfn,
3516 dump_buf + offset,
3517 dump,
3518 p_block_defs->name, 0,
3519 block_dwords, 32, false,
3520 "STATIC", false, 0);
3521
3522 if (dump && !dev_data->block_in_reset[block_id]) {
3523 u8 dbg_client_id =
3524 p_block_defs->dbg_client_id[dev_data->chip_id];
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003525 u32 addr = BYTES_TO_DWORDS(DBG_REG_CALENDAR_OUT_DATA);
3526 u32 len = STATIC_DEBUG_LINE_DWORDS;
Tomer Tayarc965db42016-09-07 16:36:24 +03003527
3528 /* Enable block's client */
3529 qed_bus_enable_clients(p_hwfn, p_ptt,
3530 BIT(dbg_client_id));
3531
3532 for (line_id = 0; line_id < NUM_DBG_BUS_LINES;
3533 line_id++) {
3534 /* Configure debug line ID */
3535 qed_config_dbg_line(p_hwfn,
3536 p_ptt,
3537 (enum block_id)block_id,
3538 (u8)line_id,
3539 0xf, 0, 0, 0);
3540
3541 /* Read debug line info */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003542 offset +=
3543 qed_grc_dump_addr_range(p_hwfn,
3544 p_ptt,
3545 dump_buf + offset,
3546 dump,
3547 addr,
3548 len);
Tomer Tayarc965db42016-09-07 16:36:24 +03003549 }
3550
3551 /* Disable block's client and debug output */
3552 qed_bus_enable_clients(p_hwfn, p_ptt, 0);
3553 qed_wr(p_hwfn, p_ptt,
3554 p_block_defs->dbg_cycle_enable_addr, 0);
3555 } else {
3556 /* All lines are invalid - dump zeros */
3557 if (dump)
3558 memset(dump_buf + offset, 0,
3559 DWORDS_TO_BYTES(block_dwords));
3560 offset += block_dwords;
3561 }
3562 }
3563
3564 if (dump) {
3565 qed_bus_enable_dbg_block(p_hwfn, p_ptt, false);
3566 qed_bus_enable_clients(p_hwfn, p_ptt, 0);
3567 }
3568
3569 return offset;
3570}
3571
3572/* Performs GRC Dump to the specified buffer.
3573 * Returns the dumped size in dwords.
3574 */
3575static enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn,
3576 struct qed_ptt *p_ptt,
3577 u32 *dump_buf,
3578 bool dump, u32 *num_dumped_dwords)
3579{
3580 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3581 bool parities_masked = false;
3582 u8 i, port_mode = 0;
3583 u32 offset = 0;
3584
Tomer Tayarc965db42016-09-07 16:36:24 +03003585 *num_dumped_dwords = 0;
3586
Tomer Tayarc965db42016-09-07 16:36:24 +03003587 /* Find port mode */
3588 if (dump) {
3589 switch (qed_rd(p_hwfn, p_ptt, MISC_REG_PORT_MODE)) {
3590 case 0:
3591 port_mode = 1;
3592 break;
3593 case 1:
3594 port_mode = 2;
3595 break;
3596 case 2:
3597 port_mode = 4;
3598 break;
3599 }
3600 }
3601
3602 /* Update reset state */
3603 if (dump)
3604 qed_update_blocks_reset_state(p_hwfn, p_ptt);
3605
3606 /* Dump global params */
3607 offset += qed_dump_common_global_params(p_hwfn,
3608 p_ptt,
3609 dump_buf + offset, dump, 4);
3610 offset += qed_dump_str_param(dump_buf + offset,
3611 dump, "dump-type", "grc-dump");
3612 offset += qed_dump_num_param(dump_buf + offset,
3613 dump,
3614 "num-lcids",
3615 qed_grc_get_param(p_hwfn,
3616 DBG_GRC_PARAM_NUM_LCIDS));
3617 offset += qed_dump_num_param(dump_buf + offset,
3618 dump,
3619 "num-ltids",
3620 qed_grc_get_param(p_hwfn,
3621 DBG_GRC_PARAM_NUM_LTIDS));
3622 offset += qed_dump_num_param(dump_buf + offset,
3623 dump, "num-ports", port_mode);
3624
3625 /* Dump reset registers (dumped before taking blocks out of reset ) */
3626 if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
3627 offset += qed_grc_dump_reset_regs(p_hwfn,
3628 p_ptt,
3629 dump_buf + offset, dump);
3630
3631 /* Take all blocks out of reset (using reset registers) */
3632 if (dump) {
3633 qed_grc_unreset_blocks(p_hwfn, p_ptt);
3634 qed_update_blocks_reset_state(p_hwfn, p_ptt);
3635 }
3636
3637 /* Disable all parities using MFW command */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003638 if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {
Tomer Tayarc965db42016-09-07 16:36:24 +03003639 parities_masked = !qed_mcp_mask_parities(p_hwfn, p_ptt, 1);
3640 if (!parities_masked) {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003641 DP_NOTICE(p_hwfn,
3642 "Failed to mask parities using MFW\n");
Tomer Tayarc965db42016-09-07 16:36:24 +03003643 if (qed_grc_get_param
3644 (p_hwfn, DBG_GRC_PARAM_PARITY_SAFE))
3645 return DBG_STATUS_MCP_COULD_NOT_MASK_PRTY;
Tomer Tayarc965db42016-09-07 16:36:24 +03003646 }
3647 }
3648
3649 /* Dump modified registers (dumped before modifying them) */
3650 if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
3651 offset += qed_grc_dump_modified_regs(p_hwfn,
3652 p_ptt,
3653 dump_buf + offset, dump);
3654
3655 /* Stall storms */
3656 if (dump &&
3657 (qed_grc_is_included(p_hwfn,
3658 DBG_GRC_PARAM_DUMP_IOR) ||
3659 qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)))
3660 qed_grc_stall_storms(p_hwfn, p_ptt, true);
3661
3662 /* Dump all regs */
3663 if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS)) {
3664 /* Dump all blocks except MCP */
3665 bool block_enable[MAX_BLOCK_ID];
3666
3667 for (i = 0; i < MAX_BLOCK_ID; i++)
3668 block_enable[i] = true;
3669 block_enable[BLOCK_MCP] = false;
3670 offset += qed_grc_dump_registers(p_hwfn,
3671 p_ptt,
3672 dump_buf +
3673 offset,
3674 dump,
3675 block_enable, NULL, NULL);
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003676
3677 /* Dump special registers */
3678 offset += qed_grc_dump_special_regs(p_hwfn,
3679 p_ptt,
3680 dump_buf + offset, dump);
Tomer Tayarc965db42016-09-07 16:36:24 +03003681 }
3682
3683 /* Dump memories */
3684 offset += qed_grc_dump_memories(p_hwfn, p_ptt, dump_buf + offset, dump);
3685
3686 /* Dump MCP */
3687 if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP))
3688 offset += qed_grc_dump_mcp(p_hwfn,
3689 p_ptt, dump_buf + offset, dump);
3690
3691 /* Dump context */
3692 if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX))
3693 offset += qed_grc_dump_ctx(p_hwfn,
3694 p_ptt, dump_buf + offset, dump);
3695
3696 /* Dump RSS memories */
3697 if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RSS))
3698 offset += qed_grc_dump_rss(p_hwfn,
3699 p_ptt, dump_buf + offset, dump);
3700
3701 /* Dump Big RAM */
3702 for (i = 0; i < NUM_BIG_RAM_TYPES; i++)
3703 if (qed_grc_is_included(p_hwfn, s_big_ram_defs[i].grc_param))
3704 offset += qed_grc_dump_big_ram(p_hwfn,
3705 p_ptt,
3706 dump_buf + offset,
3707 dump, i);
3708
3709 /* Dump IORs */
3710 if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IOR))
3711 offset += qed_grc_dump_iors(p_hwfn,
3712 p_ptt, dump_buf + offset, dump);
3713
3714 /* Dump VFC */
3715 if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC))
3716 offset += qed_grc_dump_vfc(p_hwfn,
3717 p_ptt, dump_buf + offset, dump);
3718
3719 /* Dump PHY tbus */
3720 if (qed_grc_is_included(p_hwfn,
3721 DBG_GRC_PARAM_DUMP_PHY) && dev_data->chip_id ==
3722 CHIP_K2 && dev_data->platform_id == PLATFORM_ASIC)
3723 offset += qed_grc_dump_phy(p_hwfn,
3724 p_ptt, dump_buf + offset, dump);
3725
3726 /* Dump static debug data */
3727 if (qed_grc_is_included(p_hwfn,
3728 DBG_GRC_PARAM_DUMP_STATIC) &&
3729 dev_data->bus.state == DBG_BUS_STATE_IDLE)
3730 offset += qed_grc_dump_static_debug(p_hwfn,
3731 p_ptt,
3732 dump_buf + offset, dump);
3733
3734 /* Dump last section */
3735 offset += qed_dump_last_section(dump_buf, offset, dump);
3736 if (dump) {
3737 /* Unstall storms */
3738 if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_UNSTALL))
3739 qed_grc_stall_storms(p_hwfn, p_ptt, false);
3740
3741 /* Clear parity status */
3742 qed_grc_clear_all_prty(p_hwfn, p_ptt);
3743
3744 /* Enable all parities using MFW command */
3745 if (parities_masked)
3746 qed_mcp_mask_parities(p_hwfn, p_ptt, 0);
3747 }
3748
3749 *num_dumped_dwords = offset;
3750
3751 return DBG_STATUS_OK;
3752}
3753
3754/* Writes the specified failing Idle Check rule to the specified buffer.
3755 * Returns the dumped size in dwords.
3756 */
3757static u32 qed_idle_chk_dump_failure(struct qed_hwfn *p_hwfn,
3758 struct qed_ptt *p_ptt,
3759 u32 *
3760 dump_buf,
3761 bool dump,
3762 u16 rule_id,
3763 const struct dbg_idle_chk_rule *rule,
3764 u16 fail_entry_id, u32 *cond_reg_values)
3765{
3766 const union dbg_idle_chk_reg *regs = &((const union dbg_idle_chk_reg *)
3767 s_dbg_arrays
3768 [BIN_BUF_DBG_IDLE_CHK_REGS].
3769 ptr)[rule->reg_offset];
3770 const struct dbg_idle_chk_cond_reg *cond_regs = &regs[0].cond_reg;
3771 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3772 struct dbg_idle_chk_result_hdr *hdr =
3773 (struct dbg_idle_chk_result_hdr *)dump_buf;
3774 const struct dbg_idle_chk_info_reg *info_regs =
3775 &regs[rule->num_cond_regs].info_reg;
3776 u32 next_reg_offset = 0, i, offset = 0;
3777 u8 reg_id;
3778
3779 /* Dump rule data */
3780 if (dump) {
3781 memset(hdr, 0, sizeof(*hdr));
3782 hdr->rule_id = rule_id;
3783 hdr->mem_entry_id = fail_entry_id;
3784 hdr->severity = rule->severity;
3785 hdr->num_dumped_cond_regs = rule->num_cond_regs;
3786 }
3787
3788 offset += IDLE_CHK_RESULT_HDR_DWORDS;
3789
3790 /* Dump condition register values */
3791 for (reg_id = 0; reg_id < rule->num_cond_regs; reg_id++) {
3792 const struct dbg_idle_chk_cond_reg *reg = &cond_regs[reg_id];
3793
3794 /* Write register header */
3795 if (dump) {
3796 struct dbg_idle_chk_result_reg_hdr *reg_hdr =
3797 (struct dbg_idle_chk_result_reg_hdr *)(dump_buf
3798 + offset);
3799 offset += IDLE_CHK_RESULT_REG_HDR_DWORDS;
3800 memset(reg_hdr, 0,
3801 sizeof(struct dbg_idle_chk_result_reg_hdr));
3802 reg_hdr->start_entry = reg->start_entry;
3803 reg_hdr->size = reg->entry_size;
3804 SET_FIELD(reg_hdr->data,
3805 DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM,
3806 reg->num_entries > 1 || reg->start_entry > 0
3807 ? 1 : 0);
3808 SET_FIELD(reg_hdr->data,
3809 DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID, reg_id);
3810
3811 /* Write register values */
3812 for (i = 0; i < reg_hdr->size;
3813 i++, next_reg_offset++, offset++)
3814 dump_buf[offset] =
3815 cond_reg_values[next_reg_offset];
3816 } else {
3817 offset += IDLE_CHK_RESULT_REG_HDR_DWORDS +
3818 reg->entry_size;
3819 }
3820 }
3821
3822 /* Dump info register values */
3823 for (reg_id = 0; reg_id < rule->num_info_regs; reg_id++) {
3824 const struct dbg_idle_chk_info_reg *reg = &info_regs[reg_id];
3825 u32 block_id;
3826
3827 if (!dump) {
3828 offset += IDLE_CHK_RESULT_REG_HDR_DWORDS + reg->size;
3829 continue;
3830 }
3831
3832 /* Check if register's block is in reset */
3833 block_id = GET_FIELD(reg->data, DBG_IDLE_CHK_INFO_REG_BLOCK_ID);
3834 if (block_id >= MAX_BLOCK_ID) {
3835 DP_NOTICE(p_hwfn, "Invalid block_id\n");
3836 return 0;
3837 }
3838
3839 if (!dev_data->block_in_reset[block_id]) {
3840 bool eval_mode = GET_FIELD(reg->mode.data,
3841 DBG_MODE_HDR_EVAL_MODE) > 0;
3842 bool mode_match = true;
3843
3844 /* Check mode */
3845 if (eval_mode) {
3846 u16 modes_buf_offset =
3847 GET_FIELD(reg->mode.data,
3848 DBG_MODE_HDR_MODES_BUF_OFFSET);
3849 mode_match =
3850 qed_is_mode_match(p_hwfn,
3851 &modes_buf_offset);
3852 }
3853
3854 if (mode_match) {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003855 u32 addr =
3856 GET_FIELD(reg->data,
3857 DBG_IDLE_CHK_INFO_REG_ADDRESS);
Tomer Tayarc965db42016-09-07 16:36:24 +03003858
3859 /* Write register header */
3860 struct dbg_idle_chk_result_reg_hdr *reg_hdr =
3861 (struct dbg_idle_chk_result_reg_hdr *)
3862 (dump_buf + offset);
3863
3864 offset += IDLE_CHK_RESULT_REG_HDR_DWORDS;
3865 hdr->num_dumped_info_regs++;
3866 memset(reg_hdr, 0, sizeof(*reg_hdr));
3867 reg_hdr->size = reg->size;
3868 SET_FIELD(reg_hdr->data,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003869 DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID,
3870 rule->num_cond_regs + reg_id);
Tomer Tayarc965db42016-09-07 16:36:24 +03003871
3872 /* Write register values */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003873 offset +=
3874 qed_grc_dump_addr_range(p_hwfn,
3875 p_ptt,
3876 dump_buf + offset,
3877 dump,
3878 addr,
3879 reg->size);
Tomer Tayarc965db42016-09-07 16:36:24 +03003880 }
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003881 }
Tomer Tayarc965db42016-09-07 16:36:24 +03003882 }
3883
3884 return offset;
3885}
3886
3887/* Dumps idle check rule entries. Returns the dumped size in dwords. */
3888static u32
3889qed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
3890 u32 *dump_buf, bool dump,
3891 const struct dbg_idle_chk_rule *input_rules,
3892 u32 num_input_rules, u32 *num_failing_rules)
3893{
3894 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3895 u32 cond_reg_values[IDLE_CHK_MAX_ENTRIES_SIZE];
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003896 u32 i, offset = 0;
Tomer Tayarc965db42016-09-07 16:36:24 +03003897 u16 entry_id;
3898 u8 reg_id;
3899
3900 *num_failing_rules = 0;
3901 for (i = 0; i < num_input_rules; i++) {
3902 const struct dbg_idle_chk_cond_reg *cond_regs;
3903 const struct dbg_idle_chk_rule *rule;
3904 const union dbg_idle_chk_reg *regs;
3905 u16 num_reg_entries = 1;
3906 bool check_rule = true;
3907 const u32 *imm_values;
3908
3909 rule = &input_rules[i];
3910 regs = &((const union dbg_idle_chk_reg *)
3911 s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr)
3912 [rule->reg_offset];
3913 cond_regs = &regs[0].cond_reg;
3914 imm_values = &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr
3915 [rule->imm_offset];
3916
3917 /* Check if all condition register blocks are out of reset, and
3918 * find maximal number of entries (all condition registers that
3919 * are memories must have the same size, which is > 1).
3920 */
3921 for (reg_id = 0; reg_id < rule->num_cond_regs && check_rule;
3922 reg_id++) {
3923 u32 block_id = GET_FIELD(cond_regs[reg_id].data,
3924 DBG_IDLE_CHK_COND_REG_BLOCK_ID);
3925
3926 if (block_id >= MAX_BLOCK_ID) {
3927 DP_NOTICE(p_hwfn, "Invalid block_id\n");
3928 return 0;
3929 }
3930
3931 check_rule = !dev_data->block_in_reset[block_id];
3932 if (cond_regs[reg_id].num_entries > num_reg_entries)
3933 num_reg_entries = cond_regs[reg_id].num_entries;
3934 }
3935
3936 if (!check_rule && dump)
3937 continue;
3938
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003939 if (!dump) {
3940 u32 entry_dump_size =
3941 qed_idle_chk_dump_failure(p_hwfn,
3942 p_ptt,
3943 dump_buf + offset,
3944 false,
3945 rule->rule_id,
3946 rule,
3947 0,
3948 NULL);
3949
3950 offset += num_reg_entries * entry_dump_size;
3951 (*num_failing_rules) += num_reg_entries;
3952 continue;
3953 }
3954
Tomer Tayarc965db42016-09-07 16:36:24 +03003955 /* Go over all register entries (number of entries is the same
3956 * for all condition registers).
3957 */
3958 for (entry_id = 0; entry_id < num_reg_entries; entry_id++) {
3959 /* Read current entry of all condition registers */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003960 u32 next_reg_offset = 0;
Tomer Tayarc965db42016-09-07 16:36:24 +03003961
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003962 for (reg_id = 0; reg_id < rule->num_cond_regs;
3963 reg_id++) {
3964 const struct dbg_idle_chk_cond_reg *reg =
3965 &cond_regs[reg_id];
Tomer Tayarc965db42016-09-07 16:36:24 +03003966
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003967 /* Find GRC address (if it's a memory,the
3968 * address of the specific entry is calculated).
3969 */
3970 u32 addr =
3971 GET_FIELD(reg->data,
3972 DBG_IDLE_CHK_COND_REG_ADDRESS);
Tomer Tayarc965db42016-09-07 16:36:24 +03003973
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003974 if (reg->num_entries > 1 ||
3975 reg->start_entry > 0) {
3976 u32 padded_entry_size =
3977 reg->entry_size > 1 ?
3978 roundup_pow_of_two(reg->entry_size) :
3979 1;
Tomer Tayarc965db42016-09-07 16:36:24 +03003980
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003981 addr += (reg->start_entry + entry_id) *
3982 padded_entry_size;
Tomer Tayarc965db42016-09-07 16:36:24 +03003983 }
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02003984
3985 /* Read registers */
3986 if (next_reg_offset + reg->entry_size >=
3987 IDLE_CHK_MAX_ENTRIES_SIZE) {
3988 DP_NOTICE(p_hwfn,
3989 "idle check registers entry is too large\n");
3990 return 0;
3991 }
3992
3993 next_reg_offset +=
3994 qed_grc_dump_addr_range(p_hwfn,
3995 p_ptt,
3996 cond_reg_values +
3997 next_reg_offset,
3998 dump, addr,
3999 reg->entry_size);
Tomer Tayarc965db42016-09-07 16:36:24 +03004000 }
4001
4002 /* Call rule's condition function - a return value of
4003 * true indicates failure.
4004 */
4005 if ((*cond_arr[rule->cond_id])(cond_reg_values,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004006 imm_values)) {
Tomer Tayarc965db42016-09-07 16:36:24 +03004007 offset +=
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004008 qed_idle_chk_dump_failure(p_hwfn,
4009 p_ptt,
4010 dump_buf + offset,
4011 dump,
4012 rule->rule_id,
4013 rule,
4014 entry_id,
4015 cond_reg_values);
Tomer Tayarc965db42016-09-07 16:36:24 +03004016 (*num_failing_rules)++;
4017 break;
4018 }
4019 }
4020 }
4021
4022 return offset;
4023}
4024
4025/* Performs Idle Check Dump to the specified buffer.
4026 * Returns the dumped size in dwords.
4027 */
4028static u32 qed_idle_chk_dump(struct qed_hwfn *p_hwfn,
4029 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
4030{
4031 u32 offset = 0, input_offset = 0, num_failing_rules = 0;
4032 u32 num_failing_rules_offset;
4033
4034 /* Dump global params */
4035 offset += qed_dump_common_global_params(p_hwfn,
4036 p_ptt,
4037 dump_buf + offset, dump, 1);
4038 offset += qed_dump_str_param(dump_buf + offset,
4039 dump, "dump-type", "idle-chk");
4040
4041 /* Dump idle check section header with a single parameter */
4042 offset += qed_dump_section_hdr(dump_buf + offset, dump, "idle_chk", 1);
4043 num_failing_rules_offset = offset;
4044 offset += qed_dump_num_param(dump_buf + offset, dump, "num_rules", 0);
4045 while (input_offset <
4046 s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].size_in_dwords) {
4047 const struct dbg_idle_chk_cond_hdr *cond_hdr =
4048 (const struct dbg_idle_chk_cond_hdr *)
4049 &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr
4050 [input_offset++];
4051 bool eval_mode = GET_FIELD(cond_hdr->mode.data,
4052 DBG_MODE_HDR_EVAL_MODE) > 0;
4053 bool mode_match = true;
4054
4055 /* Check mode */
4056 if (eval_mode) {
4057 u16 modes_buf_offset =
4058 GET_FIELD(cond_hdr->mode.data,
4059 DBG_MODE_HDR_MODES_BUF_OFFSET);
4060
4061 mode_match = qed_is_mode_match(p_hwfn,
4062 &modes_buf_offset);
4063 }
4064
4065 if (mode_match) {
4066 u32 curr_failing_rules;
4067
4068 offset +=
4069 qed_idle_chk_dump_rule_entries(p_hwfn,
4070 p_ptt,
4071 dump_buf + offset,
4072 dump,
4073 (const struct dbg_idle_chk_rule *)
4074 &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].
4075 ptr[input_offset],
4076 cond_hdr->data_size / IDLE_CHK_RULE_SIZE_DWORDS,
4077 &curr_failing_rules);
4078 num_failing_rules += curr_failing_rules;
4079 }
4080
4081 input_offset += cond_hdr->data_size;
4082 }
4083
4084 /* Overwrite num_rules parameter */
4085 if (dump)
4086 qed_dump_num_param(dump_buf + num_failing_rules_offset,
4087 dump, "num_rules", num_failing_rules);
4088
4089 return offset;
4090}
4091
4092/* Finds the meta data image in NVRAM. */
4093static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
4094 struct qed_ptt *p_ptt,
4095 u32 image_type,
4096 u32 *nvram_offset_bytes,
4097 u32 *nvram_size_bytes)
4098{
4099 u32 ret_mcp_resp, ret_mcp_param, ret_txn_size;
4100 struct mcp_file_att file_att;
4101
4102 /* Call NVRAM get file command */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004103 int nvm_result = qed_mcp_nvm_rd_cmd(p_hwfn,
4104 p_ptt,
4105 DRV_MSG_CODE_NVM_GET_FILE_ATT,
4106 image_type,
4107 &ret_mcp_resp,
4108 &ret_mcp_param,
4109 &ret_txn_size,
4110 (u32 *)&file_att);
Tomer Tayarc965db42016-09-07 16:36:24 +03004111
4112 /* Check response */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004113 if (nvm_result ||
4114 (ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
Tomer Tayarc965db42016-09-07 16:36:24 +03004115 return DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
4116
4117 /* Update return values */
4118 *nvram_offset_bytes = file_att.nvm_start_addr;
4119 *nvram_size_bytes = file_att.len;
4120 DP_VERBOSE(p_hwfn,
4121 QED_MSG_DEBUG,
4122 "find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\n",
4123 image_type, *nvram_offset_bytes, *nvram_size_bytes);
4124
4125 /* Check alignment */
4126 if (*nvram_size_bytes & 0x3)
4127 return DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE;
4128 return DBG_STATUS_OK;
4129}
4130
4131static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
4132 struct qed_ptt *p_ptt,
4133 u32 nvram_offset_bytes,
4134 u32 nvram_size_bytes, u32 *ret_buf)
4135{
4136 u32 ret_mcp_resp, ret_mcp_param, ret_read_size;
4137 u32 bytes_to_copy, read_offset = 0;
4138 s32 bytes_left = nvram_size_bytes;
4139
4140 DP_VERBOSE(p_hwfn,
4141 QED_MSG_DEBUG,
4142 "nvram_read: reading image of size %d bytes from NVRAM\n",
4143 nvram_size_bytes);
4144 do {
4145 bytes_to_copy =
4146 (bytes_left >
4147 MCP_DRV_NVM_BUF_LEN) ? MCP_DRV_NVM_BUF_LEN : bytes_left;
4148
4149 /* Call NVRAM read command */
4150 if (qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt,
4151 DRV_MSG_CODE_NVM_READ_NVRAM,
4152 (nvram_offset_bytes +
4153 read_offset) |
4154 (bytes_to_copy <<
4155 DRV_MB_PARAM_NVM_LEN_SHIFT),
4156 &ret_mcp_resp, &ret_mcp_param,
4157 &ret_read_size,
4158 (u32 *)((u8 *)ret_buf +
4159 read_offset)) != 0)
4160 return DBG_STATUS_NVRAM_READ_FAILED;
4161
4162 /* Check response */
4163 if ((ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
4164 return DBG_STATUS_NVRAM_READ_FAILED;
4165
4166 /* Update read offset */
4167 read_offset += ret_read_size;
4168 bytes_left -= ret_read_size;
4169 } while (bytes_left > 0);
4170
4171 return DBG_STATUS_OK;
4172}
4173
4174/* Get info on the MCP Trace data in the scratchpad:
4175 * - trace_data_grc_addr - the GRC address of the trace data
4176 * - trace_data_size_bytes - the size in bytes of the MCP Trace data (without
4177 * the header)
4178 */
4179static enum dbg_status qed_mcp_trace_get_data_info(struct qed_hwfn *p_hwfn,
4180 struct qed_ptt *p_ptt,
4181 u32 *trace_data_grc_addr,
4182 u32 *trace_data_size_bytes)
4183{
4184 /* Read MCP trace section offsize structure from MCP scratchpad */
4185 u32 spad_trace_offsize = qed_rd(p_hwfn,
4186 p_ptt,
4187 MCP_SPAD_TRACE_OFFSIZE_ADDR);
4188 u32 signature;
4189
4190 /* Extract MCP trace section GRC address from offsize structure (within
4191 * scratchpad).
4192 */
4193 *trace_data_grc_addr =
4194 MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize);
4195
4196 /* Read signature from MCP trace section */
4197 signature = qed_rd(p_hwfn, p_ptt,
4198 *trace_data_grc_addr +
4199 offsetof(struct mcp_trace, signature));
4200 if (signature != MFW_TRACE_SIGNATURE)
4201 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4202
4203 /* Read trace size from MCP trace section */
4204 *trace_data_size_bytes = qed_rd(p_hwfn,
4205 p_ptt,
4206 *trace_data_grc_addr +
4207 offsetof(struct mcp_trace, size));
4208 return DBG_STATUS_OK;
4209}
4210
4211/* Reads MCP trace meta data image from NVRAM.
4212 * - running_bundle_id (OUT) - the running bundle ID (invalid when loaded from
4213 * file)
4214 * - trace_meta_offset_bytes (OUT) - the NVRAM offset in bytes in which the MCP
4215 * Trace meta data starts (invalid when loaded from file)
4216 * - trace_meta_size_bytes (OUT) - the size in bytes of the MCP Trace meta data
4217 */
4218static enum dbg_status qed_mcp_trace_get_meta_info(struct qed_hwfn *p_hwfn,
4219 struct qed_ptt *p_ptt,
4220 u32 trace_data_size_bytes,
4221 u32 *running_bundle_id,
4222 u32 *trace_meta_offset_bytes,
4223 u32 *trace_meta_size_bytes)
4224{
4225 /* Read MCP trace section offsize structure from MCP scratchpad */
4226 u32 spad_trace_offsize = qed_rd(p_hwfn,
4227 p_ptt,
4228 MCP_SPAD_TRACE_OFFSIZE_ADDR);
4229
4230 /* Find running bundle ID */
4231 u32 running_mfw_addr =
4232 MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize) +
4233 QED_SECTION_SIZE(spad_trace_offsize) + trace_data_size_bytes;
Tomer Tayarc965db42016-09-07 16:36:24 +03004234 u32 nvram_image_type;
4235
4236 *running_bundle_id = qed_rd(p_hwfn, p_ptt, running_mfw_addr);
4237 if (*running_bundle_id > 1)
4238 return DBG_STATUS_INVALID_NVRAM_BUNDLE;
4239
4240 /* Find image in NVRAM */
4241 nvram_image_type =
4242 (*running_bundle_id ==
4243 DIR_ID_1) ? NVM_TYPE_MFW_TRACE1 : NVM_TYPE_MFW_TRACE2;
Tomer Tayarc965db42016-09-07 16:36:24 +03004244
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004245 return qed_find_nvram_image(p_hwfn,
4246 p_ptt,
4247 nvram_image_type,
4248 trace_meta_offset_bytes,
4249 trace_meta_size_bytes);
Tomer Tayarc965db42016-09-07 16:36:24 +03004250}
4251
4252/* Reads the MCP Trace meta data (from NVRAM or buffer) into the specified
4253 * buffer.
4254 */
4255static enum dbg_status qed_mcp_trace_read_meta(struct qed_hwfn *p_hwfn,
4256 struct qed_ptt *p_ptt,
4257 u32 nvram_offset_in_bytes,
4258 u32 size_in_bytes, u32 *buf)
4259{
4260 u8 *byte_buf = (u8 *)buf;
4261 u8 modules_num, i;
4262 u32 signature;
4263
4264 /* Read meta data from NVRAM */
4265 enum dbg_status status = qed_nvram_read(p_hwfn,
4266 p_ptt,
4267 nvram_offset_in_bytes,
4268 size_in_bytes,
4269 buf);
4270
4271 if (status != DBG_STATUS_OK)
4272 return status;
4273
4274 /* Extract and check first signature */
4275 signature = qed_read_unaligned_dword(byte_buf);
4276 byte_buf += sizeof(u32);
4277 if (signature != MCP_TRACE_META_IMAGE_SIGNATURE)
4278 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4279
4280 /* Extract number of modules */
4281 modules_num = *(byte_buf++);
4282
4283 /* Skip all modules */
4284 for (i = 0; i < modules_num; i++) {
4285 u8 module_len = *(byte_buf++);
4286
4287 byte_buf += module_len;
4288 }
4289
4290 /* Extract and check second signature */
4291 signature = qed_read_unaligned_dword(byte_buf);
4292 byte_buf += sizeof(u32);
4293 if (signature != MCP_TRACE_META_IMAGE_SIGNATURE)
4294 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4295 return DBG_STATUS_OK;
4296}
4297
4298/* Dump MCP Trace */
Yuval Mintz8c93bea2016-10-13 22:57:03 +03004299static enum dbg_status qed_mcp_trace_dump(struct qed_hwfn *p_hwfn,
4300 struct qed_ptt *p_ptt,
4301 u32 *dump_buf,
4302 bool dump, u32 *num_dumped_dwords)
Tomer Tayarc965db42016-09-07 16:36:24 +03004303{
4304 u32 trace_data_grc_addr, trace_data_size_bytes, trace_data_size_dwords;
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004305 u32 trace_meta_size_dwords = 0, running_bundle_id, offset = 0;
4306 u32 trace_meta_offset_bytes = 0, trace_meta_size_bytes = 0;
Tomer Tayarc965db42016-09-07 16:36:24 +03004307 enum dbg_status status;
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004308 bool mcp_access;
Tomer Tayarc965db42016-09-07 16:36:24 +03004309 int halted = 0;
4310
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004311 mcp_access = !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP);
4312
Tomer Tayarc965db42016-09-07 16:36:24 +03004313 *num_dumped_dwords = 0;
4314
4315 /* Get trace data info */
4316 status = qed_mcp_trace_get_data_info(p_hwfn,
4317 p_ptt,
4318 &trace_data_grc_addr,
4319 &trace_data_size_bytes);
4320 if (status != DBG_STATUS_OK)
4321 return status;
4322
4323 /* Dump global params */
4324 offset += qed_dump_common_global_params(p_hwfn,
4325 p_ptt,
4326 dump_buf + offset, dump, 1);
4327 offset += qed_dump_str_param(dump_buf + offset,
4328 dump, "dump-type", "mcp-trace");
4329
4330 /* Halt MCP while reading from scratchpad so the read data will be
4331 * consistent if halt fails, MCP trace is taken anyway, with a small
4332 * risk that it may be corrupt.
4333 */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004334 if (dump && mcp_access) {
Tomer Tayarc965db42016-09-07 16:36:24 +03004335 halted = !qed_mcp_halt(p_hwfn, p_ptt);
4336 if (!halted)
4337 DP_NOTICE(p_hwfn, "MCP halt failed!\n");
4338 }
4339
4340 /* Find trace data size */
4341 trace_data_size_dwords =
4342 DIV_ROUND_UP(trace_data_size_bytes + sizeof(struct mcp_trace),
4343 BYTES_IN_DWORD);
4344
4345 /* Dump trace data section header and param */
4346 offset += qed_dump_section_hdr(dump_buf + offset,
4347 dump, "mcp_trace_data", 1);
4348 offset += qed_dump_num_param(dump_buf + offset,
4349 dump, "size", trace_data_size_dwords);
4350
4351 /* Read trace data from scratchpad into dump buffer */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004352 offset += qed_grc_dump_addr_range(p_hwfn,
4353 p_ptt,
4354 dump_buf + offset,
4355 dump,
4356 BYTES_TO_DWORDS(trace_data_grc_addr),
4357 trace_data_size_dwords);
Tomer Tayarc965db42016-09-07 16:36:24 +03004358
4359 /* Resume MCP (only if halt succeeded) */
4360 if (halted && qed_mcp_resume(p_hwfn, p_ptt) != 0)
4361 DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n");
4362
4363 /* Dump trace meta section header */
4364 offset += qed_dump_section_hdr(dump_buf + offset,
4365 dump, "mcp_trace_meta", 1);
4366
4367 /* Read trace meta info */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004368 if (mcp_access) {
4369 status = qed_mcp_trace_get_meta_info(p_hwfn,
4370 p_ptt,
4371 trace_data_size_bytes,
4372 &running_bundle_id,
4373 &trace_meta_offset_bytes,
4374 &trace_meta_size_bytes);
4375 if (status == DBG_STATUS_OK)
4376 trace_meta_size_dwords =
4377 BYTES_TO_DWORDS(trace_meta_size_bytes);
Tomer Tayarc965db42016-09-07 16:36:24 +03004378 }
4379
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004380 /* Dump trace meta size param */
4381 offset += qed_dump_num_param(dump_buf + offset,
4382 dump, "size", trace_meta_size_dwords);
4383
4384 /* Read trace meta image into dump buffer */
4385 if (dump && trace_meta_size_dwords)
4386 status = qed_mcp_trace_read_meta(p_hwfn,
4387 p_ptt,
4388 trace_meta_offset_bytes,
4389 trace_meta_size_bytes,
4390 dump_buf + offset);
4391 if (status == DBG_STATUS_OK)
4392 offset += trace_meta_size_dwords;
Tomer Tayarc965db42016-09-07 16:36:24 +03004393
4394 *num_dumped_dwords = offset;
4395
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004396 /* If no mcp access, indicate that the dump doesn't contain the meta
4397 * data from NVRAM.
4398 */
4399 return mcp_access ? status : DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
Tomer Tayarc965db42016-09-07 16:36:24 +03004400}
4401
4402/* Dump GRC FIFO */
Yuval Mintz8c93bea2016-10-13 22:57:03 +03004403static enum dbg_status qed_reg_fifo_dump(struct qed_hwfn *p_hwfn,
4404 struct qed_ptt *p_ptt,
4405 u32 *dump_buf,
4406 bool dump, u32 *num_dumped_dwords)
Tomer Tayarc965db42016-09-07 16:36:24 +03004407{
4408 u32 offset = 0, dwords_read, size_param_offset;
4409 bool fifo_has_data;
4410
4411 *num_dumped_dwords = 0;
4412
4413 /* Dump global params */
4414 offset += qed_dump_common_global_params(p_hwfn,
4415 p_ptt,
4416 dump_buf + offset, dump, 1);
4417 offset += qed_dump_str_param(dump_buf + offset,
4418 dump, "dump-type", "reg-fifo");
4419
4420 /* Dump fifo data section header and param. The size param is 0 for now,
4421 * and is overwritten after reading the FIFO.
4422 */
4423 offset += qed_dump_section_hdr(dump_buf + offset,
4424 dump, "reg_fifo_data", 1);
4425 size_param_offset = offset;
4426 offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4427
4428 if (!dump) {
4429 /* FIFO max size is REG_FIFO_DEPTH_DWORDS. There is no way to
4430 * test how much data is available, except for reading it.
4431 */
4432 offset += REG_FIFO_DEPTH_DWORDS;
4433 *num_dumped_dwords = offset;
4434 return DBG_STATUS_OK;
4435 }
4436
4437 fifo_has_data = qed_rd(p_hwfn, p_ptt,
4438 GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
4439
4440 /* Pull available data from fifo. Use DMAE since this is widebus memory
4441 * and must be accessed atomically. Test for dwords_read not passing
4442 * buffer size since more entries could be added to the buffer as we are
4443 * emptying it.
4444 */
4445 for (dwords_read = 0;
4446 fifo_has_data && dwords_read < REG_FIFO_DEPTH_DWORDS;
4447 dwords_read += REG_FIFO_ELEMENT_DWORDS, offset +=
4448 REG_FIFO_ELEMENT_DWORDS) {
4449 if (qed_dmae_grc2host(p_hwfn, p_ptt, GRC_REG_TRACE_FIFO,
4450 (u64)(uintptr_t)(&dump_buf[offset]),
4451 REG_FIFO_ELEMENT_DWORDS, 0))
4452 return DBG_STATUS_DMAE_FAILED;
4453 fifo_has_data = qed_rd(p_hwfn, p_ptt,
4454 GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
4455 }
4456
4457 qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4458 dwords_read);
4459
4460 *num_dumped_dwords = offset;
4461 return DBG_STATUS_OK;
4462}
4463
4464/* Dump IGU FIFO */
Yuval Mintz8c93bea2016-10-13 22:57:03 +03004465static enum dbg_status qed_igu_fifo_dump(struct qed_hwfn *p_hwfn,
4466 struct qed_ptt *p_ptt,
4467 u32 *dump_buf,
4468 bool dump, u32 *num_dumped_dwords)
Tomer Tayarc965db42016-09-07 16:36:24 +03004469{
4470 u32 offset = 0, dwords_read, size_param_offset;
4471 bool fifo_has_data;
4472
4473 *num_dumped_dwords = 0;
4474
4475 /* Dump global params */
4476 offset += qed_dump_common_global_params(p_hwfn,
4477 p_ptt,
4478 dump_buf + offset, dump, 1);
4479 offset += qed_dump_str_param(dump_buf + offset,
4480 dump, "dump-type", "igu-fifo");
4481
4482 /* Dump fifo data section header and param. The size param is 0 for now,
4483 * and is overwritten after reading the FIFO.
4484 */
4485 offset += qed_dump_section_hdr(dump_buf + offset,
4486 dump, "igu_fifo_data", 1);
4487 size_param_offset = offset;
4488 offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4489
4490 if (!dump) {
4491 /* FIFO max size is IGU_FIFO_DEPTH_DWORDS. There is no way to
4492 * test how much data is available, except for reading it.
4493 */
4494 offset += IGU_FIFO_DEPTH_DWORDS;
4495 *num_dumped_dwords = offset;
4496 return DBG_STATUS_OK;
4497 }
4498
4499 fifo_has_data = qed_rd(p_hwfn, p_ptt,
4500 IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
4501
4502 /* Pull available data from fifo. Use DMAE since this is widebus memory
4503 * and must be accessed atomically. Test for dwords_read not passing
4504 * buffer size since more entries could be added to the buffer as we are
4505 * emptying it.
4506 */
4507 for (dwords_read = 0;
4508 fifo_has_data && dwords_read < IGU_FIFO_DEPTH_DWORDS;
4509 dwords_read += IGU_FIFO_ELEMENT_DWORDS, offset +=
4510 IGU_FIFO_ELEMENT_DWORDS) {
4511 if (qed_dmae_grc2host(p_hwfn, p_ptt,
4512 IGU_REG_ERROR_HANDLING_MEMORY,
4513 (u64)(uintptr_t)(&dump_buf[offset]),
4514 IGU_FIFO_ELEMENT_DWORDS, 0))
4515 return DBG_STATUS_DMAE_FAILED;
4516 fifo_has_data = qed_rd(p_hwfn, p_ptt,
4517 IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
4518 }
4519
4520 qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4521 dwords_read);
4522
4523 *num_dumped_dwords = offset;
4524 return DBG_STATUS_OK;
4525}
4526
4527/* Protection Override dump */
Yuval Mintz8c93bea2016-10-13 22:57:03 +03004528static enum dbg_status qed_protection_override_dump(struct qed_hwfn *p_hwfn,
4529 struct qed_ptt *p_ptt,
4530 u32 *dump_buf,
4531 bool dump,
4532 u32 *num_dumped_dwords)
Tomer Tayarc965db42016-09-07 16:36:24 +03004533{
4534 u32 offset = 0, size_param_offset, override_window_dwords;
4535
4536 *num_dumped_dwords = 0;
4537
4538 /* Dump global params */
4539 offset += qed_dump_common_global_params(p_hwfn,
4540 p_ptt,
4541 dump_buf + offset, dump, 1);
4542 offset += qed_dump_str_param(dump_buf + offset,
4543 dump, "dump-type", "protection-override");
4544
4545 /* Dump data section header and param. The size param is 0 for now, and
4546 * is overwritten after reading the data.
4547 */
4548 offset += qed_dump_section_hdr(dump_buf + offset,
4549 dump, "protection_override_data", 1);
4550 size_param_offset = offset;
4551 offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4552
4553 if (!dump) {
4554 offset += PROTECTION_OVERRIDE_DEPTH_DWORDS;
4555 *num_dumped_dwords = offset;
4556 return DBG_STATUS_OK;
4557 }
4558
4559 /* Add override window info to buffer */
4560 override_window_dwords =
4561 qed_rd(p_hwfn, p_ptt,
4562 GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW) *
4563 PROTECTION_OVERRIDE_ELEMENT_DWORDS;
4564 if (qed_dmae_grc2host(p_hwfn, p_ptt,
4565 GRC_REG_PROTECTION_OVERRIDE_WINDOW,
4566 (u64)(uintptr_t)(dump_buf + offset),
4567 override_window_dwords, 0))
4568 return DBG_STATUS_DMAE_FAILED;
4569 offset += override_window_dwords;
4570 qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4571 override_window_dwords);
4572
4573 *num_dumped_dwords = offset;
4574 return DBG_STATUS_OK;
4575}
4576
4577/* Performs FW Asserts Dump to the specified buffer.
4578 * Returns the dumped size in dwords.
4579 */
4580static u32 qed_fw_asserts_dump(struct qed_hwfn *p_hwfn,
4581 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
4582{
4583 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004584 struct fw_asserts_ram_section *asserts;
Tomer Tayarc965db42016-09-07 16:36:24 +03004585 char storm_letter_str[2] = "?";
4586 struct fw_info fw_info;
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004587 u32 offset = 0;
Tomer Tayarc965db42016-09-07 16:36:24 +03004588 u8 storm_id;
4589
4590 /* Dump global params */
4591 offset += qed_dump_common_global_params(p_hwfn,
4592 p_ptt,
4593 dump_buf + offset, dump, 1);
4594 offset += qed_dump_str_param(dump_buf + offset,
4595 dump, "dump-type", "fw-asserts");
4596 for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004597 u32 fw_asserts_section_addr, next_list_idx_addr, next_list_idx;
4598 u32 last_list_idx, addr;
Tomer Tayarc965db42016-09-07 16:36:24 +03004599
4600 if (dev_data->block_in_reset[s_storm_defs[storm_id].block_id])
4601 continue;
4602
4603 /* Read FW info for the current Storm */
4604 qed_read_fw_info(p_hwfn, p_ptt, storm_id, &fw_info);
4605
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004606 asserts = &fw_info.fw_asserts_section;
4607
Tomer Tayarc965db42016-09-07 16:36:24 +03004608 /* Dump FW Asserts section header and params */
4609 storm_letter_str[0] = s_storm_defs[storm_id].letter;
4610 offset += qed_dump_section_hdr(dump_buf + offset, dump,
4611 "fw_asserts", 2);
4612 offset += qed_dump_str_param(dump_buf + offset, dump, "storm",
4613 storm_letter_str);
4614 offset += qed_dump_num_param(dump_buf + offset, dump, "size",
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004615 asserts->list_element_dword_size);
Tomer Tayarc965db42016-09-07 16:36:24 +03004616
4617 if (!dump) {
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004618 offset += asserts->list_element_dword_size;
Tomer Tayarc965db42016-09-07 16:36:24 +03004619 continue;
4620 }
4621
4622 /* Read and dump FW Asserts data */
4623 fw_asserts_section_addr =
4624 s_storm_defs[storm_id].sem_fast_mem_addr +
4625 SEM_FAST_REG_INT_RAM +
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004626 RAM_LINES_TO_BYTES(asserts->section_ram_line_offset);
Tomer Tayarc965db42016-09-07 16:36:24 +03004627 next_list_idx_addr =
4628 fw_asserts_section_addr +
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004629 DWORDS_TO_BYTES(asserts->list_next_index_dword_offset);
Tomer Tayarc965db42016-09-07 16:36:24 +03004630 next_list_idx = qed_rd(p_hwfn, p_ptt, next_list_idx_addr);
4631 last_list_idx = (next_list_idx > 0
4632 ? next_list_idx
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004633 : asserts->list_num_elements) - 1;
4634 addr = BYTES_TO_DWORDS(fw_asserts_section_addr) +
4635 asserts->list_dword_offset +
4636 last_list_idx * asserts->list_element_dword_size;
4637 offset +=
4638 qed_grc_dump_addr_range(p_hwfn, p_ptt,
4639 dump_buf + offset,
4640 dump, addr,
4641 asserts->list_element_dword_size);
Tomer Tayarc965db42016-09-07 16:36:24 +03004642 }
4643
4644 /* Dump last section */
4645 offset += qed_dump_section_hdr(dump_buf + offset, dump, "last", 0);
4646 return offset;
4647}
4648
4649/***************************** Public Functions *******************************/
4650
4651enum dbg_status qed_dbg_set_bin_ptr(const u8 * const bin_ptr)
4652{
4653 /* Convert binary data to debug arrays */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004654 struct bin_buffer_hdr *buf_array = (struct bin_buffer_hdr *)bin_ptr;
Tomer Tayarc965db42016-09-07 16:36:24 +03004655 u8 buf_id;
4656
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004657 for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++) {
Tomer Tayarc965db42016-09-07 16:36:24 +03004658 s_dbg_arrays[buf_id].ptr =
4659 (u32 *)(bin_ptr + buf_array[buf_id].offset);
4660 s_dbg_arrays[buf_id].size_in_dwords =
4661 BYTES_TO_DWORDS(buf_array[buf_id].length);
4662 }
4663
4664 return DBG_STATUS_OK;
4665}
4666
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004667/* Assign default GRC param values */
4668void qed_dbg_grc_set_params_default(struct qed_hwfn *p_hwfn)
4669{
4670 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4671 u32 i;
4672
4673 for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
4674 dev_data->grc.param_val[i] =
4675 s_grc_param_defs[i].default_val[dev_data->chip_id];
4676}
4677
Tomer Tayarc965db42016-09-07 16:36:24 +03004678enum dbg_status qed_dbg_grc_get_dump_buf_size(struct qed_hwfn *p_hwfn,
4679 struct qed_ptt *p_ptt,
4680 u32 *buf_size)
4681{
4682 enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
4683
4684 *buf_size = 0;
4685 if (status != DBG_STATUS_OK)
4686 return status;
4687 if (!s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
4688 !s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr ||
4689 !s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr ||
4690 !s_dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||
4691 !s_dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)
4692 return DBG_STATUS_DBG_ARRAY_NOT_SET;
4693 return qed_grc_dump(p_hwfn, p_ptt, NULL, false, buf_size);
4694}
4695
4696enum dbg_status qed_dbg_grc_dump(struct qed_hwfn *p_hwfn,
4697 struct qed_ptt *p_ptt,
4698 u32 *dump_buf,
4699 u32 buf_size_in_dwords,
4700 u32 *num_dumped_dwords)
4701{
4702 u32 needed_buf_size_in_dwords;
4703 enum dbg_status status;
4704
4705 status = qed_dbg_grc_get_dump_buf_size(p_hwfn, p_ptt,
4706 &needed_buf_size_in_dwords);
4707
4708 *num_dumped_dwords = 0;
4709 if (status != DBG_STATUS_OK)
4710 return status;
4711 if (buf_size_in_dwords < needed_buf_size_in_dwords)
4712 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
4713
4714 /* GRC Dump */
4715 status = qed_grc_dump(p_hwfn, p_ptt, dump_buf, true, num_dumped_dwords);
4716
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004717 /* Revert GRC params to their default */
4718 qed_dbg_grc_set_params_default(p_hwfn);
4719
Tomer Tayarc965db42016-09-07 16:36:24 +03004720 return status;
4721}
4722
4723enum dbg_status qed_dbg_idle_chk_get_dump_buf_size(struct qed_hwfn *p_hwfn,
4724 struct qed_ptt *p_ptt,
4725 u32 *buf_size)
4726{
4727 enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
4728 struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4729
4730 *buf_size = 0;
4731 if (status != DBG_STATUS_OK)
4732 return status;
4733 if (!s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
4734 !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr ||
4735 !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr ||
4736 !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr)
4737 return DBG_STATUS_DBG_ARRAY_NOT_SET;
4738 if (!dev_data->idle_chk.buf_size_set) {
4739 dev_data->idle_chk.buf_size = qed_idle_chk_dump(p_hwfn,
4740 p_ptt,
4741 NULL, false);
4742 dev_data->idle_chk.buf_size_set = true;
4743 }
4744
4745 *buf_size = dev_data->idle_chk.buf_size;
4746 return DBG_STATUS_OK;
4747}
4748
4749enum dbg_status qed_dbg_idle_chk_dump(struct qed_hwfn *p_hwfn,
4750 struct qed_ptt *p_ptt,
4751 u32 *dump_buf,
4752 u32 buf_size_in_dwords,
4753 u32 *num_dumped_dwords)
4754{
4755 u32 needed_buf_size_in_dwords;
4756 enum dbg_status status;
4757
4758 status = qed_dbg_idle_chk_get_dump_buf_size(p_hwfn, p_ptt,
4759 &needed_buf_size_in_dwords);
4760
4761 *num_dumped_dwords = 0;
4762 if (status != DBG_STATUS_OK)
4763 return status;
4764 if (buf_size_in_dwords < needed_buf_size_in_dwords)
4765 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
4766
4767 /* Update reset state */
4768 qed_update_blocks_reset_state(p_hwfn, p_ptt);
4769
4770 /* Idle Check Dump */
4771 *num_dumped_dwords = qed_idle_chk_dump(p_hwfn, p_ptt, dump_buf, true);
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004772
4773 /* Revert GRC params to their default */
4774 qed_dbg_grc_set_params_default(p_hwfn);
4775
Tomer Tayarc965db42016-09-07 16:36:24 +03004776 return DBG_STATUS_OK;
4777}
4778
4779enum dbg_status qed_dbg_mcp_trace_get_dump_buf_size(struct qed_hwfn *p_hwfn,
4780 struct qed_ptt *p_ptt,
4781 u32 *buf_size)
4782{
4783 enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
4784
4785 *buf_size = 0;
4786 if (status != DBG_STATUS_OK)
4787 return status;
4788 return qed_mcp_trace_dump(p_hwfn, p_ptt, NULL, false, buf_size);
4789}
4790
4791enum dbg_status qed_dbg_mcp_trace_dump(struct qed_hwfn *p_hwfn,
4792 struct qed_ptt *p_ptt,
4793 u32 *dump_buf,
4794 u32 buf_size_in_dwords,
4795 u32 *num_dumped_dwords)
4796{
4797 u32 needed_buf_size_in_dwords;
4798 enum dbg_status status;
4799
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004800 /* validate buffer size */
4801 status =
4802 qed_dbg_mcp_trace_get_dump_buf_size(p_hwfn, p_ptt,
Tomer Tayarc965db42016-09-07 16:36:24 +03004803 &needed_buf_size_in_dwords);
4804
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004805 if (status != DBG_STATUS_OK &&
4806 status != DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
Tomer Tayarc965db42016-09-07 16:36:24 +03004807 return status;
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004808
Tomer Tayarc965db42016-09-07 16:36:24 +03004809 if (buf_size_in_dwords < needed_buf_size_in_dwords)
4810 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
4811
4812 /* Update reset state */
4813 qed_update_blocks_reset_state(p_hwfn, p_ptt);
4814
4815 /* Perform dump */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004816 status = qed_mcp_trace_dump(p_hwfn,
4817 p_ptt, dump_buf, true, num_dumped_dwords);
4818
4819 /* Revert GRC params to their default */
4820 qed_dbg_grc_set_params_default(p_hwfn);
4821
4822 return status;
Tomer Tayarc965db42016-09-07 16:36:24 +03004823}
4824
4825enum dbg_status qed_dbg_reg_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn,
4826 struct qed_ptt *p_ptt,
4827 u32 *buf_size)
4828{
4829 enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
4830
4831 *buf_size = 0;
4832 if (status != DBG_STATUS_OK)
4833 return status;
4834 return qed_reg_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);
4835}
4836
4837enum dbg_status qed_dbg_reg_fifo_dump(struct qed_hwfn *p_hwfn,
4838 struct qed_ptt *p_ptt,
4839 u32 *dump_buf,
4840 u32 buf_size_in_dwords,
4841 u32 *num_dumped_dwords)
4842{
4843 u32 needed_buf_size_in_dwords;
4844 enum dbg_status status;
4845
4846 status = qed_dbg_reg_fifo_get_dump_buf_size(p_hwfn, p_ptt,
4847 &needed_buf_size_in_dwords);
4848
4849 *num_dumped_dwords = 0;
4850 if (status != DBG_STATUS_OK)
4851 return status;
4852 if (buf_size_in_dwords < needed_buf_size_in_dwords)
4853 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
4854
4855 /* Update reset state */
4856 qed_update_blocks_reset_state(p_hwfn, p_ptt);
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004857
4858 status = qed_reg_fifo_dump(p_hwfn,
4859 p_ptt, dump_buf, true, num_dumped_dwords);
4860
4861 /* Revert GRC params to their default */
4862 qed_dbg_grc_set_params_default(p_hwfn);
4863
4864 return status;
Tomer Tayarc965db42016-09-07 16:36:24 +03004865}
4866
4867enum dbg_status qed_dbg_igu_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn,
4868 struct qed_ptt *p_ptt,
4869 u32 *buf_size)
4870{
4871 enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
4872
4873 *buf_size = 0;
4874 if (status != DBG_STATUS_OK)
4875 return status;
4876 return qed_igu_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);
4877}
4878
4879enum dbg_status qed_dbg_igu_fifo_dump(struct qed_hwfn *p_hwfn,
4880 struct qed_ptt *p_ptt,
4881 u32 *dump_buf,
4882 u32 buf_size_in_dwords,
4883 u32 *num_dumped_dwords)
4884{
4885 u32 needed_buf_size_in_dwords;
4886 enum dbg_status status;
4887
4888 status = qed_dbg_igu_fifo_get_dump_buf_size(p_hwfn, p_ptt,
4889 &needed_buf_size_in_dwords);
4890
4891 *num_dumped_dwords = 0;
4892 if (status != DBG_STATUS_OK)
4893 return status;
4894 if (buf_size_in_dwords < needed_buf_size_in_dwords)
4895 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
4896
4897 /* Update reset state */
4898 qed_update_blocks_reset_state(p_hwfn, p_ptt);
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004899
4900 status = qed_igu_fifo_dump(p_hwfn,
4901 p_ptt, dump_buf, true, num_dumped_dwords);
4902 /* Revert GRC params to their default */
4903 qed_dbg_grc_set_params_default(p_hwfn);
4904
4905 return status;
Tomer Tayarc965db42016-09-07 16:36:24 +03004906}
4907
4908enum dbg_status
4909qed_dbg_protection_override_get_dump_buf_size(struct qed_hwfn *p_hwfn,
4910 struct qed_ptt *p_ptt,
4911 u32 *buf_size)
4912{
4913 enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
4914
4915 *buf_size = 0;
4916 if (status != DBG_STATUS_OK)
4917 return status;
4918 return qed_protection_override_dump(p_hwfn,
4919 p_ptt, NULL, false, buf_size);
4920}
4921
4922enum dbg_status qed_dbg_protection_override_dump(struct qed_hwfn *p_hwfn,
4923 struct qed_ptt *p_ptt,
4924 u32 *dump_buf,
4925 u32 buf_size_in_dwords,
4926 u32 *num_dumped_dwords)
4927{
4928 u32 needed_buf_size_in_dwords;
4929 enum dbg_status status;
4930
4931 status = qed_dbg_protection_override_get_dump_buf_size(p_hwfn, p_ptt,
4932 &needed_buf_size_in_dwords);
4933
4934 *num_dumped_dwords = 0;
4935 if (status != DBG_STATUS_OK)
4936 return status;
4937 if (buf_size_in_dwords < needed_buf_size_in_dwords)
4938 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
4939
4940 /* Update reset state */
4941 qed_update_blocks_reset_state(p_hwfn, p_ptt);
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02004942
4943 status = qed_protection_override_dump(p_hwfn,
4944 p_ptt,
4945 dump_buf,
4946 true, num_dumped_dwords);
4947
4948 /* Revert GRC params to their default */
4949 qed_dbg_grc_set_params_default(p_hwfn);
4950
4951 return status;
Tomer Tayarc965db42016-09-07 16:36:24 +03004952}
4953
4954enum dbg_status qed_dbg_fw_asserts_get_dump_buf_size(struct qed_hwfn *p_hwfn,
4955 struct qed_ptt *p_ptt,
4956 u32 *buf_size)
4957{
4958 enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
4959
4960 *buf_size = 0;
4961 if (status != DBG_STATUS_OK)
4962 return status;
4963
4964 /* Update reset state */
4965 qed_update_blocks_reset_state(p_hwfn, p_ptt);
4966 *buf_size = qed_fw_asserts_dump(p_hwfn, p_ptt, NULL, false);
4967 return DBG_STATUS_OK;
4968}
4969
4970enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn *p_hwfn,
4971 struct qed_ptt *p_ptt,
4972 u32 *dump_buf,
4973 u32 buf_size_in_dwords,
4974 u32 *num_dumped_dwords)
4975{
4976 u32 needed_buf_size_in_dwords;
4977 enum dbg_status status;
4978
4979 status = qed_dbg_fw_asserts_get_dump_buf_size(p_hwfn, p_ptt,
4980 &needed_buf_size_in_dwords);
4981
4982 *num_dumped_dwords = 0;
4983 if (status != DBG_STATUS_OK)
4984 return status;
4985 if (buf_size_in_dwords < needed_buf_size_in_dwords)
4986 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
4987
4988 *num_dumped_dwords = qed_fw_asserts_dump(p_hwfn, p_ptt, dump_buf, true);
4989 return DBG_STATUS_OK;
4990}
4991
4992/******************************* Data Types **********************************/
4993
4994struct mcp_trace_format {
4995 u32 data;
4996#define MCP_TRACE_FORMAT_MODULE_MASK 0x0000ffff
4997#define MCP_TRACE_FORMAT_MODULE_SHIFT 0
4998#define MCP_TRACE_FORMAT_LEVEL_MASK 0x00030000
4999#define MCP_TRACE_FORMAT_LEVEL_SHIFT 16
5000#define MCP_TRACE_FORMAT_P1_SIZE_MASK 0x000c0000
5001#define MCP_TRACE_FORMAT_P1_SIZE_SHIFT 18
5002#define MCP_TRACE_FORMAT_P2_SIZE_MASK 0x00300000
5003#define MCP_TRACE_FORMAT_P2_SIZE_SHIFT 20
5004#define MCP_TRACE_FORMAT_P3_SIZE_MASK 0x00c00000
5005#define MCP_TRACE_FORMAT_P3_SIZE_SHIFT 22
5006#define MCP_TRACE_FORMAT_LEN_MASK 0xff000000
5007#define MCP_TRACE_FORMAT_LEN_SHIFT 24
5008 char *format_str;
5009};
5010
5011struct mcp_trace_meta {
5012 u32 modules_num;
5013 char **modules;
5014 u32 formats_num;
5015 struct mcp_trace_format *formats;
5016};
5017
5018/* Reg fifo element */
5019struct reg_fifo_element {
5020 u64 data;
5021#define REG_FIFO_ELEMENT_ADDRESS_SHIFT 0
5022#define REG_FIFO_ELEMENT_ADDRESS_MASK 0x7fffff
5023#define REG_FIFO_ELEMENT_ACCESS_SHIFT 23
5024#define REG_FIFO_ELEMENT_ACCESS_MASK 0x1
5025#define REG_FIFO_ELEMENT_PF_SHIFT 24
5026#define REG_FIFO_ELEMENT_PF_MASK 0xf
5027#define REG_FIFO_ELEMENT_VF_SHIFT 28
5028#define REG_FIFO_ELEMENT_VF_MASK 0xff
5029#define REG_FIFO_ELEMENT_PORT_SHIFT 36
5030#define REG_FIFO_ELEMENT_PORT_MASK 0x3
5031#define REG_FIFO_ELEMENT_PRIVILEGE_SHIFT 38
5032#define REG_FIFO_ELEMENT_PRIVILEGE_MASK 0x3
5033#define REG_FIFO_ELEMENT_PROTECTION_SHIFT 40
5034#define REG_FIFO_ELEMENT_PROTECTION_MASK 0x7
5035#define REG_FIFO_ELEMENT_MASTER_SHIFT 43
5036#define REG_FIFO_ELEMENT_MASTER_MASK 0xf
5037#define REG_FIFO_ELEMENT_ERROR_SHIFT 47
5038#define REG_FIFO_ELEMENT_ERROR_MASK 0x1f
5039};
5040
5041/* IGU fifo element */
5042struct igu_fifo_element {
5043 u32 dword0;
5044#define IGU_FIFO_ELEMENT_DWORD0_FID_SHIFT 0
5045#define IGU_FIFO_ELEMENT_DWORD0_FID_MASK 0xff
5046#define IGU_FIFO_ELEMENT_DWORD0_IS_PF_SHIFT 8
5047#define IGU_FIFO_ELEMENT_DWORD0_IS_PF_MASK 0x1
5048#define IGU_FIFO_ELEMENT_DWORD0_SOURCE_SHIFT 9
5049#define IGU_FIFO_ELEMENT_DWORD0_SOURCE_MASK 0xf
5050#define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_SHIFT 13
5051#define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_MASK 0xf
5052#define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_SHIFT 17
5053#define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_MASK 0x7fff
5054 u32 dword1;
5055 u32 dword2;
5056#define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_SHIFT 0
5057#define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_MASK 0x1
5058#define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_SHIFT 1
5059#define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_MASK 0xffffffff
5060 u32 reserved;
5061};
5062
5063struct igu_fifo_wr_data {
5064 u32 data;
5065#define IGU_FIFO_WR_DATA_PROD_CONS_SHIFT 0
5066#define IGU_FIFO_WR_DATA_PROD_CONS_MASK 0xffffff
5067#define IGU_FIFO_WR_DATA_UPDATE_FLAG_SHIFT 24
5068#define IGU_FIFO_WR_DATA_UPDATE_FLAG_MASK 0x1
5069#define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_SHIFT 25
5070#define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_MASK 0x3
5071#define IGU_FIFO_WR_DATA_SEGMENT_SHIFT 27
5072#define IGU_FIFO_WR_DATA_SEGMENT_MASK 0x1
5073#define IGU_FIFO_WR_DATA_TIMER_MASK_SHIFT 28
5074#define IGU_FIFO_WR_DATA_TIMER_MASK_MASK 0x1
5075#define IGU_FIFO_WR_DATA_CMD_TYPE_SHIFT 31
5076#define IGU_FIFO_WR_DATA_CMD_TYPE_MASK 0x1
5077};
5078
5079struct igu_fifo_cleanup_wr_data {
5080 u32 data;
5081#define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_SHIFT 0
5082#define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_MASK 0x7ffffff
5083#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_SHIFT 27
5084#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_MASK 0x1
5085#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_SHIFT 28
5086#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_MASK 0x7
5087#define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_SHIFT 31
5088#define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_MASK 0x1
5089};
5090
5091/* Protection override element */
5092struct protection_override_element {
5093 u64 data;
5094#define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_SHIFT 0
5095#define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_MASK 0x7fffff
5096#define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_SHIFT 23
5097#define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_MASK 0xffffff
5098#define PROTECTION_OVERRIDE_ELEMENT_READ_SHIFT 47
5099#define PROTECTION_OVERRIDE_ELEMENT_READ_MASK 0x1
5100#define PROTECTION_OVERRIDE_ELEMENT_WRITE_SHIFT 48
5101#define PROTECTION_OVERRIDE_ELEMENT_WRITE_MASK 0x1
5102#define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_SHIFT 49
5103#define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_MASK 0x7
5104#define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_SHIFT 52
5105#define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_MASK 0x7
5106};
5107
5108enum igu_fifo_sources {
5109 IGU_SRC_PXP0,
5110 IGU_SRC_PXP1,
5111 IGU_SRC_PXP2,
5112 IGU_SRC_PXP3,
5113 IGU_SRC_PXP4,
5114 IGU_SRC_PXP5,
5115 IGU_SRC_PXP6,
5116 IGU_SRC_PXP7,
5117 IGU_SRC_CAU,
5118 IGU_SRC_ATTN,
5119 IGU_SRC_GRC
5120};
5121
5122enum igu_fifo_addr_types {
5123 IGU_ADDR_TYPE_MSIX_MEM,
5124 IGU_ADDR_TYPE_WRITE_PBA,
5125 IGU_ADDR_TYPE_WRITE_INT_ACK,
5126 IGU_ADDR_TYPE_WRITE_ATTN_BITS,
5127 IGU_ADDR_TYPE_READ_INT,
5128 IGU_ADDR_TYPE_WRITE_PROD_UPDATE,
5129 IGU_ADDR_TYPE_RESERVED
5130};
5131
5132struct igu_fifo_addr_data {
5133 u16 start_addr;
5134 u16 end_addr;
5135 char *desc;
5136 char *vf_desc;
5137 enum igu_fifo_addr_types type;
5138};
5139
5140/******************************** Constants **********************************/
5141
5142#define MAX_MSG_LEN 1024
5143#define MCP_TRACE_MAX_MODULE_LEN 8
5144#define MCP_TRACE_FORMAT_MAX_PARAMS 3
5145#define MCP_TRACE_FORMAT_PARAM_WIDTH \
5146 (MCP_TRACE_FORMAT_P2_SIZE_SHIFT - MCP_TRACE_FORMAT_P1_SIZE_SHIFT)
5147#define REG_FIFO_ELEMENT_ADDR_FACTOR 4
5148#define REG_FIFO_ELEMENT_IS_PF_VF_VAL 127
5149#define PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR 4
5150
5151/********************************* Macros ************************************/
5152
5153#define BYTES_TO_DWORDS(bytes) ((bytes) / BYTES_IN_DWORD)
5154
5155/***************************** Constant Arrays *******************************/
5156
5157/* Status string array */
5158static const char * const s_status_str[] = {
5159 "Operation completed successfully",
5160 "Debug application version wasn't set",
5161 "Unsupported debug application version",
5162 "The debug block wasn't reset since the last recording",
5163 "Invalid arguments",
5164 "The debug output was already set",
5165 "Invalid PCI buffer size",
5166 "PCI buffer allocation failed",
5167 "A PCI buffer wasn't allocated",
5168 "Too many inputs were enabled. Enabled less inputs, or set 'unifyInputs' to true",
5169 "GRC/Timestamp input overlap in cycle dword 0",
5170 "Cannot record Storm data since the entire recording cycle is used by HW",
5171 "The Storm was already enabled",
5172 "The specified Storm wasn't enabled",
5173 "The block was already enabled",
5174 "The specified block wasn't enabled",
5175 "No input was enabled for recording",
5176 "Filters and triggers are not allowed when recording in 64b units",
5177 "The filter was already enabled",
5178 "The trigger was already enabled",
5179 "The trigger wasn't enabled",
5180 "A constraint can be added only after a filter was enabled or a trigger state was added",
5181 "Cannot add more than 3 trigger states",
5182 "Cannot add more than 4 constraints per filter or trigger state",
5183 "The recording wasn't started",
5184 "A trigger was configured, but it didn't trigger",
5185 "No data was recorded",
5186 "Dump buffer is too small",
5187 "Dumped data is not aligned to chunks",
5188 "Unknown chip",
5189 "Failed allocating virtual memory",
5190 "The input block is in reset",
5191 "Invalid MCP trace signature found in NVRAM",
5192 "Invalid bundle ID found in NVRAM",
5193 "Failed getting NVRAM image",
5194 "NVRAM image is not dword-aligned",
5195 "Failed reading from NVRAM",
5196 "Idle check parsing failed",
5197 "MCP Trace data is corrupt",
5198 "Dump doesn't contain meta data - it must be provided in an image file",
5199 "Failed to halt MCP",
5200 "Failed to resume MCP after halt",
5201 "DMAE transaction failed",
5202 "Failed to empty SEMI sync FIFO",
5203 "IGU FIFO data is corrupt",
5204 "MCP failed to mask parities",
5205 "FW Asserts parsing failed",
5206 "GRC FIFO data is corrupt",
5207 "Protection Override data is corrupt",
5208 "Debug arrays were not set (when using binary files, dbg_set_bin_ptr must be called)",
5209 "When a block is filtered, no other blocks can be recorded unless inputs are unified (due to a HW bug)"
5210};
5211
5212/* Idle check severity names array */
5213static const char * const s_idle_chk_severity_str[] = {
5214 "Error",
5215 "Error if no traffic",
5216 "Warning"
5217};
5218
5219/* MCP Trace level names array */
5220static const char * const s_mcp_trace_level_str[] = {
5221 "ERROR",
5222 "TRACE",
5223 "DEBUG"
5224};
5225
5226/* Parsing strings */
5227static const char * const s_access_strs[] = {
5228 "read",
5229 "write"
5230};
5231
5232static const char * const s_privilege_strs[] = {
5233 "VF",
5234 "PDA",
5235 "HV",
5236 "UA"
5237};
5238
5239static const char * const s_protection_strs[] = {
5240 "(default)",
5241 "(default)",
5242 "(default)",
5243 "(default)",
5244 "override VF",
5245 "override PDA",
5246 "override HV",
5247 "override UA"
5248};
5249
5250static const char * const s_master_strs[] = {
5251 "???",
5252 "pxp",
5253 "mcp",
5254 "msdm",
5255 "psdm",
5256 "ysdm",
5257 "usdm",
5258 "tsdm",
5259 "xsdm",
5260 "dbu",
5261 "dmae",
5262 "???",
5263 "???",
5264 "???",
5265 "???",
5266 "???"
5267};
5268
5269static const char * const s_reg_fifo_error_strs[] = {
5270 "grc timeout",
5271 "address doesn't belong to any block",
5272 "reserved address in block or write to read-only address",
5273 "privilege/protection mismatch",
5274 "path isolation error"
5275};
5276
5277static const char * const s_igu_fifo_source_strs[] = {
5278 "TSTORM",
5279 "MSTORM",
5280 "USTORM",
5281 "XSTORM",
5282 "YSTORM",
5283 "PSTORM",
5284 "PCIE",
5285 "NIG_QM_PBF",
5286 "CAU",
5287 "ATTN",
5288 "GRC",
5289};
5290
5291static const char * const s_igu_fifo_error_strs[] = {
5292 "no error",
5293 "length error",
5294 "function disabled",
5295 "VF sent command to attnetion address",
5296 "host sent prod update command",
5297 "read of during interrupt register while in MIMD mode",
5298 "access to PXP BAR reserved address",
5299 "producer update command to attention index",
5300 "unknown error",
5301 "SB index not valid",
5302 "SB relative index and FID not found",
5303 "FID not match",
5304 "command with error flag asserted (PCI error or CAU discard)",
5305 "VF sent cleanup and RF cleanup is disabled",
5306 "cleanup command on type bigger than 4"
5307};
5308
5309/* IGU FIFO address data */
5310static const struct igu_fifo_addr_data s_igu_fifo_addr_data[] = {
5311 {0x0, 0x101, "MSI-X Memory", NULL, IGU_ADDR_TYPE_MSIX_MEM},
5312 {0x102, 0x1ff, "reserved", NULL, IGU_ADDR_TYPE_RESERVED},
5313 {0x200, 0x200, "Write PBA[0:63]", NULL, IGU_ADDR_TYPE_WRITE_PBA},
5314 {0x201, 0x201, "Write PBA[64:127]", "reserved",
5315 IGU_ADDR_TYPE_WRITE_PBA},
5316 {0x202, 0x202, "Write PBA[128]", "reserved", IGU_ADDR_TYPE_WRITE_PBA},
5317 {0x203, 0x3ff, "reserved", NULL, IGU_ADDR_TYPE_RESERVED},
5318 {0x400, 0x5ef, "Write interrupt acknowledgment", NULL,
5319 IGU_ADDR_TYPE_WRITE_INT_ACK},
5320 {0x5f0, 0x5f0, "Attention bits update", NULL,
5321 IGU_ADDR_TYPE_WRITE_ATTN_BITS},
5322 {0x5f1, 0x5f1, "Attention bits set", NULL,
5323 IGU_ADDR_TYPE_WRITE_ATTN_BITS},
5324 {0x5f2, 0x5f2, "Attention bits clear", NULL,
5325 IGU_ADDR_TYPE_WRITE_ATTN_BITS},
5326 {0x5f3, 0x5f3, "Read interrupt 0:63 with mask", NULL,
5327 IGU_ADDR_TYPE_READ_INT},
5328 {0x5f4, 0x5f4, "Read interrupt 0:31 with mask", NULL,
5329 IGU_ADDR_TYPE_READ_INT},
5330 {0x5f5, 0x5f5, "Read interrupt 32:63 with mask", NULL,
5331 IGU_ADDR_TYPE_READ_INT},
5332 {0x5f6, 0x5f6, "Read interrupt 0:63 without mask", NULL,
5333 IGU_ADDR_TYPE_READ_INT},
5334 {0x5f7, 0x5ff, "reserved", NULL, IGU_ADDR_TYPE_RESERVED},
5335 {0x600, 0x7ff, "Producer update", NULL, IGU_ADDR_TYPE_WRITE_PROD_UPDATE}
5336};
5337
5338/******************************** Variables **********************************/
5339
5340/* MCP Trace meta data - used in case the dump doesn't contain the meta data
5341 * (e.g. due to no NVRAM access).
5342 */
5343static struct dbg_array s_mcp_trace_meta = { NULL, 0 };
5344
5345/* Temporary buffer, used for print size calculations */
5346static char s_temp_buf[MAX_MSG_LEN];
5347
5348/***************************** Public Functions *******************************/
5349
5350enum dbg_status qed_dbg_user_set_bin_ptr(const u8 * const bin_ptr)
5351{
5352 /* Convert binary data to debug arrays */
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02005353 struct bin_buffer_hdr *buf_array = (struct bin_buffer_hdr *)bin_ptr;
Tomer Tayarc965db42016-09-07 16:36:24 +03005354 u8 buf_id;
5355
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02005356 for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++) {
Tomer Tayarc965db42016-09-07 16:36:24 +03005357 s_dbg_arrays[buf_id].ptr =
5358 (u32 *)(bin_ptr + buf_array[buf_id].offset);
5359 s_dbg_arrays[buf_id].size_in_dwords =
5360 BYTES_TO_DWORDS(buf_array[buf_id].length);
5361 }
5362
5363 return DBG_STATUS_OK;
5364}
5365
5366static u32 qed_cyclic_add(u32 a, u32 b, u32 size)
5367{
5368 return (a + b) % size;
5369}
5370
5371static u32 qed_cyclic_sub(u32 a, u32 b, u32 size)
5372{
5373 return (size + a - b) % size;
5374}
5375
5376/* Reads the specified number of bytes from the specified cyclic buffer (up to 4
5377 * bytes) and returns them as a dword value. the specified buffer offset is
5378 * updated.
5379 */
5380static u32 qed_read_from_cyclic_buf(void *buf,
5381 u32 *offset,
5382 u32 buf_size, u8 num_bytes_to_read)
5383{
5384 u8 *bytes_buf = (u8 *)buf;
5385 u8 *val_ptr;
5386 u32 val = 0;
5387 u8 i;
5388
5389 val_ptr = (u8 *)&val;
5390
5391 for (i = 0; i < num_bytes_to_read; i++) {
5392 val_ptr[i] = bytes_buf[*offset];
5393 *offset = qed_cyclic_add(*offset, 1, buf_size);
5394 }
5395
5396 return val;
5397}
5398
5399/* Reads and returns the next byte from the specified buffer.
5400 * The specified buffer offset is updated.
5401 */
5402static u8 qed_read_byte_from_buf(void *buf, u32 *offset)
5403{
5404 return ((u8 *)buf)[(*offset)++];
5405}
5406
5407/* Reads and returns the next dword from the specified buffer.
5408 * The specified buffer offset is updated.
5409 */
5410static u32 qed_read_dword_from_buf(void *buf, u32 *offset)
5411{
5412 u32 dword_val = *(u32 *)&((u8 *)buf)[*offset];
5413
5414 *offset += 4;
5415 return dword_val;
5416}
5417
5418/* Reads the next string from the specified buffer, and copies it to the
5419 * specified pointer. The specified buffer offset is updated.
5420 */
5421static void qed_read_str_from_buf(void *buf, u32 *offset, u32 size, char *dest)
5422{
5423 const char *source_str = &((const char *)buf)[*offset];
5424
5425 strncpy(dest, source_str, size);
5426 dest[size - 1] = '\0';
5427 *offset += size;
5428}
5429
5430/* Returns a pointer to the specified offset (in bytes) of the specified buffer.
5431 * If the specified buffer in NULL, a temporary buffer pointer is returned.
5432 */
5433static char *qed_get_buf_ptr(void *buf, u32 offset)
5434{
5435 return buf ? (char *)buf + offset : s_temp_buf;
5436}
5437
5438/* Reads a param from the specified buffer. Returns the number of dwords read.
5439 * If the returned str_param is NULL, the param is numeric and its value is
5440 * returned in num_param.
5441 * Otheriwise, the param is a string and its pointer is returned in str_param.
5442 */
5443static u32 qed_read_param(u32 *dump_buf,
5444 const char **param_name,
5445 const char **param_str_val, u32 *param_num_val)
5446{
5447 char *char_buf = (char *)dump_buf;
5448 u32 offset = 0; /* In bytes */
5449
5450 /* Extract param name */
5451 *param_name = char_buf;
5452 offset += strlen(*param_name) + 1;
5453
5454 /* Check param type */
5455 if (*(char_buf + offset++)) {
5456 /* String param */
5457 *param_str_val = char_buf + offset;
5458 offset += strlen(*param_str_val) + 1;
5459 if (offset & 0x3)
5460 offset += (4 - (offset & 0x3));
5461 } else {
5462 /* Numeric param */
5463 *param_str_val = NULL;
5464 if (offset & 0x3)
5465 offset += (4 - (offset & 0x3));
5466 *param_num_val = *(u32 *)(char_buf + offset);
5467 offset += 4;
5468 }
5469
5470 return offset / 4;
5471}
5472
5473/* Reads a section header from the specified buffer.
5474 * Returns the number of dwords read.
5475 */
5476static u32 qed_read_section_hdr(u32 *dump_buf,
5477 const char **section_name,
5478 u32 *num_section_params)
5479{
5480 const char *param_str_val;
5481
5482 return qed_read_param(dump_buf,
5483 section_name, &param_str_val, num_section_params);
5484}
5485
5486/* Reads section params from the specified buffer and prints them to the results
5487 * buffer. Returns the number of dwords read.
5488 */
5489static u32 qed_print_section_params(u32 *dump_buf,
5490 u32 num_section_params,
5491 char *results_buf, u32 *num_chars_printed)
5492{
5493 u32 i, dump_offset = 0, results_offset = 0;
5494
5495 for (i = 0; i < num_section_params; i++) {
5496 const char *param_name;
5497 const char *param_str_val;
5498 u32 param_num_val = 0;
5499
5500 dump_offset += qed_read_param(dump_buf + dump_offset,
5501 &param_name,
5502 &param_str_val, &param_num_val);
5503 if (param_str_val)
5504 /* String param */
5505 results_offset +=
5506 sprintf(qed_get_buf_ptr(results_buf,
5507 results_offset),
5508 "%s: %s\n", param_name, param_str_val);
5509 else if (strcmp(param_name, "fw-timestamp"))
5510 /* Numeric param */
5511 results_offset +=
5512 sprintf(qed_get_buf_ptr(results_buf,
5513 results_offset),
5514 "%s: %d\n", param_name, param_num_val);
5515 }
5516
5517 results_offset +=
5518 sprintf(qed_get_buf_ptr(results_buf, results_offset), "\n");
5519 *num_chars_printed = results_offset;
5520 return dump_offset;
5521}
5522
5523const char *qed_dbg_get_status_str(enum dbg_status status)
5524{
5525 return (status <
5526 MAX_DBG_STATUS) ? s_status_str[status] : "Invalid debug status";
5527}
5528
5529/* Parses the idle check rules and returns the number of characters printed.
5530 * In case of parsing error, returns 0.
5531 */
5532static u32 qed_parse_idle_chk_dump_rules(struct qed_hwfn *p_hwfn,
5533 u32 *dump_buf,
5534 u32 *dump_buf_end,
5535 u32 num_rules,
5536 bool print_fw_idle_chk,
5537 char *results_buf,
5538 u32 *num_errors, u32 *num_warnings)
5539{
5540 u32 rule_idx, results_offset = 0; /* Offset in results_buf in bytes */
5541 u16 i, j;
5542
5543 *num_errors = 0;
5544 *num_warnings = 0;
5545
5546 /* Go over dumped results */
5547 for (rule_idx = 0; rule_idx < num_rules && dump_buf < dump_buf_end;
5548 rule_idx++) {
5549 const struct dbg_idle_chk_rule_parsing_data *rule_parsing_data;
5550 struct dbg_idle_chk_result_hdr *hdr;
5551 const char *parsing_str;
5552 u32 parsing_str_offset;
5553 const char *lsi_msg;
5554 u8 curr_reg_id = 0;
5555 bool has_fw_msg;
5556
5557 hdr = (struct dbg_idle_chk_result_hdr *)dump_buf;
5558 rule_parsing_data =
5559 (const struct dbg_idle_chk_rule_parsing_data *)
5560 &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].
5561 ptr[hdr->rule_id];
5562 parsing_str_offset =
5563 GET_FIELD(rule_parsing_data->data,
5564 DBG_IDLE_CHK_RULE_PARSING_DATA_STR_OFFSET);
5565 has_fw_msg =
5566 GET_FIELD(rule_parsing_data->data,
5567 DBG_IDLE_CHK_RULE_PARSING_DATA_HAS_FW_MSG) > 0;
5568 parsing_str = &((const char *)
5569 s_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr)
5570 [parsing_str_offset];
5571 lsi_msg = parsing_str;
5572
5573 if (hdr->severity >= MAX_DBG_IDLE_CHK_SEVERITY_TYPES)
5574 return 0;
5575
5576 /* Skip rule header */
5577 dump_buf += (sizeof(struct dbg_idle_chk_result_hdr) / 4);
5578
5579 /* Update errors/warnings count */
5580 if (hdr->severity == IDLE_CHK_SEVERITY_ERROR ||
5581 hdr->severity == IDLE_CHK_SEVERITY_ERROR_NO_TRAFFIC)
5582 (*num_errors)++;
5583 else
5584 (*num_warnings)++;
5585
5586 /* Print rule severity */
5587 results_offset +=
5588 sprintf(qed_get_buf_ptr(results_buf,
5589 results_offset), "%s: ",
5590 s_idle_chk_severity_str[hdr->severity]);
5591
5592 /* Print rule message */
5593 if (has_fw_msg)
5594 parsing_str += strlen(parsing_str) + 1;
5595 results_offset +=
5596 sprintf(qed_get_buf_ptr(results_buf,
5597 results_offset), "%s.",
5598 has_fw_msg &&
5599 print_fw_idle_chk ? parsing_str : lsi_msg);
5600 parsing_str += strlen(parsing_str) + 1;
5601
5602 /* Print register values */
5603 results_offset +=
5604 sprintf(qed_get_buf_ptr(results_buf,
5605 results_offset), " Registers:");
5606 for (i = 0;
5607 i < hdr->num_dumped_cond_regs + hdr->num_dumped_info_regs;
5608 i++) {
5609 struct dbg_idle_chk_result_reg_hdr *reg_hdr
5610 = (struct dbg_idle_chk_result_reg_hdr *)
5611 dump_buf;
5612 bool is_mem =
5613 GET_FIELD(reg_hdr->data,
5614 DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM);
5615 u8 reg_id =
5616 GET_FIELD(reg_hdr->data,
5617 DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID);
5618
5619 /* Skip reg header */
5620 dump_buf +=
5621 (sizeof(struct dbg_idle_chk_result_reg_hdr) / 4);
5622
5623 /* Skip register names until the required reg_id is
5624 * reached.
5625 */
5626 for (; reg_id > curr_reg_id;
5627 curr_reg_id++,
5628 parsing_str += strlen(parsing_str) + 1);
5629
5630 results_offset +=
5631 sprintf(qed_get_buf_ptr(results_buf,
5632 results_offset), " %s",
5633 parsing_str);
5634 if (i < hdr->num_dumped_cond_regs && is_mem)
5635 results_offset +=
5636 sprintf(qed_get_buf_ptr(results_buf,
5637 results_offset),
5638 "[%d]", hdr->mem_entry_id +
5639 reg_hdr->start_entry);
5640 results_offset +=
5641 sprintf(qed_get_buf_ptr(results_buf,
5642 results_offset), "=");
5643 for (j = 0; j < reg_hdr->size; j++, dump_buf++) {
5644 results_offset +=
5645 sprintf(qed_get_buf_ptr(results_buf,
5646 results_offset),
5647 "0x%x", *dump_buf);
5648 if (j < reg_hdr->size - 1)
5649 results_offset +=
5650 sprintf(qed_get_buf_ptr
5651 (results_buf,
5652 results_offset), ",");
5653 }
5654 }
5655
5656 results_offset +=
5657 sprintf(qed_get_buf_ptr(results_buf, results_offset), "\n");
5658 }
5659
5660 /* Check if end of dump buffer was exceeded */
5661 if (dump_buf > dump_buf_end)
5662 return 0;
5663 return results_offset;
5664}
5665
5666/* Parses an idle check dump buffer.
5667 * If result_buf is not NULL, the idle check results are printed to it.
5668 * In any case, the required results buffer size is assigned to
5669 * parsed_results_bytes.
5670 * The parsing status is returned.
5671 */
5672static enum dbg_status qed_parse_idle_chk_dump(struct qed_hwfn *p_hwfn,
5673 u32 *dump_buf,
5674 u32 num_dumped_dwords,
5675 char *results_buf,
5676 u32 *parsed_results_bytes,
5677 u32 *num_errors,
5678 u32 *num_warnings)
5679{
5680 const char *section_name, *param_name, *param_str_val;
5681 u32 *dump_buf_end = dump_buf + num_dumped_dwords;
5682 u32 num_section_params = 0, num_rules;
5683 u32 results_offset = 0; /* Offset in results_buf in bytes */
5684
5685 *parsed_results_bytes = 0;
5686 *num_errors = 0;
5687 *num_warnings = 0;
5688 if (!s_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr ||
5689 !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr)
5690 return DBG_STATUS_DBG_ARRAY_NOT_SET;
5691
5692 /* Read global_params section */
5693 dump_buf += qed_read_section_hdr(dump_buf,
5694 &section_name, &num_section_params);
5695 if (strcmp(section_name, "global_params"))
5696 return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
5697
5698 /* Print global params */
5699 dump_buf += qed_print_section_params(dump_buf,
5700 num_section_params,
5701 results_buf, &results_offset);
5702
5703 /* Read idle_chk section */
5704 dump_buf += qed_read_section_hdr(dump_buf,
5705 &section_name, &num_section_params);
5706 if (strcmp(section_name, "idle_chk") || num_section_params != 1)
5707 return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
5708
5709 dump_buf += qed_read_param(dump_buf,
5710 &param_name, &param_str_val, &num_rules);
5711 if (strcmp(param_name, "num_rules") != 0)
5712 return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
5713
5714 if (num_rules) {
5715 u32 rules_print_size;
5716
5717 /* Print FW output */
5718 results_offset +=
5719 sprintf(qed_get_buf_ptr(results_buf,
5720 results_offset),
5721 "FW_IDLE_CHECK:\n");
5722 rules_print_size =
5723 qed_parse_idle_chk_dump_rules(p_hwfn, dump_buf,
5724 dump_buf_end, num_rules,
5725 true,
5726 results_buf ?
5727 results_buf +
5728 results_offset : NULL,
5729 num_errors, num_warnings);
5730 results_offset += rules_print_size;
5731 if (rules_print_size == 0)
5732 return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
5733
5734 /* Print LSI output */
5735 results_offset +=
5736 sprintf(qed_get_buf_ptr(results_buf,
5737 results_offset),
5738 "\nLSI_IDLE_CHECK:\n");
5739 rules_print_size =
5740 qed_parse_idle_chk_dump_rules(p_hwfn, dump_buf,
5741 dump_buf_end, num_rules,
5742 false,
5743 results_buf ?
5744 results_buf +
5745 results_offset : NULL,
5746 num_errors, num_warnings);
5747 results_offset += rules_print_size;
5748 if (rules_print_size == 0)
5749 return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
5750 }
5751
5752 /* Print errors/warnings count */
5753 if (*num_errors) {
5754 results_offset +=
5755 sprintf(qed_get_buf_ptr(results_buf,
5756 results_offset),
5757 "\nIdle Check failed!!! (with %d errors and %d warnings)\n",
5758 *num_errors, *num_warnings);
5759 } else if (*num_warnings) {
5760 results_offset +=
5761 sprintf(qed_get_buf_ptr(results_buf,
5762 results_offset),
5763 "\nIdle Check completed successfuly (with %d warnings)\n",
5764 *num_warnings);
5765 } else {
5766 results_offset +=
5767 sprintf(qed_get_buf_ptr(results_buf,
5768 results_offset),
5769 "\nIdle Check completed successfuly\n");
5770 }
5771
5772 /* Add 1 for string NULL termination */
5773 *parsed_results_bytes = results_offset + 1;
5774 return DBG_STATUS_OK;
5775}
5776
5777enum dbg_status qed_get_idle_chk_results_buf_size(struct qed_hwfn *p_hwfn,
5778 u32 *dump_buf,
5779 u32 num_dumped_dwords,
5780 u32 *results_buf_size)
5781{
5782 u32 num_errors, num_warnings;
5783
5784 return qed_parse_idle_chk_dump(p_hwfn,
5785 dump_buf,
5786 num_dumped_dwords,
5787 NULL,
5788 results_buf_size,
5789 &num_errors, &num_warnings);
5790}
5791
5792enum dbg_status qed_print_idle_chk_results(struct qed_hwfn *p_hwfn,
5793 u32 *dump_buf,
5794 u32 num_dumped_dwords,
5795 char *results_buf,
5796 u32 *num_errors, u32 *num_warnings)
5797{
5798 u32 parsed_buf_size;
5799
5800 return qed_parse_idle_chk_dump(p_hwfn,
5801 dump_buf,
5802 num_dumped_dwords,
5803 results_buf,
5804 &parsed_buf_size,
5805 num_errors, num_warnings);
5806}
5807
5808/* Frees the specified MCP Trace meta data */
5809static void qed_mcp_trace_free_meta(struct qed_hwfn *p_hwfn,
5810 struct mcp_trace_meta *meta)
5811{
5812 u32 i;
5813
5814 /* Release modules */
5815 if (meta->modules) {
5816 for (i = 0; i < meta->modules_num; i++)
5817 kfree(meta->modules[i]);
5818 kfree(meta->modules);
5819 }
5820
5821 /* Release formats */
5822 if (meta->formats) {
5823 for (i = 0; i < meta->formats_num; i++)
5824 kfree(meta->formats[i].format_str);
5825 kfree(meta->formats);
5826 }
5827}
5828
5829/* Allocates and fills MCP Trace meta data based on the specified meta data
5830 * dump buffer.
5831 * Returns debug status code.
5832 */
5833static enum dbg_status qed_mcp_trace_alloc_meta(struct qed_hwfn *p_hwfn,
5834 const u32 *meta_buf,
5835 struct mcp_trace_meta *meta)
5836{
5837 u8 *meta_buf_bytes = (u8 *)meta_buf;
5838 u32 offset = 0, signature, i;
5839
5840 memset(meta, 0, sizeof(*meta));
5841
5842 /* Read first signature */
5843 signature = qed_read_dword_from_buf(meta_buf_bytes, &offset);
5844 if (signature != MCP_TRACE_META_IMAGE_SIGNATURE)
5845 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
5846
5847 /* Read number of modules and allocate memory for all the modules
5848 * pointers.
5849 */
5850 meta->modules_num = qed_read_byte_from_buf(meta_buf_bytes, &offset);
5851 meta->modules = kzalloc(meta->modules_num * sizeof(char *), GFP_KERNEL);
5852 if (!meta->modules)
5853 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
5854
5855 /* Allocate and read all module strings */
5856 for (i = 0; i < meta->modules_num; i++) {
5857 u8 module_len = qed_read_byte_from_buf(meta_buf_bytes, &offset);
5858
5859 *(meta->modules + i) = kzalloc(module_len, GFP_KERNEL);
5860 if (!(*(meta->modules + i))) {
5861 /* Update number of modules to be released */
5862 meta->modules_num = i ? i - 1 : 0;
5863 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
5864 }
5865
5866 qed_read_str_from_buf(meta_buf_bytes, &offset, module_len,
5867 *(meta->modules + i));
5868 if (module_len > MCP_TRACE_MAX_MODULE_LEN)
5869 (*(meta->modules + i))[MCP_TRACE_MAX_MODULE_LEN] = '\0';
5870 }
5871
5872 /* Read second signature */
5873 signature = qed_read_dword_from_buf(meta_buf_bytes, &offset);
5874 if (signature != MCP_TRACE_META_IMAGE_SIGNATURE)
5875 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
5876
5877 /* Read number of formats and allocate memory for all formats */
5878 meta->formats_num = qed_read_dword_from_buf(meta_buf_bytes, &offset);
5879 meta->formats = kzalloc(meta->formats_num *
5880 sizeof(struct mcp_trace_format),
5881 GFP_KERNEL);
5882 if (!meta->formats)
5883 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
5884
5885 /* Allocate and read all strings */
5886 for (i = 0; i < meta->formats_num; i++) {
5887 struct mcp_trace_format *format_ptr = &meta->formats[i];
5888 u8 format_len;
5889
5890 format_ptr->data = qed_read_dword_from_buf(meta_buf_bytes,
5891 &offset);
5892 format_len =
5893 (format_ptr->data &
5894 MCP_TRACE_FORMAT_LEN_MASK) >> MCP_TRACE_FORMAT_LEN_SHIFT;
5895 format_ptr->format_str = kzalloc(format_len, GFP_KERNEL);
5896 if (!format_ptr->format_str) {
5897 /* Update number of modules to be released */
5898 meta->formats_num = i ? i - 1 : 0;
5899 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
5900 }
5901
5902 qed_read_str_from_buf(meta_buf_bytes,
5903 &offset,
5904 format_len, format_ptr->format_str);
5905 }
5906
5907 return DBG_STATUS_OK;
5908}
5909
5910/* Parses an MCP Trace dump buffer.
5911 * If result_buf is not NULL, the MCP Trace results are printed to it.
5912 * In any case, the required results buffer size is assigned to
5913 * parsed_results_bytes.
5914 * The parsing status is returned.
5915 */
5916static enum dbg_status qed_parse_mcp_trace_dump(struct qed_hwfn *p_hwfn,
5917 u32 *dump_buf,
5918 u32 num_dumped_dwords,
5919 char *results_buf,
5920 u32 *parsed_results_bytes)
5921{
5922 u32 results_offset = 0, param_mask, param_shift, param_num_val;
5923 u32 num_section_params, offset, end_offset, bytes_left;
5924 const char *section_name, *param_name, *param_str_val;
5925 u32 trace_data_dwords, trace_meta_dwords;
5926 struct mcp_trace_meta meta;
5927 struct mcp_trace *trace;
5928 enum dbg_status status;
5929 const u32 *meta_buf;
5930 u8 *trace_buf;
5931
5932 *parsed_results_bytes = 0;
5933
5934 /* Read global_params section */
5935 dump_buf += qed_read_section_hdr(dump_buf,
5936 &section_name, &num_section_params);
5937 if (strcmp(section_name, "global_params"))
5938 return DBG_STATUS_MCP_TRACE_BAD_DATA;
5939
5940 /* Print global params */
5941 dump_buf += qed_print_section_params(dump_buf,
5942 num_section_params,
5943 results_buf, &results_offset);
5944
5945 /* Read trace_data section */
5946 dump_buf += qed_read_section_hdr(dump_buf,
5947 &section_name, &num_section_params);
5948 if (strcmp(section_name, "mcp_trace_data") || num_section_params != 1)
5949 return DBG_STATUS_MCP_TRACE_BAD_DATA;
5950 dump_buf += qed_read_param(dump_buf,
5951 &param_name, &param_str_val, &param_num_val);
5952 if (strcmp(param_name, "size"))
5953 return DBG_STATUS_MCP_TRACE_BAD_DATA;
5954 trace_data_dwords = param_num_val;
5955
5956 /* Prepare trace info */
5957 trace = (struct mcp_trace *)dump_buf;
5958 trace_buf = (u8 *)dump_buf + sizeof(struct mcp_trace);
5959 offset = trace->trace_oldest;
5960 end_offset = trace->trace_prod;
5961 bytes_left = qed_cyclic_sub(end_offset, offset, trace->size);
5962 dump_buf += trace_data_dwords;
5963
5964 /* Read meta_data section */
5965 dump_buf += qed_read_section_hdr(dump_buf,
5966 &section_name, &num_section_params);
5967 if (strcmp(section_name, "mcp_trace_meta"))
5968 return DBG_STATUS_MCP_TRACE_BAD_DATA;
5969 dump_buf += qed_read_param(dump_buf,
5970 &param_name, &param_str_val, &param_num_val);
5971 if (strcmp(param_name, "size") != 0)
5972 return DBG_STATUS_MCP_TRACE_BAD_DATA;
5973 trace_meta_dwords = param_num_val;
5974
5975 /* Choose meta data buffer */
5976 if (!trace_meta_dwords) {
5977 /* Dump doesn't include meta data */
5978 if (!s_mcp_trace_meta.ptr)
5979 return DBG_STATUS_MCP_TRACE_NO_META;
5980 meta_buf = s_mcp_trace_meta.ptr;
5981 } else {
5982 /* Dump includes meta data */
5983 meta_buf = dump_buf;
5984 }
5985
5986 /* Allocate meta data memory */
5987 status = qed_mcp_trace_alloc_meta(p_hwfn, meta_buf, &meta);
5988 if (status != DBG_STATUS_OK)
5989 goto free_mem;
5990
5991 /* Ignore the level and modules masks - just print everything that is
5992 * already in the buffer.
5993 */
5994 while (bytes_left) {
5995 struct mcp_trace_format *format_ptr;
5996 u8 format_level, format_module;
5997 u32 params[3] = { 0, 0, 0 };
5998 u32 header, format_idx, i;
5999
6000 if (bytes_left < MFW_TRACE_ENTRY_SIZE) {
6001 status = DBG_STATUS_MCP_TRACE_BAD_DATA;
6002 goto free_mem;
6003 }
6004
6005 header = qed_read_from_cyclic_buf(trace_buf,
6006 &offset,
6007 trace->size,
6008 MFW_TRACE_ENTRY_SIZE);
6009 bytes_left -= MFW_TRACE_ENTRY_SIZE;
6010 format_idx = header & MFW_TRACE_EVENTID_MASK;
6011
6012 /* Skip message if its index doesn't exist in the meta data */
6013 if (format_idx > meta.formats_num) {
6014 u8 format_size =
6015 (u8)((header &
6016 MFW_TRACE_PRM_SIZE_MASK) >>
6017 MFW_TRACE_PRM_SIZE_SHIFT);
6018
6019 if (bytes_left < format_size) {
6020 status = DBG_STATUS_MCP_TRACE_BAD_DATA;
6021 goto free_mem;
6022 }
6023
6024 offset = qed_cyclic_add(offset,
6025 format_size, trace->size);
6026 bytes_left -= format_size;
6027 continue;
6028 }
6029
6030 format_ptr = &meta.formats[format_idx];
6031 for (i = 0,
6032 param_mask = MCP_TRACE_FORMAT_P1_SIZE_MASK, param_shift =
6033 MCP_TRACE_FORMAT_P1_SIZE_SHIFT;
6034 i < MCP_TRACE_FORMAT_MAX_PARAMS;
6035 i++, param_mask <<= MCP_TRACE_FORMAT_PARAM_WIDTH,
6036 param_shift += MCP_TRACE_FORMAT_PARAM_WIDTH) {
6037 /* Extract param size (0..3) */
6038 u8 param_size =
6039 (u8)((format_ptr->data &
6040 param_mask) >> param_shift);
6041
6042 /* If the param size is zero, there are no other
6043 * parameters.
6044 */
6045 if (!param_size)
6046 break;
6047
6048 /* Size is encoded using 2 bits, where 3 is used to
6049 * encode 4.
6050 */
6051 if (param_size == 3)
6052 param_size = 4;
6053 if (bytes_left < param_size) {
6054 status = DBG_STATUS_MCP_TRACE_BAD_DATA;
6055 goto free_mem;
6056 }
6057
6058 params[i] = qed_read_from_cyclic_buf(trace_buf,
6059 &offset,
6060 trace->size,
6061 param_size);
6062 bytes_left -= param_size;
6063 }
6064
6065 format_level =
6066 (u8)((format_ptr->data &
6067 MCP_TRACE_FORMAT_LEVEL_MASK) >>
6068 MCP_TRACE_FORMAT_LEVEL_SHIFT);
6069 format_module =
6070 (u8)((format_ptr->data &
6071 MCP_TRACE_FORMAT_MODULE_MASK) >>
6072 MCP_TRACE_FORMAT_MODULE_SHIFT);
6073 if (format_level >= ARRAY_SIZE(s_mcp_trace_level_str)) {
6074 status = DBG_STATUS_MCP_TRACE_BAD_DATA;
6075 goto free_mem;
6076 }
6077
6078 /* Print current message to results buffer */
6079 results_offset +=
6080 sprintf(qed_get_buf_ptr(results_buf,
6081 results_offset), "%s %-8s: ",
6082 s_mcp_trace_level_str[format_level],
6083 meta.modules[format_module]);
6084 results_offset +=
6085 sprintf(qed_get_buf_ptr(results_buf,
6086 results_offset),
6087 format_ptr->format_str, params[0], params[1],
6088 params[2]);
6089 }
6090
6091free_mem:
6092 *parsed_results_bytes = results_offset + 1;
6093 qed_mcp_trace_free_meta(p_hwfn, &meta);
6094 return status;
6095}
6096
6097enum dbg_status qed_get_mcp_trace_results_buf_size(struct qed_hwfn *p_hwfn,
6098 u32 *dump_buf,
6099 u32 num_dumped_dwords,
6100 u32 *results_buf_size)
6101{
6102 return qed_parse_mcp_trace_dump(p_hwfn,
6103 dump_buf,
6104 num_dumped_dwords,
6105 NULL, results_buf_size);
6106}
6107
6108enum dbg_status qed_print_mcp_trace_results(struct qed_hwfn *p_hwfn,
6109 u32 *dump_buf,
6110 u32 num_dumped_dwords,
6111 char *results_buf)
6112{
6113 u32 parsed_buf_size;
6114
6115 return qed_parse_mcp_trace_dump(p_hwfn,
6116 dump_buf,
6117 num_dumped_dwords,
6118 results_buf, &parsed_buf_size);
6119}
6120
6121/* Parses a Reg FIFO dump buffer.
6122 * If result_buf is not NULL, the Reg FIFO results are printed to it.
6123 * In any case, the required results buffer size is assigned to
6124 * parsed_results_bytes.
6125 * The parsing status is returned.
6126 */
6127static enum dbg_status qed_parse_reg_fifo_dump(struct qed_hwfn *p_hwfn,
6128 u32 *dump_buf,
6129 u32 num_dumped_dwords,
6130 char *results_buf,
6131 u32 *parsed_results_bytes)
6132{
6133 u32 results_offset = 0, param_num_val, num_section_params, num_elements;
6134 const char *section_name, *param_name, *param_str_val;
6135 struct reg_fifo_element *elements;
6136 u8 i, j, err_val, vf_val;
6137 char vf_str[4];
6138
6139 /* Read global_params section */
6140 dump_buf += qed_read_section_hdr(dump_buf,
6141 &section_name, &num_section_params);
6142 if (strcmp(section_name, "global_params"))
6143 return DBG_STATUS_REG_FIFO_BAD_DATA;
6144
6145 /* Print global params */
6146 dump_buf += qed_print_section_params(dump_buf,
6147 num_section_params,
6148 results_buf, &results_offset);
6149
6150 /* Read reg_fifo_data section */
6151 dump_buf += qed_read_section_hdr(dump_buf,
6152 &section_name, &num_section_params);
6153 if (strcmp(section_name, "reg_fifo_data"))
6154 return DBG_STATUS_REG_FIFO_BAD_DATA;
6155 dump_buf += qed_read_param(dump_buf,
6156 &param_name, &param_str_val, &param_num_val);
6157 if (strcmp(param_name, "size"))
6158 return DBG_STATUS_REG_FIFO_BAD_DATA;
6159 if (param_num_val % REG_FIFO_ELEMENT_DWORDS)
6160 return DBG_STATUS_REG_FIFO_BAD_DATA;
6161 num_elements = param_num_val / REG_FIFO_ELEMENT_DWORDS;
6162 elements = (struct reg_fifo_element *)dump_buf;
6163
6164 /* Decode elements */
6165 for (i = 0; i < num_elements; i++) {
6166 bool err_printed = false;
6167
6168 /* Discover if element belongs to a VF or a PF */
6169 vf_val = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_VF);
6170 if (vf_val == REG_FIFO_ELEMENT_IS_PF_VF_VAL)
6171 sprintf(vf_str, "%s", "N/A");
6172 else
6173 sprintf(vf_str, "%d", vf_val);
6174
6175 /* Add parsed element to parsed buffer */
6176 results_offset +=
6177 sprintf(qed_get_buf_ptr(results_buf,
6178 results_offset),
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02006179 "raw: 0x%016llx, address: 0x%07x, access: %-5s, pf: %2d, vf: %s, port: %d, privilege: %-3s, protection: %-12s, master: %-4s, errors: ",
Tomer Tayarc965db42016-09-07 16:36:24 +03006180 elements[i].data,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02006181 (u32)GET_FIELD(elements[i].data,
Tomer Tayarc965db42016-09-07 16:36:24 +03006182 REG_FIFO_ELEMENT_ADDRESS) *
6183 REG_FIFO_ELEMENT_ADDR_FACTOR,
6184 s_access_strs[GET_FIELD(elements[i].data,
6185 REG_FIFO_ELEMENT_ACCESS)],
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02006186 (u32)GET_FIELD(elements[i].data,
6187 REG_FIFO_ELEMENT_PF), vf_str,
6188 (u32)GET_FIELD(elements[i].data,
Tomer Tayarc965db42016-09-07 16:36:24 +03006189 REG_FIFO_ELEMENT_PORT),
6190 s_privilege_strs[GET_FIELD(elements[i].
6191 data,
6192 REG_FIFO_ELEMENT_PRIVILEGE)],
6193 s_protection_strs[GET_FIELD(elements[i].data,
6194 REG_FIFO_ELEMENT_PROTECTION)],
6195 s_master_strs[GET_FIELD(elements[i].data,
6196 REG_FIFO_ELEMENT_MASTER)]);
6197
6198 /* Print errors */
6199 for (j = 0,
6200 err_val = GET_FIELD(elements[i].data,
6201 REG_FIFO_ELEMENT_ERROR);
6202 j < ARRAY_SIZE(s_reg_fifo_error_strs);
6203 j++, err_val >>= 1) {
6204 if (!(err_val & 0x1))
6205 continue;
6206 if (err_printed)
6207 results_offset +=
6208 sprintf(qed_get_buf_ptr(results_buf,
6209 results_offset),
6210 ", ");
6211 results_offset +=
6212 sprintf(qed_get_buf_ptr(results_buf,
6213 results_offset), "%s",
6214 s_reg_fifo_error_strs[j]);
6215 err_printed = true;
6216 }
6217
6218 results_offset +=
6219 sprintf(qed_get_buf_ptr(results_buf, results_offset), "\n");
6220 }
6221
6222 results_offset += sprintf(qed_get_buf_ptr(results_buf,
6223 results_offset),
6224 "fifo contained %d elements", num_elements);
6225
6226 /* Add 1 for string NULL termination */
6227 *parsed_results_bytes = results_offset + 1;
6228 return DBG_STATUS_OK;
6229}
6230
6231enum dbg_status qed_get_reg_fifo_results_buf_size(struct qed_hwfn *p_hwfn,
6232 u32 *dump_buf,
6233 u32 num_dumped_dwords,
6234 u32 *results_buf_size)
6235{
6236 return qed_parse_reg_fifo_dump(p_hwfn,
6237 dump_buf,
6238 num_dumped_dwords,
6239 NULL, results_buf_size);
6240}
6241
6242enum dbg_status qed_print_reg_fifo_results(struct qed_hwfn *p_hwfn,
6243 u32 *dump_buf,
6244 u32 num_dumped_dwords,
6245 char *results_buf)
6246{
6247 u32 parsed_buf_size;
6248
6249 return qed_parse_reg_fifo_dump(p_hwfn,
6250 dump_buf,
6251 num_dumped_dwords,
6252 results_buf, &parsed_buf_size);
6253}
6254
6255/* Parses an IGU FIFO dump buffer.
6256 * If result_buf is not NULL, the IGU FIFO results are printed to it.
6257 * In any case, the required results buffer size is assigned to
6258 * parsed_results_bytes.
6259 * The parsing status is returned.
6260 */
6261static enum dbg_status qed_parse_igu_fifo_dump(struct qed_hwfn *p_hwfn,
6262 u32 *dump_buf,
6263 u32 num_dumped_dwords,
6264 char *results_buf,
6265 u32 *parsed_results_bytes)
6266{
6267 u32 results_offset = 0, param_num_val, num_section_params, num_elements;
6268 const char *section_name, *param_name, *param_str_val;
6269 struct igu_fifo_element *elements;
6270 char parsed_addr_data[32];
6271 char parsed_wr_data[256];
6272 u8 i, j;
6273
6274 /* Read global_params section */
6275 dump_buf += qed_read_section_hdr(dump_buf,
6276 &section_name, &num_section_params);
6277 if (strcmp(section_name, "global_params"))
6278 return DBG_STATUS_IGU_FIFO_BAD_DATA;
6279
6280 /* Print global params */
6281 dump_buf += qed_print_section_params(dump_buf,
6282 num_section_params,
6283 results_buf, &results_offset);
6284
6285 /* Read igu_fifo_data section */
6286 dump_buf += qed_read_section_hdr(dump_buf,
6287 &section_name, &num_section_params);
6288 if (strcmp(section_name, "igu_fifo_data"))
6289 return DBG_STATUS_IGU_FIFO_BAD_DATA;
6290 dump_buf += qed_read_param(dump_buf,
6291 &param_name, &param_str_val, &param_num_val);
6292 if (strcmp(param_name, "size"))
6293 return DBG_STATUS_IGU_FIFO_BAD_DATA;
6294 if (param_num_val % IGU_FIFO_ELEMENT_DWORDS)
6295 return DBG_STATUS_IGU_FIFO_BAD_DATA;
6296 num_elements = param_num_val / IGU_FIFO_ELEMENT_DWORDS;
6297 elements = (struct igu_fifo_element *)dump_buf;
6298
6299 /* Decode elements */
6300 for (i = 0; i < num_elements; i++) {
6301 /* dword12 (dword index 1 and 2) contains bits 32..95 of the
6302 * FIFO element.
6303 */
6304 u64 dword12 =
6305 ((u64)elements[i].dword2 << 32) | elements[i].dword1;
6306 bool is_wr_cmd = GET_FIELD(dword12,
6307 IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD);
6308 bool is_pf = GET_FIELD(elements[i].dword0,
6309 IGU_FIFO_ELEMENT_DWORD0_IS_PF);
6310 u16 cmd_addr = GET_FIELD(elements[i].dword0,
6311 IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR);
6312 u8 source = GET_FIELD(elements[i].dword0,
6313 IGU_FIFO_ELEMENT_DWORD0_SOURCE);
6314 u8 err_type = GET_FIELD(elements[i].dword0,
6315 IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE);
6316 const struct igu_fifo_addr_data *addr_data = NULL;
6317
6318 if (source >= ARRAY_SIZE(s_igu_fifo_source_strs))
6319 return DBG_STATUS_IGU_FIFO_BAD_DATA;
6320 if (err_type >= ARRAY_SIZE(s_igu_fifo_error_strs))
6321 return DBG_STATUS_IGU_FIFO_BAD_DATA;
6322
6323 /* Find address data */
6324 for (j = 0; j < ARRAY_SIZE(s_igu_fifo_addr_data) && !addr_data;
6325 j++)
6326 if (cmd_addr >= s_igu_fifo_addr_data[j].start_addr &&
6327 cmd_addr <= s_igu_fifo_addr_data[j].end_addr)
6328 addr_data = &s_igu_fifo_addr_data[j];
6329 if (!addr_data)
6330 return DBG_STATUS_IGU_FIFO_BAD_DATA;
6331
6332 /* Prepare parsed address data */
6333 switch (addr_data->type) {
6334 case IGU_ADDR_TYPE_MSIX_MEM:
6335 sprintf(parsed_addr_data,
6336 " vector_num=0x%x", cmd_addr / 2);
6337 break;
6338 case IGU_ADDR_TYPE_WRITE_INT_ACK:
6339 case IGU_ADDR_TYPE_WRITE_PROD_UPDATE:
6340 sprintf(parsed_addr_data,
6341 " SB=0x%x", cmd_addr - addr_data->start_addr);
6342 break;
6343 default:
6344 parsed_addr_data[0] = '\0';
6345 }
6346
6347 /* Prepare parsed write data */
6348 if (is_wr_cmd) {
6349 u32 wr_data = GET_FIELD(dword12,
6350 IGU_FIFO_ELEMENT_DWORD12_WR_DATA);
6351 u32 prod_cons = GET_FIELD(wr_data,
6352 IGU_FIFO_WR_DATA_PROD_CONS);
6353 u8 is_cleanup = GET_FIELD(wr_data,
6354 IGU_FIFO_WR_DATA_CMD_TYPE);
6355
6356 if (source == IGU_SRC_ATTN) {
6357 sprintf(parsed_wr_data,
6358 "prod: 0x%x, ", prod_cons);
6359 } else {
6360 if (is_cleanup) {
6361 u8 cleanup_val = GET_FIELD(wr_data,
6362 IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL);
6363 u8 cleanup_type = GET_FIELD(wr_data,
6364 IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE);
6365
6366 sprintf(parsed_wr_data,
6367 "cmd_type: cleanup, cleanup_val: %s, cleanup_type: %d, ",
6368 cleanup_val ? "set" : "clear",
6369 cleanup_type);
6370 } else {
6371 u8 update_flag = GET_FIELD(wr_data,
6372 IGU_FIFO_WR_DATA_UPDATE_FLAG);
6373 u8 en_dis_int_for_sb =
6374 GET_FIELD(wr_data,
6375 IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB);
6376 u8 segment = GET_FIELD(wr_data,
6377 IGU_FIFO_WR_DATA_SEGMENT);
6378 u8 timer_mask = GET_FIELD(wr_data,
6379 IGU_FIFO_WR_DATA_TIMER_MASK);
6380
6381 sprintf(parsed_wr_data,
6382 "cmd_type: prod/cons update, prod/cons: 0x%x, update_flag: %s, en_dis_int_for_sb: %s, segment: %s, timer_mask=%d, ",
6383 prod_cons,
6384 update_flag ? "update" : "nop",
6385 en_dis_int_for_sb
6386 ? (en_dis_int_for_sb ==
6387 1 ? "disable" : "nop") :
6388 "enable",
6389 segment ? "attn" : "regular",
6390 timer_mask);
6391 }
6392 }
6393 } else {
6394 parsed_wr_data[0] = '\0';
6395 }
6396
6397 /* Add parsed element to parsed buffer */
6398 results_offset +=
6399 sprintf(qed_get_buf_ptr(results_buf,
6400 results_offset),
6401 "raw: 0x%01x%08x%08x, %s: %d, source: %s, type: %s, cmd_addr: 0x%x (%s%s), %serror: %s\n",
6402 elements[i].dword2, elements[i].dword1,
6403 elements[i].dword0,
6404 is_pf ? "pf" : "vf",
6405 GET_FIELD(elements[i].dword0,
6406 IGU_FIFO_ELEMENT_DWORD0_FID),
6407 s_igu_fifo_source_strs[source],
6408 is_wr_cmd ? "wr" : "rd", cmd_addr,
6409 (!is_pf && addr_data->vf_desc)
6410 ? addr_data->vf_desc : addr_data->desc,
6411 parsed_addr_data, parsed_wr_data,
6412 s_igu_fifo_error_strs[err_type]);
6413 }
6414
6415 results_offset += sprintf(qed_get_buf_ptr(results_buf,
6416 results_offset),
6417 "fifo contained %d elements", num_elements);
6418
6419 /* Add 1 for string NULL termination */
6420 *parsed_results_bytes = results_offset + 1;
6421 return DBG_STATUS_OK;
6422}
6423
6424enum dbg_status qed_get_igu_fifo_results_buf_size(struct qed_hwfn *p_hwfn,
6425 u32 *dump_buf,
6426 u32 num_dumped_dwords,
6427 u32 *results_buf_size)
6428{
6429 return qed_parse_igu_fifo_dump(p_hwfn,
6430 dump_buf,
6431 num_dumped_dwords,
6432 NULL, results_buf_size);
6433}
6434
6435enum dbg_status qed_print_igu_fifo_results(struct qed_hwfn *p_hwfn,
6436 u32 *dump_buf,
6437 u32 num_dumped_dwords,
6438 char *results_buf)
6439{
6440 u32 parsed_buf_size;
6441
6442 return qed_parse_igu_fifo_dump(p_hwfn,
6443 dump_buf,
6444 num_dumped_dwords,
6445 results_buf, &parsed_buf_size);
6446}
6447
6448static enum dbg_status
6449qed_parse_protection_override_dump(struct qed_hwfn *p_hwfn,
6450 u32 *dump_buf,
6451 u32 num_dumped_dwords,
6452 char *results_buf,
6453 u32 *parsed_results_bytes)
6454{
6455 u32 results_offset = 0, param_num_val, num_section_params, num_elements;
6456 const char *section_name, *param_name, *param_str_val;
6457 struct protection_override_element *elements;
6458 u8 i;
6459
6460 /* Read global_params section */
6461 dump_buf += qed_read_section_hdr(dump_buf,
6462 &section_name, &num_section_params);
6463 if (strcmp(section_name, "global_params"))
6464 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
6465
6466 /* Print global params */
6467 dump_buf += qed_print_section_params(dump_buf,
6468 num_section_params,
6469 results_buf, &results_offset);
6470
6471 /* Read protection_override_data section */
6472 dump_buf += qed_read_section_hdr(dump_buf,
6473 &section_name, &num_section_params);
6474 if (strcmp(section_name, "protection_override_data"))
6475 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
6476 dump_buf += qed_read_param(dump_buf,
6477 &param_name, &param_str_val, &param_num_val);
6478 if (strcmp(param_name, "size"))
6479 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
6480 if (param_num_val % PROTECTION_OVERRIDE_ELEMENT_DWORDS != 0)
6481 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
6482 num_elements = param_num_val / PROTECTION_OVERRIDE_ELEMENT_DWORDS;
6483 elements = (struct protection_override_element *)dump_buf;
6484
6485 /* Decode elements */
6486 for (i = 0; i < num_elements; i++) {
6487 u32 address = GET_FIELD(elements[i].data,
6488 PROTECTION_OVERRIDE_ELEMENT_ADDRESS) *
6489 PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR;
6490
6491 results_offset +=
6492 sprintf(qed_get_buf_ptr(results_buf,
6493 results_offset),
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02006494 "window %2d, address: 0x%07x, size: %7d regs, read: %d, write: %d, read protection: %-12s, write protection: %-12s\n",
Tomer Tayarc965db42016-09-07 16:36:24 +03006495 i, address,
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02006496 (u32)GET_FIELD(elements[i].data,
Tomer Tayarc965db42016-09-07 16:36:24 +03006497 PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE),
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02006498 (u32)GET_FIELD(elements[i].data,
Tomer Tayarc965db42016-09-07 16:36:24 +03006499 PROTECTION_OVERRIDE_ELEMENT_READ),
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02006500 (u32)GET_FIELD(elements[i].data,
Tomer Tayarc965db42016-09-07 16:36:24 +03006501 PROTECTION_OVERRIDE_ELEMENT_WRITE),
6502 s_protection_strs[GET_FIELD(elements[i].data,
6503 PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION)],
6504 s_protection_strs[GET_FIELD(elements[i].data,
6505 PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION)]);
6506 }
6507
6508 results_offset += sprintf(qed_get_buf_ptr(results_buf,
6509 results_offset),
6510 "protection override contained %d elements",
6511 num_elements);
6512
6513 /* Add 1 for string NULL termination */
6514 *parsed_results_bytes = results_offset + 1;
6515 return DBG_STATUS_OK;
6516}
6517
6518enum dbg_status
6519qed_get_protection_override_results_buf_size(struct qed_hwfn *p_hwfn,
6520 u32 *dump_buf,
6521 u32 num_dumped_dwords,
6522 u32 *results_buf_size)
6523{
6524 return qed_parse_protection_override_dump(p_hwfn,
6525 dump_buf,
6526 num_dumped_dwords,
6527 NULL, results_buf_size);
6528}
6529
6530enum dbg_status qed_print_protection_override_results(struct qed_hwfn *p_hwfn,
6531 u32 *dump_buf,
6532 u32 num_dumped_dwords,
6533 char *results_buf)
6534{
6535 u32 parsed_buf_size;
6536
6537 return qed_parse_protection_override_dump(p_hwfn,
6538 dump_buf,
6539 num_dumped_dwords,
6540 results_buf,
6541 &parsed_buf_size);
6542}
6543
6544/* Parses a FW Asserts dump buffer.
6545 * If result_buf is not NULL, the FW Asserts results are printed to it.
6546 * In any case, the required results buffer size is assigned to
6547 * parsed_results_bytes.
6548 * The parsing status is returned.
6549 */
6550static enum dbg_status qed_parse_fw_asserts_dump(struct qed_hwfn *p_hwfn,
6551 u32 *dump_buf,
6552 u32 num_dumped_dwords,
6553 char *results_buf,
6554 u32 *parsed_results_bytes)
6555{
6556 u32 results_offset = 0, num_section_params, param_num_val, i;
6557 const char *param_name, *param_str_val, *section_name;
6558 bool last_section_found = false;
6559
6560 *parsed_results_bytes = 0;
6561
6562 /* Read global_params section */
6563 dump_buf += qed_read_section_hdr(dump_buf,
6564 &section_name, &num_section_params);
6565 if (strcmp(section_name, "global_params"))
6566 return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
6567
6568 /* Print global params */
6569 dump_buf += qed_print_section_params(dump_buf,
6570 num_section_params,
6571 results_buf, &results_offset);
6572 while (!last_section_found) {
6573 const char *storm_letter = NULL;
6574 u32 storm_dump_size = 0;
6575
6576 dump_buf += qed_read_section_hdr(dump_buf,
6577 &section_name,
6578 &num_section_params);
6579 if (!strcmp(section_name, "last")) {
6580 last_section_found = true;
6581 continue;
6582 } else if (strcmp(section_name, "fw_asserts")) {
6583 return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
6584 }
6585
6586 /* Extract params */
6587 for (i = 0; i < num_section_params; i++) {
6588 dump_buf += qed_read_param(dump_buf,
6589 &param_name,
6590 &param_str_val,
6591 &param_num_val);
6592 if (!strcmp(param_name, "storm"))
6593 storm_letter = param_str_val;
6594 else if (!strcmp(param_name, "size"))
6595 storm_dump_size = param_num_val;
6596 else
6597 return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
6598 }
6599
6600 if (!storm_letter || !storm_dump_size)
6601 return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
6602
6603 /* Print data */
6604 results_offset += sprintf(qed_get_buf_ptr(results_buf,
6605 results_offset),
6606 "\n%sSTORM_ASSERT: size=%d\n",
6607 storm_letter, storm_dump_size);
6608 for (i = 0; i < storm_dump_size; i++, dump_buf++)
6609 results_offset +=
6610 sprintf(qed_get_buf_ptr(results_buf,
6611 results_offset),
6612 "%08x\n", *dump_buf);
6613 }
6614
6615 /* Add 1 for string NULL termination */
6616 *parsed_results_bytes = results_offset + 1;
6617 return DBG_STATUS_OK;
6618}
6619
6620enum dbg_status qed_get_fw_asserts_results_buf_size(struct qed_hwfn *p_hwfn,
6621 u32 *dump_buf,
6622 u32 num_dumped_dwords,
6623 u32 *results_buf_size)
6624{
6625 return qed_parse_fw_asserts_dump(p_hwfn,
6626 dump_buf,
6627 num_dumped_dwords,
6628 NULL, results_buf_size);
6629}
6630
6631enum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn,
6632 u32 *dump_buf,
6633 u32 num_dumped_dwords,
6634 char *results_buf)
6635{
6636 u32 parsed_buf_size;
6637
6638 return qed_parse_fw_asserts_dump(p_hwfn,
6639 dump_buf,
6640 num_dumped_dwords,
6641 results_buf, &parsed_buf_size);
6642}
6643
6644/* Wrapper for unifying the idle_chk and mcp_trace api */
Yuval Mintz8c93bea2016-10-13 22:57:03 +03006645static enum dbg_status
6646qed_print_idle_chk_results_wrapper(struct qed_hwfn *p_hwfn,
6647 u32 *dump_buf,
6648 u32 num_dumped_dwords,
6649 char *results_buf)
Tomer Tayarc965db42016-09-07 16:36:24 +03006650{
6651 u32 num_errors, num_warnnings;
6652
6653 return qed_print_idle_chk_results(p_hwfn, dump_buf, num_dumped_dwords,
6654 results_buf, &num_errors,
6655 &num_warnnings);
6656}
6657
6658/* Feature meta data lookup table */
6659static struct {
6660 char *name;
6661 enum dbg_status (*get_size)(struct qed_hwfn *p_hwfn,
6662 struct qed_ptt *p_ptt, u32 *size);
6663 enum dbg_status (*perform_dump)(struct qed_hwfn *p_hwfn,
6664 struct qed_ptt *p_ptt, u32 *dump_buf,
6665 u32 buf_size, u32 *dumped_dwords);
6666 enum dbg_status (*print_results)(struct qed_hwfn *p_hwfn,
6667 u32 *dump_buf, u32 num_dumped_dwords,
6668 char *results_buf);
6669 enum dbg_status (*results_buf_size)(struct qed_hwfn *p_hwfn,
6670 u32 *dump_buf,
6671 u32 num_dumped_dwords,
6672 u32 *results_buf_size);
6673} qed_features_lookup[] = {
6674 {
6675 "grc", qed_dbg_grc_get_dump_buf_size,
6676 qed_dbg_grc_dump, NULL, NULL}, {
6677 "idle_chk",
6678 qed_dbg_idle_chk_get_dump_buf_size,
6679 qed_dbg_idle_chk_dump,
6680 qed_print_idle_chk_results_wrapper,
6681 qed_get_idle_chk_results_buf_size}, {
6682 "mcp_trace",
6683 qed_dbg_mcp_trace_get_dump_buf_size,
6684 qed_dbg_mcp_trace_dump, qed_print_mcp_trace_results,
6685 qed_get_mcp_trace_results_buf_size}, {
6686 "reg_fifo",
6687 qed_dbg_reg_fifo_get_dump_buf_size,
6688 qed_dbg_reg_fifo_dump, qed_print_reg_fifo_results,
6689 qed_get_reg_fifo_results_buf_size}, {
6690 "igu_fifo",
6691 qed_dbg_igu_fifo_get_dump_buf_size,
6692 qed_dbg_igu_fifo_dump, qed_print_igu_fifo_results,
6693 qed_get_igu_fifo_results_buf_size}, {
6694 "protection_override",
6695 qed_dbg_protection_override_get_dump_buf_size,
6696 qed_dbg_protection_override_dump,
6697 qed_print_protection_override_results,
6698 qed_get_protection_override_results_buf_size}, {
6699 "fw_asserts",
6700 qed_dbg_fw_asserts_get_dump_buf_size,
6701 qed_dbg_fw_asserts_dump,
6702 qed_print_fw_asserts_results,
6703 qed_get_fw_asserts_results_buf_size},};
6704
6705static void qed_dbg_print_feature(u8 *p_text_buf, u32 text_size)
6706{
6707 u32 i, precision = 80;
6708
6709 if (!p_text_buf)
6710 return;
6711
6712 pr_notice("\n%.*s", precision, p_text_buf);
6713 for (i = precision; i < text_size; i += precision)
6714 pr_cont("%.*s", precision, p_text_buf + i);
6715 pr_cont("\n");
6716}
6717
6718#define QED_RESULTS_BUF_MIN_SIZE 16
6719/* Generic function for decoding debug feature info */
Yuval Mintz8c93bea2016-10-13 22:57:03 +03006720static enum dbg_status format_feature(struct qed_hwfn *p_hwfn,
6721 enum qed_dbg_features feature_idx)
Tomer Tayarc965db42016-09-07 16:36:24 +03006722{
6723 struct qed_dbg_feature *feature =
6724 &p_hwfn->cdev->dbg_params.features[feature_idx];
6725 u32 text_size_bytes, null_char_pos, i;
6726 enum dbg_status rc;
6727 char *text_buf;
6728
6729 /* Check if feature supports formatting capability */
6730 if (!qed_features_lookup[feature_idx].results_buf_size)
6731 return DBG_STATUS_OK;
6732
6733 /* Obtain size of formatted output */
6734 rc = qed_features_lookup[feature_idx].
6735 results_buf_size(p_hwfn, (u32 *)feature->dump_buf,
6736 feature->dumped_dwords, &text_size_bytes);
6737 if (rc != DBG_STATUS_OK)
6738 return rc;
6739
6740 /* Make sure that the allocated size is a multiple of dword (4 bytes) */
6741 null_char_pos = text_size_bytes - 1;
6742 text_size_bytes = (text_size_bytes + 3) & ~0x3;
6743
6744 if (text_size_bytes < QED_RESULTS_BUF_MIN_SIZE) {
6745 DP_NOTICE(p_hwfn->cdev,
6746 "formatted size of feature was too small %d. Aborting\n",
6747 text_size_bytes);
6748 return DBG_STATUS_INVALID_ARGS;
6749 }
6750
6751 /* Allocate temp text buf */
6752 text_buf = vzalloc(text_size_bytes);
6753 if (!text_buf)
6754 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6755
6756 /* Decode feature opcodes to string on temp buf */
6757 rc = qed_features_lookup[feature_idx].
6758 print_results(p_hwfn, (u32 *)feature->dump_buf,
6759 feature->dumped_dwords, text_buf);
6760 if (rc != DBG_STATUS_OK) {
6761 vfree(text_buf);
6762 return rc;
6763 }
6764
6765 /* Replace the original null character with a '\n' character.
6766 * The bytes that were added as a result of the dword alignment are also
6767 * padded with '\n' characters.
6768 */
6769 for (i = null_char_pos; i < text_size_bytes; i++)
6770 text_buf[i] = '\n';
6771
6772 /* Dump printable feature to log */
6773 if (p_hwfn->cdev->dbg_params.print_data)
6774 qed_dbg_print_feature(text_buf, text_size_bytes);
6775
6776 /* Free the old dump_buf and point the dump_buf to the newly allocagted
6777 * and formatted text buffer.
6778 */
6779 vfree(feature->dump_buf);
6780 feature->dump_buf = text_buf;
6781 feature->buf_size = text_size_bytes;
6782 feature->dumped_dwords = text_size_bytes / 4;
6783 return rc;
6784}
6785
6786/* Generic function for performing the dump of a debug feature. */
Yuval Mintz8c93bea2016-10-13 22:57:03 +03006787static enum dbg_status qed_dbg_dump(struct qed_hwfn *p_hwfn,
6788 struct qed_ptt *p_ptt,
6789 enum qed_dbg_features feature_idx)
Tomer Tayarc965db42016-09-07 16:36:24 +03006790{
6791 struct qed_dbg_feature *feature =
6792 &p_hwfn->cdev->dbg_params.features[feature_idx];
6793 u32 buf_size_dwords;
6794 enum dbg_status rc;
6795
6796 DP_NOTICE(p_hwfn->cdev, "Collecting a debug feature [\"%s\"]\n",
6797 qed_features_lookup[feature_idx].name);
6798
6799 /* Dump_buf was already allocated need to free (this can happen if dump
6800 * was called but file was never read).
6801 * We can't use the buffer as is since size may have changed.
6802 */
6803 if (feature->dump_buf) {
6804 vfree(feature->dump_buf);
6805 feature->dump_buf = NULL;
6806 }
6807
6808 /* Get buffer size from hsi, allocate accordingly, and perform the
6809 * dump.
6810 */
6811 rc = qed_features_lookup[feature_idx].get_size(p_hwfn, p_ptt,
6812 &buf_size_dwords);
Mintz, Yuvalbe086e72017-03-11 18:39:18 +02006813 if (rc != DBG_STATUS_OK && rc != DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
Tomer Tayarc965db42016-09-07 16:36:24 +03006814 return rc;
6815 feature->buf_size = buf_size_dwords * sizeof(u32);
6816 feature->dump_buf = vmalloc(feature->buf_size);
6817 if (!feature->dump_buf)
6818 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6819
6820 rc = qed_features_lookup[feature_idx].
6821 perform_dump(p_hwfn, p_ptt, (u32 *)feature->dump_buf,
6822 feature->buf_size / sizeof(u32),
6823 &feature->dumped_dwords);
6824
6825 /* If mcp is stuck we get DBG_STATUS_NVRAM_GET_IMAGE_FAILED error.
6826 * In this case the buffer holds valid binary data, but we wont able
6827 * to parse it (since parsing relies on data in NVRAM which is only
6828 * accessible when MFW is responsive). skip the formatting but return
6829 * success so that binary data is provided.
6830 */
6831 if (rc == DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
6832 return DBG_STATUS_OK;
6833
6834 if (rc != DBG_STATUS_OK)
6835 return rc;
6836
6837 /* Format output */
6838 rc = format_feature(p_hwfn, feature_idx);
6839 return rc;
6840}
6841
6842int qed_dbg_grc(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
6843{
6844 return qed_dbg_feature(cdev, buffer, DBG_FEATURE_GRC, num_dumped_bytes);
6845}
6846
6847int qed_dbg_grc_size(struct qed_dev *cdev)
6848{
6849 return qed_dbg_feature_size(cdev, DBG_FEATURE_GRC);
6850}
6851
6852int qed_dbg_idle_chk(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
6853{
6854 return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IDLE_CHK,
6855 num_dumped_bytes);
6856}
6857
6858int qed_dbg_idle_chk_size(struct qed_dev *cdev)
6859{
6860 return qed_dbg_feature_size(cdev, DBG_FEATURE_IDLE_CHK);
6861}
6862
6863int qed_dbg_reg_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
6864{
6865 return qed_dbg_feature(cdev, buffer, DBG_FEATURE_REG_FIFO,
6866 num_dumped_bytes);
6867}
6868
6869int qed_dbg_reg_fifo_size(struct qed_dev *cdev)
6870{
6871 return qed_dbg_feature_size(cdev, DBG_FEATURE_REG_FIFO);
6872}
6873
6874int qed_dbg_igu_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
6875{
6876 return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IGU_FIFO,
6877 num_dumped_bytes);
6878}
6879
6880int qed_dbg_igu_fifo_size(struct qed_dev *cdev)
6881{
6882 return qed_dbg_feature_size(cdev, DBG_FEATURE_IGU_FIFO);
6883}
6884
6885int qed_dbg_protection_override(struct qed_dev *cdev, void *buffer,
6886 u32 *num_dumped_bytes)
6887{
6888 return qed_dbg_feature(cdev, buffer, DBG_FEATURE_PROTECTION_OVERRIDE,
6889 num_dumped_bytes);
6890}
6891
6892int qed_dbg_protection_override_size(struct qed_dev *cdev)
6893{
6894 return qed_dbg_feature_size(cdev, DBG_FEATURE_PROTECTION_OVERRIDE);
6895}
6896
6897int qed_dbg_fw_asserts(struct qed_dev *cdev, void *buffer,
6898 u32 *num_dumped_bytes)
6899{
6900 return qed_dbg_feature(cdev, buffer, DBG_FEATURE_FW_ASSERTS,
6901 num_dumped_bytes);
6902}
6903
6904int qed_dbg_fw_asserts_size(struct qed_dev *cdev)
6905{
6906 return qed_dbg_feature_size(cdev, DBG_FEATURE_FW_ASSERTS);
6907}
6908
6909int qed_dbg_mcp_trace(struct qed_dev *cdev, void *buffer,
6910 u32 *num_dumped_bytes)
6911{
6912 return qed_dbg_feature(cdev, buffer, DBG_FEATURE_MCP_TRACE,
6913 num_dumped_bytes);
6914}
6915
6916int qed_dbg_mcp_trace_size(struct qed_dev *cdev)
6917{
6918 return qed_dbg_feature_size(cdev, DBG_FEATURE_MCP_TRACE);
6919}
6920
6921/* Defines the amount of bytes allocated for recording the length of debugfs
6922 * feature buffer.
6923 */
6924#define REGDUMP_HEADER_SIZE sizeof(u32)
6925#define REGDUMP_HEADER_FEATURE_SHIFT 24
6926#define REGDUMP_HEADER_ENGINE_SHIFT 31
6927#define REGDUMP_HEADER_OMIT_ENGINE_SHIFT 30
6928enum debug_print_features {
6929 OLD_MODE = 0,
6930 IDLE_CHK = 1,
6931 GRC_DUMP = 2,
6932 MCP_TRACE = 3,
6933 REG_FIFO = 4,
6934 PROTECTION_OVERRIDE = 5,
6935 IGU_FIFO = 6,
6936 PHY = 7,
6937 FW_ASSERTS = 8,
6938};
6939
6940static u32 qed_calc_regdump_header(enum debug_print_features feature,
6941 int engine, u32 feature_size, u8 omit_engine)
6942{
6943 /* Insert the engine, feature and mode inside the header and combine it
6944 * with feature size.
6945 */
6946 return feature_size | (feature << REGDUMP_HEADER_FEATURE_SHIFT) |
6947 (omit_engine << REGDUMP_HEADER_OMIT_ENGINE_SHIFT) |
6948 (engine << REGDUMP_HEADER_ENGINE_SHIFT);
6949}
6950
6951int qed_dbg_all_data(struct qed_dev *cdev, void *buffer)
6952{
6953 u8 cur_engine, omit_engine = 0, org_engine;
6954 u32 offset = 0, feature_size;
6955 int rc;
6956
6957 if (cdev->num_hwfns == 1)
6958 omit_engine = 1;
6959
6960 org_engine = qed_get_debug_engine(cdev);
6961 for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
6962 /* Collect idle_chks and grcDump for each hw function */
6963 DP_VERBOSE(cdev, QED_MSG_DEBUG,
6964 "obtaining idle_chk and grcdump for current engine\n");
6965 qed_set_debug_engine(cdev, cur_engine);
6966
6967 /* First idle_chk */
6968 rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset +
6969 REGDUMP_HEADER_SIZE, &feature_size);
6970 if (!rc) {
6971 *(u32 *)((u8 *)buffer + offset) =
6972 qed_calc_regdump_header(IDLE_CHK, cur_engine,
6973 feature_size, omit_engine);
6974 offset += (feature_size + REGDUMP_HEADER_SIZE);
6975 } else {
6976 DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
6977 }
6978
6979 /* Second idle_chk */
6980 rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset +
6981 REGDUMP_HEADER_SIZE, &feature_size);
6982 if (!rc) {
6983 *(u32 *)((u8 *)buffer + offset) =
6984 qed_calc_regdump_header(IDLE_CHK, cur_engine,
6985 feature_size, omit_engine);
6986 offset += (feature_size + REGDUMP_HEADER_SIZE);
6987 } else {
6988 DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
6989 }
6990
6991 /* reg_fifo dump */
6992 rc = qed_dbg_reg_fifo(cdev, (u8 *)buffer + offset +
6993 REGDUMP_HEADER_SIZE, &feature_size);
6994 if (!rc) {
6995 *(u32 *)((u8 *)buffer + offset) =
6996 qed_calc_regdump_header(REG_FIFO, cur_engine,
6997 feature_size, omit_engine);
6998 offset += (feature_size + REGDUMP_HEADER_SIZE);
6999 } else {
7000 DP_ERR(cdev, "qed_dbg_reg_fifo failed. rc = %d\n", rc);
7001 }
7002
7003 /* igu_fifo dump */
7004 rc = qed_dbg_igu_fifo(cdev, (u8 *)buffer + offset +
7005 REGDUMP_HEADER_SIZE, &feature_size);
7006 if (!rc) {
7007 *(u32 *)((u8 *)buffer + offset) =
7008 qed_calc_regdump_header(IGU_FIFO, cur_engine,
7009 feature_size, omit_engine);
7010 offset += (feature_size + REGDUMP_HEADER_SIZE);
7011 } else {
7012 DP_ERR(cdev, "qed_dbg_igu_fifo failed. rc = %d", rc);
7013 }
7014
7015 /* protection_override dump */
7016 rc = qed_dbg_protection_override(cdev, (u8 *)buffer + offset +
7017 REGDUMP_HEADER_SIZE,
7018 &feature_size);
7019 if (!rc) {
7020 *(u32 *)((u8 *)buffer + offset) =
7021 qed_calc_regdump_header(PROTECTION_OVERRIDE,
7022 cur_engine,
7023 feature_size, omit_engine);
7024 offset += (feature_size + REGDUMP_HEADER_SIZE);
7025 } else {
7026 DP_ERR(cdev,
7027 "qed_dbg_protection_override failed. rc = %d\n",
7028 rc);
7029 }
7030
7031 /* fw_asserts dump */
7032 rc = qed_dbg_fw_asserts(cdev, (u8 *)buffer + offset +
7033 REGDUMP_HEADER_SIZE, &feature_size);
7034 if (!rc) {
7035 *(u32 *)((u8 *)buffer + offset) =
7036 qed_calc_regdump_header(FW_ASSERTS, cur_engine,
7037 feature_size, omit_engine);
7038 offset += (feature_size + REGDUMP_HEADER_SIZE);
7039 } else {
7040 DP_ERR(cdev, "qed_dbg_fw_asserts failed. rc = %d\n",
7041 rc);
7042 }
7043
7044 /* GRC dump - must be last because when mcp stuck it will
7045 * clutter idle_chk, reg_fifo, ...
7046 */
7047 rc = qed_dbg_grc(cdev, (u8 *)buffer + offset +
7048 REGDUMP_HEADER_SIZE, &feature_size);
7049 if (!rc) {
7050 *(u32 *)((u8 *)buffer + offset) =
7051 qed_calc_regdump_header(GRC_DUMP, cur_engine,
7052 feature_size, omit_engine);
7053 offset += (feature_size + REGDUMP_HEADER_SIZE);
7054 } else {
7055 DP_ERR(cdev, "qed_dbg_grc failed. rc = %d", rc);
7056 }
7057 }
7058
7059 /* mcp_trace */
7060 rc = qed_dbg_mcp_trace(cdev, (u8 *)buffer + offset +
7061 REGDUMP_HEADER_SIZE, &feature_size);
7062 if (!rc) {
7063 *(u32 *)((u8 *)buffer + offset) =
7064 qed_calc_regdump_header(MCP_TRACE, cur_engine,
7065 feature_size, omit_engine);
7066 offset += (feature_size + REGDUMP_HEADER_SIZE);
7067 } else {
7068 DP_ERR(cdev, "qed_dbg_mcp_trace failed. rc = %d\n", rc);
7069 }
7070
7071 qed_set_debug_engine(cdev, org_engine);
7072
7073 return 0;
7074}
7075
7076int qed_dbg_all_data_size(struct qed_dev *cdev)
7077{
7078 u8 cur_engine, org_engine;
7079 u32 regs_len = 0;
7080
7081 org_engine = qed_get_debug_engine(cdev);
7082 for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
7083 /* Engine specific */
7084 DP_VERBOSE(cdev, QED_MSG_DEBUG,
7085 "calculating idle_chk and grcdump register length for current engine\n");
7086 qed_set_debug_engine(cdev, cur_engine);
7087 regs_len += REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
7088 REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
7089 REGDUMP_HEADER_SIZE + qed_dbg_grc_size(cdev) +
7090 REGDUMP_HEADER_SIZE + qed_dbg_reg_fifo_size(cdev) +
7091 REGDUMP_HEADER_SIZE + qed_dbg_igu_fifo_size(cdev) +
7092 REGDUMP_HEADER_SIZE +
7093 qed_dbg_protection_override_size(cdev) +
7094 REGDUMP_HEADER_SIZE + qed_dbg_fw_asserts_size(cdev);
7095 }
7096
7097 /* Engine common */
7098 regs_len += REGDUMP_HEADER_SIZE + qed_dbg_mcp_trace_size(cdev);
7099 qed_set_debug_engine(cdev, org_engine);
7100
7101 return regs_len;
7102}
7103
7104int qed_dbg_feature(struct qed_dev *cdev, void *buffer,
7105 enum qed_dbg_features feature, u32 *num_dumped_bytes)
7106{
7107 struct qed_hwfn *p_hwfn =
7108 &cdev->hwfns[cdev->dbg_params.engine_for_debug];
7109 struct qed_dbg_feature *qed_feature =
7110 &cdev->dbg_params.features[feature];
7111 enum dbg_status dbg_rc;
7112 struct qed_ptt *p_ptt;
7113 int rc = 0;
7114
7115 /* Acquire ptt */
7116 p_ptt = qed_ptt_acquire(p_hwfn);
7117 if (!p_ptt)
7118 return -EINVAL;
7119
7120 /* Get dump */
7121 dbg_rc = qed_dbg_dump(p_hwfn, p_ptt, feature);
7122 if (dbg_rc != DBG_STATUS_OK) {
7123 DP_VERBOSE(cdev, QED_MSG_DEBUG, "%s\n",
7124 qed_dbg_get_status_str(dbg_rc));
7125 *num_dumped_bytes = 0;
7126 rc = -EINVAL;
7127 goto out;
7128 }
7129
7130 DP_VERBOSE(cdev, QED_MSG_DEBUG,
7131 "copying debugfs feature to external buffer\n");
7132 memcpy(buffer, qed_feature->dump_buf, qed_feature->buf_size);
7133 *num_dumped_bytes = cdev->dbg_params.features[feature].dumped_dwords *
7134 4;
7135
7136out:
7137 qed_ptt_release(p_hwfn, p_ptt);
7138 return rc;
7139}
7140
7141int qed_dbg_feature_size(struct qed_dev *cdev, enum qed_dbg_features feature)
7142{
7143 struct qed_hwfn *p_hwfn =
7144 &cdev->hwfns[cdev->dbg_params.engine_for_debug];
7145 struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
7146 struct qed_dbg_feature *qed_feature =
7147 &cdev->dbg_params.features[feature];
7148 u32 buf_size_dwords;
7149 enum dbg_status rc;
7150
7151 if (!p_ptt)
7152 return -EINVAL;
7153
7154 rc = qed_features_lookup[feature].get_size(p_hwfn, p_ptt,
7155 &buf_size_dwords);
7156 if (rc != DBG_STATUS_OK)
7157 buf_size_dwords = 0;
7158
7159 qed_ptt_release(p_hwfn, p_ptt);
7160 qed_feature->buf_size = buf_size_dwords * sizeof(u32);
7161 return qed_feature->buf_size;
7162}
7163
7164u8 qed_get_debug_engine(struct qed_dev *cdev)
7165{
7166 return cdev->dbg_params.engine_for_debug;
7167}
7168
7169void qed_set_debug_engine(struct qed_dev *cdev, int engine_number)
7170{
7171 DP_VERBOSE(cdev, QED_MSG_DEBUG, "set debug engine to %d\n",
7172 engine_number);
7173 cdev->dbg_params.engine_for_debug = engine_number;
7174}
7175
7176void qed_dbg_pf_init(struct qed_dev *cdev)
7177{
7178 const u8 *dbg_values;
7179
7180 /* Debug values are after init values.
7181 * The offset is the first dword of the file.
7182 */
7183 dbg_values = cdev->firmware->data + *(u32 *)cdev->firmware->data;
7184 qed_dbg_set_bin_ptr((u8 *)dbg_values);
7185 qed_dbg_user_set_bin_ptr((u8 *)dbg_values);
7186}
7187
7188void qed_dbg_pf_exit(struct qed_dev *cdev)
7189{
7190 struct qed_dbg_feature *feature = NULL;
7191 enum qed_dbg_features feature_idx;
7192
7193 /* Debug features' buffers may be allocated if debug feature was used
7194 * but dump wasn't called.
7195 */
7196 for (feature_idx = 0; feature_idx < DBG_FEATURE_NUM; feature_idx++) {
7197 feature = &cdev->dbg_params.features[feature_idx];
7198 if (feature->dump_buf) {
7199 vfree(feature->dump_buf);
7200 feature->dump_buf = NULL;
7201 }
7202 }
7203}