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