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