Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
0002 /* QLogic qed NIC Driver
0003  * Copyright (c) 2015 QLogic Corporation
0004  * Copyright (c) 2019-2021 Marvell International Ltd.
0005  */
0006 
0007 #include <linux/module.h>
0008 #include <linux/vmalloc.h>
0009 #include <linux/crc32.h>
0010 #include "qed.h"
0011 #include "qed_cxt.h"
0012 #include "qed_hsi.h"
0013 #include "qed_dbg_hsi.h"
0014 #include "qed_hw.h"
0015 #include "qed_mcp.h"
0016 #include "qed_reg_addr.h"
0017 
0018 /* Memory groups enum */
0019 enum mem_groups {
0020     MEM_GROUP_PXP_MEM,
0021     MEM_GROUP_DMAE_MEM,
0022     MEM_GROUP_CM_MEM,
0023     MEM_GROUP_QM_MEM,
0024     MEM_GROUP_DORQ_MEM,
0025     MEM_GROUP_BRB_RAM,
0026     MEM_GROUP_BRB_MEM,
0027     MEM_GROUP_PRS_MEM,
0028     MEM_GROUP_SDM_MEM,
0029     MEM_GROUP_PBUF,
0030     MEM_GROUP_IOR,
0031     MEM_GROUP_RAM,
0032     MEM_GROUP_BTB_RAM,
0033     MEM_GROUP_RDIF_CTX,
0034     MEM_GROUP_TDIF_CTX,
0035     MEM_GROUP_CFC_MEM,
0036     MEM_GROUP_CONN_CFC_MEM,
0037     MEM_GROUP_CAU_PI,
0038     MEM_GROUP_CAU_MEM,
0039     MEM_GROUP_CAU_MEM_EXT,
0040     MEM_GROUP_PXP_ILT,
0041     MEM_GROUP_MULD_MEM,
0042     MEM_GROUP_BTB_MEM,
0043     MEM_GROUP_IGU_MEM,
0044     MEM_GROUP_IGU_MSIX,
0045     MEM_GROUP_CAU_SB,
0046     MEM_GROUP_BMB_RAM,
0047     MEM_GROUP_BMB_MEM,
0048     MEM_GROUP_TM_MEM,
0049     MEM_GROUP_TASK_CFC_MEM,
0050     MEM_GROUPS_NUM
0051 };
0052 
0053 /* Memory groups names */
0054 static const char * const s_mem_group_names[] = {
0055     "PXP_MEM",
0056     "DMAE_MEM",
0057     "CM_MEM",
0058     "QM_MEM",
0059     "DORQ_MEM",
0060     "BRB_RAM",
0061     "BRB_MEM",
0062     "PRS_MEM",
0063     "SDM_MEM",
0064     "PBUF",
0065     "IOR",
0066     "RAM",
0067     "BTB_RAM",
0068     "RDIF_CTX",
0069     "TDIF_CTX",
0070     "CFC_MEM",
0071     "CONN_CFC_MEM",
0072     "CAU_PI",
0073     "CAU_MEM",
0074     "CAU_MEM_EXT",
0075     "PXP_ILT",
0076     "MULD_MEM",
0077     "BTB_MEM",
0078     "IGU_MEM",
0079     "IGU_MSIX",
0080     "CAU_SB",
0081     "BMB_RAM",
0082     "BMB_MEM",
0083     "TM_MEM",
0084     "TASK_CFC_MEM",
0085 };
0086 
0087 /* Idle check conditions */
0088 
0089 static u32 cond5(const u32 *r, const u32 *imm)
0090 {
0091     return ((r[0] & imm[0]) != imm[1]) && ((r[1] & imm[2]) != imm[3]);
0092 }
0093 
0094 static u32 cond7(const u32 *r, const u32 *imm)
0095 {
0096     return ((r[0] >> imm[0]) & imm[1]) != imm[2];
0097 }
0098 
0099 static u32 cond6(const u32 *r, const u32 *imm)
0100 {
0101     return (r[0] & imm[0]) != imm[1];
0102 }
0103 
0104 static u32 cond9(const u32 *r, const u32 *imm)
0105 {
0106     return ((r[0] & imm[0]) >> imm[1]) !=
0107         (((r[0] & imm[2]) >> imm[3]) | ((r[1] & imm[4]) << imm[5]));
0108 }
0109 
0110 static u32 cond10(const u32 *r, const u32 *imm)
0111 {
0112     return ((r[0] & imm[0]) >> imm[1]) != (r[0] & imm[2]);
0113 }
0114 
0115 static u32 cond4(const u32 *r, const u32 *imm)
0116 {
0117     return (r[0] & ~imm[0]) != imm[1];
0118 }
0119 
0120 static u32 cond0(const u32 *r, const u32 *imm)
0121 {
0122     return (r[0] & ~r[1]) != imm[0];
0123 }
0124 
0125 static u32 cond14(const u32 *r, const u32 *imm)
0126 {
0127     return (r[0] | imm[0]) != imm[1];
0128 }
0129 
0130 static u32 cond1(const u32 *r, const u32 *imm)
0131 {
0132     return r[0] != imm[0];
0133 }
0134 
0135 static u32 cond11(const u32 *r, const u32 *imm)
0136 {
0137     return r[0] != r[1] && r[2] == imm[0];
0138 }
0139 
0140 static u32 cond12(const u32 *r, const u32 *imm)
0141 {
0142     return r[0] != r[1] && r[2] > imm[0];
0143 }
0144 
0145 static u32 cond3(const u32 *r, const u32 *imm)
0146 {
0147     return r[0] != r[1];
0148 }
0149 
0150 static u32 cond13(const u32 *r, const u32 *imm)
0151 {
0152     return r[0] & imm[0];
0153 }
0154 
0155 static u32 cond8(const u32 *r, const u32 *imm)
0156 {
0157     return r[0] < (r[1] - imm[0]);
0158 }
0159 
0160 static u32 cond2(const u32 *r, const u32 *imm)
0161 {
0162     return r[0] > imm[0];
0163 }
0164 
0165 /* Array of Idle Check conditions */
0166 static u32(*cond_arr[]) (const u32 *r, const u32 *imm) = {
0167     cond0,
0168     cond1,
0169     cond2,
0170     cond3,
0171     cond4,
0172     cond5,
0173     cond6,
0174     cond7,
0175     cond8,
0176     cond9,
0177     cond10,
0178     cond11,
0179     cond12,
0180     cond13,
0181     cond14,
0182 };
0183 
0184 #define NUM_PHYS_BLOCKS 84
0185 
0186 #define NUM_DBG_RESET_REGS 8
0187 
0188 /******************************* Data Types **********************************/
0189 
0190 enum hw_types {
0191     HW_TYPE_ASIC,
0192     PLATFORM_RESERVED,
0193     PLATFORM_RESERVED2,
0194     PLATFORM_RESERVED3,
0195     PLATFORM_RESERVED4,
0196     MAX_HW_TYPES
0197 };
0198 
0199 /* CM context types */
0200 enum cm_ctx_types {
0201     CM_CTX_CONN_AG,
0202     CM_CTX_CONN_ST,
0203     CM_CTX_TASK_AG,
0204     CM_CTX_TASK_ST,
0205     NUM_CM_CTX_TYPES
0206 };
0207 
0208 /* Debug bus frame modes */
0209 enum dbg_bus_frame_modes {
0210     DBG_BUS_FRAME_MODE_4ST = 0, /* 4 Storm dwords (no HW) */
0211     DBG_BUS_FRAME_MODE_2ST_2HW = 1, /* 2 Storm dwords, 2 HW dwords */
0212     DBG_BUS_FRAME_MODE_1ST_3HW = 2, /* 1 Storm dwords, 3 HW dwords */
0213     DBG_BUS_FRAME_MODE_4HW = 3, /* 4 HW dwords (no Storms) */
0214     DBG_BUS_FRAME_MODE_8HW = 4, /* 8 HW dwords (no Storms) */
0215     DBG_BUS_NUM_FRAME_MODES
0216 };
0217 
0218 /* Debug bus SEMI frame modes */
0219 enum dbg_bus_semi_frame_modes {
0220     DBG_BUS_SEMI_FRAME_MODE_4FAST = 0,  /* 4 fast dw */
0221     DBG_BUS_SEMI_FRAME_MODE_2FAST_2SLOW = 1, /* 2 fast dw, 2 slow dw */
0222     DBG_BUS_SEMI_FRAME_MODE_1FAST_3SLOW = 2, /* 1 fast dw,3 slow dw */
0223     DBG_BUS_SEMI_FRAME_MODE_4SLOW = 3,  /* 4 slow dw */
0224     DBG_BUS_SEMI_NUM_FRAME_MODES
0225 };
0226 
0227 /* Debug bus filter types */
0228 enum dbg_bus_filter_types {
0229     DBG_BUS_FILTER_TYPE_OFF,    /* Filter always off */
0230     DBG_BUS_FILTER_TYPE_PRE,    /* Filter before trigger only */
0231     DBG_BUS_FILTER_TYPE_POST,   /* Filter after trigger only */
0232     DBG_BUS_FILTER_TYPE_ON  /* Filter always on */
0233 };
0234 
0235 /* Debug bus pre-trigger recording types */
0236 enum dbg_bus_pre_trigger_types {
0237     DBG_BUS_PRE_TRIGGER_FROM_ZERO,  /* Record from time 0 */
0238     DBG_BUS_PRE_TRIGGER_NUM_CHUNKS, /* Record some chunks before trigger */
0239     DBG_BUS_PRE_TRIGGER_DROP    /* Drop data before trigger */
0240 };
0241 
0242 /* Debug bus post-trigger recording types */
0243 enum dbg_bus_post_trigger_types {
0244     DBG_BUS_POST_TRIGGER_RECORD,    /* Start recording after trigger */
0245     DBG_BUS_POST_TRIGGER_DROP   /* Drop data after trigger */
0246 };
0247 
0248 /* Debug bus other engine mode */
0249 enum dbg_bus_other_engine_modes {
0250     DBG_BUS_OTHER_ENGINE_MODE_NONE,
0251     DBG_BUS_OTHER_ENGINE_MODE_DOUBLE_BW_TX,
0252     DBG_BUS_OTHER_ENGINE_MODE_DOUBLE_BW_RX,
0253     DBG_BUS_OTHER_ENGINE_MODE_CROSS_ENGINE_TX,
0254     DBG_BUS_OTHER_ENGINE_MODE_CROSS_ENGINE_RX
0255 };
0256 
0257 /* DBG block Framing mode definitions */
0258 struct framing_mode_defs {
0259     u8 id;
0260     u8 blocks_dword_mask;
0261     u8 storms_dword_mask;
0262     u8 semi_framing_mode_id;
0263     u8 full_buf_thr;
0264 };
0265 
0266 /* Chip constant definitions */
0267 struct chip_defs {
0268     const char *name;
0269     u8 dwords_per_cycle;
0270     u8 num_framing_modes;
0271     u32 num_ilt_pages;
0272     struct framing_mode_defs *framing_modes;
0273 };
0274 
0275 /* HW type constant definitions */
0276 struct hw_type_defs {
0277     const char *name;
0278     u32 delay_factor;
0279     u32 dmae_thresh;
0280     u32 log_thresh;
0281 };
0282 
0283 /* RBC reset definitions */
0284 struct rbc_reset_defs {
0285     u32 reset_reg_addr;
0286     u32 reset_val[MAX_CHIP_IDS];
0287 };
0288 
0289 /* Storm constant definitions.
0290  * Addresses are in bytes, sizes are in quad-regs.
0291  */
0292 struct storm_defs {
0293     char letter;
0294     enum block_id sem_block_id;
0295     enum dbg_bus_clients dbg_client_id[MAX_CHIP_IDS];
0296     bool has_vfc;
0297     u32 sem_fast_mem_addr;
0298     u32 sem_frame_mode_addr;
0299     u32 sem_slow_enable_addr;
0300     u32 sem_slow_mode_addr;
0301     u32 sem_slow_mode1_conf_addr;
0302     u32 sem_sync_dbg_empty_addr;
0303     u32 sem_gpre_vect_addr;
0304     u32 cm_ctx_wr_addr;
0305     u32 cm_ctx_rd_addr[NUM_CM_CTX_TYPES];
0306     u32 cm_ctx_lid_sizes[MAX_CHIP_IDS][NUM_CM_CTX_TYPES];
0307 };
0308 
0309 /* Debug Bus Constraint operation constant definitions */
0310 struct dbg_bus_constraint_op_defs {
0311     u8 hw_op_val;
0312     bool is_cyclic;
0313 };
0314 
0315 /* Storm Mode definitions */
0316 struct storm_mode_defs {
0317     const char *name;
0318     bool is_fast_dbg;
0319     u8 id_in_hw;
0320     u32 src_disable_reg_addr;
0321     u32 src_enable_val;
0322     bool exists[MAX_CHIP_IDS];
0323 };
0324 
0325 struct grc_param_defs {
0326     u32 default_val[MAX_CHIP_IDS];
0327     u32 min;
0328     u32 max;
0329     bool is_preset;
0330     bool is_persistent;
0331     u32 exclude_all_preset_val;
0332     u32 crash_preset_val[MAX_CHIP_IDS];
0333 };
0334 
0335 /* Address is in 128b units. Width is in bits. */
0336 struct rss_mem_defs {
0337     const char *mem_name;
0338     const char *type_name;
0339     u32 addr;
0340     u32 entry_width;
0341     u32 num_entries[MAX_CHIP_IDS];
0342 };
0343 
0344 struct vfc_ram_defs {
0345     const char *mem_name;
0346     const char *type_name;
0347     u32 base_row;
0348     u32 num_rows;
0349 };
0350 
0351 struct big_ram_defs {
0352     const char *instance_name;
0353     enum mem_groups mem_group_id;
0354     enum mem_groups ram_mem_group_id;
0355     enum dbg_grc_params grc_param;
0356     u32 addr_reg_addr;
0357     u32 data_reg_addr;
0358     u32 is_256b_reg_addr;
0359     u32 is_256b_bit_offset[MAX_CHIP_IDS];
0360     u32 ram_size[MAX_CHIP_IDS]; /* In dwords */
0361 };
0362 
0363 struct phy_defs {
0364     const char *phy_name;
0365 
0366     /* PHY base GRC address */
0367     u32 base_addr;
0368 
0369     /* Relative address of indirect TBUS address register (bits 0..7) */
0370     u32 tbus_addr_lo_addr;
0371 
0372     /* Relative address of indirect TBUS address register (bits 8..10) */
0373     u32 tbus_addr_hi_addr;
0374 
0375     /* Relative address of indirect TBUS data register (bits 0..7) */
0376     u32 tbus_data_lo_addr;
0377 
0378     /* Relative address of indirect TBUS data register (bits 8..11) */
0379     u32 tbus_data_hi_addr;
0380 };
0381 
0382 /* Split type definitions */
0383 struct split_type_defs {
0384     const char *name;
0385 };
0386 
0387 /******************************** Constants **********************************/
0388 
0389 #define BYTES_IN_DWORD          sizeof(u32)
0390 /* In the macros below, size and offset are specified in bits */
0391 #define CEIL_DWORDS(size)       DIV_ROUND_UP(size, 32)
0392 #define FIELD_BIT_OFFSET(type, field)   type ## _ ## field ## _ ## OFFSET
0393 #define FIELD_BIT_SIZE(type, field) type ## _ ## field ## _ ## SIZE
0394 #define FIELD_DWORD_OFFSET(type, field) \
0395      ((int)(FIELD_BIT_OFFSET(type, field) / 32))
0396 #define FIELD_DWORD_SHIFT(type, field)  (FIELD_BIT_OFFSET(type, field) % 32)
0397 #define FIELD_BIT_MASK(type, field) \
0398     (((1 << FIELD_BIT_SIZE(type, field)) - 1) << \
0399      FIELD_DWORD_SHIFT(type, field))
0400 
0401 #define SET_VAR_FIELD(var, type, field, val) \
0402     do { \
0403         var[FIELD_DWORD_OFFSET(type, field)] &= \
0404         (~FIELD_BIT_MASK(type, field)); \
0405         var[FIELD_DWORD_OFFSET(type, field)] |= \
0406         (val) << FIELD_DWORD_SHIFT(type, field); \
0407     } while (0)
0408 
0409 #define ARR_REG_WR(dev, ptt, addr, arr, arr_size) \
0410     do { \
0411         for (i = 0; i < (arr_size); i++) \
0412             qed_wr(dev, ptt, addr,  (arr)[i]); \
0413     } while (0)
0414 
0415 #define DWORDS_TO_BYTES(dwords)     ((dwords) * BYTES_IN_DWORD)
0416 #define BYTES_TO_DWORDS(bytes)      ((bytes) / BYTES_IN_DWORD)
0417 
0418 /* extra lines include a signature line + optional latency events line */
0419 #define NUM_EXTRA_DBG_LINES(block) \
0420     (GET_FIELD((block)->flags, DBG_BLOCK_CHIP_HAS_LATENCY_EVENTS) ? 2 : 1)
0421 #define NUM_DBG_LINES(block) \
0422     ((block)->num_of_dbg_bus_lines + NUM_EXTRA_DBG_LINES(block))
0423 
0424 #define USE_DMAE            true
0425 #define PROTECT_WIDE_BUS        true
0426 
0427 #define RAM_LINES_TO_DWORDS(lines)  ((lines) * 2)
0428 #define RAM_LINES_TO_BYTES(lines) \
0429     DWORDS_TO_BYTES(RAM_LINES_TO_DWORDS(lines))
0430 
0431 #define REG_DUMP_LEN_SHIFT      24
0432 #define MEM_DUMP_ENTRY_SIZE_DWORDS \
0433     BYTES_TO_DWORDS(sizeof(struct dbg_dump_mem))
0434 
0435 #define IDLE_CHK_RULE_SIZE_DWORDS \
0436     BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_rule))
0437 
0438 #define IDLE_CHK_RESULT_HDR_DWORDS \
0439     BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_hdr))
0440 
0441 #define IDLE_CHK_RESULT_REG_HDR_DWORDS \
0442     BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_reg_hdr))
0443 
0444 #define PAGE_MEM_DESC_SIZE_DWORDS \
0445     BYTES_TO_DWORDS(sizeof(struct phys_mem_desc))
0446 
0447 #define IDLE_CHK_MAX_ENTRIES_SIZE   32
0448 
0449 /* The sizes and offsets below are specified in bits */
0450 #define VFC_CAM_CMD_STRUCT_SIZE     64
0451 #define VFC_CAM_CMD_ROW_OFFSET      48
0452 #define VFC_CAM_CMD_ROW_SIZE        9
0453 #define VFC_CAM_ADDR_STRUCT_SIZE    16
0454 #define VFC_CAM_ADDR_OP_OFFSET      0
0455 #define VFC_CAM_ADDR_OP_SIZE        4
0456 #define VFC_CAM_RESP_STRUCT_SIZE    256
0457 #define VFC_RAM_ADDR_STRUCT_SIZE    16
0458 #define VFC_RAM_ADDR_OP_OFFSET      0
0459 #define VFC_RAM_ADDR_OP_SIZE        2
0460 #define VFC_RAM_ADDR_ROW_OFFSET     2
0461 #define VFC_RAM_ADDR_ROW_SIZE       10
0462 #define VFC_RAM_RESP_STRUCT_SIZE    256
0463 
0464 #define VFC_CAM_CMD_DWORDS      CEIL_DWORDS(VFC_CAM_CMD_STRUCT_SIZE)
0465 #define VFC_CAM_ADDR_DWORDS     CEIL_DWORDS(VFC_CAM_ADDR_STRUCT_SIZE)
0466 #define VFC_CAM_RESP_DWORDS     CEIL_DWORDS(VFC_CAM_RESP_STRUCT_SIZE)
0467 #define VFC_RAM_CMD_DWORDS      VFC_CAM_CMD_DWORDS
0468 #define VFC_RAM_ADDR_DWORDS     CEIL_DWORDS(VFC_RAM_ADDR_STRUCT_SIZE)
0469 #define VFC_RAM_RESP_DWORDS     CEIL_DWORDS(VFC_RAM_RESP_STRUCT_SIZE)
0470 
0471 #define NUM_VFC_RAM_TYPES       4
0472 
0473 #define VFC_CAM_NUM_ROWS        512
0474 
0475 #define VFC_OPCODE_CAM_RD       14
0476 #define VFC_OPCODE_RAM_RD       0
0477 
0478 #define NUM_RSS_MEM_TYPES       5
0479 
0480 #define NUM_BIG_RAM_TYPES       3
0481 #define BIG_RAM_NAME_LEN        3
0482 
0483 #define NUM_PHY_TBUS_ADDRESSES      2048
0484 #define PHY_DUMP_SIZE_DWORDS        (NUM_PHY_TBUS_ADDRESSES / 2)
0485 
0486 #define RESET_REG_UNRESET_OFFSET    4
0487 
0488 #define STALL_DELAY_MS          500
0489 
0490 #define STATIC_DEBUG_LINE_DWORDS    9
0491 
0492 #define NUM_COMMON_GLOBAL_PARAMS    10
0493 
0494 #define MAX_RECURSION_DEPTH     10
0495 
0496 #define FW_IMG_KUKU                     0
0497 #define FW_IMG_MAIN         1
0498 #define FW_IMG_L2B                      2
0499 
0500 #define REG_FIFO_ELEMENT_DWORDS     2
0501 #define REG_FIFO_DEPTH_ELEMENTS     32
0502 #define REG_FIFO_DEPTH_DWORDS \
0503     (REG_FIFO_ELEMENT_DWORDS * REG_FIFO_DEPTH_ELEMENTS)
0504 
0505 #define IGU_FIFO_ELEMENT_DWORDS     4
0506 #define IGU_FIFO_DEPTH_ELEMENTS     64
0507 #define IGU_FIFO_DEPTH_DWORDS \
0508     (IGU_FIFO_ELEMENT_DWORDS * IGU_FIFO_DEPTH_ELEMENTS)
0509 
0510 #define PROTECTION_OVERRIDE_ELEMENT_DWORDS  2
0511 #define PROTECTION_OVERRIDE_DEPTH_ELEMENTS  20
0512 #define PROTECTION_OVERRIDE_DEPTH_DWORDS \
0513     (PROTECTION_OVERRIDE_DEPTH_ELEMENTS * \
0514      PROTECTION_OVERRIDE_ELEMENT_DWORDS)
0515 
0516 #define MCP_SPAD_TRACE_OFFSIZE_ADDR \
0517     (MCP_REG_SCRATCH + \
0518      offsetof(struct static_init, sections[SPAD_SECTION_TRACE]))
0519 
0520 #define MAX_SW_PLTAFORM_STR_SIZE    64
0521 
0522 #define EMPTY_FW_VERSION_STR        "???_???_???_???"
0523 #define EMPTY_FW_IMAGE_STR      "???????????????"
0524 
0525 /***************************** Constant Arrays *******************************/
0526 
0527 /* DBG block framing mode definitions, in descending preference order */
0528 static struct framing_mode_defs s_framing_mode_defs[4] = {
0529     {DBG_BUS_FRAME_MODE_4ST, 0x0, 0xf,
0530      DBG_BUS_SEMI_FRAME_MODE_4FAST,
0531      10},
0532     {DBG_BUS_FRAME_MODE_4HW, 0xf, 0x0, DBG_BUS_SEMI_FRAME_MODE_4SLOW,
0533      10},
0534     {DBG_BUS_FRAME_MODE_2ST_2HW, 0x3, 0xc,
0535      DBG_BUS_SEMI_FRAME_MODE_2FAST_2SLOW, 10},
0536     {DBG_BUS_FRAME_MODE_1ST_3HW, 0x7, 0x8,
0537      DBG_BUS_SEMI_FRAME_MODE_1FAST_3SLOW, 10}
0538 };
0539 
0540 /* Chip constant definitions array */
0541 static struct chip_defs s_chip_defs[MAX_CHIP_IDS] = {
0542     {"bb", 4, DBG_BUS_NUM_FRAME_MODES, PSWRQ2_REG_ILT_MEMORY_SIZE_BB / 2,
0543      s_framing_mode_defs},
0544     {"ah", 4, DBG_BUS_NUM_FRAME_MODES, PSWRQ2_REG_ILT_MEMORY_SIZE_K2 / 2,
0545      s_framing_mode_defs}
0546 };
0547 
0548 /* Storm constant definitions array */
0549 static struct storm_defs s_storm_defs[] = {
0550     /* Tstorm */
0551     {'T', BLOCK_TSEM,
0552         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
0553         true,
0554         TSEM_REG_FAST_MEMORY,
0555         TSEM_REG_DBG_FRAME_MODE, TSEM_REG_SLOW_DBG_ACTIVE,
0556         TSEM_REG_SLOW_DBG_MODE, TSEM_REG_DBG_MODE1_CFG,
0557         TSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_DBG_GPRE_VECT,
0558         TCM_REG_CTX_RBC_ACCS,
0559         {TCM_REG_AGG_CON_CTX, TCM_REG_SM_CON_CTX, TCM_REG_AGG_TASK_CTX,
0560          TCM_REG_SM_TASK_CTX},
0561         {{4, 16, 2, 4}, {4, 16, 2, 4}} /* {bb} {k2} */
0562     },
0563 
0564     /* Mstorm */
0565     {'M', BLOCK_MSEM,
0566         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
0567         false,
0568         MSEM_REG_FAST_MEMORY,
0569         MSEM_REG_DBG_FRAME_MODE,
0570         MSEM_REG_SLOW_DBG_ACTIVE,
0571         MSEM_REG_SLOW_DBG_MODE,
0572         MSEM_REG_DBG_MODE1_CFG,
0573         MSEM_REG_SYNC_DBG_EMPTY,
0574         MSEM_REG_DBG_GPRE_VECT,
0575         MCM_REG_CTX_RBC_ACCS,
0576         {MCM_REG_AGG_CON_CTX, MCM_REG_SM_CON_CTX, MCM_REG_AGG_TASK_CTX,
0577          MCM_REG_SM_TASK_CTX },
0578         {{1, 10, 2, 7}, {1, 10, 2, 7}} /* {bb} {k2}*/
0579     },
0580 
0581     /* Ustorm */
0582     {'U', BLOCK_USEM,
0583         {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
0584         false,
0585         USEM_REG_FAST_MEMORY,
0586         USEM_REG_DBG_FRAME_MODE,
0587         USEM_REG_SLOW_DBG_ACTIVE,
0588         USEM_REG_SLOW_DBG_MODE,
0589         USEM_REG_DBG_MODE1_CFG,
0590         USEM_REG_SYNC_DBG_EMPTY,
0591         USEM_REG_DBG_GPRE_VECT,
0592         UCM_REG_CTX_RBC_ACCS,
0593         {UCM_REG_AGG_CON_CTX, UCM_REG_SM_CON_CTX, UCM_REG_AGG_TASK_CTX,
0594          UCM_REG_SM_TASK_CTX},
0595         {{2, 13, 3, 3}, {2, 13, 3, 3}} /* {bb} {k2} */
0596     },
0597 
0598     /* Xstorm */
0599     {'X', BLOCK_XSEM,
0600         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
0601         false,
0602         XSEM_REG_FAST_MEMORY,
0603         XSEM_REG_DBG_FRAME_MODE,
0604         XSEM_REG_SLOW_DBG_ACTIVE,
0605         XSEM_REG_SLOW_DBG_MODE,
0606         XSEM_REG_DBG_MODE1_CFG,
0607         XSEM_REG_SYNC_DBG_EMPTY,
0608         XSEM_REG_DBG_GPRE_VECT,
0609         XCM_REG_CTX_RBC_ACCS,
0610         {XCM_REG_AGG_CON_CTX, XCM_REG_SM_CON_CTX, 0, 0},
0611         {{9, 15, 0, 0}, {9, 15, 0, 0}} /* {bb} {k2} */
0612     },
0613 
0614     /* Ystorm */
0615     {'Y', BLOCK_YSEM,
0616         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY},
0617         false,
0618         YSEM_REG_FAST_MEMORY,
0619         YSEM_REG_DBG_FRAME_MODE,
0620         YSEM_REG_SLOW_DBG_ACTIVE,
0621         YSEM_REG_SLOW_DBG_MODE,
0622         YSEM_REG_DBG_MODE1_CFG,
0623         YSEM_REG_SYNC_DBG_EMPTY,
0624         YSEM_REG_DBG_GPRE_VECT,
0625         YCM_REG_CTX_RBC_ACCS,
0626         {YCM_REG_AGG_CON_CTX, YCM_REG_SM_CON_CTX, YCM_REG_AGG_TASK_CTX,
0627          YCM_REG_SM_TASK_CTX},
0628         {{2, 3, 2, 12}, {2, 3, 2, 12}} /* {bb} {k2} */
0629     },
0630 
0631     /* Pstorm */
0632     {'P', BLOCK_PSEM,
0633         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
0634         true,
0635         PSEM_REG_FAST_MEMORY,
0636         PSEM_REG_DBG_FRAME_MODE,
0637         PSEM_REG_SLOW_DBG_ACTIVE,
0638         PSEM_REG_SLOW_DBG_MODE,
0639         PSEM_REG_DBG_MODE1_CFG,
0640         PSEM_REG_SYNC_DBG_EMPTY,
0641         PSEM_REG_DBG_GPRE_VECT,
0642         PCM_REG_CTX_RBC_ACCS,
0643         {0, PCM_REG_SM_CON_CTX, 0, 0},
0644         {{0, 10, 0, 0}, {0, 10, 0, 0}} /* {bb} {k2} */
0645     },
0646 };
0647 
0648 static struct hw_type_defs s_hw_type_defs[] = {
0649     /* HW_TYPE_ASIC */
0650     {"asic", 1, 256, 32768},
0651     {"reserved", 0, 0, 0},
0652     {"reserved2", 0, 0, 0},
0653     {"reserved3", 0, 0, 0},
0654     {"reserved4", 0, 0, 0}
0655 };
0656 
0657 static struct grc_param_defs s_grc_param_defs[] = {
0658     /* DBG_GRC_PARAM_DUMP_TSTORM */
0659     {{1, 1}, 0, 1, false, false, 1, {1, 1}},
0660 
0661     /* DBG_GRC_PARAM_DUMP_MSTORM */
0662     {{1, 1}, 0, 1, false, false, 1, {1, 1}},
0663 
0664     /* DBG_GRC_PARAM_DUMP_USTORM */
0665     {{1, 1}, 0, 1, false, false, 1, {1, 1}},
0666 
0667     /* DBG_GRC_PARAM_DUMP_XSTORM */
0668     {{1, 1}, 0, 1, false, false, 1, {1, 1}},
0669 
0670     /* DBG_GRC_PARAM_DUMP_YSTORM */
0671     {{1, 1}, 0, 1, false, false, 1, {1, 1}},
0672 
0673     /* DBG_GRC_PARAM_DUMP_PSTORM */
0674     {{1, 1}, 0, 1, false, false, 1, {1, 1}},
0675 
0676     /* DBG_GRC_PARAM_DUMP_REGS */
0677     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0678 
0679     /* DBG_GRC_PARAM_DUMP_RAM */
0680     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0681 
0682     /* DBG_GRC_PARAM_DUMP_PBUF */
0683     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0684 
0685     /* DBG_GRC_PARAM_DUMP_IOR */
0686     {{0, 0}, 0, 1, false, false, 0, {1, 1}},
0687 
0688     /* DBG_GRC_PARAM_DUMP_VFC */
0689     {{0, 0}, 0, 1, false, false, 0, {1, 1}},
0690 
0691     /* DBG_GRC_PARAM_DUMP_CM_CTX */
0692     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0693 
0694     /* DBG_GRC_PARAM_DUMP_ILT */
0695     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0696 
0697     /* DBG_GRC_PARAM_DUMP_RSS */
0698     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0699 
0700     /* DBG_GRC_PARAM_DUMP_CAU */
0701     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0702 
0703     /* DBG_GRC_PARAM_DUMP_QM */
0704     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0705 
0706     /* DBG_GRC_PARAM_DUMP_MCP */
0707     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0708 
0709     /* DBG_GRC_PARAM_DUMP_DORQ */
0710     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0711 
0712     /* DBG_GRC_PARAM_DUMP_CFC */
0713     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0714 
0715     /* DBG_GRC_PARAM_DUMP_IGU */
0716     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0717 
0718     /* DBG_GRC_PARAM_DUMP_BRB */
0719     {{0, 0}, 0, 1, false, false, 0, {1, 1}},
0720 
0721     /* DBG_GRC_PARAM_DUMP_BTB */
0722     {{0, 0}, 0, 1, false, false, 0, {1, 1}},
0723 
0724     /* DBG_GRC_PARAM_DUMP_BMB */
0725     {{0, 0}, 0, 1, false, false, 0, {0, 0}},
0726 
0727     /* DBG_GRC_PARAM_RESERVED1 */
0728     {{0, 0}, 0, 1, false, false, 0, {0, 0}},
0729 
0730     /* DBG_GRC_PARAM_DUMP_MULD */
0731     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0732 
0733     /* DBG_GRC_PARAM_DUMP_PRS */
0734     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0735 
0736     /* DBG_GRC_PARAM_DUMP_DMAE */
0737     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0738 
0739     /* DBG_GRC_PARAM_DUMP_TM */
0740     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0741 
0742     /* DBG_GRC_PARAM_DUMP_SDM */
0743     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0744 
0745     /* DBG_GRC_PARAM_DUMP_DIF */
0746     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0747 
0748     /* DBG_GRC_PARAM_DUMP_STATIC */
0749     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0750 
0751     /* DBG_GRC_PARAM_UNSTALL */
0752     {{0, 0}, 0, 1, false, false, 0, {0, 0}},
0753 
0754     /* DBG_GRC_PARAM_RESERVED2 */
0755     {{0, 0}, 0, 1, false, false, 0, {0, 0}},
0756 
0757     /* DBG_GRC_PARAM_MCP_TRACE_META_SIZE */
0758     {{0, 0}, 1, 0xffffffff, false, true, 0, {0, 0}},
0759 
0760     /* DBG_GRC_PARAM_EXCLUDE_ALL */
0761     {{0, 0}, 0, 1, true, false, 0, {0, 0}},
0762 
0763     /* DBG_GRC_PARAM_CRASH */
0764     {{0, 0}, 0, 1, true, false, 0, {0, 0}},
0765 
0766     /* DBG_GRC_PARAM_PARITY_SAFE */
0767     {{0, 0}, 0, 1, false, false, 0, {0, 0}},
0768 
0769     /* DBG_GRC_PARAM_DUMP_CM */
0770     {{1, 1}, 0, 1, false, false, 0, {1, 1}},
0771 
0772     /* DBG_GRC_PARAM_DUMP_PHY */
0773     {{0, 0}, 0, 1, false, false, 0, {0, 0}},
0774 
0775     /* DBG_GRC_PARAM_NO_MCP */
0776     {{0, 0}, 0, 1, false, false, 0, {0, 0}},
0777 
0778     /* DBG_GRC_PARAM_NO_FW_VER */
0779     {{0, 0}, 0, 1, false, false, 0, {0, 0}},
0780 
0781     /* DBG_GRC_PARAM_RESERVED3 */
0782     {{0, 0}, 0, 1, false, false, 0, {0, 0}},
0783 
0784     /* DBG_GRC_PARAM_DUMP_MCP_HW_DUMP */
0785     {{0, 1}, 0, 1, false, false, 0, {0, 1}},
0786 
0787     /* DBG_GRC_PARAM_DUMP_ILT_CDUC */
0788     {{1, 1}, 0, 1, false, false, 0, {0, 0}},
0789 
0790     /* DBG_GRC_PARAM_DUMP_ILT_CDUT */
0791     {{1, 1}, 0, 1, false, false, 0, {0, 0}},
0792 
0793     /* DBG_GRC_PARAM_DUMP_CAU_EXT */
0794     {{0, 0}, 0, 1, false, false, 0, {1, 1}}
0795 };
0796 
0797 static struct rss_mem_defs s_rss_mem_defs[] = {
0798     {"rss_mem_cid", "rss_cid", 0, 32,
0799      {256, 320}},
0800 
0801     {"rss_mem_key_msb", "rss_key", 1024, 256,
0802      {128, 208}},
0803 
0804     {"rss_mem_key_lsb", "rss_key", 2048, 64,
0805      {128, 208}},
0806 
0807     {"rss_mem_info", "rss_info", 3072, 16,
0808      {128, 208}},
0809 
0810     {"rss_mem_ind", "rss_ind", 4096, 16,
0811      {16384, 26624}}
0812 };
0813 
0814 static struct vfc_ram_defs s_vfc_ram_defs[] = {
0815     {"vfc_ram_tt1", "vfc_ram", 0, 512},
0816     {"vfc_ram_mtt2", "vfc_ram", 512, 128},
0817     {"vfc_ram_stt2", "vfc_ram", 640, 32},
0818     {"vfc_ram_ro_vect", "vfc_ram", 672, 32}
0819 };
0820 
0821 static struct big_ram_defs s_big_ram_defs[] = {
0822     {"BRB", MEM_GROUP_BRB_MEM, MEM_GROUP_BRB_RAM, DBG_GRC_PARAM_DUMP_BRB,
0823      BRB_REG_BIG_RAM_ADDRESS, BRB_REG_BIG_RAM_DATA,
0824      MISC_REG_BLOCK_256B_EN, {0, 0},
0825      {153600, 180224}},
0826 
0827     {"BTB", MEM_GROUP_BTB_MEM, MEM_GROUP_BTB_RAM, DBG_GRC_PARAM_DUMP_BTB,
0828      BTB_REG_BIG_RAM_ADDRESS, BTB_REG_BIG_RAM_DATA,
0829      MISC_REG_BLOCK_256B_EN, {0, 1},
0830      {92160, 117760}},
0831 
0832     {"BMB", MEM_GROUP_BMB_MEM, MEM_GROUP_BMB_RAM, DBG_GRC_PARAM_DUMP_BMB,
0833      BMB_REG_BIG_RAM_ADDRESS, BMB_REG_BIG_RAM_DATA,
0834      MISCS_REG_BLOCK_256B_EN, {0, 0},
0835      {36864, 36864}}
0836 };
0837 
0838 static struct rbc_reset_defs s_rbc_reset_defs[] = {
0839     {MISCS_REG_RESET_PL_HV,
0840      {0x0, 0x400}},
0841     {MISC_REG_RESET_PL_PDA_VMAIN_1,
0842      {0x4404040, 0x4404040}},
0843     {MISC_REG_RESET_PL_PDA_VMAIN_2,
0844      {0x7, 0x7c00007}},
0845     {MISC_REG_RESET_PL_PDA_VAUX,
0846      {0x2, 0x2}},
0847 };
0848 
0849 static struct phy_defs s_phy_defs[] = {
0850     {"nw_phy", NWS_REG_NWS_CMU_K2,
0851      PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_7_0_K2,
0852      PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_15_8_K2,
0853      PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_7_0_K2,
0854      PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_11_8_K2},
0855     {"sgmii_phy", MS_REG_MS_CMU_K2,
0856      PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X132_K2,
0857      PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X133_K2,
0858      PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X130_K2,
0859      PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X131_K2},
0860     {"pcie_phy0", PHY_PCIE_REG_PHY0_K2,
0861      PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2,
0862      PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2,
0863      PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2,
0864      PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2},
0865     {"pcie_phy1", PHY_PCIE_REG_PHY1_K2,
0866      PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2,
0867      PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2,
0868      PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2,
0869      PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2},
0870 };
0871 
0872 static struct split_type_defs s_split_type_defs[] = {
0873     /* SPLIT_TYPE_NONE */
0874     {"eng"},
0875 
0876     /* SPLIT_TYPE_PORT */
0877     {"port"},
0878 
0879     /* SPLIT_TYPE_PF */
0880     {"pf"},
0881 
0882     /* SPLIT_TYPE_PORT_PF */
0883     {"port"},
0884 
0885     /* SPLIT_TYPE_VF */
0886     {"vf"}
0887 };
0888 
0889 /******************************** Variables **********************************/
0890 
0891 /* The version of the calling app */
0892 static u32 s_app_ver;
0893 
0894 /**************************** Private Functions ******************************/
0895 
0896 static void qed_static_asserts(void)
0897 {
0898 }
0899 
0900 /* Reads and returns a single dword from the specified unaligned buffer */
0901 static u32 qed_read_unaligned_dword(u8 *buf)
0902 {
0903     u32 dword;
0904 
0905     memcpy((u8 *)&dword, buf, sizeof(dword));
0906     return dword;
0907 }
0908 
0909 /* Sets the value of the specified GRC param */
0910 static void qed_grc_set_param(struct qed_hwfn *p_hwfn,
0911                   enum dbg_grc_params grc_param, u32 val)
0912 {
0913     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
0914 
0915     dev_data->grc.param_val[grc_param] = val;
0916 }
0917 
0918 /* Returns the value of the specified GRC param */
0919 static u32 qed_grc_get_param(struct qed_hwfn *p_hwfn,
0920                  enum dbg_grc_params grc_param)
0921 {
0922     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
0923 
0924     return dev_data->grc.param_val[grc_param];
0925 }
0926 
0927 /* Initializes the GRC parameters */
0928 static void qed_dbg_grc_init_params(struct qed_hwfn *p_hwfn)
0929 {
0930     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
0931 
0932     if (!dev_data->grc.params_initialized) {
0933         qed_dbg_grc_set_params_default(p_hwfn);
0934         dev_data->grc.params_initialized = 1;
0935     }
0936 }
0937 
0938 /* Sets pointer and size for the specified binary buffer type */
0939 static void qed_set_dbg_bin_buf(struct qed_hwfn *p_hwfn,
0940                 enum bin_dbg_buffer_type buf_type,
0941                 const u32 *ptr, u32 size)
0942 {
0943     struct virt_mem_desc *buf = &p_hwfn->dbg_arrays[buf_type];
0944 
0945     buf->ptr = (void *)ptr;
0946     buf->size = size;
0947 }
0948 
0949 /* Initializes debug data for the specified device */
0950 static enum dbg_status qed_dbg_dev_init(struct qed_hwfn *p_hwfn)
0951 {
0952     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
0953     u8 num_pfs = 0, max_pfs_per_port = 0;
0954 
0955     if (dev_data->initialized)
0956         return DBG_STATUS_OK;
0957 
0958     if (!s_app_ver)
0959         return DBG_STATUS_APP_VERSION_NOT_SET;
0960 
0961     /* Set chip */
0962     if (QED_IS_K2(p_hwfn->cdev)) {
0963         dev_data->chip_id = CHIP_K2;
0964         dev_data->mode_enable[MODE_K2] = 1;
0965         dev_data->num_vfs = MAX_NUM_VFS_K2;
0966         num_pfs = MAX_NUM_PFS_K2;
0967         max_pfs_per_port = MAX_NUM_PFS_K2 / 2;
0968     } else if (QED_IS_BB_B0(p_hwfn->cdev)) {
0969         dev_data->chip_id = CHIP_BB;
0970         dev_data->mode_enable[MODE_BB] = 1;
0971         dev_data->num_vfs = MAX_NUM_VFS_BB;
0972         num_pfs = MAX_NUM_PFS_BB;
0973         max_pfs_per_port = MAX_NUM_PFS_BB;
0974     } else {
0975         return DBG_STATUS_UNKNOWN_CHIP;
0976     }
0977 
0978     /* Set HW type */
0979     dev_data->hw_type = HW_TYPE_ASIC;
0980     dev_data->mode_enable[MODE_ASIC] = 1;
0981 
0982     /* Set port mode */
0983     switch (p_hwfn->cdev->num_ports_in_engine) {
0984     case 1:
0985         dev_data->mode_enable[MODE_PORTS_PER_ENG_1] = 1;
0986         break;
0987     case 2:
0988         dev_data->mode_enable[MODE_PORTS_PER_ENG_2] = 1;
0989         break;
0990     case 4:
0991         dev_data->mode_enable[MODE_PORTS_PER_ENG_4] = 1;
0992         break;
0993     }
0994 
0995     /* Set 100G mode */
0996     if (QED_IS_CMT(p_hwfn->cdev))
0997         dev_data->mode_enable[MODE_100G] = 1;
0998 
0999     /* Set number of ports */
1000     if (dev_data->mode_enable[MODE_PORTS_PER_ENG_1] ||
1001         dev_data->mode_enable[MODE_100G])
1002         dev_data->num_ports = 1;
1003     else if (dev_data->mode_enable[MODE_PORTS_PER_ENG_2])
1004         dev_data->num_ports = 2;
1005     else if (dev_data->mode_enable[MODE_PORTS_PER_ENG_4])
1006         dev_data->num_ports = 4;
1007 
1008     /* Set number of PFs per port */
1009     dev_data->num_pfs_per_port = min_t(u32,
1010                        num_pfs / dev_data->num_ports,
1011                        max_pfs_per_port);
1012 
1013     /* Initializes the GRC parameters */
1014     qed_dbg_grc_init_params(p_hwfn);
1015 
1016     dev_data->use_dmae = true;
1017     dev_data->initialized = 1;
1018 
1019     return DBG_STATUS_OK;
1020 }
1021 
1022 static const struct dbg_block *get_dbg_block(struct qed_hwfn *p_hwfn,
1023                          enum block_id block_id)
1024 {
1025     const struct dbg_block *dbg_block;
1026 
1027     dbg_block = p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS].ptr;
1028     return dbg_block + block_id;
1029 }
1030 
1031 static const struct dbg_block_chip *qed_get_dbg_block_per_chip(struct qed_hwfn
1032                                    *p_hwfn,
1033                                    enum block_id
1034                                    block_id)
1035 {
1036     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1037 
1038     return (const struct dbg_block_chip *)
1039         p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS_CHIP_DATA].ptr +
1040         block_id * MAX_CHIP_IDS + dev_data->chip_id;
1041 }
1042 
1043 static const struct dbg_reset_reg *qed_get_dbg_reset_reg(struct qed_hwfn
1044                              *p_hwfn,
1045                              u8 reset_reg_id)
1046 {
1047     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1048 
1049     return (const struct dbg_reset_reg *)
1050         p_hwfn->dbg_arrays[BIN_BUF_DBG_RESET_REGS].ptr +
1051         reset_reg_id * MAX_CHIP_IDS + dev_data->chip_id;
1052 }
1053 
1054 /* Reads the FW info structure for the specified Storm from the chip,
1055  * and writes it to the specified fw_info pointer.
1056  */
1057 static void qed_read_storm_fw_info(struct qed_hwfn *p_hwfn,
1058                    struct qed_ptt *p_ptt,
1059                    u8 storm_id, struct fw_info *fw_info)
1060 {
1061     struct storm_defs *storm = &s_storm_defs[storm_id];
1062     struct fw_info_location fw_info_location;
1063     u32 addr, i, size, *dest;
1064 
1065     memset(&fw_info_location, 0, sizeof(fw_info_location));
1066     memset(fw_info, 0, sizeof(*fw_info));
1067 
1068     /* Read first the address that points to fw_info location.
1069      * The address is located in the last line of the Storm RAM.
1070      */
1071     addr = storm->sem_fast_mem_addr + SEM_FAST_REG_INT_RAM +
1072         DWORDS_TO_BYTES(SEM_FAST_REG_INT_RAM_SIZE) -
1073         sizeof(fw_info_location);
1074 
1075     dest = (u32 *)&fw_info_location;
1076     size = BYTES_TO_DWORDS(sizeof(fw_info_location));
1077 
1078     for (i = 0; i < size; i++, addr += BYTES_IN_DWORD)
1079         dest[i] = qed_rd(p_hwfn, p_ptt, addr);
1080 
1081     /* Read FW version info from Storm RAM */
1082     size = le32_to_cpu(fw_info_location.size);
1083     if (!size || size > sizeof(*fw_info))
1084         return;
1085 
1086     addr = le32_to_cpu(fw_info_location.grc_addr);
1087     dest = (u32 *)fw_info;
1088     size = BYTES_TO_DWORDS(size);
1089 
1090     for (i = 0; i < size; i++, addr += BYTES_IN_DWORD)
1091         dest[i] = qed_rd(p_hwfn, p_ptt, addr);
1092 }
1093 
1094 /* Dumps the specified string to the specified buffer.
1095  * Returns the dumped size in bytes.
1096  */
1097 static u32 qed_dump_str(char *dump_buf, bool dump, const char *str)
1098 {
1099     if (dump)
1100         strcpy(dump_buf, str);
1101 
1102     return (u32)strlen(str) + 1;
1103 }
1104 
1105 /* Dumps zeros to align the specified buffer to dwords.
1106  * Returns the dumped size in bytes.
1107  */
1108 static u32 qed_dump_align(char *dump_buf, bool dump, u32 byte_offset)
1109 {
1110     u8 offset_in_dword, align_size;
1111 
1112     offset_in_dword = (u8)(byte_offset & 0x3);
1113     align_size = offset_in_dword ? BYTES_IN_DWORD - offset_in_dword : 0;
1114 
1115     if (dump && align_size)
1116         memset(dump_buf, 0, align_size);
1117 
1118     return align_size;
1119 }
1120 
1121 /* Writes the specified string param to the specified buffer.
1122  * Returns the dumped size in dwords.
1123  */
1124 static u32 qed_dump_str_param(u32 *dump_buf,
1125                   bool dump,
1126                   const char *param_name, const char *param_val)
1127 {
1128     char *char_buf = (char *)dump_buf;
1129     u32 offset = 0;
1130 
1131     /* Dump param name */
1132     offset += qed_dump_str(char_buf + offset, dump, param_name);
1133 
1134     /* Indicate a string param value */
1135     if (dump)
1136         *(char_buf + offset) = 1;
1137     offset++;
1138 
1139     /* Dump param value */
1140     offset += qed_dump_str(char_buf + offset, dump, param_val);
1141 
1142     /* Align buffer to next dword */
1143     offset += qed_dump_align(char_buf + offset, dump, offset);
1144 
1145     return BYTES_TO_DWORDS(offset);
1146 }
1147 
1148 /* Writes the specified numeric param to the specified buffer.
1149  * Returns the dumped size in dwords.
1150  */
1151 static u32 qed_dump_num_param(u32 *dump_buf,
1152                   bool dump, const char *param_name, u32 param_val)
1153 {
1154     char *char_buf = (char *)dump_buf;
1155     u32 offset = 0;
1156 
1157     /* Dump param name */
1158     offset += qed_dump_str(char_buf + offset, dump, param_name);
1159 
1160     /* Indicate a numeric param value */
1161     if (dump)
1162         *(char_buf + offset) = 0;
1163     offset++;
1164 
1165     /* Align buffer to next dword */
1166     offset += qed_dump_align(char_buf + offset, dump, offset);
1167 
1168     /* Dump param value (and change offset from bytes to dwords) */
1169     offset = BYTES_TO_DWORDS(offset);
1170     if (dump)
1171         *(dump_buf + offset) = param_val;
1172     offset++;
1173 
1174     return offset;
1175 }
1176 
1177 /* Reads the FW version and writes it as a param to the specified buffer.
1178  * Returns the dumped size in dwords.
1179  */
1180 static u32 qed_dump_fw_ver_param(struct qed_hwfn *p_hwfn,
1181                  struct qed_ptt *p_ptt,
1182                  u32 *dump_buf, bool dump)
1183 {
1184     char fw_ver_str[16] = EMPTY_FW_VERSION_STR;
1185     char fw_img_str[16] = EMPTY_FW_IMAGE_STR;
1186     struct fw_info fw_info = { {0}, {0} };
1187     u32 offset = 0;
1188 
1189     if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {
1190         /* Read FW info from chip */
1191         qed_read_fw_info(p_hwfn, p_ptt, &fw_info);
1192 
1193         /* Create FW version/image strings */
1194         if (snprintf(fw_ver_str, sizeof(fw_ver_str),
1195                  "%d_%d_%d_%d", fw_info.ver.num.major,
1196                  fw_info.ver.num.minor, fw_info.ver.num.rev,
1197                  fw_info.ver.num.eng) < 0)
1198             DP_NOTICE(p_hwfn,
1199                   "Unexpected debug error: invalid FW version string\n");
1200         switch (fw_info.ver.image_id) {
1201         case FW_IMG_KUKU:
1202             strcpy(fw_img_str, "kuku");
1203             break;
1204         case FW_IMG_MAIN:
1205             strcpy(fw_img_str, "main");
1206             break;
1207         case FW_IMG_L2B:
1208             strcpy(fw_img_str, "l2b");
1209             break;
1210         default:
1211             strcpy(fw_img_str, "unknown");
1212             break;
1213         }
1214     }
1215 
1216     /* Dump FW version, image and timestamp */
1217     offset += qed_dump_str_param(dump_buf + offset,
1218                      dump, "fw-version", fw_ver_str);
1219     offset += qed_dump_str_param(dump_buf + offset,
1220                      dump, "fw-image", fw_img_str);
1221     offset += qed_dump_num_param(dump_buf + offset, dump, "fw-timestamp",
1222                      le32_to_cpu(fw_info.ver.timestamp));
1223 
1224     return offset;
1225 }
1226 
1227 /* Reads the MFW version and writes it as a param to the specified buffer.
1228  * Returns the dumped size in dwords.
1229  */
1230 static u32 qed_dump_mfw_ver_param(struct qed_hwfn *p_hwfn,
1231                   struct qed_ptt *p_ptt,
1232                   u32 *dump_buf, bool dump)
1233 {
1234     char mfw_ver_str[16] = EMPTY_FW_VERSION_STR;
1235 
1236     if (dump &&
1237         !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {
1238         u32 global_section_offsize, global_section_addr, mfw_ver;
1239         u32 public_data_addr, global_section_offsize_addr;
1240 
1241         /* Find MCP public data GRC address. Needs to be ORed with
1242          * MCP_REG_SCRATCH due to a HW bug.
1243          */
1244         public_data_addr = qed_rd(p_hwfn,
1245                       p_ptt,
1246                       MISC_REG_SHARED_MEM_ADDR) |
1247                    MCP_REG_SCRATCH;
1248 
1249         /* Find MCP public global section offset */
1250         global_section_offsize_addr = public_data_addr +
1251                           offsetof(struct mcp_public_data,
1252                                sections) +
1253                           sizeof(offsize_t) * PUBLIC_GLOBAL;
1254         global_section_offsize = qed_rd(p_hwfn, p_ptt,
1255                         global_section_offsize_addr);
1256         global_section_addr =
1257             MCP_REG_SCRATCH +
1258             (global_section_offsize & OFFSIZE_OFFSET_MASK) * 4;
1259 
1260         /* Read MFW version from MCP public global section */
1261         mfw_ver = qed_rd(p_hwfn, p_ptt,
1262                  global_section_addr +
1263                  offsetof(struct public_global, mfw_ver));
1264 
1265         /* Dump MFW version param */
1266         if (snprintf(mfw_ver_str, sizeof(mfw_ver_str), "%d_%d_%d_%d",
1267                  (u8)(mfw_ver >> 24), (u8)(mfw_ver >> 16),
1268                  (u8)(mfw_ver >> 8), (u8)mfw_ver) < 0)
1269             DP_NOTICE(p_hwfn,
1270                   "Unexpected debug error: invalid MFW version string\n");
1271     }
1272 
1273     return qed_dump_str_param(dump_buf, dump, "mfw-version", mfw_ver_str);
1274 }
1275 
1276 /* Reads the chip revision from the chip and writes it as a param to the
1277  * specified buffer. Returns the dumped size in dwords.
1278  */
1279 static u32 qed_dump_chip_revision_param(struct qed_hwfn *p_hwfn,
1280                     struct qed_ptt *p_ptt,
1281                     u32 *dump_buf, bool dump)
1282 {
1283     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1284     char param_str[3] = "??";
1285 
1286     if (dev_data->hw_type == HW_TYPE_ASIC) {
1287         u32 chip_rev, chip_metal;
1288 
1289         chip_rev = qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_REV);
1290         chip_metal = qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_METAL);
1291 
1292         param_str[0] = 'a' + (u8)chip_rev;
1293         param_str[1] = '0' + (u8)chip_metal;
1294     }
1295 
1296     return qed_dump_str_param(dump_buf, dump, "chip-revision", param_str);
1297 }
1298 
1299 /* Writes a section header to the specified buffer.
1300  * Returns the dumped size in dwords.
1301  */
1302 static u32 qed_dump_section_hdr(u32 *dump_buf,
1303                 bool dump, const char *name, u32 num_params)
1304 {
1305     return qed_dump_num_param(dump_buf, dump, name, num_params);
1306 }
1307 
1308 /* Writes the common global params to the specified buffer.
1309  * Returns the dumped size in dwords.
1310  */
1311 static u32 qed_dump_common_global_params(struct qed_hwfn *p_hwfn,
1312                      struct qed_ptt *p_ptt,
1313                      u32 *dump_buf,
1314                      bool dump,
1315                      u8 num_specific_global_params)
1316 {
1317     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1318     u32 offset = 0;
1319     u8 num_params;
1320 
1321     /* Dump global params section header */
1322     num_params = NUM_COMMON_GLOBAL_PARAMS + num_specific_global_params +
1323         (dev_data->chip_id == CHIP_BB ? 1 : 0);
1324     offset += qed_dump_section_hdr(dump_buf + offset,
1325                        dump, "global_params", num_params);
1326 
1327     /* Store params */
1328     offset += qed_dump_fw_ver_param(p_hwfn, p_ptt, dump_buf + offset, dump);
1329     offset += qed_dump_mfw_ver_param(p_hwfn,
1330                      p_ptt, dump_buf + offset, dump);
1331     offset += qed_dump_chip_revision_param(p_hwfn,
1332                            p_ptt, dump_buf + offset, dump);
1333     offset += qed_dump_num_param(dump_buf + offset,
1334                      dump, "tools-version", TOOLS_VERSION);
1335     offset += qed_dump_str_param(dump_buf + offset,
1336                      dump,
1337                      "chip",
1338                      s_chip_defs[dev_data->chip_id].name);
1339     offset += qed_dump_str_param(dump_buf + offset,
1340                      dump,
1341                      "platform",
1342                      s_hw_type_defs[dev_data->hw_type].name);
1343     offset += qed_dump_num_param(dump_buf + offset,
1344                      dump, "pci-func", p_hwfn->abs_pf_id);
1345     offset += qed_dump_num_param(dump_buf + offset,
1346                      dump, "epoch", qed_get_epoch_time());
1347     if (dev_data->chip_id == CHIP_BB)
1348         offset += qed_dump_num_param(dump_buf + offset,
1349                          dump, "path", QED_PATH_ID(p_hwfn));
1350 
1351     return offset;
1352 }
1353 
1354 /* Writes the "last" section (including CRC) to the specified buffer at the
1355  * given offset. Returns the dumped size in dwords.
1356  */
1357 static u32 qed_dump_last_section(u32 *dump_buf, u32 offset, bool dump)
1358 {
1359     u32 start_offset = offset;
1360 
1361     /* Dump CRC section header */
1362     offset += qed_dump_section_hdr(dump_buf + offset, dump, "last", 0);
1363 
1364     /* Calculate CRC32 and add it to the dword after the "last" section */
1365     if (dump)
1366         *(dump_buf + offset) = ~crc32(0xffffffff,
1367                           (u8 *)dump_buf,
1368                           DWORDS_TO_BYTES(offset));
1369 
1370     offset++;
1371 
1372     return offset - start_offset;
1373 }
1374 
1375 /* Update blocks reset state  */
1376 static void qed_update_blocks_reset_state(struct qed_hwfn *p_hwfn,
1377                       struct qed_ptt *p_ptt)
1378 {
1379     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1380     u32 reg_val[NUM_DBG_RESET_REGS] = { 0 };
1381     u8 rst_reg_id;
1382     u32 blk_id;
1383 
1384     /* Read reset registers */
1385     for (rst_reg_id = 0; rst_reg_id < NUM_DBG_RESET_REGS; rst_reg_id++) {
1386         const struct dbg_reset_reg *rst_reg;
1387         bool rst_reg_removed;
1388         u32 rst_reg_addr;
1389 
1390         rst_reg = qed_get_dbg_reset_reg(p_hwfn, rst_reg_id);
1391         rst_reg_removed = GET_FIELD(rst_reg->data,
1392                         DBG_RESET_REG_IS_REMOVED);
1393         rst_reg_addr = DWORDS_TO_BYTES(GET_FIELD(rst_reg->data,
1394                              DBG_RESET_REG_ADDR));
1395 
1396         if (!rst_reg_removed)
1397             reg_val[rst_reg_id] = qed_rd(p_hwfn, p_ptt,
1398                              rst_reg_addr);
1399     }
1400 
1401     /* Check if blocks are in reset */
1402     for (blk_id = 0; blk_id < NUM_PHYS_BLOCKS; blk_id++) {
1403         const struct dbg_block_chip *blk;
1404         bool has_rst_reg;
1405         bool is_removed;
1406 
1407         blk = qed_get_dbg_block_per_chip(p_hwfn, (enum block_id)blk_id);
1408         is_removed = GET_FIELD(blk->flags, DBG_BLOCK_CHIP_IS_REMOVED);
1409         has_rst_reg = GET_FIELD(blk->flags,
1410                     DBG_BLOCK_CHIP_HAS_RESET_REG);
1411 
1412         if (!is_removed && has_rst_reg)
1413             dev_data->block_in_reset[blk_id] =
1414                 !(reg_val[blk->reset_reg_id] &
1415                   BIT(blk->reset_reg_bit_offset));
1416     }
1417 }
1418 
1419 /* is_mode_match recursive function */
1420 static bool qed_is_mode_match_rec(struct qed_hwfn *p_hwfn,
1421                   u16 *modes_buf_offset, u8 rec_depth)
1422 {
1423     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1424     u8 *dbg_array;
1425     bool arg1, arg2;
1426     u8 tree_val;
1427 
1428     if (rec_depth > MAX_RECURSION_DEPTH) {
1429         DP_NOTICE(p_hwfn,
1430               "Unexpected error: is_mode_match_rec exceeded the max recursion depth. This is probably due to a corrupt init/debug buffer.\n");
1431         return false;
1432     }
1433 
1434     /* Get next element from modes tree buffer */
1435     dbg_array = p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr;
1436     tree_val = dbg_array[(*modes_buf_offset)++];
1437 
1438     switch (tree_val) {
1439     case INIT_MODE_OP_NOT:
1440         return !qed_is_mode_match_rec(p_hwfn,
1441                           modes_buf_offset, rec_depth + 1);
1442     case INIT_MODE_OP_OR:
1443     case INIT_MODE_OP_AND:
1444         arg1 = qed_is_mode_match_rec(p_hwfn,
1445                          modes_buf_offset, rec_depth + 1);
1446         arg2 = qed_is_mode_match_rec(p_hwfn,
1447                          modes_buf_offset, rec_depth + 1);
1448         return (tree_val == INIT_MODE_OP_OR) ? (arg1 ||
1449                             arg2) : (arg1 && arg2);
1450     default:
1451         return dev_data->mode_enable[tree_val - MAX_INIT_MODE_OPS] > 0;
1452     }
1453 }
1454 
1455 /* Returns true if the mode (specified using modes_buf_offset) is enabled */
1456 static bool qed_is_mode_match(struct qed_hwfn *p_hwfn, u16 *modes_buf_offset)
1457 {
1458     return qed_is_mode_match_rec(p_hwfn, modes_buf_offset, 0);
1459 }
1460 
1461 /* Enable / disable the Debug block */
1462 static void qed_bus_enable_dbg_block(struct qed_hwfn *p_hwfn,
1463                      struct qed_ptt *p_ptt, bool enable)
1464 {
1465     qed_wr(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON, enable ? 1 : 0);
1466 }
1467 
1468 /* Resets the Debug block */
1469 static void qed_bus_reset_dbg_block(struct qed_hwfn *p_hwfn,
1470                     struct qed_ptt *p_ptt)
1471 {
1472     u32 reset_reg_addr, old_reset_reg_val, new_reset_reg_val;
1473     const struct dbg_reset_reg *reset_reg;
1474     const struct dbg_block_chip *block;
1475 
1476     block = qed_get_dbg_block_per_chip(p_hwfn, BLOCK_DBG);
1477     reset_reg = qed_get_dbg_reset_reg(p_hwfn, block->reset_reg_id);
1478     reset_reg_addr =
1479         DWORDS_TO_BYTES(GET_FIELD(reset_reg->data, DBG_RESET_REG_ADDR));
1480 
1481     old_reset_reg_val = qed_rd(p_hwfn, p_ptt, reset_reg_addr);
1482     new_reset_reg_val =
1483         old_reset_reg_val & ~BIT(block->reset_reg_bit_offset);
1484 
1485     qed_wr(p_hwfn, p_ptt, reset_reg_addr, new_reset_reg_val);
1486     qed_wr(p_hwfn, p_ptt, reset_reg_addr, old_reset_reg_val);
1487 }
1488 
1489 /* Enable / disable Debug Bus clients according to the specified mask
1490  * (1 = enable, 0 = disable).
1491  */
1492 static void qed_bus_enable_clients(struct qed_hwfn *p_hwfn,
1493                    struct qed_ptt *p_ptt, u32 client_mask)
1494 {
1495     qed_wr(p_hwfn, p_ptt, DBG_REG_CLIENT_ENABLE, client_mask);
1496 }
1497 
1498 static void qed_bus_config_dbg_line(struct qed_hwfn *p_hwfn,
1499                     struct qed_ptt *p_ptt,
1500                     enum block_id block_id,
1501                     u8 line_id,
1502                     u8 enable_mask,
1503                     u8 right_shift,
1504                     u8 force_valid_mask, u8 force_frame_mask)
1505 {
1506     const struct dbg_block_chip *block =
1507         qed_get_dbg_block_per_chip(p_hwfn, block_id);
1508 
1509     qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_select_reg_addr),
1510            line_id);
1511     qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_dword_enable_reg_addr),
1512            enable_mask);
1513     qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_shift_reg_addr),
1514            right_shift);
1515     qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_force_valid_reg_addr),
1516            force_valid_mask);
1517     qed_wr(p_hwfn, p_ptt, DWORDS_TO_BYTES(block->dbg_force_frame_reg_addr),
1518            force_frame_mask);
1519 }
1520 
1521 /* Disable debug bus in all blocks */
1522 static void qed_bus_disable_blocks(struct qed_hwfn *p_hwfn,
1523                    struct qed_ptt *p_ptt)
1524 {
1525     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1526     u32 block_id;
1527 
1528     /* Disable all blocks */
1529     for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
1530         const struct dbg_block_chip *block_per_chip =
1531             qed_get_dbg_block_per_chip(p_hwfn,
1532                            (enum block_id)block_id);
1533 
1534         if (GET_FIELD(block_per_chip->flags,
1535                   DBG_BLOCK_CHIP_IS_REMOVED) ||
1536             dev_data->block_in_reset[block_id])
1537             continue;
1538 
1539         /* Disable debug bus */
1540         if (GET_FIELD(block_per_chip->flags,
1541                   DBG_BLOCK_CHIP_HAS_DBG_BUS)) {
1542             u32 dbg_en_addr =
1543                 block_per_chip->dbg_dword_enable_reg_addr;
1544             u16 modes_buf_offset =
1545                 GET_FIELD(block_per_chip->dbg_bus_mode.data,
1546                       DBG_MODE_HDR_MODES_BUF_OFFSET);
1547             bool eval_mode =
1548                 GET_FIELD(block_per_chip->dbg_bus_mode.data,
1549                       DBG_MODE_HDR_EVAL_MODE) > 0;
1550 
1551             if (!eval_mode ||
1552                 qed_is_mode_match(p_hwfn, &modes_buf_offset))
1553                 qed_wr(p_hwfn, p_ptt,
1554                        DWORDS_TO_BYTES(dbg_en_addr),
1555                        0);
1556         }
1557     }
1558 }
1559 
1560 /* Returns true if the specified entity (indicated by GRC param) should be
1561  * included in the dump, false otherwise.
1562  */
1563 static bool qed_grc_is_included(struct qed_hwfn *p_hwfn,
1564                 enum dbg_grc_params grc_param)
1565 {
1566     return qed_grc_get_param(p_hwfn, grc_param) > 0;
1567 }
1568 
1569 /* Returns the storm_id that matches the specified Storm letter,
1570  * or MAX_DBG_STORMS if invalid storm letter.
1571  */
1572 static enum dbg_storms qed_get_id_from_letter(char storm_letter)
1573 {
1574     u8 storm_id;
1575 
1576     for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++)
1577         if (s_storm_defs[storm_id].letter == storm_letter)
1578             return (enum dbg_storms)storm_id;
1579 
1580     return MAX_DBG_STORMS;
1581 }
1582 
1583 /* Returns true of the specified Storm should be included in the dump, false
1584  * otherwise.
1585  */
1586 static bool qed_grc_is_storm_included(struct qed_hwfn *p_hwfn,
1587                       enum dbg_storms storm)
1588 {
1589     return qed_grc_get_param(p_hwfn, (enum dbg_grc_params)storm) > 0;
1590 }
1591 
1592 /* Returns true if the specified memory should be included in the dump, false
1593  * otherwise.
1594  */
1595 static bool qed_grc_is_mem_included(struct qed_hwfn *p_hwfn,
1596                     enum block_id block_id, u8 mem_group_id)
1597 {
1598     const struct dbg_block *block;
1599     u8 i;
1600 
1601     block = get_dbg_block(p_hwfn, block_id);
1602 
1603     /* If the block is associated with a Storm, check Storm match */
1604     if (block->associated_storm_letter) {
1605         enum dbg_storms associated_storm_id =
1606             qed_get_id_from_letter(block->associated_storm_letter);
1607 
1608         if (associated_storm_id == MAX_DBG_STORMS ||
1609             !qed_grc_is_storm_included(p_hwfn, associated_storm_id))
1610             return false;
1611     }
1612 
1613     for (i = 0; i < NUM_BIG_RAM_TYPES; i++) {
1614         struct big_ram_defs *big_ram = &s_big_ram_defs[i];
1615 
1616         if (mem_group_id == big_ram->mem_group_id ||
1617             mem_group_id == big_ram->ram_mem_group_id)
1618             return qed_grc_is_included(p_hwfn, big_ram->grc_param);
1619     }
1620 
1621     switch (mem_group_id) {
1622     case MEM_GROUP_PXP_ILT:
1623     case MEM_GROUP_PXP_MEM:
1624         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PXP);
1625     case MEM_GROUP_RAM:
1626         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RAM);
1627     case MEM_GROUP_PBUF:
1628         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PBUF);
1629     case MEM_GROUP_CAU_MEM:
1630     case MEM_GROUP_CAU_SB:
1631     case MEM_GROUP_CAU_PI:
1632         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU);
1633     case MEM_GROUP_CAU_MEM_EXT:
1634         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU_EXT);
1635     case MEM_GROUP_QM_MEM:
1636         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_QM);
1637     case MEM_GROUP_CFC_MEM:
1638     case MEM_GROUP_CONN_CFC_MEM:
1639     case MEM_GROUP_TASK_CFC_MEM:
1640         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CFC) ||
1641                qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX);
1642     case MEM_GROUP_DORQ_MEM:
1643         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DORQ);
1644     case MEM_GROUP_IGU_MEM:
1645     case MEM_GROUP_IGU_MSIX:
1646         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IGU);
1647     case MEM_GROUP_MULD_MEM:
1648         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MULD);
1649     case MEM_GROUP_PRS_MEM:
1650         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PRS);
1651     case MEM_GROUP_DMAE_MEM:
1652         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DMAE);
1653     case MEM_GROUP_TM_MEM:
1654         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_TM);
1655     case MEM_GROUP_SDM_MEM:
1656         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_SDM);
1657     case MEM_GROUP_TDIF_CTX:
1658     case MEM_GROUP_RDIF_CTX:
1659         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DIF);
1660     case MEM_GROUP_CM_MEM:
1661         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM);
1662     case MEM_GROUP_IOR:
1663         return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IOR);
1664     default:
1665         return true;
1666     }
1667 }
1668 
1669 /* Stalls all Storms */
1670 static void qed_grc_stall_storms(struct qed_hwfn *p_hwfn,
1671                  struct qed_ptt *p_ptt, bool stall)
1672 {
1673     u32 reg_addr;
1674     u8 storm_id;
1675 
1676     for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
1677         if (!qed_grc_is_storm_included(p_hwfn,
1678                            (enum dbg_storms)storm_id))
1679             continue;
1680 
1681         reg_addr = s_storm_defs[storm_id].sem_fast_mem_addr +
1682             SEM_FAST_REG_STALL_0;
1683         qed_wr(p_hwfn, p_ptt, reg_addr, stall ? 1 : 0);
1684     }
1685 
1686     msleep(STALL_DELAY_MS);
1687 }
1688 
1689 /* Takes all blocks out of reset. If rbc_only is true, only RBC clients are
1690  * taken out of reset.
1691  */
1692 static void qed_grc_unreset_blocks(struct qed_hwfn *p_hwfn,
1693                    struct qed_ptt *p_ptt, bool rbc_only)
1694 {
1695     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1696     u8 chip_id = dev_data->chip_id;
1697     u32 i;
1698 
1699     /* Take RBCs out of reset */
1700     for (i = 0; i < ARRAY_SIZE(s_rbc_reset_defs); i++)
1701         if (s_rbc_reset_defs[i].reset_val[dev_data->chip_id])
1702             qed_wr(p_hwfn,
1703                    p_ptt,
1704                    s_rbc_reset_defs[i].reset_reg_addr +
1705                    RESET_REG_UNRESET_OFFSET,
1706                    s_rbc_reset_defs[i].reset_val[chip_id]);
1707 
1708     if (!rbc_only) {
1709         u32 reg_val[NUM_DBG_RESET_REGS] = { 0 };
1710         u8 reset_reg_id;
1711         u32 block_id;
1712 
1713         /* Fill reset regs values */
1714         for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) {
1715             bool is_removed, has_reset_reg, unreset_before_dump;
1716             const struct dbg_block_chip *block;
1717 
1718             block = qed_get_dbg_block_per_chip(p_hwfn,
1719                                (enum block_id)
1720                                block_id);
1721             is_removed =
1722                 GET_FIELD(block->flags, DBG_BLOCK_CHIP_IS_REMOVED);
1723             has_reset_reg =
1724                 GET_FIELD(block->flags,
1725                       DBG_BLOCK_CHIP_HAS_RESET_REG);
1726             unreset_before_dump =
1727                 GET_FIELD(block->flags,
1728                       DBG_BLOCK_CHIP_UNRESET_BEFORE_DUMP);
1729 
1730             if (!is_removed && has_reset_reg && unreset_before_dump)
1731                 reg_val[block->reset_reg_id] |=
1732                     BIT(block->reset_reg_bit_offset);
1733         }
1734 
1735         /* Write reset registers */
1736         for (reset_reg_id = 0; reset_reg_id < NUM_DBG_RESET_REGS;
1737              reset_reg_id++) {
1738             const struct dbg_reset_reg *reset_reg;
1739             u32 reset_reg_addr;
1740 
1741             reset_reg = qed_get_dbg_reset_reg(p_hwfn, reset_reg_id);
1742 
1743             if (GET_FIELD
1744                 (reset_reg->data, DBG_RESET_REG_IS_REMOVED))
1745                 continue;
1746 
1747             if (reg_val[reset_reg_id]) {
1748                 reset_reg_addr =
1749                     GET_FIELD(reset_reg->data,
1750                           DBG_RESET_REG_ADDR);
1751                 qed_wr(p_hwfn,
1752                        p_ptt,
1753                        DWORDS_TO_BYTES(reset_reg_addr) +
1754                        RESET_REG_UNRESET_OFFSET,
1755                        reg_val[reset_reg_id]);
1756             }
1757         }
1758     }
1759 }
1760 
1761 /* Returns the attention block data of the specified block */
1762 static const struct dbg_attn_block_type_data *
1763 qed_get_block_attn_data(struct qed_hwfn *p_hwfn,
1764             enum block_id block_id, enum dbg_attn_type attn_type)
1765 {
1766     const struct dbg_attn_block *base_attn_block_arr =
1767         (const struct dbg_attn_block *)
1768         p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr;
1769 
1770     return &base_attn_block_arr[block_id].per_type_data[attn_type];
1771 }
1772 
1773 /* Returns the attention registers of the specified block */
1774 static const struct dbg_attn_reg *
1775 qed_get_block_attn_regs(struct qed_hwfn *p_hwfn,
1776             enum block_id block_id, enum dbg_attn_type attn_type,
1777             u8 *num_attn_regs)
1778 {
1779     const struct dbg_attn_block_type_data *block_type_data =
1780         qed_get_block_attn_data(p_hwfn, block_id, attn_type);
1781 
1782     *num_attn_regs = block_type_data->num_regs;
1783 
1784     return (const struct dbg_attn_reg *)
1785         p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr +
1786         block_type_data->regs_offset;
1787 }
1788 
1789 /* For each block, clear the status of all parities */
1790 static void qed_grc_clear_all_prty(struct qed_hwfn *p_hwfn,
1791                    struct qed_ptt *p_ptt)
1792 {
1793     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1794     const struct dbg_attn_reg *attn_reg_arr;
1795     u32 block_id, sts_clr_address;
1796     u8 reg_idx, num_attn_regs;
1797 
1798     for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) {
1799         if (dev_data->block_in_reset[block_id])
1800             continue;
1801 
1802         attn_reg_arr = qed_get_block_attn_regs(p_hwfn,
1803                                (enum block_id)block_id,
1804                                ATTN_TYPE_PARITY,
1805                                &num_attn_regs);
1806 
1807         for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
1808             const struct dbg_attn_reg *reg_data =
1809                 &attn_reg_arr[reg_idx];
1810             u16 modes_buf_offset;
1811             bool eval_mode;
1812 
1813             /* Check mode */
1814             eval_mode = GET_FIELD(reg_data->mode.data,
1815                           DBG_MODE_HDR_EVAL_MODE) > 0;
1816             modes_buf_offset =
1817                 GET_FIELD(reg_data->mode.data,
1818                       DBG_MODE_HDR_MODES_BUF_OFFSET);
1819 
1820             sts_clr_address = reg_data->sts_clr_address;
1821             /* If Mode match: clear parity status */
1822             if (!eval_mode ||
1823                 qed_is_mode_match(p_hwfn, &modes_buf_offset))
1824                 qed_rd(p_hwfn, p_ptt,
1825                        DWORDS_TO_BYTES(sts_clr_address));
1826         }
1827     }
1828 }
1829 
1830 /* Finds the meta data image in NVRAM */
1831 static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
1832                         struct qed_ptt *p_ptt,
1833                         u32 image_type,
1834                         u32 *nvram_offset_bytes,
1835                         u32 *nvram_size_bytes)
1836 {
1837     u32 ret_mcp_resp, ret_mcp_param, ret_txn_size;
1838     struct mcp_file_att file_att;
1839     int nvm_result;
1840 
1841     /* Call NVRAM get file command */
1842     nvm_result = qed_mcp_nvm_rd_cmd(p_hwfn,
1843                     p_ptt,
1844                     DRV_MSG_CODE_NVM_GET_FILE_ATT,
1845                     image_type,
1846                     &ret_mcp_resp,
1847                     &ret_mcp_param,
1848                     &ret_txn_size,
1849                     (u32 *)&file_att, false);
1850 
1851     /* Check response */
1852     if (nvm_result || (ret_mcp_resp & FW_MSG_CODE_MASK) !=
1853         FW_MSG_CODE_NVM_OK)
1854         return DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
1855 
1856     /* Update return values */
1857     *nvram_offset_bytes = file_att.nvm_start_addr;
1858     *nvram_size_bytes = file_att.len;
1859 
1860     DP_VERBOSE(p_hwfn,
1861            QED_MSG_DEBUG,
1862            "find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\n",
1863            image_type, *nvram_offset_bytes, *nvram_size_bytes);
1864 
1865     /* Check alignment */
1866     if (*nvram_size_bytes & 0x3)
1867         return DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE;
1868 
1869     return DBG_STATUS_OK;
1870 }
1871 
1872 /* Reads data from NVRAM */
1873 static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
1874                       struct qed_ptt *p_ptt,
1875                       u32 nvram_offset_bytes,
1876                       u32 nvram_size_bytes, u32 *ret_buf)
1877 {
1878     u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy;
1879     s32 bytes_left = nvram_size_bytes;
1880     u32 read_offset = 0, param = 0;
1881 
1882     DP_VERBOSE(p_hwfn,
1883            QED_MSG_DEBUG,
1884            "nvram_read: reading image of size %d bytes from NVRAM\n",
1885            nvram_size_bytes);
1886 
1887     do {
1888         bytes_to_copy =
1889             (bytes_left >
1890              MCP_DRV_NVM_BUF_LEN) ? MCP_DRV_NVM_BUF_LEN : bytes_left;
1891 
1892         /* Call NVRAM read command */
1893         SET_MFW_FIELD(param,
1894                   DRV_MB_PARAM_NVM_OFFSET,
1895                   nvram_offset_bytes + read_offset);
1896         SET_MFW_FIELD(param, DRV_MB_PARAM_NVM_LEN, bytes_to_copy);
1897         if (qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt,
1898                        DRV_MSG_CODE_NVM_READ_NVRAM, param,
1899                        &ret_mcp_resp,
1900                        &ret_mcp_param, &ret_read_size,
1901                        (u32 *)((u8 *)ret_buf + read_offset),
1902                        false))
1903             return DBG_STATUS_NVRAM_READ_FAILED;
1904 
1905         /* Check response */
1906         if ((ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
1907             return DBG_STATUS_NVRAM_READ_FAILED;
1908 
1909         /* Update read offset */
1910         read_offset += ret_read_size;
1911         bytes_left -= ret_read_size;
1912     } while (bytes_left > 0);
1913 
1914     return DBG_STATUS_OK;
1915 }
1916 
1917 /* Dumps GRC registers section header. Returns the dumped size in dwords.
1918  * the following parameters are dumped:
1919  * - count: no. of dumped entries
1920  * - split_type: split type
1921  * - split_id: split ID (dumped only if split_id != SPLIT_TYPE_NONE)
1922  * - reg_type_name: register type name (dumped only if reg_type_name != NULL)
1923  */
1924 static u32 qed_grc_dump_regs_hdr(u32 *dump_buf,
1925                  bool dump,
1926                  u32 num_reg_entries,
1927                  enum init_split_types split_type,
1928                  u8 split_id, const char *reg_type_name)
1929 {
1930     u8 num_params = 2 +
1931         (split_type != SPLIT_TYPE_NONE ? 1 : 0) + (reg_type_name ? 1 : 0);
1932     u32 offset = 0;
1933 
1934     offset += qed_dump_section_hdr(dump_buf + offset,
1935                        dump, "grc_regs", num_params);
1936     offset += qed_dump_num_param(dump_buf + offset,
1937                      dump, "count", num_reg_entries);
1938     offset += qed_dump_str_param(dump_buf + offset,
1939                      dump, "split",
1940                      s_split_type_defs[split_type].name);
1941     if (split_type != SPLIT_TYPE_NONE)
1942         offset += qed_dump_num_param(dump_buf + offset,
1943                          dump, "id", split_id);
1944     if (reg_type_name)
1945         offset += qed_dump_str_param(dump_buf + offset,
1946                          dump, "type", reg_type_name);
1947 
1948     return offset;
1949 }
1950 
1951 /* Reads the specified registers into the specified buffer.
1952  * The addr and len arguments are specified in dwords.
1953  */
1954 void qed_read_regs(struct qed_hwfn *p_hwfn,
1955            struct qed_ptt *p_ptt, u32 *buf, u32 addr, u32 len)
1956 {
1957     u32 i;
1958 
1959     for (i = 0; i < len; i++)
1960         buf[i] = qed_rd(p_hwfn, p_ptt, DWORDS_TO_BYTES(addr + i));
1961 }
1962 
1963 /* Dumps the GRC registers in the specified address range.
1964  * Returns the dumped size in dwords.
1965  * The addr and len arguments are specified in dwords.
1966  */
1967 static u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn,
1968                    struct qed_ptt *p_ptt,
1969                    u32 *dump_buf,
1970                    bool dump, u32 addr, u32 len, bool wide_bus,
1971                    enum init_split_types split_type,
1972                    u8 split_id)
1973 {
1974     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1975     u8 port_id = 0, pf_id = 0, vf_id = 0, fid = 0;
1976     bool read_using_dmae = false;
1977     u32 thresh;
1978 
1979     if (!dump)
1980         return len;
1981 
1982     switch (split_type) {
1983     case SPLIT_TYPE_PORT:
1984         port_id = split_id;
1985         break;
1986     case SPLIT_TYPE_PF:
1987         pf_id = split_id;
1988         break;
1989     case SPLIT_TYPE_PORT_PF:
1990         port_id = split_id / dev_data->num_pfs_per_port;
1991         pf_id = port_id + dev_data->num_ports *
1992             (split_id % dev_data->num_pfs_per_port);
1993         break;
1994     case SPLIT_TYPE_VF:
1995         vf_id = split_id;
1996         break;
1997     default:
1998         break;
1999     }
2000 
2001     /* Try reading using DMAE */
2002     if (dev_data->use_dmae && split_type != SPLIT_TYPE_VF &&
2003         (len >= s_hw_type_defs[dev_data->hw_type].dmae_thresh ||
2004          (PROTECT_WIDE_BUS && wide_bus))) {
2005         struct qed_dmae_params dmae_params;
2006 
2007         /* Set DMAE params */
2008         memset(&dmae_params, 0, sizeof(dmae_params));
2009         SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_COMPLETION_DST, 1);
2010         switch (split_type) {
2011         case SPLIT_TYPE_PORT:
2012             SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_PORT_VALID,
2013                   1);
2014             dmae_params.port_id = port_id;
2015             break;
2016         case SPLIT_TYPE_PF:
2017             SET_FIELD(dmae_params.flags,
2018                   QED_DMAE_PARAMS_SRC_PF_VALID, 1);
2019             dmae_params.src_pfid = pf_id;
2020             break;
2021         case SPLIT_TYPE_PORT_PF:
2022             SET_FIELD(dmae_params.flags, QED_DMAE_PARAMS_PORT_VALID,
2023                   1);
2024             SET_FIELD(dmae_params.flags,
2025                   QED_DMAE_PARAMS_SRC_PF_VALID, 1);
2026             dmae_params.port_id = port_id;
2027             dmae_params.src_pfid = pf_id;
2028             break;
2029         default:
2030             break;
2031         }
2032 
2033         /* Execute DMAE command */
2034         read_using_dmae = !qed_dmae_grc2host(p_hwfn,
2035                              p_ptt,
2036                              DWORDS_TO_BYTES(addr),
2037                              (u64)(uintptr_t)(dump_buf),
2038                              len, &dmae_params);
2039         if (!read_using_dmae) {
2040             dev_data->use_dmae = 0;
2041             DP_VERBOSE(p_hwfn,
2042                    QED_MSG_DEBUG,
2043                    "Failed reading from chip using DMAE, using GRC instead\n");
2044         }
2045     }
2046 
2047     if (read_using_dmae)
2048         goto print_log;
2049 
2050     /* If not read using DMAE, read using GRC */
2051 
2052     /* Set pretend */
2053     if (split_type != dev_data->pretend.split_type ||
2054         split_id != dev_data->pretend.split_id) {
2055         switch (split_type) {
2056         case SPLIT_TYPE_PORT:
2057             qed_port_pretend(p_hwfn, p_ptt, port_id);
2058             break;
2059         case SPLIT_TYPE_PF:
2060             fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID,
2061                       pf_id);
2062             qed_fid_pretend(p_hwfn, p_ptt, fid);
2063             break;
2064         case SPLIT_TYPE_PORT_PF:
2065             fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID,
2066                       pf_id);
2067             qed_port_fid_pretend(p_hwfn, p_ptt, port_id, fid);
2068             break;
2069         case SPLIT_TYPE_VF:
2070             fid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFVALID, 1)
2071                   | FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFID,
2072                       vf_id);
2073             qed_fid_pretend(p_hwfn, p_ptt, fid);
2074             break;
2075         default:
2076             break;
2077         }
2078 
2079         dev_data->pretend.split_type = (u8)split_type;
2080         dev_data->pretend.split_id = split_id;
2081     }
2082 
2083     /* Read registers using GRC */
2084     qed_read_regs(p_hwfn, p_ptt, dump_buf, addr, len);
2085 
2086 print_log:
2087     /* Print log */
2088     dev_data->num_regs_read += len;
2089     thresh = s_hw_type_defs[dev_data->hw_type].log_thresh;
2090     if ((dev_data->num_regs_read / thresh) >
2091         ((dev_data->num_regs_read - len) / thresh))
2092         DP_VERBOSE(p_hwfn,
2093                QED_MSG_DEBUG,
2094                "Dumped %d registers...\n", dev_data->num_regs_read);
2095 
2096     return len;
2097 }
2098 
2099 /* Dumps GRC registers sequence header. Returns the dumped size in dwords.
2100  * The addr and len arguments are specified in dwords.
2101  */
2102 static u32 qed_grc_dump_reg_entry_hdr(u32 *dump_buf,
2103                       bool dump, u32 addr, u32 len)
2104 {
2105     if (dump)
2106         *dump_buf = addr | (len << REG_DUMP_LEN_SHIFT);
2107 
2108     return 1;
2109 }
2110 
2111 /* Dumps GRC registers sequence. Returns the dumped size in dwords.
2112  * The addr and len arguments are specified in dwords.
2113  */
2114 static u32 qed_grc_dump_reg_entry(struct qed_hwfn *p_hwfn,
2115                   struct qed_ptt *p_ptt,
2116                   u32 *dump_buf,
2117                   bool dump, u32 addr, u32 len, bool wide_bus,
2118                   enum init_split_types split_type, u8 split_id)
2119 {
2120     u32 offset = 0;
2121 
2122     offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, len);
2123     offset += qed_grc_dump_addr_range(p_hwfn,
2124                       p_ptt,
2125                       dump_buf + offset,
2126                       dump, addr, len, wide_bus,
2127                       split_type, split_id);
2128 
2129     return offset;
2130 }
2131 
2132 /* Dumps GRC registers sequence with skip cycle.
2133  * Returns the dumped size in dwords.
2134  * - addr:  start GRC address in dwords
2135  * - total_len: total no. of dwords to dump
2136  * - read_len:  no. consecutive dwords to read
2137  * - skip_len:  no. of dwords to skip (and fill with zeros)
2138  */
2139 static u32 qed_grc_dump_reg_entry_skip(struct qed_hwfn *p_hwfn,
2140                        struct qed_ptt *p_ptt,
2141                        u32 *dump_buf,
2142                        bool dump,
2143                        u32 addr,
2144                        u32 total_len,
2145                        u32 read_len, u32 skip_len)
2146 {
2147     u32 offset = 0, reg_offset = 0;
2148 
2149     offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, total_len);
2150 
2151     if (!dump)
2152         return offset + total_len;
2153 
2154     while (reg_offset < total_len) {
2155         u32 curr_len = min_t(u32, read_len, total_len - reg_offset);
2156 
2157         offset += qed_grc_dump_addr_range(p_hwfn,
2158                           p_ptt,
2159                           dump_buf + offset,
2160                           dump,  addr, curr_len, false,
2161                           SPLIT_TYPE_NONE, 0);
2162         reg_offset += curr_len;
2163         addr += curr_len;
2164 
2165         if (reg_offset < total_len) {
2166             curr_len = min_t(u32, skip_len, total_len - skip_len);
2167             memset(dump_buf + offset, 0, DWORDS_TO_BYTES(curr_len));
2168             offset += curr_len;
2169             reg_offset += curr_len;
2170             addr += curr_len;
2171         }
2172     }
2173 
2174     return offset;
2175 }
2176 
2177 /* Dumps GRC registers entries. Returns the dumped size in dwords. */
2178 static u32 qed_grc_dump_regs_entries(struct qed_hwfn *p_hwfn,
2179                      struct qed_ptt *p_ptt,
2180                      struct virt_mem_desc input_regs_arr,
2181                      u32 *dump_buf,
2182                      bool dump,
2183                      enum init_split_types split_type,
2184                      u8 split_id,
2185                      bool block_enable[MAX_BLOCK_ID],
2186                      u32 *num_dumped_reg_entries)
2187 {
2188     u32 i, offset = 0, input_offset = 0;
2189     bool mode_match = true;
2190 
2191     *num_dumped_reg_entries = 0;
2192 
2193     while (input_offset < BYTES_TO_DWORDS(input_regs_arr.size)) {
2194         const struct dbg_dump_cond_hdr *cond_hdr =
2195             (const struct dbg_dump_cond_hdr *)
2196             input_regs_arr.ptr + input_offset++;
2197         u16 modes_buf_offset;
2198         bool eval_mode;
2199 
2200         /* Check mode/block */
2201         eval_mode = GET_FIELD(cond_hdr->mode.data,
2202                       DBG_MODE_HDR_EVAL_MODE) > 0;
2203         if (eval_mode) {
2204             modes_buf_offset =
2205                 GET_FIELD(cond_hdr->mode.data,
2206                       DBG_MODE_HDR_MODES_BUF_OFFSET);
2207             mode_match = qed_is_mode_match(p_hwfn,
2208                                &modes_buf_offset);
2209         }
2210 
2211         if (!mode_match || !block_enable[cond_hdr->block_id]) {
2212             input_offset += cond_hdr->data_size;
2213             continue;
2214         }
2215 
2216         for (i = 0; i < cond_hdr->data_size; i++, input_offset++) {
2217             const struct dbg_dump_reg *reg =
2218                 (const struct dbg_dump_reg *)
2219                 input_regs_arr.ptr + input_offset;
2220             u32 addr, len;
2221             bool wide_bus;
2222 
2223             addr = GET_FIELD(reg->data, DBG_DUMP_REG_ADDRESS);
2224             len = GET_FIELD(reg->data, DBG_DUMP_REG_LENGTH);
2225             wide_bus = GET_FIELD(reg->data, DBG_DUMP_REG_WIDE_BUS);
2226             offset += qed_grc_dump_reg_entry(p_hwfn,
2227                              p_ptt,
2228                              dump_buf + offset,
2229                              dump,
2230                              addr,
2231                              len,
2232                              wide_bus,
2233                              split_type, split_id);
2234             (*num_dumped_reg_entries)++;
2235         }
2236     }
2237 
2238     return offset;
2239 }
2240 
2241 /* Dumps GRC registers entries. Returns the dumped size in dwords. */
2242 static u32 qed_grc_dump_split_data(struct qed_hwfn *p_hwfn,
2243                    struct qed_ptt *p_ptt,
2244                    struct virt_mem_desc input_regs_arr,
2245                    u32 *dump_buf,
2246                    bool dump,
2247                    bool block_enable[MAX_BLOCK_ID],
2248                    enum init_split_types split_type,
2249                    u8 split_id, const char *reg_type_name)
2250 {
2251     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2252     enum init_split_types hdr_split_type = split_type;
2253     u32 num_dumped_reg_entries, offset;
2254     u8 hdr_split_id = split_id;
2255 
2256     /* In PORT_PF split type, print a port split header */
2257     if (split_type == SPLIT_TYPE_PORT_PF) {
2258         hdr_split_type = SPLIT_TYPE_PORT;
2259         hdr_split_id = split_id / dev_data->num_pfs_per_port;
2260     }
2261 
2262     /* Calculate register dump header size (and skip it for now) */
2263     offset = qed_grc_dump_regs_hdr(dump_buf,
2264                        false,
2265                        0,
2266                        hdr_split_type,
2267                        hdr_split_id, reg_type_name);
2268 
2269     /* Dump registers */
2270     offset += qed_grc_dump_regs_entries(p_hwfn,
2271                         p_ptt,
2272                         input_regs_arr,
2273                         dump_buf + offset,
2274                         dump,
2275                         split_type,
2276                         split_id,
2277                         block_enable,
2278                         &num_dumped_reg_entries);
2279 
2280     /* Write register dump header */
2281     if (dump && num_dumped_reg_entries > 0)
2282         qed_grc_dump_regs_hdr(dump_buf,
2283                       dump,
2284                       num_dumped_reg_entries,
2285                       hdr_split_type,
2286                       hdr_split_id, reg_type_name);
2287 
2288     return num_dumped_reg_entries > 0 ? offset : 0;
2289 }
2290 
2291 /* Dumps registers according to the input registers array. Returns the dumped
2292  * size in dwords.
2293  */
2294 static u32 qed_grc_dump_registers(struct qed_hwfn *p_hwfn,
2295                   struct qed_ptt *p_ptt,
2296                   u32 *dump_buf,
2297                   bool dump,
2298                   bool block_enable[MAX_BLOCK_ID],
2299                   const char *reg_type_name)
2300 {
2301     struct virt_mem_desc *dbg_buf =
2302         &p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG];
2303     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2304     u32 offset = 0, input_offset = 0;
2305 
2306     while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) {
2307         const struct dbg_dump_split_hdr *split_hdr;
2308         struct virt_mem_desc curr_input_regs_arr;
2309         enum init_split_types split_type;
2310         u16 split_count = 0;
2311         u32 split_data_size;
2312         u8 split_id;
2313 
2314         split_hdr =
2315             (const struct dbg_dump_split_hdr *)
2316             dbg_buf->ptr + input_offset++;
2317         split_type =
2318             GET_FIELD(split_hdr->hdr,
2319                   DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
2320         split_data_size = GET_FIELD(split_hdr->hdr,
2321                         DBG_DUMP_SPLIT_HDR_DATA_SIZE);
2322         curr_input_regs_arr.ptr =
2323             (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr +
2324             input_offset;
2325         curr_input_regs_arr.size = DWORDS_TO_BYTES(split_data_size);
2326 
2327         switch (split_type) {
2328         case SPLIT_TYPE_NONE:
2329             split_count = 1;
2330             break;
2331         case SPLIT_TYPE_PORT:
2332             split_count = dev_data->num_ports;
2333             break;
2334         case SPLIT_TYPE_PF:
2335         case SPLIT_TYPE_PORT_PF:
2336             split_count = dev_data->num_ports *
2337                 dev_data->num_pfs_per_port;
2338             break;
2339         case SPLIT_TYPE_VF:
2340             split_count = dev_data->num_vfs;
2341             break;
2342         default:
2343             return 0;
2344         }
2345 
2346         for (split_id = 0; split_id < split_count; split_id++)
2347             offset += qed_grc_dump_split_data(p_hwfn, p_ptt,
2348                               curr_input_regs_arr,
2349                               dump_buf + offset,
2350                               dump, block_enable,
2351                               split_type,
2352                               split_id,
2353                               reg_type_name);
2354 
2355         input_offset += split_data_size;
2356     }
2357 
2358     /* Cancel pretends (pretend to original PF) */
2359     if (dump) {
2360         qed_fid_pretend(p_hwfn, p_ptt,
2361                 FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID,
2362                         p_hwfn->rel_pf_id));
2363         dev_data->pretend.split_type = SPLIT_TYPE_NONE;
2364         dev_data->pretend.split_id = 0;
2365     }
2366 
2367     return offset;
2368 }
2369 
2370 /* Dump reset registers. Returns the dumped size in dwords. */
2371 static u32 qed_grc_dump_reset_regs(struct qed_hwfn *p_hwfn,
2372                    struct qed_ptt *p_ptt,
2373                    u32 *dump_buf, bool dump)
2374 {
2375     u32 offset = 0, num_regs = 0;
2376     u8 reset_reg_id;
2377 
2378     /* Calculate header size */
2379     offset += qed_grc_dump_regs_hdr(dump_buf,
2380                     false,
2381                     0, SPLIT_TYPE_NONE, 0, "RESET_REGS");
2382 
2383     /* Write reset registers */
2384     for (reset_reg_id = 0; reset_reg_id < NUM_DBG_RESET_REGS;
2385          reset_reg_id++) {
2386         const struct dbg_reset_reg *reset_reg;
2387         u32 reset_reg_addr;
2388 
2389         reset_reg = qed_get_dbg_reset_reg(p_hwfn, reset_reg_id);
2390 
2391         if (GET_FIELD(reset_reg->data, DBG_RESET_REG_IS_REMOVED))
2392             continue;
2393 
2394         reset_reg_addr = GET_FIELD(reset_reg->data, DBG_RESET_REG_ADDR);
2395         offset += qed_grc_dump_reg_entry(p_hwfn,
2396                          p_ptt,
2397                          dump_buf + offset,
2398                          dump,
2399                          reset_reg_addr,
2400                          1, false, SPLIT_TYPE_NONE, 0);
2401         num_regs++;
2402     }
2403 
2404     /* Write header */
2405     if (dump)
2406         qed_grc_dump_regs_hdr(dump_buf,
2407                       true, num_regs, SPLIT_TYPE_NONE,
2408                       0, "RESET_REGS");
2409 
2410     return offset;
2411 }
2412 
2413 /* Dump registers that are modified during GRC Dump and therefore must be
2414  * dumped first. Returns the dumped size in dwords.
2415  */
2416 static u32 qed_grc_dump_modified_regs(struct qed_hwfn *p_hwfn,
2417                       struct qed_ptt *p_ptt,
2418                       u32 *dump_buf, bool dump)
2419 {
2420     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2421     u32 block_id, offset = 0, stall_regs_offset;
2422     const struct dbg_attn_reg *attn_reg_arr;
2423     u8 storm_id, reg_idx, num_attn_regs;
2424     u32 num_reg_entries = 0;
2425 
2426     /* Write empty header for attention registers */
2427     offset += qed_grc_dump_regs_hdr(dump_buf,
2428                     false,
2429                     0, SPLIT_TYPE_NONE, 0, "ATTN_REGS");
2430 
2431     /* Write parity registers */
2432     for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) {
2433         if (dev_data->block_in_reset[block_id] && dump)
2434             continue;
2435 
2436         attn_reg_arr = qed_get_block_attn_regs(p_hwfn,
2437                                (enum block_id)block_id,
2438                                ATTN_TYPE_PARITY,
2439                                &num_attn_regs);
2440 
2441         for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
2442             const struct dbg_attn_reg *reg_data =
2443                 &attn_reg_arr[reg_idx];
2444             u16 modes_buf_offset;
2445             bool eval_mode;
2446             u32 addr;
2447 
2448             /* Check mode */
2449             eval_mode = GET_FIELD(reg_data->mode.data,
2450                           DBG_MODE_HDR_EVAL_MODE) > 0;
2451             modes_buf_offset =
2452                 GET_FIELD(reg_data->mode.data,
2453                       DBG_MODE_HDR_MODES_BUF_OFFSET);
2454             if (eval_mode &&
2455                 !qed_is_mode_match(p_hwfn, &modes_buf_offset))
2456                 continue;
2457 
2458             /* Mode match: read & dump registers */
2459             addr = reg_data->mask_address;
2460             offset += qed_grc_dump_reg_entry(p_hwfn,
2461                              p_ptt,
2462                              dump_buf + offset,
2463                              dump,
2464                              addr,
2465                              1, false,
2466                              SPLIT_TYPE_NONE, 0);
2467             addr = GET_FIELD(reg_data->data,
2468                      DBG_ATTN_REG_STS_ADDRESS);
2469             offset += qed_grc_dump_reg_entry(p_hwfn,
2470                              p_ptt,
2471                              dump_buf + offset,
2472                              dump,
2473                              addr,
2474                              1, false,
2475                              SPLIT_TYPE_NONE, 0);
2476             num_reg_entries += 2;
2477         }
2478     }
2479 
2480     /* Overwrite header for attention registers */
2481     if (dump)
2482         qed_grc_dump_regs_hdr(dump_buf,
2483                       true,
2484                       num_reg_entries,
2485                       SPLIT_TYPE_NONE, 0, "ATTN_REGS");
2486 
2487     /* Write empty header for stall registers */
2488     stall_regs_offset = offset;
2489     offset += qed_grc_dump_regs_hdr(dump_buf,
2490                     false, 0, SPLIT_TYPE_NONE, 0, "REGS");
2491 
2492     /* Write Storm stall status registers */
2493     for (storm_id = 0, num_reg_entries = 0; storm_id < MAX_DBG_STORMS;
2494          storm_id++) {
2495         struct storm_defs *storm = &s_storm_defs[storm_id];
2496         u32 addr;
2497 
2498         if (dev_data->block_in_reset[storm->sem_block_id] && dump)
2499             continue;
2500 
2501         addr =
2502             BYTES_TO_DWORDS(storm->sem_fast_mem_addr +
2503                     SEM_FAST_REG_STALLED);
2504         offset += qed_grc_dump_reg_entry(p_hwfn,
2505                          p_ptt,
2506                          dump_buf + offset,
2507                          dump,
2508                          addr,
2509                          1,
2510                          false, SPLIT_TYPE_NONE, 0);
2511         num_reg_entries++;
2512     }
2513 
2514     /* Overwrite header for stall registers */
2515     if (dump)
2516         qed_grc_dump_regs_hdr(dump_buf + stall_regs_offset,
2517                       true,
2518                       num_reg_entries,
2519                       SPLIT_TYPE_NONE, 0, "REGS");
2520 
2521     return offset;
2522 }
2523 
2524 /* Dumps registers that can't be represented in the debug arrays */
2525 static u32 qed_grc_dump_special_regs(struct qed_hwfn *p_hwfn,
2526                      struct qed_ptt *p_ptt,
2527                      u32 *dump_buf, bool dump)
2528 {
2529     u32 offset = 0, addr;
2530 
2531     offset += qed_grc_dump_regs_hdr(dump_buf,
2532                     dump, 2, SPLIT_TYPE_NONE, 0, "REGS");
2533 
2534     /* Dump R/TDIF_REG_DEBUG_ERROR_INFO_SIZE (every 8'th register should be
2535      * skipped).
2536      */
2537     addr = BYTES_TO_DWORDS(RDIF_REG_DEBUG_ERROR_INFO);
2538     offset += qed_grc_dump_reg_entry_skip(p_hwfn,
2539                           p_ptt,
2540                           dump_buf + offset,
2541                           dump,
2542                           addr,
2543                           RDIF_REG_DEBUG_ERROR_INFO_SIZE,
2544                           7,
2545                           1);
2546     addr = BYTES_TO_DWORDS(TDIF_REG_DEBUG_ERROR_INFO);
2547     offset +=
2548         qed_grc_dump_reg_entry_skip(p_hwfn,
2549                     p_ptt,
2550                     dump_buf + offset,
2551                     dump,
2552                     addr,
2553                     TDIF_REG_DEBUG_ERROR_INFO_SIZE,
2554                     7,
2555                     1);
2556 
2557     return offset;
2558 }
2559 
2560 /* Dumps a GRC memory header (section and params). Returns the dumped size in
2561  * dwords. The following parameters are dumped:
2562  * - name:     dumped only if it's not NULL.
2563  * - addr:     in dwords, dumped only if name is NULL.
2564  * - len:      in dwords, always dumped.
2565  * - width:    dumped if it's not zero.
2566  * - packed:       dumped only if it's not false.
2567  * - mem_group:    always dumped.
2568  * - is_storm:     true only if the memory is related to a Storm.
2569  * - storm_letter: valid only if is_storm is true.
2570  *
2571  */
2572 static u32 qed_grc_dump_mem_hdr(struct qed_hwfn *p_hwfn,
2573                 u32 *dump_buf,
2574                 bool dump,
2575                 const char *name,
2576                 u32 addr,
2577                 u32 len,
2578                 u32 bit_width,
2579                 bool packed,
2580                 const char *mem_group, char storm_letter)
2581 {
2582     u8 num_params = 3;
2583     u32 offset = 0;
2584     char buf[64];
2585 
2586     if (!len)
2587         DP_NOTICE(p_hwfn,
2588               "Unexpected GRC Dump error: dumped memory size must be non-zero\n");
2589 
2590     if (bit_width)
2591         num_params++;
2592     if (packed)
2593         num_params++;
2594 
2595     /* Dump section header */
2596     offset += qed_dump_section_hdr(dump_buf + offset,
2597                        dump, "grc_mem", num_params);
2598 
2599     if (name) {
2600         /* Dump name */
2601         if (storm_letter) {
2602             strcpy(buf, "?STORM_");
2603             buf[0] = storm_letter;
2604             strcpy(buf + strlen(buf), name);
2605         } else {
2606             strcpy(buf, name);
2607         }
2608 
2609         offset += qed_dump_str_param(dump_buf + offset,
2610                          dump, "name", buf);
2611     } else {
2612         /* Dump address */
2613         u32 addr_in_bytes = DWORDS_TO_BYTES(addr);
2614 
2615         offset += qed_dump_num_param(dump_buf + offset,
2616                          dump, "addr", addr_in_bytes);
2617     }
2618 
2619     /* Dump len */
2620     offset += qed_dump_num_param(dump_buf + offset, dump, "len", len);
2621 
2622     /* Dump bit width */
2623     if (bit_width)
2624         offset += qed_dump_num_param(dump_buf + offset,
2625                          dump, "width", bit_width);
2626 
2627     /* Dump packed */
2628     if (packed)
2629         offset += qed_dump_num_param(dump_buf + offset,
2630                          dump, "packed", 1);
2631 
2632     /* Dump reg type */
2633     if (storm_letter) {
2634         strcpy(buf, "?STORM_");
2635         buf[0] = storm_letter;
2636         strcpy(buf + strlen(buf), mem_group);
2637     } else {
2638         strcpy(buf, mem_group);
2639     }
2640 
2641     offset += qed_dump_str_param(dump_buf + offset, dump, "type", buf);
2642 
2643     return offset;
2644 }
2645 
2646 /* Dumps a single GRC memory. If name is NULL, the memory is stored by address.
2647  * Returns the dumped size in dwords.
2648  * The addr and len arguments are specified in dwords.
2649  */
2650 static u32 qed_grc_dump_mem(struct qed_hwfn *p_hwfn,
2651                 struct qed_ptt *p_ptt,
2652                 u32 *dump_buf,
2653                 bool dump,
2654                 const char *name,
2655                 u32 addr,
2656                 u32 len,
2657                 bool wide_bus,
2658                 u32 bit_width,
2659                 bool packed,
2660                 const char *mem_group, char storm_letter)
2661 {
2662     u32 offset = 0;
2663 
2664     offset += qed_grc_dump_mem_hdr(p_hwfn,
2665                        dump_buf + offset,
2666                        dump,
2667                        name,
2668                        addr,
2669                        len,
2670                        bit_width,
2671                        packed, mem_group, storm_letter);
2672     offset += qed_grc_dump_addr_range(p_hwfn,
2673                       p_ptt,
2674                       dump_buf + offset,
2675                       dump, addr, len, wide_bus,
2676                       SPLIT_TYPE_NONE, 0);
2677 
2678     return offset;
2679 }
2680 
2681 /* Dumps GRC memories entries. Returns the dumped size in dwords. */
2682 static u32 qed_grc_dump_mem_entries(struct qed_hwfn *p_hwfn,
2683                     struct qed_ptt *p_ptt,
2684                     struct virt_mem_desc input_mems_arr,
2685                     u32 *dump_buf, bool dump)
2686 {
2687     u32 i, offset = 0, input_offset = 0;
2688     bool mode_match = true;
2689 
2690     while (input_offset < BYTES_TO_DWORDS(input_mems_arr.size)) {
2691         const struct dbg_dump_cond_hdr *cond_hdr;
2692         u16 modes_buf_offset;
2693         u32 num_entries;
2694         bool eval_mode;
2695 
2696         cond_hdr =
2697             (const struct dbg_dump_cond_hdr *)input_mems_arr.ptr +
2698             input_offset++;
2699         num_entries = cond_hdr->data_size / MEM_DUMP_ENTRY_SIZE_DWORDS;
2700 
2701         /* Check required mode */
2702         eval_mode = GET_FIELD(cond_hdr->mode.data,
2703                       DBG_MODE_HDR_EVAL_MODE) > 0;
2704         if (eval_mode) {
2705             modes_buf_offset =
2706                 GET_FIELD(cond_hdr->mode.data,
2707                       DBG_MODE_HDR_MODES_BUF_OFFSET);
2708             mode_match = qed_is_mode_match(p_hwfn,
2709                                &modes_buf_offset);
2710         }
2711 
2712         if (!mode_match) {
2713             input_offset += cond_hdr->data_size;
2714             continue;
2715         }
2716 
2717         for (i = 0; i < num_entries;
2718              i++, input_offset += MEM_DUMP_ENTRY_SIZE_DWORDS) {
2719             const struct dbg_dump_mem *mem =
2720                 (const struct dbg_dump_mem *)((u32 *)
2721                               input_mems_arr.ptr
2722                               + input_offset);
2723             const struct dbg_block *block;
2724             char storm_letter = 0;
2725             u32 mem_addr, mem_len;
2726             bool mem_wide_bus;
2727             u8 mem_group_id;
2728 
2729             mem_group_id = GET_FIELD(mem->dword0,
2730                          DBG_DUMP_MEM_MEM_GROUP_ID);
2731             if (mem_group_id >= MEM_GROUPS_NUM) {
2732                 DP_NOTICE(p_hwfn, "Invalid mem_group_id\n");
2733                 return 0;
2734             }
2735 
2736             if (!qed_grc_is_mem_included(p_hwfn,
2737                              (enum block_id)
2738                              cond_hdr->block_id,
2739                              mem_group_id))
2740                 continue;
2741 
2742             mem_addr = GET_FIELD(mem->dword0, DBG_DUMP_MEM_ADDRESS);
2743             mem_len = GET_FIELD(mem->dword1, DBG_DUMP_MEM_LENGTH);
2744             mem_wide_bus = GET_FIELD(mem->dword1,
2745                          DBG_DUMP_MEM_WIDE_BUS);
2746 
2747             block = get_dbg_block(p_hwfn,
2748                           cond_hdr->block_id);
2749 
2750             /* If memory is associated with Storm,
2751              * update storm details
2752              */
2753             if (block->associated_storm_letter)
2754                 storm_letter = block->associated_storm_letter;
2755 
2756             /* Dump memory */
2757             offset += qed_grc_dump_mem(p_hwfn,
2758                         p_ptt,
2759                         dump_buf + offset,
2760                         dump,
2761                         NULL,
2762                         mem_addr,
2763                         mem_len,
2764                         mem_wide_bus,
2765                         0,
2766                         false,
2767                         s_mem_group_names[mem_group_id],
2768                         storm_letter);
2769         }
2770     }
2771 
2772     return offset;
2773 }
2774 
2775 /* Dumps GRC memories according to the input array dump_mem.
2776  * Returns the dumped size in dwords.
2777  */
2778 static u32 qed_grc_dump_memories(struct qed_hwfn *p_hwfn,
2779                  struct qed_ptt *p_ptt,
2780                  u32 *dump_buf, bool dump)
2781 {
2782     struct virt_mem_desc *dbg_buf =
2783         &p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_MEM];
2784     u32 offset = 0, input_offset = 0;
2785 
2786     while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) {
2787         const struct dbg_dump_split_hdr *split_hdr;
2788         struct virt_mem_desc curr_input_mems_arr;
2789         enum init_split_types split_type;
2790         u32 split_data_size;
2791 
2792         split_hdr =
2793             (const struct dbg_dump_split_hdr *)dbg_buf->ptr +
2794             input_offset++;
2795         split_type = GET_FIELD(split_hdr->hdr,
2796                        DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
2797         split_data_size = GET_FIELD(split_hdr->hdr,
2798                         DBG_DUMP_SPLIT_HDR_DATA_SIZE);
2799         curr_input_mems_arr.ptr = (u32 *)dbg_buf->ptr + input_offset;
2800         curr_input_mems_arr.size = DWORDS_TO_BYTES(split_data_size);
2801 
2802         if (split_type == SPLIT_TYPE_NONE)
2803             offset += qed_grc_dump_mem_entries(p_hwfn,
2804                                p_ptt,
2805                                curr_input_mems_arr,
2806                                dump_buf + offset,
2807                                dump);
2808         else
2809             DP_NOTICE(p_hwfn,
2810                   "Dumping split memories is currently not supported\n");
2811 
2812         input_offset += split_data_size;
2813     }
2814 
2815     return offset;
2816 }
2817 
2818 /* Dumps GRC context data for the specified Storm.
2819  * Returns the dumped size in dwords.
2820  * The lid_size argument is specified in quad-regs.
2821  */
2822 static u32 qed_grc_dump_ctx_data(struct qed_hwfn *p_hwfn,
2823                  struct qed_ptt *p_ptt,
2824                  u32 *dump_buf,
2825                  bool dump,
2826                  const char *name,
2827                  u32 num_lids,
2828                  enum cm_ctx_types ctx_type, u8 storm_id)
2829 {
2830     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2831     struct storm_defs *storm = &s_storm_defs[storm_id];
2832     u32 i, lid, lid_size, total_size;
2833     u32 rd_reg_addr, offset = 0;
2834 
2835     /* Convert quad-regs to dwords */
2836     lid_size = storm->cm_ctx_lid_sizes[dev_data->chip_id][ctx_type] * 4;
2837 
2838     if (!lid_size)
2839         return 0;
2840 
2841     total_size = num_lids * lid_size;
2842 
2843     offset += qed_grc_dump_mem_hdr(p_hwfn,
2844                        dump_buf + offset,
2845                        dump,
2846                        name,
2847                        0,
2848                        total_size,
2849                        lid_size * 32,
2850                        false, name, storm->letter);
2851 
2852     if (!dump)
2853         return offset + total_size;
2854 
2855     rd_reg_addr = BYTES_TO_DWORDS(storm->cm_ctx_rd_addr[ctx_type]);
2856 
2857     /* Dump context data */
2858     for (lid = 0; lid < num_lids; lid++) {
2859         for (i = 0; i < lid_size; i++) {
2860             qed_wr(p_hwfn,
2861                    p_ptt, storm->cm_ctx_wr_addr, (i << 9) | lid);
2862             offset += qed_grc_dump_addr_range(p_hwfn,
2863                               p_ptt,
2864                               dump_buf + offset,
2865                               dump,
2866                               rd_reg_addr,
2867                               1,
2868                               false,
2869                               SPLIT_TYPE_NONE, 0);
2870         }
2871     }
2872 
2873     return offset;
2874 }
2875 
2876 /* Dumps GRC contexts. Returns the dumped size in dwords. */
2877 static u32 qed_grc_dump_ctx(struct qed_hwfn *p_hwfn,
2878                 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
2879 {
2880     u32 offset = 0;
2881     u8 storm_id;
2882 
2883     for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
2884         if (!qed_grc_is_storm_included(p_hwfn,
2885                            (enum dbg_storms)storm_id))
2886             continue;
2887 
2888         /* Dump Conn AG context size */
2889         offset += qed_grc_dump_ctx_data(p_hwfn,
2890                         p_ptt,
2891                         dump_buf + offset,
2892                         dump,
2893                         "CONN_AG_CTX",
2894                         NUM_OF_LCIDS,
2895                         CM_CTX_CONN_AG, storm_id);
2896 
2897         /* Dump Conn ST context size */
2898         offset += qed_grc_dump_ctx_data(p_hwfn,
2899                         p_ptt,
2900                         dump_buf + offset,
2901                         dump,
2902                         "CONN_ST_CTX",
2903                         NUM_OF_LCIDS,
2904                         CM_CTX_CONN_ST, storm_id);
2905 
2906         /* Dump Task AG context size */
2907         offset += qed_grc_dump_ctx_data(p_hwfn,
2908                         p_ptt,
2909                         dump_buf + offset,
2910                         dump,
2911                         "TASK_AG_CTX",
2912                         NUM_OF_LTIDS,
2913                         CM_CTX_TASK_AG, storm_id);
2914 
2915         /* Dump Task ST context size */
2916         offset += qed_grc_dump_ctx_data(p_hwfn,
2917                         p_ptt,
2918                         dump_buf + offset,
2919                         dump,
2920                         "TASK_ST_CTX",
2921                         NUM_OF_LTIDS,
2922                         CM_CTX_TASK_ST, storm_id);
2923     }
2924 
2925     return offset;
2926 }
2927 
2928 #define VFC_STATUS_RESP_READY_BIT   0
2929 #define VFC_STATUS_BUSY_BIT     1
2930 #define VFC_STATUS_SENDING_CMD_BIT  2
2931 
2932 #define VFC_POLLING_DELAY_MS    1
2933 #define VFC_POLLING_COUNT       20
2934 
2935 /* Reads data from VFC. Returns the number of dwords read (0 on error).
2936  * Sizes are specified in dwords.
2937  */
2938 static u32 qed_grc_dump_read_from_vfc(struct qed_hwfn *p_hwfn,
2939                       struct qed_ptt *p_ptt,
2940                       struct storm_defs *storm,
2941                       u32 *cmd_data,
2942                       u32 cmd_size,
2943                       u32 *addr_data,
2944                       u32 addr_size,
2945                       u32 resp_size, u32 *dump_buf)
2946 {
2947     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2948     u32 vfc_status, polling_ms, polling_count = 0, i;
2949     u32 reg_addr, sem_base;
2950     bool is_ready = false;
2951 
2952     sem_base = storm->sem_fast_mem_addr;
2953     polling_ms = VFC_POLLING_DELAY_MS *
2954         s_hw_type_defs[dev_data->hw_type].delay_factor;
2955 
2956     /* Write VFC command */
2957     ARR_REG_WR(p_hwfn,
2958            p_ptt,
2959            sem_base + SEM_FAST_REG_VFC_DATA_WR,
2960            cmd_data, cmd_size);
2961 
2962     /* Write VFC address */
2963     ARR_REG_WR(p_hwfn,
2964            p_ptt,
2965            sem_base + SEM_FAST_REG_VFC_ADDR,
2966            addr_data, addr_size);
2967 
2968     /* Read response */
2969     for (i = 0; i < resp_size; i++) {
2970         /* Poll until ready */
2971         do {
2972             reg_addr = sem_base + SEM_FAST_REG_VFC_STATUS;
2973             qed_grc_dump_addr_range(p_hwfn,
2974                         p_ptt,
2975                         &vfc_status,
2976                         true,
2977                         BYTES_TO_DWORDS(reg_addr),
2978                         1,
2979                         false, SPLIT_TYPE_NONE, 0);
2980             is_ready = vfc_status & BIT(VFC_STATUS_RESP_READY_BIT);
2981 
2982             if (!is_ready) {
2983                 if (polling_count++ == VFC_POLLING_COUNT)
2984                     return 0;
2985 
2986                 msleep(polling_ms);
2987             }
2988         } while (!is_ready);
2989 
2990         reg_addr = sem_base + SEM_FAST_REG_VFC_DATA_RD;
2991         qed_grc_dump_addr_range(p_hwfn,
2992                     p_ptt,
2993                     dump_buf + i,
2994                     true,
2995                     BYTES_TO_DWORDS(reg_addr),
2996                     1, false, SPLIT_TYPE_NONE, 0);
2997     }
2998 
2999     return resp_size;
3000 }
3001 
3002 /* Dump VFC CAM. Returns the dumped size in dwords. */
3003 static u32 qed_grc_dump_vfc_cam(struct qed_hwfn *p_hwfn,
3004                 struct qed_ptt *p_ptt,
3005                 u32 *dump_buf, bool dump, u8 storm_id)
3006 {
3007     u32 total_size = VFC_CAM_NUM_ROWS * VFC_CAM_RESP_DWORDS;
3008     struct storm_defs *storm = &s_storm_defs[storm_id];
3009     u32 cam_addr[VFC_CAM_ADDR_DWORDS] = { 0 };
3010     u32 cam_cmd[VFC_CAM_CMD_DWORDS] = { 0 };
3011     u32 row, offset = 0;
3012 
3013     offset += qed_grc_dump_mem_hdr(p_hwfn,
3014                        dump_buf + offset,
3015                        dump,
3016                        "vfc_cam",
3017                        0,
3018                        total_size,
3019                        256,
3020                        false, "vfc_cam", storm->letter);
3021 
3022     if (!dump)
3023         return offset + total_size;
3024 
3025     /* Prepare CAM address */
3026     SET_VAR_FIELD(cam_addr, VFC_CAM_ADDR, OP, VFC_OPCODE_CAM_RD);
3027 
3028     /* Read VFC CAM data */
3029     for (row = 0; row < VFC_CAM_NUM_ROWS; row++) {
3030         SET_VAR_FIELD(cam_cmd, VFC_CAM_CMD, ROW, row);
3031         offset += qed_grc_dump_read_from_vfc(p_hwfn,
3032                              p_ptt,
3033                              storm,
3034                              cam_cmd,
3035                              VFC_CAM_CMD_DWORDS,
3036                              cam_addr,
3037                              VFC_CAM_ADDR_DWORDS,
3038                              VFC_CAM_RESP_DWORDS,
3039                              dump_buf + offset);
3040     }
3041 
3042     return offset;
3043 }
3044 
3045 /* Dump VFC RAM. Returns the dumped size in dwords. */
3046 static u32 qed_grc_dump_vfc_ram(struct qed_hwfn *p_hwfn,
3047                 struct qed_ptt *p_ptt,
3048                 u32 *dump_buf,
3049                 bool dump,
3050                 u8 storm_id, struct vfc_ram_defs *ram_defs)
3051 {
3052     u32 total_size = ram_defs->num_rows * VFC_RAM_RESP_DWORDS;
3053     struct storm_defs *storm = &s_storm_defs[storm_id];
3054     u32 ram_addr[VFC_RAM_ADDR_DWORDS] = { 0 };
3055     u32 ram_cmd[VFC_RAM_CMD_DWORDS] = { 0 };
3056     u32 row, offset = 0;
3057 
3058     offset += qed_grc_dump_mem_hdr(p_hwfn,
3059                        dump_buf + offset,
3060                        dump,
3061                        ram_defs->mem_name,
3062                        0,
3063                        total_size,
3064                        256,
3065                        false,
3066                        ram_defs->type_name,
3067                        storm->letter);
3068 
3069     if (!dump)
3070         return offset + total_size;
3071 
3072     /* Prepare RAM address */
3073     SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, OP, VFC_OPCODE_RAM_RD);
3074 
3075     /* Read VFC RAM data */
3076     for (row = ram_defs->base_row;
3077          row < ram_defs->base_row + ram_defs->num_rows; row++) {
3078         SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, ROW, row);
3079         offset += qed_grc_dump_read_from_vfc(p_hwfn,
3080                              p_ptt,
3081                              storm,
3082                              ram_cmd,
3083                              VFC_RAM_CMD_DWORDS,
3084                              ram_addr,
3085                              VFC_RAM_ADDR_DWORDS,
3086                              VFC_RAM_RESP_DWORDS,
3087                              dump_buf + offset);
3088     }
3089 
3090     return offset;
3091 }
3092 
3093 /* Dumps GRC VFC data. Returns the dumped size in dwords. */
3094 static u32 qed_grc_dump_vfc(struct qed_hwfn *p_hwfn,
3095                 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3096 {
3097     u8 storm_id, i;
3098     u32 offset = 0;
3099 
3100     for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
3101         if (!qed_grc_is_storm_included(p_hwfn,
3102                            (enum dbg_storms)storm_id) ||
3103             !s_storm_defs[storm_id].has_vfc)
3104             continue;
3105 
3106         /* Read CAM */
3107         offset += qed_grc_dump_vfc_cam(p_hwfn,
3108                            p_ptt,
3109                            dump_buf + offset,
3110                            dump, storm_id);
3111 
3112         /* Read RAM */
3113         for (i = 0; i < NUM_VFC_RAM_TYPES; i++)
3114             offset += qed_grc_dump_vfc_ram(p_hwfn,
3115                                p_ptt,
3116                                dump_buf + offset,
3117                                dump,
3118                                storm_id,
3119                                &s_vfc_ram_defs[i]);
3120     }
3121 
3122     return offset;
3123 }
3124 
3125 /* Dumps GRC RSS data. Returns the dumped size in dwords. */
3126 static u32 qed_grc_dump_rss(struct qed_hwfn *p_hwfn,
3127                 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3128 {
3129     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3130     u32 offset = 0;
3131     u8 rss_mem_id;
3132 
3133     for (rss_mem_id = 0; rss_mem_id < NUM_RSS_MEM_TYPES; rss_mem_id++) {
3134         u32 rss_addr, num_entries, total_dwords;
3135         struct rss_mem_defs *rss_defs;
3136         u32 addr, num_dwords_to_read;
3137         bool packed;
3138 
3139         rss_defs = &s_rss_mem_defs[rss_mem_id];
3140         rss_addr = rss_defs->addr;
3141         num_entries = rss_defs->num_entries[dev_data->chip_id];
3142         total_dwords = (num_entries * rss_defs->entry_width) / 32;
3143         packed = (rss_defs->entry_width == 16);
3144 
3145         offset += qed_grc_dump_mem_hdr(p_hwfn,
3146                            dump_buf + offset,
3147                            dump,
3148                            rss_defs->mem_name,
3149                            0,
3150                            total_dwords,
3151                            rss_defs->entry_width,
3152                            packed,
3153                            rss_defs->type_name, 0);
3154 
3155         /* Dump RSS data */
3156         if (!dump) {
3157             offset += total_dwords;
3158             continue;
3159         }
3160 
3161         addr = BYTES_TO_DWORDS(RSS_REG_RSS_RAM_DATA);
3162         while (total_dwords) {
3163             num_dwords_to_read = min_t(u32,
3164                            RSS_REG_RSS_RAM_DATA_SIZE,
3165                            total_dwords);
3166             qed_wr(p_hwfn, p_ptt, RSS_REG_RSS_RAM_ADDR, rss_addr);
3167             offset += qed_grc_dump_addr_range(p_hwfn,
3168                               p_ptt,
3169                               dump_buf + offset,
3170                               dump,
3171                               addr,
3172                               num_dwords_to_read,
3173                               false,
3174                               SPLIT_TYPE_NONE, 0);
3175             total_dwords -= num_dwords_to_read;
3176             rss_addr++;
3177         }
3178     }
3179 
3180     return offset;
3181 }
3182 
3183 /* Dumps GRC Big RAM. Returns the dumped size in dwords. */
3184 static u32 qed_grc_dump_big_ram(struct qed_hwfn *p_hwfn,
3185                 struct qed_ptt *p_ptt,
3186                 u32 *dump_buf, bool dump, u8 big_ram_id)
3187 {
3188     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3189     u32 block_size, ram_size, offset = 0, reg_val, i;
3190     char mem_name[12] = "???_BIG_RAM";
3191     char type_name[8] = "???_RAM";
3192     struct big_ram_defs *big_ram;
3193 
3194     big_ram = &s_big_ram_defs[big_ram_id];
3195     ram_size = big_ram->ram_size[dev_data->chip_id];
3196 
3197     reg_val = qed_rd(p_hwfn, p_ptt, big_ram->is_256b_reg_addr);
3198     block_size = reg_val &
3199              BIT(big_ram->is_256b_bit_offset[dev_data->chip_id]) ? 256
3200                                      : 128;
3201 
3202     strncpy(type_name, big_ram->instance_name, BIG_RAM_NAME_LEN);
3203     strncpy(mem_name, big_ram->instance_name, BIG_RAM_NAME_LEN);
3204 
3205     /* Dump memory header */
3206     offset += qed_grc_dump_mem_hdr(p_hwfn,
3207                        dump_buf + offset,
3208                        dump,
3209                        mem_name,
3210                        0,
3211                        ram_size,
3212                        block_size * 8,
3213                        false, type_name, 0);
3214 
3215     /* Read and dump Big RAM data */
3216     if (!dump)
3217         return offset + ram_size;
3218 
3219     /* Dump Big RAM */
3220     for (i = 0; i < DIV_ROUND_UP(ram_size, BRB_REG_BIG_RAM_DATA_SIZE);
3221          i++) {
3222         u32 addr, len;
3223 
3224         qed_wr(p_hwfn, p_ptt, big_ram->addr_reg_addr, i);
3225         addr = BYTES_TO_DWORDS(big_ram->data_reg_addr);
3226         len = BRB_REG_BIG_RAM_DATA_SIZE;
3227         offset += qed_grc_dump_addr_range(p_hwfn,
3228                           p_ptt,
3229                           dump_buf + offset,
3230                           dump,
3231                           addr,
3232                           len,
3233                           false, SPLIT_TYPE_NONE, 0);
3234     }
3235 
3236     return offset;
3237 }
3238 
3239 /* Dumps MCP scratchpad. Returns the dumped size in dwords. */
3240 static u32 qed_grc_dump_mcp(struct qed_hwfn *p_hwfn,
3241                 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3242 {
3243     bool block_enable[MAX_BLOCK_ID] = { 0 };
3244     u32 offset = 0, addr;
3245     bool halted = false;
3246 
3247     /* Halt MCP */
3248     if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {
3249         halted = !qed_mcp_halt(p_hwfn, p_ptt);
3250         if (!halted)
3251             DP_NOTICE(p_hwfn, "MCP halt failed!\n");
3252     }
3253 
3254     /* Dump MCP scratchpad */
3255     offset += qed_grc_dump_mem(p_hwfn,
3256                    p_ptt,
3257                    dump_buf + offset,
3258                    dump,
3259                    NULL,
3260                    BYTES_TO_DWORDS(MCP_REG_SCRATCH),
3261                    MCP_REG_SCRATCH_SIZE,
3262                    false, 0, false, "MCP", 0);
3263 
3264     /* Dump MCP cpu_reg_file */
3265     offset += qed_grc_dump_mem(p_hwfn,
3266                    p_ptt,
3267                    dump_buf + offset,
3268                    dump,
3269                    NULL,
3270                    BYTES_TO_DWORDS(MCP_REG_CPU_REG_FILE),
3271                    MCP_REG_CPU_REG_FILE_SIZE,
3272                    false, 0, false, "MCP", 0);
3273 
3274     /* Dump MCP registers */
3275     block_enable[BLOCK_MCP] = true;
3276     offset += qed_grc_dump_registers(p_hwfn,
3277                      p_ptt,
3278                      dump_buf + offset,
3279                      dump, block_enable, "MCP");
3280 
3281     /* Dump required non-MCP registers */
3282     offset += qed_grc_dump_regs_hdr(dump_buf + offset,
3283                     dump, 1, SPLIT_TYPE_NONE, 0,
3284                     "MCP");
3285     addr = BYTES_TO_DWORDS(MISC_REG_SHARED_MEM_ADDR);
3286     offset += qed_grc_dump_reg_entry(p_hwfn,
3287                      p_ptt,
3288                      dump_buf + offset,
3289                      dump,
3290                      addr,
3291                      1,
3292                      false, SPLIT_TYPE_NONE, 0);
3293 
3294     /* Release MCP */
3295     if (halted && qed_mcp_resume(p_hwfn, p_ptt))
3296         DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n");
3297 
3298     return offset;
3299 }
3300 
3301 /* Dumps the tbus indirect memory for all PHYs.
3302  * Returns the dumped size in dwords.
3303  */
3304 static u32 qed_grc_dump_phy(struct qed_hwfn *p_hwfn,
3305                 struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3306 {
3307     u32 offset = 0, tbus_lo_offset, tbus_hi_offset;
3308     char mem_name[32];
3309     u8 phy_id;
3310 
3311     for (phy_id = 0; phy_id < ARRAY_SIZE(s_phy_defs); phy_id++) {
3312         u32 addr_lo_addr, addr_hi_addr, data_lo_addr, data_hi_addr;
3313         struct phy_defs *phy_defs;
3314         u8 *bytes_buf;
3315 
3316         phy_defs = &s_phy_defs[phy_id];
3317         addr_lo_addr = phy_defs->base_addr +
3318                    phy_defs->tbus_addr_lo_addr;
3319         addr_hi_addr = phy_defs->base_addr +
3320                    phy_defs->tbus_addr_hi_addr;
3321         data_lo_addr = phy_defs->base_addr +
3322                    phy_defs->tbus_data_lo_addr;
3323         data_hi_addr = phy_defs->base_addr +
3324                    phy_defs->tbus_data_hi_addr;
3325 
3326         if (snprintf(mem_name, sizeof(mem_name), "tbus_%s",
3327                  phy_defs->phy_name) < 0)
3328             DP_NOTICE(p_hwfn,
3329                   "Unexpected debug error: invalid PHY memory name\n");
3330 
3331         offset += qed_grc_dump_mem_hdr(p_hwfn,
3332                            dump_buf + offset,
3333                            dump,
3334                            mem_name,
3335                            0,
3336                            PHY_DUMP_SIZE_DWORDS,
3337                            16, true, mem_name, 0);
3338 
3339         if (!dump) {
3340             offset += PHY_DUMP_SIZE_DWORDS;
3341             continue;
3342         }
3343 
3344         bytes_buf = (u8 *)(dump_buf + offset);
3345         for (tbus_hi_offset = 0;
3346              tbus_hi_offset < (NUM_PHY_TBUS_ADDRESSES >> 8);
3347              tbus_hi_offset++) {
3348             qed_wr(p_hwfn, p_ptt, addr_hi_addr, tbus_hi_offset);
3349             for (tbus_lo_offset = 0; tbus_lo_offset < 256;
3350                  tbus_lo_offset++) {
3351                 qed_wr(p_hwfn,
3352                        p_ptt, addr_lo_addr, tbus_lo_offset);
3353                 *(bytes_buf++) = (u8)qed_rd(p_hwfn,
3354                                 p_ptt,
3355                                 data_lo_addr);
3356                 *(bytes_buf++) = (u8)qed_rd(p_hwfn,
3357                                 p_ptt,
3358                                 data_hi_addr);
3359             }
3360         }
3361 
3362         offset += PHY_DUMP_SIZE_DWORDS;
3363     }
3364 
3365     return offset;
3366 }
3367 
3368 /* Dumps the MCP HW dump from NVRAM. Returns the dumped size in dwords. */
3369 static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn,
3370                     struct qed_ptt *p_ptt,
3371                     u32 *dump_buf, bool dump)
3372 {
3373     u32 hw_dump_offset_bytes = 0, hw_dump_size_bytes = 0;
3374     u32 hw_dump_size_dwords = 0, offset = 0;
3375     enum dbg_status status;
3376 
3377     /* Read HW dump image from NVRAM */
3378     status = qed_find_nvram_image(p_hwfn,
3379                       p_ptt,
3380                       NVM_TYPE_HW_DUMP_OUT,
3381                       &hw_dump_offset_bytes,
3382                       &hw_dump_size_bytes);
3383     if (status != DBG_STATUS_OK)
3384         return 0;
3385 
3386     hw_dump_size_dwords = BYTES_TO_DWORDS(hw_dump_size_bytes);
3387 
3388     /* Dump HW dump image section */
3389     offset += qed_dump_section_hdr(dump_buf + offset,
3390                        dump, "mcp_hw_dump", 1);
3391     offset += qed_dump_num_param(dump_buf + offset,
3392                      dump, "size", hw_dump_size_dwords);
3393 
3394     /* Read MCP HW dump image into dump buffer */
3395     if (dump && hw_dump_size_dwords) {
3396         status = qed_nvram_read(p_hwfn,
3397                     p_ptt,
3398                     hw_dump_offset_bytes,
3399                     hw_dump_size_bytes, dump_buf + offset);
3400         if (status != DBG_STATUS_OK) {
3401             DP_NOTICE(p_hwfn,
3402                   "Failed to read MCP HW Dump image from NVRAM\n");
3403             return 0;
3404         }
3405     }
3406     offset += hw_dump_size_dwords;
3407 
3408     return offset;
3409 }
3410 
3411 /* Dumps Static Debug data. Returns the dumped size in dwords. */
3412 static u32 qed_grc_dump_static_debug(struct qed_hwfn *p_hwfn,
3413                      struct qed_ptt *p_ptt,
3414                      u32 *dump_buf, bool dump)
3415 {
3416     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3417     u32 block_id, line_id, offset = 0, addr, len;
3418 
3419     /* Don't dump static debug if a debug bus recording is in progress */
3420     if (dump && qed_rd(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON))
3421         return 0;
3422 
3423     if (dump) {
3424         /* Disable debug bus in all blocks */
3425         qed_bus_disable_blocks(p_hwfn, p_ptt);
3426 
3427         qed_bus_reset_dbg_block(p_hwfn, p_ptt);
3428         qed_wr(p_hwfn,
3429                p_ptt, DBG_REG_FRAMING_MODE, DBG_BUS_FRAME_MODE_8HW);
3430         qed_wr(p_hwfn,
3431                p_ptt, DBG_REG_DEBUG_TARGET, DBG_BUS_TARGET_ID_INT_BUF);
3432         qed_wr(p_hwfn, p_ptt, DBG_REG_FULL_MODE, 1);
3433         qed_bus_enable_dbg_block(p_hwfn, p_ptt, true);
3434     }
3435 
3436     /* Dump all static debug lines for each relevant block */
3437     for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
3438         const struct dbg_block_chip *block_per_chip;
3439         const struct dbg_block *block;
3440         bool is_removed, has_dbg_bus;
3441         u16 modes_buf_offset;
3442         u32 block_dwords;
3443 
3444         block_per_chip =
3445             qed_get_dbg_block_per_chip(p_hwfn, (enum block_id)block_id);
3446         is_removed = GET_FIELD(block_per_chip->flags,
3447                        DBG_BLOCK_CHIP_IS_REMOVED);
3448         has_dbg_bus = GET_FIELD(block_per_chip->flags,
3449                     DBG_BLOCK_CHIP_HAS_DBG_BUS);
3450 
3451         if (!is_removed && has_dbg_bus &&
3452             GET_FIELD(block_per_chip->dbg_bus_mode.data,
3453                   DBG_MODE_HDR_EVAL_MODE) > 0) {
3454             modes_buf_offset =
3455                 GET_FIELD(block_per_chip->dbg_bus_mode.data,
3456                       DBG_MODE_HDR_MODES_BUF_OFFSET);
3457             if (!qed_is_mode_match(p_hwfn, &modes_buf_offset))
3458                 has_dbg_bus = false;
3459         }
3460 
3461         if (is_removed || !has_dbg_bus)
3462             continue;
3463 
3464         block_dwords = NUM_DBG_LINES(block_per_chip) *
3465                    STATIC_DEBUG_LINE_DWORDS;
3466 
3467         /* Dump static section params */
3468         block = get_dbg_block(p_hwfn, (enum block_id)block_id);
3469         offset += qed_grc_dump_mem_hdr(p_hwfn,
3470                            dump_buf + offset,
3471                            dump,
3472                            block->name,
3473                            0,
3474                            block_dwords,
3475                            32, false, "STATIC", 0);
3476 
3477         if (!dump) {
3478             offset += block_dwords;
3479             continue;
3480         }
3481 
3482         /* If all lines are invalid - dump zeros */
3483         if (dev_data->block_in_reset[block_id]) {
3484             memset(dump_buf + offset, 0,
3485                    DWORDS_TO_BYTES(block_dwords));
3486             offset += block_dwords;
3487             continue;
3488         }
3489 
3490         /* Enable block's client */
3491         qed_bus_enable_clients(p_hwfn,
3492                        p_ptt,
3493                        BIT(block_per_chip->dbg_client_id));
3494 
3495         addr = BYTES_TO_DWORDS(DBG_REG_CALENDAR_OUT_DATA);
3496         len = STATIC_DEBUG_LINE_DWORDS;
3497         for (line_id = 0; line_id < (u32)NUM_DBG_LINES(block_per_chip);
3498              line_id++) {
3499             /* Configure debug line ID */
3500             qed_bus_config_dbg_line(p_hwfn,
3501                         p_ptt,
3502                         (enum block_id)block_id,
3503                         (u8)line_id, 0xf, 0, 0, 0);
3504 
3505             /* Read debug line info */
3506             offset += qed_grc_dump_addr_range(p_hwfn,
3507                               p_ptt,
3508                               dump_buf + offset,
3509                               dump,
3510                               addr,
3511                               len,
3512                               true, SPLIT_TYPE_NONE,
3513                               0);
3514         }
3515 
3516         /* Disable block's client and debug output */
3517         qed_bus_enable_clients(p_hwfn, p_ptt, 0);
3518         qed_bus_config_dbg_line(p_hwfn, p_ptt,
3519                     (enum block_id)block_id, 0, 0, 0, 0, 0);
3520     }
3521 
3522     if (dump) {
3523         qed_bus_enable_dbg_block(p_hwfn, p_ptt, false);
3524         qed_bus_enable_clients(p_hwfn, p_ptt, 0);
3525     }
3526 
3527     return offset;
3528 }
3529 
3530 /* Performs GRC Dump to the specified buffer.
3531  * Returns the dumped size in dwords.
3532  */
3533 static enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn,
3534                     struct qed_ptt *p_ptt,
3535                     u32 *dump_buf,
3536                     bool dump, u32 *num_dumped_dwords)
3537 {
3538     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3539     bool parities_masked = false;
3540     u32 dwords_read, offset = 0;
3541     u8 i;
3542 
3543     *num_dumped_dwords = 0;
3544     dev_data->num_regs_read = 0;
3545 
3546     /* Update reset state */
3547     if (dump)
3548         qed_update_blocks_reset_state(p_hwfn, p_ptt);
3549 
3550     /* Dump global params */
3551     offset += qed_dump_common_global_params(p_hwfn,
3552                         p_ptt,
3553                         dump_buf + offset, dump, 4);
3554     offset += qed_dump_str_param(dump_buf + offset,
3555                      dump, "dump-type", "grc-dump");
3556     offset += qed_dump_num_param(dump_buf + offset,
3557                      dump,
3558                      "num-lcids",
3559                      NUM_OF_LCIDS);
3560     offset += qed_dump_num_param(dump_buf + offset,
3561                      dump,
3562                      "num-ltids",
3563                      NUM_OF_LTIDS);
3564     offset += qed_dump_num_param(dump_buf + offset,
3565                      dump, "num-ports", dev_data->num_ports);
3566 
3567     /* Dump reset registers (dumped before taking blocks out of reset ) */
3568     if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
3569         offset += qed_grc_dump_reset_regs(p_hwfn,
3570                           p_ptt,
3571                           dump_buf + offset, dump);
3572 
3573     /* Take all blocks out of reset (using reset registers) */
3574     if (dump) {
3575         qed_grc_unreset_blocks(p_hwfn, p_ptt, false);
3576         qed_update_blocks_reset_state(p_hwfn, p_ptt);
3577     }
3578 
3579     /* Disable all parities using MFW command */
3580     if (dump &&
3581         !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {
3582         parities_masked = !qed_mcp_mask_parities(p_hwfn, p_ptt, 1);
3583         if (!parities_masked) {
3584             DP_NOTICE(p_hwfn,
3585                   "Failed to mask parities using MFW\n");
3586             if (qed_grc_get_param
3587                 (p_hwfn, DBG_GRC_PARAM_PARITY_SAFE))
3588                 return DBG_STATUS_MCP_COULD_NOT_MASK_PRTY;
3589         }
3590     }
3591 
3592     /* Dump modified registers (dumped before modifying them) */
3593     if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
3594         offset += qed_grc_dump_modified_regs(p_hwfn,
3595                              p_ptt,
3596                              dump_buf + offset, dump);
3597 
3598     /* Stall storms */
3599     if (dump &&
3600         (qed_grc_is_included(p_hwfn,
3601                  DBG_GRC_PARAM_DUMP_IOR) ||
3602          qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)))
3603         qed_grc_stall_storms(p_hwfn, p_ptt, true);
3604 
3605     /* Dump all regs  */
3606     if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS)) {
3607         bool block_enable[MAX_BLOCK_ID];
3608 
3609         /* Dump all blocks except MCP */
3610         for (i = 0; i < MAX_BLOCK_ID; i++)
3611             block_enable[i] = true;
3612         block_enable[BLOCK_MCP] = false;
3613         offset += qed_grc_dump_registers(p_hwfn,
3614                          p_ptt,
3615                          dump_buf +
3616                          offset,
3617                          dump,
3618                          block_enable, NULL);
3619 
3620         /* Dump special registers */
3621         offset += qed_grc_dump_special_regs(p_hwfn,
3622                             p_ptt,
3623                             dump_buf + offset, dump);
3624     }
3625 
3626     /* Dump memories */
3627     offset += qed_grc_dump_memories(p_hwfn, p_ptt, dump_buf + offset, dump);
3628 
3629     /* Dump MCP */
3630     if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP))
3631         offset += qed_grc_dump_mcp(p_hwfn,
3632                        p_ptt, dump_buf + offset, dump);
3633 
3634     /* Dump context */
3635     if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX))
3636         offset += qed_grc_dump_ctx(p_hwfn,
3637                        p_ptt, dump_buf + offset, dump);
3638 
3639     /* Dump RSS memories */
3640     if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RSS))
3641         offset += qed_grc_dump_rss(p_hwfn,
3642                        p_ptt, dump_buf + offset, dump);
3643 
3644     /* Dump Big RAM */
3645     for (i = 0; i < NUM_BIG_RAM_TYPES; i++)
3646         if (qed_grc_is_included(p_hwfn, s_big_ram_defs[i].grc_param))
3647             offset += qed_grc_dump_big_ram(p_hwfn,
3648                                p_ptt,
3649                                dump_buf + offset,
3650                                dump, i);
3651 
3652     /* Dump VFC */
3653     if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)) {
3654         dwords_read = qed_grc_dump_vfc(p_hwfn,
3655                            p_ptt, dump_buf + offset, dump);
3656         offset += dwords_read;
3657         if (!dwords_read)
3658             return DBG_STATUS_VFC_READ_ERROR;
3659     }
3660 
3661     /* Dump PHY tbus */
3662     if (qed_grc_is_included(p_hwfn,
3663                 DBG_GRC_PARAM_DUMP_PHY) && dev_data->chip_id ==
3664         CHIP_K2 && dev_data->hw_type == HW_TYPE_ASIC)
3665         offset += qed_grc_dump_phy(p_hwfn,
3666                        p_ptt, dump_buf + offset, dump);
3667 
3668     /* Dump MCP HW Dump */
3669     if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP_HW_DUMP) &&
3670         !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP) && 1)
3671         offset += qed_grc_dump_mcp_hw_dump(p_hwfn,
3672                            p_ptt,
3673                            dump_buf + offset, dump);
3674 
3675     /* Dump static debug data (only if not during debug bus recording) */
3676     if (qed_grc_is_included(p_hwfn,
3677                 DBG_GRC_PARAM_DUMP_STATIC) &&
3678         (!dump || dev_data->bus.state == DBG_BUS_STATE_IDLE))
3679         offset += qed_grc_dump_static_debug(p_hwfn,
3680                             p_ptt,
3681                             dump_buf + offset, dump);
3682 
3683     /* Dump last section */
3684     offset += qed_dump_last_section(dump_buf, offset, dump);
3685 
3686     if (dump) {
3687         /* Unstall storms */
3688         if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_UNSTALL))
3689             qed_grc_stall_storms(p_hwfn, p_ptt, false);
3690 
3691         /* Clear parity status */
3692         qed_grc_clear_all_prty(p_hwfn, p_ptt);
3693 
3694         /* Enable all parities using MFW command */
3695         if (parities_masked)
3696             qed_mcp_mask_parities(p_hwfn, p_ptt, 0);
3697     }
3698 
3699     *num_dumped_dwords = offset;
3700 
3701     return DBG_STATUS_OK;
3702 }
3703 
3704 /* Writes the specified failing Idle Check rule to the specified buffer.
3705  * Returns the dumped size in dwords.
3706  */
3707 static u32 qed_idle_chk_dump_failure(struct qed_hwfn *p_hwfn,
3708                      struct qed_ptt *p_ptt,
3709                      u32 *dump_buf,
3710                      bool dump,
3711                      u16 rule_id,
3712                      const struct dbg_idle_chk_rule *rule,
3713                      u16 fail_entry_id, u32 *cond_reg_values)
3714 {
3715     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3716     const struct dbg_idle_chk_cond_reg *cond_regs;
3717     const struct dbg_idle_chk_info_reg *info_regs;
3718     u32 i, next_reg_offset = 0, offset = 0;
3719     struct dbg_idle_chk_result_hdr *hdr;
3720     const union dbg_idle_chk_reg *regs;
3721     u8 reg_id;
3722 
3723     hdr = (struct dbg_idle_chk_result_hdr *)dump_buf;
3724     regs = (const union dbg_idle_chk_reg *)
3725         p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr +
3726         rule->reg_offset;
3727     cond_regs = &regs[0].cond_reg;
3728     info_regs = &regs[rule->num_cond_regs].info_reg;
3729 
3730     /* Dump rule data */
3731     if (dump) {
3732         memset(hdr, 0, sizeof(*hdr));
3733         hdr->rule_id = rule_id;
3734         hdr->mem_entry_id = fail_entry_id;
3735         hdr->severity = rule->severity;
3736         hdr->num_dumped_cond_regs = rule->num_cond_regs;
3737     }
3738 
3739     offset += IDLE_CHK_RESULT_HDR_DWORDS;
3740 
3741     /* Dump condition register values */
3742     for (reg_id = 0; reg_id < rule->num_cond_regs; reg_id++) {
3743         const struct dbg_idle_chk_cond_reg *reg = &cond_regs[reg_id];
3744         struct dbg_idle_chk_result_reg_hdr *reg_hdr;
3745 
3746         reg_hdr =
3747             (struct dbg_idle_chk_result_reg_hdr *)(dump_buf + offset);
3748 
3749         /* Write register header */
3750         if (!dump) {
3751             offset += IDLE_CHK_RESULT_REG_HDR_DWORDS +
3752                 reg->entry_size;
3753             continue;
3754         }
3755 
3756         offset += IDLE_CHK_RESULT_REG_HDR_DWORDS;
3757         memset(reg_hdr, 0, sizeof(*reg_hdr));
3758         reg_hdr->start_entry = reg->start_entry;
3759         reg_hdr->size = reg->entry_size;
3760         SET_FIELD(reg_hdr->data,
3761               DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM,
3762               reg->num_entries > 1 || reg->start_entry > 0 ? 1 : 0);
3763         SET_FIELD(reg_hdr->data,
3764               DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID, reg_id);
3765 
3766         /* Write register values */
3767         for (i = 0; i < reg_hdr->size; i++, next_reg_offset++, offset++)
3768             dump_buf[offset] = cond_reg_values[next_reg_offset];
3769     }
3770 
3771     /* Dump info register values */
3772     for (reg_id = 0; reg_id < rule->num_info_regs; reg_id++) {
3773         const struct dbg_idle_chk_info_reg *reg = &info_regs[reg_id];
3774         u32 block_id;
3775 
3776         /* Check if register's block is in reset */
3777         if (!dump) {
3778             offset += IDLE_CHK_RESULT_REG_HDR_DWORDS + reg->size;
3779             continue;
3780         }
3781 
3782         block_id = GET_FIELD(reg->data, DBG_IDLE_CHK_INFO_REG_BLOCK_ID);
3783         if (block_id >= MAX_BLOCK_ID) {
3784             DP_NOTICE(p_hwfn, "Invalid block_id\n");
3785             return 0;
3786         }
3787 
3788         if (!dev_data->block_in_reset[block_id]) {
3789             struct dbg_idle_chk_result_reg_hdr *reg_hdr;
3790             bool wide_bus, eval_mode, mode_match = true;
3791             u16 modes_buf_offset;
3792             u32 addr;
3793 
3794             reg_hdr = (struct dbg_idle_chk_result_reg_hdr *)
3795                   (dump_buf + offset);
3796 
3797             /* Check mode */
3798             eval_mode = GET_FIELD(reg->mode.data,
3799                           DBG_MODE_HDR_EVAL_MODE) > 0;
3800             if (eval_mode) {
3801                 modes_buf_offset =
3802                     GET_FIELD(reg->mode.data,
3803                           DBG_MODE_HDR_MODES_BUF_OFFSET);
3804                 mode_match =
3805                     qed_is_mode_match(p_hwfn,
3806                               &modes_buf_offset);
3807             }
3808 
3809             if (!mode_match)
3810                 continue;
3811 
3812             addr = GET_FIELD(reg->data,
3813                      DBG_IDLE_CHK_INFO_REG_ADDRESS);
3814             wide_bus = GET_FIELD(reg->data,
3815                          DBG_IDLE_CHK_INFO_REG_WIDE_BUS);
3816 
3817             /* Write register header */
3818             offset += IDLE_CHK_RESULT_REG_HDR_DWORDS;
3819             hdr->num_dumped_info_regs++;
3820             memset(reg_hdr, 0, sizeof(*reg_hdr));
3821             reg_hdr->size = reg->size;
3822             SET_FIELD(reg_hdr->data,
3823                   DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID,
3824                   rule->num_cond_regs + reg_id);
3825 
3826             /* Write register values */
3827             offset += qed_grc_dump_addr_range(p_hwfn,
3828                               p_ptt,
3829                               dump_buf + offset,
3830                               dump,
3831                               addr,
3832                               reg->size, wide_bus,
3833                               SPLIT_TYPE_NONE, 0);
3834         }
3835     }
3836 
3837     return offset;
3838 }
3839 
3840 /* Dumps idle check rule entries. Returns the dumped size in dwords. */
3841 static u32
3842 qed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
3843                    u32 *dump_buf, bool dump,
3844                    const struct dbg_idle_chk_rule *input_rules,
3845                    u32 num_input_rules, u32 *num_failing_rules)
3846 {
3847     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3848     u32 cond_reg_values[IDLE_CHK_MAX_ENTRIES_SIZE];
3849     u32 i, offset = 0;
3850     u16 entry_id;
3851     u8 reg_id;
3852 
3853     *num_failing_rules = 0;
3854 
3855     for (i = 0; i < num_input_rules; i++) {
3856         const struct dbg_idle_chk_cond_reg *cond_regs;
3857         const struct dbg_idle_chk_rule *rule;
3858         const union dbg_idle_chk_reg *regs;
3859         u16 num_reg_entries = 1;
3860         bool check_rule = true;
3861         const u32 *imm_values;
3862 
3863         rule = &input_rules[i];
3864         regs = (const union dbg_idle_chk_reg *)
3865             p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr +
3866             rule->reg_offset;
3867         cond_regs = &regs[0].cond_reg;
3868         imm_values =
3869             (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr +
3870             rule->imm_offset;
3871 
3872         /* Check if all condition register blocks are out of reset, and
3873          * find maximal number of entries (all condition registers that
3874          * are memories must have the same size, which is > 1).
3875          */
3876         for (reg_id = 0; reg_id < rule->num_cond_regs && check_rule;
3877              reg_id++) {
3878             u32 block_id =
3879                 GET_FIELD(cond_regs[reg_id].data,
3880                       DBG_IDLE_CHK_COND_REG_BLOCK_ID);
3881 
3882             if (block_id >= MAX_BLOCK_ID) {
3883                 DP_NOTICE(p_hwfn, "Invalid block_id\n");
3884                 return 0;
3885             }
3886 
3887             check_rule = !dev_data->block_in_reset[block_id];
3888             if (cond_regs[reg_id].num_entries > num_reg_entries)
3889                 num_reg_entries = cond_regs[reg_id].num_entries;
3890         }
3891 
3892         if (!check_rule && dump)
3893             continue;
3894 
3895         if (!dump) {
3896             u32 entry_dump_size =
3897                 qed_idle_chk_dump_failure(p_hwfn,
3898                               p_ptt,
3899                               dump_buf + offset,
3900                               false,
3901                               rule->rule_id,
3902                               rule,
3903                               0,
3904                               NULL);
3905 
3906             offset += num_reg_entries * entry_dump_size;
3907             (*num_failing_rules) += num_reg_entries;
3908             continue;
3909         }
3910 
3911         /* Go over all register entries (number of entries is the same
3912          * for all condition registers).
3913          */
3914         for (entry_id = 0; entry_id < num_reg_entries; entry_id++) {
3915             u32 next_reg_offset = 0;
3916 
3917             /* Read current entry of all condition registers */
3918             for (reg_id = 0; reg_id < rule->num_cond_regs;
3919                  reg_id++) {
3920                 const struct dbg_idle_chk_cond_reg *reg =
3921                     &cond_regs[reg_id];
3922                 u32 padded_entry_size, addr;
3923                 bool wide_bus;
3924 
3925                 /* Find GRC address (if it's a memory, the
3926                  * address of the specific entry is calculated).
3927                  */
3928                 addr = GET_FIELD(reg->data,
3929                          DBG_IDLE_CHK_COND_REG_ADDRESS);
3930                 wide_bus =
3931                     GET_FIELD(reg->data,
3932                           DBG_IDLE_CHK_COND_REG_WIDE_BUS);
3933                 if (reg->num_entries > 1 ||
3934                     reg->start_entry > 0) {
3935                     padded_entry_size =
3936                        reg->entry_size > 1 ?
3937                        roundup_pow_of_two(reg->entry_size) :
3938                        1;
3939                     addr += (reg->start_entry + entry_id) *
3940                         padded_entry_size;
3941                 }
3942 
3943                 /* Read registers */
3944                 if (next_reg_offset + reg->entry_size >=
3945                     IDLE_CHK_MAX_ENTRIES_SIZE) {
3946                     DP_NOTICE(p_hwfn,
3947                           "idle check registers entry is too large\n");
3948                     return 0;
3949                 }
3950 
3951                 next_reg_offset +=
3952                     qed_grc_dump_addr_range(p_hwfn, p_ptt,
3953                                 cond_reg_values +
3954                                 next_reg_offset,
3955                                 dump, addr,
3956                                 reg->entry_size,
3957                                 wide_bus,
3958                                 SPLIT_TYPE_NONE, 0);
3959             }
3960 
3961             /* Call rule condition function.
3962              * If returns true, it's a failure.
3963              */
3964             if ((*cond_arr[rule->cond_id]) (cond_reg_values,
3965                             imm_values)) {
3966                 offset += qed_idle_chk_dump_failure(p_hwfn,
3967                             p_ptt,
3968                             dump_buf + offset,
3969                             dump,
3970                             rule->rule_id,
3971                             rule,
3972                             entry_id,
3973                             cond_reg_values);
3974                 (*num_failing_rules)++;
3975             }
3976         }
3977     }
3978 
3979     return offset;
3980 }
3981 
3982 /* Performs Idle Check Dump to the specified buffer.
3983  * Returns the dumped size in dwords.
3984  */
3985 static u32 qed_idle_chk_dump(struct qed_hwfn *p_hwfn,
3986                  struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3987 {
3988     struct virt_mem_desc *dbg_buf =
3989         &p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES];
3990     u32 num_failing_rules_offset, offset = 0,
3991         input_offset = 0, num_failing_rules = 0;
3992 
3993     /* Dump global params  - 1 must match below amount of params */
3994     offset += qed_dump_common_global_params(p_hwfn,
3995                         p_ptt,
3996                         dump_buf + offset, dump, 1);
3997     offset += qed_dump_str_param(dump_buf + offset,
3998                      dump, "dump-type", "idle-chk");
3999 
4000     /* Dump idle check section header with a single parameter */
4001     offset += qed_dump_section_hdr(dump_buf + offset, dump, "idle_chk", 1);
4002     num_failing_rules_offset = offset;
4003     offset += qed_dump_num_param(dump_buf + offset, dump, "num_rules", 0);
4004 
4005     while (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) {
4006         const struct dbg_idle_chk_cond_hdr *cond_hdr =
4007             (const struct dbg_idle_chk_cond_hdr *)dbg_buf->ptr +
4008             input_offset++;
4009         bool eval_mode, mode_match = true;
4010         u32 curr_failing_rules;
4011         u16 modes_buf_offset;
4012 
4013         /* Check mode */
4014         eval_mode = GET_FIELD(cond_hdr->mode.data,
4015                       DBG_MODE_HDR_EVAL_MODE) > 0;
4016         if (eval_mode) {
4017             modes_buf_offset =
4018                 GET_FIELD(cond_hdr->mode.data,
4019                       DBG_MODE_HDR_MODES_BUF_OFFSET);
4020             mode_match = qed_is_mode_match(p_hwfn,
4021                                &modes_buf_offset);
4022         }
4023 
4024         if (mode_match) {
4025             const struct dbg_idle_chk_rule *rule =
4026                 (const struct dbg_idle_chk_rule *)((u32 *)
4027                                    dbg_buf->ptr
4028                                    + input_offset);
4029             u32 num_input_rules =
4030                 cond_hdr->data_size / IDLE_CHK_RULE_SIZE_DWORDS;
4031             offset +=
4032                 qed_idle_chk_dump_rule_entries(p_hwfn,
4033                                p_ptt,
4034                                dump_buf +
4035                                offset,
4036                                dump,
4037                                rule,
4038                                num_input_rules,
4039                                &curr_failing_rules);
4040             num_failing_rules += curr_failing_rules;
4041         }
4042 
4043         input_offset += cond_hdr->data_size;
4044     }
4045 
4046     /* Overwrite num_rules parameter */
4047     if (dump)
4048         qed_dump_num_param(dump_buf + num_failing_rules_offset,
4049                    dump, "num_rules", num_failing_rules);
4050 
4051     /* Dump last section */
4052     offset += qed_dump_last_section(dump_buf, offset, dump);
4053 
4054     return offset;
4055 }
4056 
4057 /* Get info on the MCP Trace data in the scratchpad:
4058  * - trace_data_grc_addr (OUT): trace data GRC address in bytes
4059  * - trace_data_size (OUT): trace data size in bytes (without the header)
4060  */
4061 static enum dbg_status qed_mcp_trace_get_data_info(struct qed_hwfn *p_hwfn,
4062                            struct qed_ptt *p_ptt,
4063                            u32 *trace_data_grc_addr,
4064                            u32 *trace_data_size)
4065 {
4066     u32 spad_trace_offsize, signature;
4067 
4068     /* Read trace section offsize structure from MCP scratchpad */
4069     spad_trace_offsize = qed_rd(p_hwfn, p_ptt, MCP_SPAD_TRACE_OFFSIZE_ADDR);
4070 
4071     /* Extract trace section address from offsize (in scratchpad) */
4072     *trace_data_grc_addr =
4073         MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize);
4074 
4075     /* Read signature from MCP trace section */
4076     signature = qed_rd(p_hwfn, p_ptt,
4077                *trace_data_grc_addr +
4078                offsetof(struct mcp_trace, signature));
4079 
4080     if (signature != MFW_TRACE_SIGNATURE)
4081         return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4082 
4083     /* Read trace size from MCP trace section */
4084     *trace_data_size = qed_rd(p_hwfn,
4085                   p_ptt,
4086                   *trace_data_grc_addr +
4087                   offsetof(struct mcp_trace, size));
4088 
4089     return DBG_STATUS_OK;
4090 }
4091 
4092 /* Reads MCP trace meta data image from NVRAM
4093  * - running_bundle_id (OUT): running bundle ID (invalid when loaded from file)
4094  * - trace_meta_offset (OUT): trace meta offset in NVRAM in bytes (invalid when
4095  *                loaded from file).
4096  * - trace_meta_size (OUT):   size in bytes of the trace meta data.
4097  */
4098 static enum dbg_status qed_mcp_trace_get_meta_info(struct qed_hwfn *p_hwfn,
4099                            struct qed_ptt *p_ptt,
4100                            u32 trace_data_size_bytes,
4101                            u32 *running_bundle_id,
4102                            u32 *trace_meta_offset,
4103                            u32 *trace_meta_size)
4104 {
4105     u32 spad_trace_offsize, nvram_image_type, running_mfw_addr;
4106 
4107     /* Read MCP trace section offsize structure from MCP scratchpad */
4108     spad_trace_offsize = qed_rd(p_hwfn, p_ptt, MCP_SPAD_TRACE_OFFSIZE_ADDR);
4109 
4110     /* Find running bundle ID */
4111     running_mfw_addr =
4112         MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize) +
4113         QED_SECTION_SIZE(spad_trace_offsize) + trace_data_size_bytes;
4114     *running_bundle_id = qed_rd(p_hwfn, p_ptt, running_mfw_addr);
4115     if (*running_bundle_id > 1)
4116         return DBG_STATUS_INVALID_NVRAM_BUNDLE;
4117 
4118     /* Find image in NVRAM */
4119     nvram_image_type =
4120         (*running_bundle_id ==
4121          DIR_ID_1) ? NVM_TYPE_MFW_TRACE1 : NVM_TYPE_MFW_TRACE2;
4122     return qed_find_nvram_image(p_hwfn,
4123                     p_ptt,
4124                     nvram_image_type,
4125                     trace_meta_offset, trace_meta_size);
4126 }
4127 
4128 /* Reads the MCP Trace meta data from NVRAM into the specified buffer */
4129 static enum dbg_status qed_mcp_trace_read_meta(struct qed_hwfn *p_hwfn,
4130                            struct qed_ptt *p_ptt,
4131                            u32 nvram_offset_in_bytes,
4132                            u32 size_in_bytes, u32 *buf)
4133 {
4134     u8 modules_num, module_len, i, *byte_buf = (u8 *)buf;
4135     enum dbg_status status;
4136     u32 signature;
4137 
4138     /* Read meta data from NVRAM */
4139     status = qed_nvram_read(p_hwfn,
4140                 p_ptt,
4141                 nvram_offset_in_bytes, size_in_bytes, buf);
4142     if (status != DBG_STATUS_OK)
4143         return status;
4144 
4145     /* Extract and check first signature */
4146     signature = qed_read_unaligned_dword(byte_buf);
4147     byte_buf += sizeof(signature);
4148     if (signature != NVM_MAGIC_VALUE)
4149         return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4150 
4151     /* Extract number of modules */
4152     modules_num = *(byte_buf++);
4153 
4154     /* Skip all modules */
4155     for (i = 0; i < modules_num; i++) {
4156         module_len = *(byte_buf++);
4157         byte_buf += module_len;
4158     }
4159 
4160     /* Extract and check second signature */
4161     signature = qed_read_unaligned_dword(byte_buf);
4162     byte_buf += sizeof(signature);
4163     if (signature != NVM_MAGIC_VALUE)
4164         return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4165 
4166     return DBG_STATUS_OK;
4167 }
4168 
4169 /* Dump MCP Trace */
4170 static enum dbg_status qed_mcp_trace_dump(struct qed_hwfn *p_hwfn,
4171                       struct qed_ptt *p_ptt,
4172                       u32 *dump_buf,
4173                       bool dump, u32 *num_dumped_dwords)
4174 {
4175     u32 trace_data_grc_addr, trace_data_size_bytes, trace_data_size_dwords;
4176     u32 trace_meta_size_dwords = 0, running_bundle_id, offset = 0;
4177     u32 trace_meta_offset_bytes = 0, trace_meta_size_bytes = 0;
4178     enum dbg_status status;
4179     int halted = 0;
4180     bool use_mfw;
4181 
4182     *num_dumped_dwords = 0;
4183 
4184     use_mfw = !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP);
4185 
4186     /* Get trace data info */
4187     status = qed_mcp_trace_get_data_info(p_hwfn,
4188                          p_ptt,
4189                          &trace_data_grc_addr,
4190                          &trace_data_size_bytes);
4191     if (status != DBG_STATUS_OK)
4192         return status;
4193 
4194     /* Dump global params */
4195     offset += qed_dump_common_global_params(p_hwfn,
4196                         p_ptt,
4197                         dump_buf + offset, dump, 1);
4198     offset += qed_dump_str_param(dump_buf + offset,
4199                      dump, "dump-type", "mcp-trace");
4200 
4201     /* Halt MCP while reading from scratchpad so the read data will be
4202      * consistent. if halt fails, MCP trace is taken anyway, with a small
4203      * risk that it may be corrupt.
4204      */
4205     if (dump && use_mfw) {
4206         halted = !qed_mcp_halt(p_hwfn, p_ptt);
4207         if (!halted)
4208             DP_NOTICE(p_hwfn, "MCP halt failed!\n");
4209     }
4210 
4211     /* Find trace data size */
4212     trace_data_size_dwords =
4213         DIV_ROUND_UP(trace_data_size_bytes + sizeof(struct mcp_trace),
4214              BYTES_IN_DWORD);
4215 
4216     /* Dump trace data section header and param */
4217     offset += qed_dump_section_hdr(dump_buf + offset,
4218                        dump, "mcp_trace_data", 1);
4219     offset += qed_dump_num_param(dump_buf + offset,
4220                      dump, "size", trace_data_size_dwords);
4221 
4222     /* Read trace data from scratchpad into dump buffer */
4223     offset += qed_grc_dump_addr_range(p_hwfn,
4224                       p_ptt,
4225                       dump_buf + offset,
4226                       dump,
4227                       BYTES_TO_DWORDS(trace_data_grc_addr),
4228                       trace_data_size_dwords, false,
4229                       SPLIT_TYPE_NONE, 0);
4230 
4231     /* Resume MCP (only if halt succeeded) */
4232     if (halted && qed_mcp_resume(p_hwfn, p_ptt))
4233         DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n");
4234 
4235     /* Dump trace meta section header */
4236     offset += qed_dump_section_hdr(dump_buf + offset,
4237                        dump, "mcp_trace_meta", 1);
4238 
4239     /* If MCP Trace meta size parameter was set, use it.
4240      * Otherwise, read trace meta.
4241      * trace_meta_size_bytes is dword-aligned.
4242      */
4243     trace_meta_size_bytes =
4244         qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_MCP_TRACE_META_SIZE);
4245     if ((!trace_meta_size_bytes || dump) && use_mfw)
4246         status = qed_mcp_trace_get_meta_info(p_hwfn,
4247                              p_ptt,
4248                              trace_data_size_bytes,
4249                              &running_bundle_id,
4250                              &trace_meta_offset_bytes,
4251                              &trace_meta_size_bytes);
4252     if (status == DBG_STATUS_OK)
4253         trace_meta_size_dwords = BYTES_TO_DWORDS(trace_meta_size_bytes);
4254 
4255     /* Dump trace meta size param */
4256     offset += qed_dump_num_param(dump_buf + offset,
4257                      dump, "size", trace_meta_size_dwords);
4258 
4259     /* Read trace meta image into dump buffer */
4260     if (dump && trace_meta_size_dwords)
4261         status = qed_mcp_trace_read_meta(p_hwfn,
4262                          p_ptt,
4263                          trace_meta_offset_bytes,
4264                          trace_meta_size_bytes,
4265                          dump_buf + offset);
4266     if (status == DBG_STATUS_OK)
4267         offset += trace_meta_size_dwords;
4268 
4269     /* Dump last section */
4270     offset += qed_dump_last_section(dump_buf, offset, dump);
4271 
4272     *num_dumped_dwords = offset;
4273 
4274     /* If no mcp access, indicate that the dump doesn't contain the meta
4275      * data from NVRAM.
4276      */
4277     return use_mfw ? status : DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
4278 }
4279 
4280 /* Dump GRC FIFO */
4281 static enum dbg_status qed_reg_fifo_dump(struct qed_hwfn *p_hwfn,
4282                      struct qed_ptt *p_ptt,
4283                      u32 *dump_buf,
4284                      bool dump, u32 *num_dumped_dwords)
4285 {
4286     u32 dwords_read, size_param_offset, offset = 0, addr, len;
4287     bool fifo_has_data;
4288 
4289     *num_dumped_dwords = 0;
4290 
4291     /* Dump global params */
4292     offset += qed_dump_common_global_params(p_hwfn,
4293                         p_ptt,
4294                         dump_buf + offset, dump, 1);
4295     offset += qed_dump_str_param(dump_buf + offset,
4296                      dump, "dump-type", "reg-fifo");
4297 
4298     /* Dump fifo data section header and param. The size param is 0 for
4299      * now, and is overwritten after reading the FIFO.
4300      */
4301     offset += qed_dump_section_hdr(dump_buf + offset,
4302                        dump, "reg_fifo_data", 1);
4303     size_param_offset = offset;
4304     offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4305 
4306     if (!dump) {
4307         /* FIFO max size is REG_FIFO_DEPTH_DWORDS. There is no way to
4308          * test how much data is available, except for reading it.
4309          */
4310         offset += REG_FIFO_DEPTH_DWORDS;
4311         goto out;
4312     }
4313 
4314     fifo_has_data = qed_rd(p_hwfn, p_ptt,
4315                    GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
4316 
4317     /* Pull available data from fifo. Use DMAE since this is widebus memory
4318      * and must be accessed atomically. Test for dwords_read not passing
4319      * buffer size since more entries could be added to the buffer as we are
4320      * emptying it.
4321      */
4322     addr = BYTES_TO_DWORDS(GRC_REG_TRACE_FIFO);
4323     len = REG_FIFO_ELEMENT_DWORDS;
4324     for (dwords_read = 0;
4325          fifo_has_data && dwords_read < REG_FIFO_DEPTH_DWORDS;
4326          dwords_read += REG_FIFO_ELEMENT_DWORDS) {
4327         offset += qed_grc_dump_addr_range(p_hwfn,
4328                           p_ptt,
4329                           dump_buf + offset,
4330                           true,
4331                           addr,
4332                           len,
4333                           true, SPLIT_TYPE_NONE,
4334                           0);
4335         fifo_has_data = qed_rd(p_hwfn, p_ptt,
4336                        GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
4337     }
4338 
4339     qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4340                dwords_read);
4341 out:
4342     /* Dump last section */
4343     offset += qed_dump_last_section(dump_buf, offset, dump);
4344 
4345     *num_dumped_dwords = offset;
4346 
4347     return DBG_STATUS_OK;
4348 }
4349 
4350 /* Dump IGU FIFO */
4351 static enum dbg_status qed_igu_fifo_dump(struct qed_hwfn *p_hwfn,
4352                      struct qed_ptt *p_ptt,
4353                      u32 *dump_buf,
4354                      bool dump, u32 *num_dumped_dwords)
4355 {
4356     u32 dwords_read, size_param_offset, offset = 0, addr, len;
4357     bool fifo_has_data;
4358 
4359     *num_dumped_dwords = 0;
4360 
4361     /* Dump global params */
4362     offset += qed_dump_common_global_params(p_hwfn,
4363                         p_ptt,
4364                         dump_buf + offset, dump, 1);
4365     offset += qed_dump_str_param(dump_buf + offset,
4366                      dump, "dump-type", "igu-fifo");
4367 
4368     /* Dump fifo data section header and param. The size param is 0 for
4369      * now, and is overwritten after reading the FIFO.
4370      */
4371     offset += qed_dump_section_hdr(dump_buf + offset,
4372                        dump, "igu_fifo_data", 1);
4373     size_param_offset = offset;
4374     offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4375 
4376     if (!dump) {
4377         /* FIFO max size is IGU_FIFO_DEPTH_DWORDS. There is no way to
4378          * test how much data is available, except for reading it.
4379          */
4380         offset += IGU_FIFO_DEPTH_DWORDS;
4381         goto out;
4382     }
4383 
4384     fifo_has_data = qed_rd(p_hwfn, p_ptt,
4385                    IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
4386 
4387     /* Pull available data from fifo. Use DMAE since this is widebus memory
4388      * and must be accessed atomically. Test for dwords_read not passing
4389      * buffer size since more entries could be added to the buffer as we are
4390      * emptying it.
4391      */
4392     addr = BYTES_TO_DWORDS(IGU_REG_ERROR_HANDLING_MEMORY);
4393     len = IGU_FIFO_ELEMENT_DWORDS;
4394     for (dwords_read = 0;
4395          fifo_has_data && dwords_read < IGU_FIFO_DEPTH_DWORDS;
4396          dwords_read += IGU_FIFO_ELEMENT_DWORDS) {
4397         offset += qed_grc_dump_addr_range(p_hwfn,
4398                           p_ptt,
4399                           dump_buf + offset,
4400                           true,
4401                           addr,
4402                           len,
4403                           true, SPLIT_TYPE_NONE,
4404                           0);
4405         fifo_has_data = qed_rd(p_hwfn, p_ptt,
4406                        IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
4407     }
4408 
4409     qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4410                dwords_read);
4411 out:
4412     /* Dump last section */
4413     offset += qed_dump_last_section(dump_buf, offset, dump);
4414 
4415     *num_dumped_dwords = offset;
4416 
4417     return DBG_STATUS_OK;
4418 }
4419 
4420 /* Protection Override dump */
4421 static enum dbg_status qed_protection_override_dump(struct qed_hwfn *p_hwfn,
4422                             struct qed_ptt *p_ptt,
4423                             u32 *dump_buf,
4424                             bool dump,
4425                             u32 *num_dumped_dwords)
4426 {
4427     u32 size_param_offset, override_window_dwords, offset = 0, addr;
4428 
4429     *num_dumped_dwords = 0;
4430 
4431     /* Dump global params */
4432     offset += qed_dump_common_global_params(p_hwfn,
4433                         p_ptt,
4434                         dump_buf + offset, dump, 1);
4435     offset += qed_dump_str_param(dump_buf + offset,
4436                      dump, "dump-type", "protection-override");
4437 
4438     /* Dump data section header and param. The size param is 0 for now,
4439      * and is overwritten after reading the data.
4440      */
4441     offset += qed_dump_section_hdr(dump_buf + offset,
4442                        dump, "protection_override_data", 1);
4443     size_param_offset = offset;
4444     offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4445 
4446     if (!dump) {
4447         offset += PROTECTION_OVERRIDE_DEPTH_DWORDS;
4448         goto out;
4449     }
4450 
4451     /* Add override window info to buffer */
4452     override_window_dwords =
4453         qed_rd(p_hwfn, p_ptt, GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW) *
4454         PROTECTION_OVERRIDE_ELEMENT_DWORDS;
4455     if (override_window_dwords) {
4456         addr = BYTES_TO_DWORDS(GRC_REG_PROTECTION_OVERRIDE_WINDOW);
4457         offset += qed_grc_dump_addr_range(p_hwfn,
4458                           p_ptt,
4459                           dump_buf + offset,
4460                           true,
4461                           addr,
4462                           override_window_dwords,
4463                           true, SPLIT_TYPE_NONE, 0);
4464         qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4465                    override_window_dwords);
4466     }
4467 out:
4468     /* Dump last section */
4469     offset += qed_dump_last_section(dump_buf, offset, dump);
4470 
4471     *num_dumped_dwords = offset;
4472 
4473     return DBG_STATUS_OK;
4474 }
4475 
4476 /* Performs FW Asserts Dump to the specified buffer.
4477  * Returns the dumped size in dwords.
4478  */
4479 static u32 qed_fw_asserts_dump(struct qed_hwfn *p_hwfn,
4480                    struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
4481 {
4482     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4483     struct fw_asserts_ram_section *asserts;
4484     char storm_letter_str[2] = "?";
4485     struct fw_info fw_info;
4486     u32 offset = 0;
4487     u8 storm_id;
4488 
4489     /* Dump global params */
4490     offset += qed_dump_common_global_params(p_hwfn,
4491                         p_ptt,
4492                         dump_buf + offset, dump, 1);
4493     offset += qed_dump_str_param(dump_buf + offset,
4494                      dump, "dump-type", "fw-asserts");
4495 
4496     /* Find Storm dump size */
4497     for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
4498         u32 fw_asserts_section_addr, next_list_idx_addr, next_list_idx;
4499         struct storm_defs *storm = &s_storm_defs[storm_id];
4500         u32 last_list_idx, addr;
4501 
4502         if (dev_data->block_in_reset[storm->sem_block_id])
4503             continue;
4504 
4505         /* Read FW info for the current Storm */
4506         qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, &fw_info);
4507 
4508         asserts = &fw_info.fw_asserts_section;
4509 
4510         /* Dump FW Asserts section header and params */
4511         storm_letter_str[0] = storm->letter;
4512         offset += qed_dump_section_hdr(dump_buf + offset,
4513                            dump, "fw_asserts", 2);
4514         offset += qed_dump_str_param(dump_buf + offset,
4515                          dump, "storm", storm_letter_str);
4516         offset += qed_dump_num_param(dump_buf + offset,
4517                          dump,
4518                          "size",
4519                          asserts->list_element_dword_size);
4520 
4521         /* Read and dump FW Asserts data */
4522         if (!dump) {
4523             offset += asserts->list_element_dword_size;
4524             continue;
4525         }
4526 
4527         addr = le16_to_cpu(asserts->section_ram_line_offset);
4528         fw_asserts_section_addr = storm->sem_fast_mem_addr +
4529                       SEM_FAST_REG_INT_RAM +
4530                       RAM_LINES_TO_BYTES(addr);
4531 
4532         next_list_idx_addr = fw_asserts_section_addr +
4533             DWORDS_TO_BYTES(asserts->list_next_index_dword_offset);
4534         next_list_idx = qed_rd(p_hwfn, p_ptt, next_list_idx_addr);
4535         last_list_idx = (next_list_idx > 0 ?
4536                  next_list_idx :
4537                  asserts->list_num_elements) - 1;
4538         addr = BYTES_TO_DWORDS(fw_asserts_section_addr) +
4539                asserts->list_dword_offset +
4540                last_list_idx * asserts->list_element_dword_size;
4541         offset +=
4542             qed_grc_dump_addr_range(p_hwfn, p_ptt,
4543                         dump_buf + offset,
4544                         dump, addr,
4545                         asserts->list_element_dword_size,
4546                           false, SPLIT_TYPE_NONE, 0);
4547     }
4548 
4549     /* Dump last section */
4550     offset += qed_dump_last_section(dump_buf, offset, dump);
4551 
4552     return offset;
4553 }
4554 
4555 /* Dumps the specified ILT pages to the specified buffer.
4556  * Returns the dumped size in dwords.
4557  */
4558 static u32 qed_ilt_dump_pages_range(u32 *dump_buf, u32 *given_offset,
4559                     bool *dump, u32 start_page_id,
4560                     u32 num_pages,
4561                     struct phys_mem_desc *ilt_pages,
4562                     bool dump_page_ids, u32 buf_size_in_dwords,
4563                     u32 *given_actual_dump_size_in_dwords)
4564 {
4565     u32 actual_dump_size_in_dwords = *given_actual_dump_size_in_dwords;
4566     u32 page_id, end_page_id, offset = *given_offset;
4567     struct phys_mem_desc *mem_desc = NULL;
4568     bool continue_dump = *dump;
4569     u32 partial_page_size = 0;
4570 
4571     if (num_pages == 0)
4572         return offset;
4573 
4574     end_page_id = start_page_id + num_pages - 1;
4575 
4576     for (page_id = start_page_id; page_id <= end_page_id; page_id++) {
4577         mem_desc = &ilt_pages[page_id];
4578         if (!ilt_pages[page_id].virt_addr)
4579             continue;
4580 
4581         if (dump_page_ids) {
4582             /* Copy page ID to dump buffer
4583              * (if dump is needed and buffer is not full)
4584              */
4585             if ((continue_dump) &&
4586                 (offset + 1 > buf_size_in_dwords)) {
4587                 continue_dump = false;
4588                 actual_dump_size_in_dwords = offset;
4589             }
4590             if (continue_dump)
4591                 *(dump_buf + offset) = page_id;
4592             offset++;
4593         } else {
4594             /* Copy page memory to dump buffer */
4595             if ((continue_dump) &&
4596                 (offset + BYTES_TO_DWORDS(mem_desc->size) >
4597                  buf_size_in_dwords)) {
4598                 if (offset + BYTES_TO_DWORDS(mem_desc->size) >
4599                     buf_size_in_dwords) {
4600                     partial_page_size =
4601                         buf_size_in_dwords - offset;
4602                     memcpy(dump_buf + offset,
4603                            mem_desc->virt_addr,
4604                            partial_page_size);
4605                     continue_dump = false;
4606                     actual_dump_size_in_dwords =
4607                         offset + partial_page_size;
4608                 }
4609             }
4610 
4611             if (continue_dump)
4612                 memcpy(dump_buf + offset,
4613                        mem_desc->virt_addr, mem_desc->size);
4614             offset += BYTES_TO_DWORDS(mem_desc->size);
4615         }
4616     }
4617 
4618     *dump = continue_dump;
4619     *given_offset = offset;
4620     *given_actual_dump_size_in_dwords = actual_dump_size_in_dwords;
4621 
4622     return offset;
4623 }
4624 
4625 /* Dumps a section containing the dumped ILT pages.
4626  * Returns the dumped size in dwords.
4627  */
4628 static u32 qed_ilt_dump_pages_section(struct qed_hwfn *p_hwfn,
4629                       u32 *dump_buf,
4630                       u32 *given_offset,
4631                       bool *dump,
4632                       u32 valid_conn_pf_pages,
4633                       u32 valid_conn_vf_pages,
4634                       struct phys_mem_desc *ilt_pages,
4635                       bool dump_page_ids,
4636                       u32 buf_size_in_dwords,
4637                       u32 *given_actual_dump_size_in_dwords)
4638 {
4639     struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
4640     u32 pf_start_line, start_page_id, offset = *given_offset;
4641     u32 cdut_pf_init_pages, cdut_vf_init_pages;
4642     u32 cdut_pf_work_pages, cdut_vf_work_pages;
4643     u32 base_data_offset, size_param_offset;
4644     u32 src_pages;
4645     u32 section_header_and_param_size;
4646     u32 cdut_pf_pages, cdut_vf_pages;
4647     u32 actual_dump_size_in_dwords;
4648     bool continue_dump = *dump;
4649     bool update_size = *dump;
4650     const char *section_name;
4651     u32 i;
4652 
4653     actual_dump_size_in_dwords = *given_actual_dump_size_in_dwords;
4654     section_name = dump_page_ids ? "ilt_page_ids" : "ilt_page_mem";
4655     cdut_pf_init_pages = qed_get_cdut_num_pf_init_pages(p_hwfn);
4656     cdut_vf_init_pages = qed_get_cdut_num_vf_init_pages(p_hwfn);
4657     cdut_pf_work_pages = qed_get_cdut_num_pf_work_pages(p_hwfn);
4658     cdut_vf_work_pages = qed_get_cdut_num_vf_work_pages(p_hwfn);
4659     cdut_pf_pages = cdut_pf_init_pages + cdut_pf_work_pages;
4660     cdut_vf_pages = cdut_vf_init_pages + cdut_vf_work_pages;
4661     pf_start_line = p_hwfn->p_cxt_mngr->pf_start_line;
4662     section_header_and_param_size = qed_dump_section_hdr(NULL,
4663                                  false,
4664                                  section_name,
4665                                  1) +
4666     qed_dump_num_param(NULL, false, "size", 0);
4667 
4668     if ((continue_dump) &&
4669         (offset + section_header_and_param_size > buf_size_in_dwords)) {
4670         continue_dump = false;
4671         update_size = false;
4672         actual_dump_size_in_dwords = offset;
4673     }
4674 
4675     offset += qed_dump_section_hdr(dump_buf + offset,
4676                        continue_dump, section_name, 1);
4677 
4678     /* Dump size parameter (0 for now, overwritten with real size later) */
4679     size_param_offset = offset;
4680     offset += qed_dump_num_param(dump_buf + offset,
4681                      continue_dump, "size", 0);
4682     base_data_offset = offset;
4683 
4684     /* CDUC pages are ordered as follows:
4685      * - PF pages - valid section (included in PF connection type mapping)
4686      * - PF pages - invalid section (not dumped)
4687      * - For each VF in the PF:
4688      *   - VF pages - valid section (included in VF connection type mapping)
4689      *   - VF pages - invalid section (not dumped)
4690      */
4691     if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUC)) {
4692         /* Dump connection PF pages */
4693         start_page_id = clients[ILT_CLI_CDUC].first.val - pf_start_line;
4694         qed_ilt_dump_pages_range(dump_buf, &offset, &continue_dump,
4695                      start_page_id, valid_conn_pf_pages,
4696                      ilt_pages, dump_page_ids,
4697                      buf_size_in_dwords,
4698                      &actual_dump_size_in_dwords);
4699 
4700         /* Dump connection VF pages */
4701         start_page_id += clients[ILT_CLI_CDUC].pf_total_lines;
4702         for (i = 0; i < p_hwfn->p_cxt_mngr->vf_count;
4703              i++, start_page_id += clients[ILT_CLI_CDUC].vf_total_lines)
4704             qed_ilt_dump_pages_range(dump_buf, &offset,
4705                          &continue_dump, start_page_id,
4706                          valid_conn_vf_pages,
4707                          ilt_pages, dump_page_ids,
4708                          buf_size_in_dwords,
4709                          &actual_dump_size_in_dwords);
4710     }
4711 
4712     /* CDUT pages are ordered as follows:
4713      * - PF init pages (not dumped)
4714      * - PF work pages
4715      * - For each VF in the PF:
4716      *   - VF init pages (not dumped)
4717      *   - VF work pages
4718      */
4719     if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUT)) {
4720         /* Dump task PF pages */
4721         start_page_id = clients[ILT_CLI_CDUT].first.val +
4722             cdut_pf_init_pages - pf_start_line;
4723         qed_ilt_dump_pages_range(dump_buf, &offset, &continue_dump,
4724                      start_page_id, cdut_pf_work_pages,
4725                      ilt_pages, dump_page_ids,
4726                      buf_size_in_dwords,
4727                      &actual_dump_size_in_dwords);
4728 
4729         /* Dump task VF pages */
4730         start_page_id = clients[ILT_CLI_CDUT].first.val +
4731             cdut_pf_pages + cdut_vf_init_pages - pf_start_line;
4732         for (i = 0; i < p_hwfn->p_cxt_mngr->vf_count;
4733              i++, start_page_id += cdut_vf_pages)
4734             qed_ilt_dump_pages_range(dump_buf, &offset,
4735                          &continue_dump, start_page_id,
4736                          cdut_vf_work_pages, ilt_pages,
4737                          dump_page_ids,
4738                          buf_size_in_dwords,
4739                          &actual_dump_size_in_dwords);
4740     }
4741 
4742     /*Dump Searcher pages */
4743     if (clients[ILT_CLI_SRC].active) {
4744         start_page_id = clients[ILT_CLI_SRC].first.val - pf_start_line;
4745         src_pages = clients[ILT_CLI_SRC].last.val -
4746             clients[ILT_CLI_SRC].first.val + 1;
4747         qed_ilt_dump_pages_range(dump_buf, &offset, &continue_dump,
4748                      start_page_id, src_pages, ilt_pages,
4749                      dump_page_ids, buf_size_in_dwords,
4750                      &actual_dump_size_in_dwords);
4751     }
4752 
4753     /* Overwrite size param */
4754     if (update_size) {
4755         u32 section_size = (*dump == continue_dump) ?
4756             offset - base_data_offset :
4757             actual_dump_size_in_dwords - base_data_offset;
4758         if (section_size > 0)
4759             qed_dump_num_param(dump_buf + size_param_offset,
4760                        *dump, "size", section_size);
4761         else if ((section_size == 0) && (*dump != continue_dump))
4762             actual_dump_size_in_dwords -=
4763                 section_header_and_param_size;
4764     }
4765 
4766     *dump = continue_dump;
4767     *given_offset = offset;
4768     *given_actual_dump_size_in_dwords = actual_dump_size_in_dwords;
4769 
4770     return offset;
4771 }
4772 
4773 /* Dumps a section containing the global parameters.
4774  * Part of ilt dump process
4775  * Returns the dumped size in dwords.
4776  */
4777 static u32
4778 qed_ilt_dump_dump_common_global_params(struct qed_hwfn *p_hwfn,
4779                        struct qed_ptt *p_ptt,
4780                        u32 *dump_buf,
4781                        bool dump,
4782                        u32 cduc_page_size,
4783                        u32 conn_ctx_size,
4784                        u32 cdut_page_size,
4785                        u32 *full_dump_size_param_offset,
4786                        u32 *actual_dump_size_param_offset)
4787 {
4788     struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
4789     u32 offset = 0;
4790 
4791     offset += qed_dump_common_global_params(p_hwfn, p_ptt,
4792                         dump_buf + offset,
4793                         dump, 30);
4794     offset += qed_dump_str_param(dump_buf + offset,
4795                      dump,
4796                      "dump-type", "ilt-dump");
4797     offset += qed_dump_num_param(dump_buf + offset,
4798                      dump,
4799                      "cduc-page-size",
4800                      cduc_page_size);
4801     offset += qed_dump_num_param(dump_buf + offset,
4802                      dump,
4803                      "cduc-first-page-id",
4804                      clients[ILT_CLI_CDUC].first.val);
4805     offset += qed_dump_num_param(dump_buf + offset,
4806                      dump,
4807                      "cduc-last-page-id",
4808                      clients[ILT_CLI_CDUC].last.val);
4809     offset += qed_dump_num_param(dump_buf + offset,
4810                      dump,
4811                      "cduc-num-pf-pages",
4812                      clients[ILT_CLI_CDUC].pf_total_lines);
4813     offset += qed_dump_num_param(dump_buf + offset,
4814                      dump,
4815                      "cduc-num-vf-pages",
4816                      clients[ILT_CLI_CDUC].vf_total_lines);
4817     offset += qed_dump_num_param(dump_buf + offset,
4818                      dump,
4819                      "max-conn-ctx-size",
4820                      conn_ctx_size);
4821     offset += qed_dump_num_param(dump_buf + offset,
4822                      dump,
4823                      "cdut-page-size",
4824                      cdut_page_size);
4825     offset += qed_dump_num_param(dump_buf + offset,
4826                      dump,
4827                      "cdut-first-page-id",
4828                      clients[ILT_CLI_CDUT].first.val);
4829     offset += qed_dump_num_param(dump_buf + offset,
4830                      dump,
4831                      "cdut-last-page-id",
4832                      clients[ILT_CLI_CDUT].last.val);
4833     offset += qed_dump_num_param(dump_buf + offset,
4834                      dump,
4835                      "cdut-num-pf-init-pages",
4836                      qed_get_cdut_num_pf_init_pages(p_hwfn));
4837     offset += qed_dump_num_param(dump_buf + offset,
4838                      dump,
4839                      "cdut-num-vf-init-pages",
4840                      qed_get_cdut_num_vf_init_pages(p_hwfn));
4841     offset += qed_dump_num_param(dump_buf + offset,
4842                      dump,
4843                      "cdut-num-pf-work-pages",
4844                      qed_get_cdut_num_pf_work_pages(p_hwfn));
4845     offset += qed_dump_num_param(dump_buf + offset,
4846                      dump,
4847                      "cdut-num-vf-work-pages",
4848                      qed_get_cdut_num_vf_work_pages(p_hwfn));
4849     offset += qed_dump_num_param(dump_buf + offset,
4850                      dump,
4851                      "max-task-ctx-size",
4852                      p_hwfn->p_cxt_mngr->task_ctx_size);
4853     offset += qed_dump_num_param(dump_buf + offset,
4854                      dump,
4855                      "first-vf-id-in-pf",
4856                      p_hwfn->p_cxt_mngr->first_vf_in_pf);
4857     offset += qed_dump_num_param(dump_buf + offset,
4858                      dump,
4859                      "num-vfs-in-pf",
4860                      p_hwfn->p_cxt_mngr->vf_count);
4861     offset += qed_dump_num_param(dump_buf + offset,
4862                      dump,
4863                      "ptr-size-bytes",
4864                      sizeof(void *));
4865     offset += qed_dump_num_param(dump_buf + offset,
4866                      dump,
4867                      "pf-start-line",
4868                      p_hwfn->p_cxt_mngr->pf_start_line);
4869     offset += qed_dump_num_param(dump_buf + offset,
4870                      dump,
4871                      "page-mem-desc-size-dwords",
4872                      PAGE_MEM_DESC_SIZE_DWORDS);
4873     offset += qed_dump_num_param(dump_buf + offset,
4874                      dump,
4875                      "ilt-shadow-size",
4876                      p_hwfn->p_cxt_mngr->ilt_shadow_size);
4877 
4878     *full_dump_size_param_offset = offset;
4879 
4880     offset += qed_dump_num_param(dump_buf + offset,
4881                      dump, "dump-size-full", 0);
4882 
4883     *actual_dump_size_param_offset = offset;
4884 
4885     offset += qed_dump_num_param(dump_buf + offset,
4886                      dump,
4887                      "dump-size-actual", 0);
4888     offset += qed_dump_num_param(dump_buf + offset,
4889                      dump,
4890                      "iscsi_task_pages",
4891                      p_hwfn->p_cxt_mngr->iscsi_task_pages);
4892     offset += qed_dump_num_param(dump_buf + offset,
4893                      dump,
4894                      "fcoe_task_pages",
4895                      p_hwfn->p_cxt_mngr->fcoe_task_pages);
4896     offset += qed_dump_num_param(dump_buf + offset,
4897                      dump,
4898                      "roce_task_pages",
4899                      p_hwfn->p_cxt_mngr->roce_task_pages);
4900     offset += qed_dump_num_param(dump_buf + offset,
4901                      dump,
4902                      "eth_task_pages",
4903                      p_hwfn->p_cxt_mngr->eth_task_pages);
4904     offset += qed_dump_num_param(dump_buf + offset,
4905                       dump,
4906                       "src-first-page-id",
4907                       clients[ILT_CLI_SRC].first.val);
4908     offset += qed_dump_num_param(dump_buf + offset,
4909                      dump,
4910                      "src-last-page-id",
4911                      clients[ILT_CLI_SRC].last.val);
4912     offset += qed_dump_num_param(dump_buf + offset,
4913                      dump,
4914                      "src-is-active",
4915                      clients[ILT_CLI_SRC].active);
4916 
4917     /* Additional/Less parameters require matching of number in call to
4918      * dump_common_global_params()
4919      */
4920 
4921     return offset;
4922 }
4923 
4924 /* Dump section containing number of PF CIDs per connection type.
4925  * Part of ilt dump process.
4926  * Returns the dumped size in dwords.
4927  */
4928 static u32 qed_ilt_dump_dump_num_pf_cids(struct qed_hwfn *p_hwfn,
4929                      u32 *dump_buf,
4930                      bool dump, u32 *valid_conn_pf_cids)
4931 {
4932     u32 num_pf_cids = 0;
4933     u32 offset = 0;
4934     u8 conn_type;
4935 
4936     offset += qed_dump_section_hdr(dump_buf + offset,
4937                        dump, "num_pf_cids_per_conn_type", 1);
4938     offset += qed_dump_num_param(dump_buf + offset,
4939                      dump, "size", NUM_OF_CONNECTION_TYPES);
4940     for (conn_type = 0, *valid_conn_pf_cids = 0;
4941          conn_type < NUM_OF_CONNECTION_TYPES; conn_type++, offset++) {
4942         num_pf_cids = p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cid_count;
4943         if (dump)
4944             *(dump_buf + offset) = num_pf_cids;
4945         *valid_conn_pf_cids += num_pf_cids;
4946     }
4947 
4948     return offset;
4949 }
4950 
4951 /* Dump section containing number of VF CIDs per connection type
4952  * Part of ilt dump process.
4953  * Returns the dumped size in dwords.
4954  */
4955 static u32 qed_ilt_dump_dump_num_vf_cids(struct qed_hwfn *p_hwfn,
4956                      u32 *dump_buf,
4957                      bool dump, u32 *valid_conn_vf_cids)
4958 {
4959     u32 num_vf_cids = 0;
4960     u32 offset = 0;
4961     u8 conn_type;
4962 
4963     offset += qed_dump_section_hdr(dump_buf + offset, dump,
4964                        "num_vf_cids_per_conn_type", 1);
4965     offset += qed_dump_num_param(dump_buf + offset,
4966                      dump, "size", NUM_OF_CONNECTION_TYPES);
4967     for (conn_type = 0, *valid_conn_vf_cids = 0;
4968          conn_type < NUM_OF_CONNECTION_TYPES; conn_type++, offset++) {
4969         num_vf_cids =
4970             p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cids_per_vf;
4971         if (dump)
4972             *(dump_buf + offset) = num_vf_cids;
4973         *valid_conn_vf_cids += num_vf_cids;
4974     }
4975 
4976     return offset;
4977 }
4978 
4979 /* Performs ILT Dump to the specified buffer.
4980  * buf_size_in_dwords - The dumped buffer size.
4981  * Returns the dumped size in dwords.
4982  */
4983 static u32 qed_ilt_dump(struct qed_hwfn *p_hwfn,
4984             struct qed_ptt *p_ptt,
4985             u32 *dump_buf, u32 buf_size_in_dwords, bool dump)
4986 {
4987 #if ((!defined VMWARE) && (!defined UEFI))
4988     struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
4989 #endif
4990     u32 valid_conn_vf_cids = 0,
4991         valid_conn_vf_pages, offset = 0, real_dumped_size = 0;
4992     u32 valid_conn_pf_cids = 0, valid_conn_pf_pages, num_pages;
4993     u32 num_cids_per_page, conn_ctx_size;
4994     u32 cduc_page_size, cdut_page_size;
4995     u32 actual_dump_size_in_dwords = 0;
4996     struct phys_mem_desc *ilt_pages;
4997     u32 actul_dump_off = 0;
4998     u32 last_section_size;
4999     u32 full_dump_off = 0;
5000     u32 section_size = 0;
5001     bool continue_dump;
5002     u32 page_id;
5003 
5004     last_section_size = qed_dump_last_section(NULL, 0, false);
5005     cduc_page_size = 1 <<
5006         (clients[ILT_CLI_CDUC].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN);
5007     cdut_page_size = 1 <<
5008         (clients[ILT_CLI_CDUT].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN);
5009     conn_ctx_size = p_hwfn->p_cxt_mngr->conn_ctx_size;
5010     num_cids_per_page = (int)(cduc_page_size / conn_ctx_size);
5011     ilt_pages = p_hwfn->p_cxt_mngr->ilt_shadow;
5012     continue_dump = dump;
5013 
5014     /* if need to dump then save memory for the last section
5015      * (last section calculates CRC of dumped data)
5016      */
5017     if (dump) {
5018         if (buf_size_in_dwords >= last_section_size) {
5019             buf_size_in_dwords -= last_section_size;
5020         } else {
5021             continue_dump = false;
5022             actual_dump_size_in_dwords = offset;
5023         }
5024     }
5025 
5026     /* Dump global params */
5027 
5028     /* if need to dump then first check that there is enough memory
5029      * in dumped buffer for this section calculate the size of this
5030      * section without dumping. if there is not enough memory - then
5031      * stop the dumping.
5032      */
5033     if (continue_dump) {
5034         section_size =
5035             qed_ilt_dump_dump_common_global_params(p_hwfn,
5036                                    p_ptt,
5037                                    NULL,
5038                                    false,
5039                                    cduc_page_size,
5040                                    conn_ctx_size,
5041                                    cdut_page_size,
5042                                    &full_dump_off,
5043                                    &actul_dump_off);
5044         if (offset + section_size > buf_size_in_dwords) {
5045             continue_dump = false;
5046             actual_dump_size_in_dwords = offset;
5047         }
5048     }
5049 
5050     offset += qed_ilt_dump_dump_common_global_params(p_hwfn,
5051                              p_ptt,
5052                              dump_buf + offset,
5053                              continue_dump,
5054                              cduc_page_size,
5055                              conn_ctx_size,
5056                              cdut_page_size,
5057                              &full_dump_off,
5058                              &actul_dump_off);
5059 
5060     /* Dump section containing number of PF CIDs per connection type
5061      * If need to dump then first check that there is enough memory in
5062      * dumped buffer for this section.
5063      */
5064     if (continue_dump) {
5065         section_size =
5066             qed_ilt_dump_dump_num_pf_cids(p_hwfn,
5067                               NULL,
5068                               false,
5069                               &valid_conn_pf_cids);
5070         if (offset + section_size > buf_size_in_dwords) {
5071             continue_dump = false;
5072             actual_dump_size_in_dwords = offset;
5073         }
5074     }
5075 
5076     offset += qed_ilt_dump_dump_num_pf_cids(p_hwfn,
5077                         dump_buf + offset,
5078                         continue_dump,
5079                         &valid_conn_pf_cids);
5080 
5081     /* Dump section containing number of VF CIDs per connection type
5082      * If need to dump then first check that there is enough memory in
5083      * dumped buffer for this section.
5084      */
5085     if (continue_dump) {
5086         section_size =
5087             qed_ilt_dump_dump_num_vf_cids(p_hwfn,
5088                               NULL,
5089                               false,
5090                               &valid_conn_vf_cids);
5091         if (offset + section_size > buf_size_in_dwords) {
5092             continue_dump = false;
5093             actual_dump_size_in_dwords = offset;
5094         }
5095     }
5096 
5097     offset += qed_ilt_dump_dump_num_vf_cids(p_hwfn,
5098                         dump_buf + offset,
5099                         continue_dump,
5100                         &valid_conn_vf_cids);
5101 
5102     /* Dump section containing physical memory descriptors for each
5103      * ILT page.
5104      */
5105     num_pages = p_hwfn->p_cxt_mngr->ilt_shadow_size;
5106 
5107     /* If need to dump then first check that there is enough memory
5108      * in dumped buffer for the section header.
5109      */
5110     if (continue_dump) {
5111         section_size = qed_dump_section_hdr(NULL,
5112                             false,
5113                             "ilt_page_desc",
5114                             1) +
5115             qed_dump_num_param(NULL,
5116                        false,
5117                        "size",
5118                        num_pages * PAGE_MEM_DESC_SIZE_DWORDS);
5119         if (offset + section_size > buf_size_in_dwords) {
5120             continue_dump = false;
5121             actual_dump_size_in_dwords = offset;
5122         }
5123     }
5124 
5125     offset += qed_dump_section_hdr(dump_buf + offset,
5126                        continue_dump, "ilt_page_desc", 1);
5127     offset += qed_dump_num_param(dump_buf + offset,
5128                      continue_dump,
5129                      "size",
5130                      num_pages * PAGE_MEM_DESC_SIZE_DWORDS);
5131 
5132     /* Copy memory descriptors to dump buffer
5133      * If need to dump then dump till the dump buffer size
5134      */
5135     if (continue_dump) {
5136         for (page_id = 0; page_id < num_pages;
5137              page_id++, offset += PAGE_MEM_DESC_SIZE_DWORDS) {
5138             if (continue_dump &&
5139                 (offset + PAGE_MEM_DESC_SIZE_DWORDS <=
5140                  buf_size_in_dwords)) {
5141                 memcpy(dump_buf + offset,
5142                        &ilt_pages[page_id],
5143                        DWORDS_TO_BYTES
5144                        (PAGE_MEM_DESC_SIZE_DWORDS));
5145             } else {
5146                 if (continue_dump) {
5147                     continue_dump = false;
5148                     actual_dump_size_in_dwords = offset;
5149                 }
5150             }
5151         }
5152     } else {
5153         offset += num_pages * PAGE_MEM_DESC_SIZE_DWORDS;
5154     }
5155 
5156     valid_conn_pf_pages = DIV_ROUND_UP(valid_conn_pf_cids,
5157                        num_cids_per_page);
5158     valid_conn_vf_pages = DIV_ROUND_UP(valid_conn_vf_cids,
5159                        num_cids_per_page);
5160 
5161     /* Dump ILT pages IDs */
5162     qed_ilt_dump_pages_section(p_hwfn, dump_buf, &offset, &continue_dump,
5163                    valid_conn_pf_pages, valid_conn_vf_pages,
5164                    ilt_pages, true, buf_size_in_dwords,
5165                    &actual_dump_size_in_dwords);
5166 
5167     /* Dump ILT pages memory */
5168     qed_ilt_dump_pages_section(p_hwfn, dump_buf, &offset, &continue_dump,
5169                    valid_conn_pf_pages, valid_conn_vf_pages,
5170                    ilt_pages, false, buf_size_in_dwords,
5171                    &actual_dump_size_in_dwords);
5172 
5173     real_dumped_size =
5174         (continue_dump == dump) ? offset : actual_dump_size_in_dwords;
5175     qed_dump_num_param(dump_buf + full_dump_off, dump,
5176                "full-dump-size", offset + last_section_size);
5177     qed_dump_num_param(dump_buf + actul_dump_off,
5178                dump,
5179                "actual-dump-size",
5180                real_dumped_size + last_section_size);
5181 
5182     /* Dump last section */
5183     real_dumped_size += qed_dump_last_section(dump_buf,
5184                           real_dumped_size, dump);
5185 
5186     return real_dumped_size;
5187 }
5188 
5189 /***************************** Public Functions *******************************/
5190 
5191 enum dbg_status qed_dbg_set_bin_ptr(struct qed_hwfn *p_hwfn,
5192                     const u8 * const bin_ptr)
5193 {
5194     struct bin_buffer_hdr *buf_hdrs = (struct bin_buffer_hdr *)bin_ptr;
5195     u8 buf_id;
5196 
5197     /* Convert binary data to debug arrays */
5198     for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++)
5199         qed_set_dbg_bin_buf(p_hwfn,
5200                     buf_id,
5201                     (u32 *)(bin_ptr + buf_hdrs[buf_id].offset),
5202                     buf_hdrs[buf_id].length);
5203 
5204     return DBG_STATUS_OK;
5205 }
5206 
5207 static enum dbg_status qed_dbg_set_app_ver(u32 ver)
5208 {
5209     if (ver < TOOLS_VERSION)
5210         return DBG_STATUS_UNSUPPORTED_APP_VERSION;
5211 
5212     s_app_ver = ver;
5213 
5214     return DBG_STATUS_OK;
5215 }
5216 
5217 bool qed_read_fw_info(struct qed_hwfn *p_hwfn,
5218               struct qed_ptt *p_ptt, struct fw_info *fw_info)
5219 {
5220     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5221     u8 storm_id;
5222 
5223     for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
5224         struct storm_defs *storm = &s_storm_defs[storm_id];
5225 
5226         /* Skip Storm if it's in reset */
5227         if (dev_data->block_in_reset[storm->sem_block_id])
5228             continue;
5229 
5230         /* Read FW info for the current Storm */
5231         qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, fw_info);
5232 
5233         return true;
5234     }
5235 
5236     return false;
5237 }
5238 
5239 enum dbg_status qed_dbg_grc_config(struct qed_hwfn *p_hwfn,
5240                    enum dbg_grc_params grc_param, u32 val)
5241 {
5242     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5243     enum dbg_status status;
5244     int i;
5245 
5246     DP_VERBOSE(p_hwfn,
5247            QED_MSG_DEBUG,
5248            "dbg_grc_config: paramId = %d, val = %d\n", grc_param, val);
5249 
5250     status = qed_dbg_dev_init(p_hwfn);
5251     if (status != DBG_STATUS_OK)
5252         return status;
5253 
5254     /* Initializes the GRC parameters (if not initialized). Needed in order
5255      * to set the default parameter values for the first time.
5256      */
5257     qed_dbg_grc_init_params(p_hwfn);
5258 
5259     if (grc_param >= MAX_DBG_GRC_PARAMS)
5260         return DBG_STATUS_INVALID_ARGS;
5261     if (val < s_grc_param_defs[grc_param].min ||
5262         val > s_grc_param_defs[grc_param].max)
5263         return DBG_STATUS_INVALID_ARGS;
5264 
5265     if (s_grc_param_defs[grc_param].is_preset) {
5266         /* Preset param */
5267 
5268         /* Disabling a preset is not allowed. Call
5269          * dbg_grc_set_params_default instead.
5270          */
5271         if (!val)
5272             return DBG_STATUS_INVALID_ARGS;
5273 
5274         /* Update all params with the preset values */
5275         for (i = 0; i < MAX_DBG_GRC_PARAMS; i++) {
5276             struct grc_param_defs *defs = &s_grc_param_defs[i];
5277             u32 preset_val;
5278             /* Skip persistent params */
5279             if (defs->is_persistent)
5280                 continue;
5281 
5282             /* Find preset value */
5283             if (grc_param == DBG_GRC_PARAM_EXCLUDE_ALL)
5284                 preset_val =
5285                     defs->exclude_all_preset_val;
5286             else if (grc_param == DBG_GRC_PARAM_CRASH)
5287                 preset_val =
5288                     defs->crash_preset_val[dev_data->chip_id];
5289             else
5290                 return DBG_STATUS_INVALID_ARGS;
5291 
5292             qed_grc_set_param(p_hwfn, i, preset_val);
5293         }
5294     } else {
5295         /* Regular param - set its value */
5296         qed_grc_set_param(p_hwfn, grc_param, val);
5297     }
5298 
5299     return DBG_STATUS_OK;
5300 }
5301 
5302 /* Assign default GRC param values */
5303 void qed_dbg_grc_set_params_default(struct qed_hwfn *p_hwfn)
5304 {
5305     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5306     u32 i;
5307 
5308     for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
5309         if (!s_grc_param_defs[i].is_persistent)
5310             dev_data->grc.param_val[i] =
5311                 s_grc_param_defs[i].default_val[dev_data->chip_id];
5312 }
5313 
5314 enum dbg_status qed_dbg_grc_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5315                           struct qed_ptt *p_ptt,
5316                           u32 *buf_size)
5317 {
5318     enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5319 
5320     *buf_size = 0;
5321 
5322     if (status != DBG_STATUS_OK)
5323         return status;
5324 
5325     if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
5326         !p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr ||
5327         !p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr ||
5328         !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||
5329         !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)
5330         return DBG_STATUS_DBG_ARRAY_NOT_SET;
5331 
5332     return qed_grc_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5333 }
5334 
5335 enum dbg_status qed_dbg_grc_dump(struct qed_hwfn *p_hwfn,
5336                  struct qed_ptt *p_ptt,
5337                  u32 *dump_buf,
5338                  u32 buf_size_in_dwords,
5339                  u32 *num_dumped_dwords)
5340 {
5341     u32 needed_buf_size_in_dwords;
5342     enum dbg_status status;
5343 
5344     *num_dumped_dwords = 0;
5345 
5346     status = qed_dbg_grc_get_dump_buf_size(p_hwfn,
5347                            p_ptt,
5348                            &needed_buf_size_in_dwords);
5349     if (status != DBG_STATUS_OK)
5350         return status;
5351 
5352     if (buf_size_in_dwords < needed_buf_size_in_dwords)
5353         return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5354 
5355     /* Doesn't do anything, needed for compile time asserts */
5356     qed_static_asserts();
5357 
5358     /* GRC Dump */
5359     status = qed_grc_dump(p_hwfn, p_ptt, dump_buf, true, num_dumped_dwords);
5360 
5361     /* Revert GRC params to their default */
5362     qed_dbg_grc_set_params_default(p_hwfn);
5363 
5364     return status;
5365 }
5366 
5367 enum dbg_status qed_dbg_idle_chk_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5368                            struct qed_ptt *p_ptt,
5369                            u32 *buf_size)
5370 {
5371     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5372     struct idle_chk_data *idle_chk = &dev_data->idle_chk;
5373     enum dbg_status status;
5374 
5375     *buf_size = 0;
5376 
5377     status = qed_dbg_dev_init(p_hwfn);
5378     if (status != DBG_STATUS_OK)
5379         return status;
5380 
5381     if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
5382         !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr ||
5383         !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr ||
5384         !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr)
5385         return DBG_STATUS_DBG_ARRAY_NOT_SET;
5386 
5387     if (!idle_chk->buf_size_set) {
5388         idle_chk->buf_size = qed_idle_chk_dump(p_hwfn,
5389                                p_ptt, NULL, false);
5390         idle_chk->buf_size_set = true;
5391     }
5392 
5393     *buf_size = idle_chk->buf_size;
5394 
5395     return DBG_STATUS_OK;
5396 }
5397 
5398 enum dbg_status qed_dbg_idle_chk_dump(struct qed_hwfn *p_hwfn,
5399                       struct qed_ptt *p_ptt,
5400                       u32 *dump_buf,
5401                       u32 buf_size_in_dwords,
5402                       u32 *num_dumped_dwords)
5403 {
5404     u32 needed_buf_size_in_dwords;
5405     enum dbg_status status;
5406 
5407     *num_dumped_dwords = 0;
5408 
5409     status = qed_dbg_idle_chk_get_dump_buf_size(p_hwfn,
5410                             p_ptt,
5411                             &needed_buf_size_in_dwords);
5412     if (status != DBG_STATUS_OK)
5413         return status;
5414 
5415     if (buf_size_in_dwords < needed_buf_size_in_dwords)
5416         return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5417 
5418     /* Update reset state */
5419     qed_grc_unreset_blocks(p_hwfn, p_ptt, true);
5420     qed_update_blocks_reset_state(p_hwfn, p_ptt);
5421 
5422     /* Idle Check Dump */
5423     *num_dumped_dwords = qed_idle_chk_dump(p_hwfn, p_ptt, dump_buf, true);
5424 
5425     /* Revert GRC params to their default */
5426     qed_dbg_grc_set_params_default(p_hwfn);
5427 
5428     return DBG_STATUS_OK;
5429 }
5430 
5431 enum dbg_status qed_dbg_mcp_trace_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5432                             struct qed_ptt *p_ptt,
5433                             u32 *buf_size)
5434 {
5435     enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5436 
5437     *buf_size = 0;
5438 
5439     if (status != DBG_STATUS_OK)
5440         return status;
5441 
5442     return qed_mcp_trace_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5443 }
5444 
5445 enum dbg_status qed_dbg_mcp_trace_dump(struct qed_hwfn *p_hwfn,
5446                        struct qed_ptt *p_ptt,
5447                        u32 *dump_buf,
5448                        u32 buf_size_in_dwords,
5449                        u32 *num_dumped_dwords)
5450 {
5451     u32 needed_buf_size_in_dwords;
5452     enum dbg_status status;
5453 
5454     status =
5455         qed_dbg_mcp_trace_get_dump_buf_size(p_hwfn,
5456                             p_ptt,
5457                             &needed_buf_size_in_dwords);
5458     if (status != DBG_STATUS_OK && status !=
5459         DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
5460         return status;
5461 
5462     if (buf_size_in_dwords < needed_buf_size_in_dwords)
5463         return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5464 
5465     /* Update reset state */
5466     qed_update_blocks_reset_state(p_hwfn, p_ptt);
5467 
5468     /* Perform dump */
5469     status = qed_mcp_trace_dump(p_hwfn,
5470                     p_ptt, dump_buf, true, num_dumped_dwords);
5471 
5472     /* Revert GRC params to their default */
5473     qed_dbg_grc_set_params_default(p_hwfn);
5474 
5475     return status;
5476 }
5477 
5478 enum dbg_status qed_dbg_reg_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5479                            struct qed_ptt *p_ptt,
5480                            u32 *buf_size)
5481 {
5482     enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5483 
5484     *buf_size = 0;
5485 
5486     if (status != DBG_STATUS_OK)
5487         return status;
5488 
5489     return qed_reg_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5490 }
5491 
5492 enum dbg_status qed_dbg_reg_fifo_dump(struct qed_hwfn *p_hwfn,
5493                       struct qed_ptt *p_ptt,
5494                       u32 *dump_buf,
5495                       u32 buf_size_in_dwords,
5496                       u32 *num_dumped_dwords)
5497 {
5498     u32 needed_buf_size_in_dwords;
5499     enum dbg_status status;
5500 
5501     *num_dumped_dwords = 0;
5502 
5503     status = qed_dbg_reg_fifo_get_dump_buf_size(p_hwfn,
5504                             p_ptt,
5505                             &needed_buf_size_in_dwords);
5506     if (status != DBG_STATUS_OK)
5507         return status;
5508 
5509     if (buf_size_in_dwords < needed_buf_size_in_dwords)
5510         return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5511 
5512     /* Update reset state */
5513     qed_update_blocks_reset_state(p_hwfn, p_ptt);
5514 
5515     status = qed_reg_fifo_dump(p_hwfn,
5516                    p_ptt, dump_buf, true, num_dumped_dwords);
5517 
5518     /* Revert GRC params to their default */
5519     qed_dbg_grc_set_params_default(p_hwfn);
5520 
5521     return status;
5522 }
5523 
5524 enum dbg_status qed_dbg_igu_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5525                            struct qed_ptt *p_ptt,
5526                            u32 *buf_size)
5527 {
5528     enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5529 
5530     *buf_size = 0;
5531 
5532     if (status != DBG_STATUS_OK)
5533         return status;
5534 
5535     return qed_igu_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5536 }
5537 
5538 enum dbg_status qed_dbg_igu_fifo_dump(struct qed_hwfn *p_hwfn,
5539                       struct qed_ptt *p_ptt,
5540                       u32 *dump_buf,
5541                       u32 buf_size_in_dwords,
5542                       u32 *num_dumped_dwords)
5543 {
5544     u32 needed_buf_size_in_dwords;
5545     enum dbg_status status;
5546 
5547     *num_dumped_dwords = 0;
5548 
5549     status = qed_dbg_igu_fifo_get_dump_buf_size(p_hwfn,
5550                             p_ptt,
5551                             &needed_buf_size_in_dwords);
5552     if (status != DBG_STATUS_OK)
5553         return status;
5554 
5555     if (buf_size_in_dwords < needed_buf_size_in_dwords)
5556         return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5557 
5558     /* Update reset state */
5559     qed_update_blocks_reset_state(p_hwfn, p_ptt);
5560 
5561     status = qed_igu_fifo_dump(p_hwfn,
5562                    p_ptt, dump_buf, true, num_dumped_dwords);
5563     /* Revert GRC params to their default */
5564     qed_dbg_grc_set_params_default(p_hwfn);
5565 
5566     return status;
5567 }
5568 
5569 enum dbg_status
5570 qed_dbg_protection_override_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5571                           struct qed_ptt *p_ptt,
5572                           u32 *buf_size)
5573 {
5574     enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5575 
5576     *buf_size = 0;
5577 
5578     if (status != DBG_STATUS_OK)
5579         return status;
5580 
5581     return qed_protection_override_dump(p_hwfn,
5582                         p_ptt, NULL, false, buf_size);
5583 }
5584 
5585 enum dbg_status qed_dbg_protection_override_dump(struct qed_hwfn *p_hwfn,
5586                          struct qed_ptt *p_ptt,
5587                          u32 *dump_buf,
5588                          u32 buf_size_in_dwords,
5589                          u32 *num_dumped_dwords)
5590 {
5591     u32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords;
5592     enum dbg_status status;
5593 
5594     *num_dumped_dwords = 0;
5595 
5596     status =
5597         qed_dbg_protection_override_get_dump_buf_size(p_hwfn,
5598                                   p_ptt,
5599                                   p_size);
5600     if (status != DBG_STATUS_OK)
5601         return status;
5602 
5603     if (buf_size_in_dwords < needed_buf_size_in_dwords)
5604         return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5605 
5606     /* Update reset state */
5607     qed_update_blocks_reset_state(p_hwfn, p_ptt);
5608 
5609     status = qed_protection_override_dump(p_hwfn,
5610                           p_ptt,
5611                           dump_buf,
5612                           true, num_dumped_dwords);
5613 
5614     /* Revert GRC params to their default */
5615     qed_dbg_grc_set_params_default(p_hwfn);
5616 
5617     return status;
5618 }
5619 
5620 enum dbg_status qed_dbg_fw_asserts_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5621                              struct qed_ptt *p_ptt,
5622                              u32 *buf_size)
5623 {
5624     enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5625 
5626     *buf_size = 0;
5627 
5628     if (status != DBG_STATUS_OK)
5629         return status;
5630 
5631     /* Update reset state */
5632     qed_update_blocks_reset_state(p_hwfn, p_ptt);
5633 
5634     *buf_size = qed_fw_asserts_dump(p_hwfn, p_ptt, NULL, false);
5635 
5636     return DBG_STATUS_OK;
5637 }
5638 
5639 enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn *p_hwfn,
5640                     struct qed_ptt *p_ptt,
5641                     u32 *dump_buf,
5642                     u32 buf_size_in_dwords,
5643                     u32 *num_dumped_dwords)
5644 {
5645     u32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords;
5646     enum dbg_status status;
5647 
5648     *num_dumped_dwords = 0;
5649 
5650     status =
5651         qed_dbg_fw_asserts_get_dump_buf_size(p_hwfn,
5652                              p_ptt,
5653                              p_size);
5654     if (status != DBG_STATUS_OK)
5655         return status;
5656 
5657     if (buf_size_in_dwords < needed_buf_size_in_dwords)
5658         return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5659 
5660     *num_dumped_dwords = qed_fw_asserts_dump(p_hwfn, p_ptt, dump_buf, true);
5661 
5662     /* Revert GRC params to their default */
5663     qed_dbg_grc_set_params_default(p_hwfn);
5664 
5665     return DBG_STATUS_OK;
5666 }
5667 
5668 static enum dbg_status qed_dbg_ilt_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5669                              struct qed_ptt *p_ptt,
5670                              u32 *buf_size)
5671 {
5672     enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5673 
5674     *buf_size = 0;
5675 
5676     if (status != DBG_STATUS_OK)
5677         return status;
5678 
5679     *buf_size = qed_ilt_dump(p_hwfn, p_ptt, NULL, 0, false);
5680 
5681     return DBG_STATUS_OK;
5682 }
5683 
5684 static enum dbg_status qed_dbg_ilt_dump(struct qed_hwfn *p_hwfn,
5685                     struct qed_ptt *p_ptt,
5686                     u32 *dump_buf,
5687                     u32 buf_size_in_dwords,
5688                     u32 *num_dumped_dwords)
5689 {
5690     *num_dumped_dwords = qed_ilt_dump(p_hwfn,
5691                       p_ptt,
5692                       dump_buf, buf_size_in_dwords, true);
5693 
5694     /* Reveret GRC params to their default */
5695     qed_dbg_grc_set_params_default(p_hwfn);
5696 
5697     return DBG_STATUS_OK;
5698 }
5699 
5700 enum dbg_status qed_dbg_read_attn(struct qed_hwfn *p_hwfn,
5701                   struct qed_ptt *p_ptt,
5702                   enum block_id block_id,
5703                   enum dbg_attn_type attn_type,
5704                   bool clear_status,
5705                   struct dbg_attn_block_result *results)
5706 {
5707     enum dbg_status status = qed_dbg_dev_init(p_hwfn);
5708     u8 reg_idx, num_attn_regs, num_result_regs = 0;
5709     const struct dbg_attn_reg *attn_reg_arr;
5710 
5711     if (status != DBG_STATUS_OK)
5712         return status;
5713 
5714     if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
5715         !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||
5716         !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)
5717         return DBG_STATUS_DBG_ARRAY_NOT_SET;
5718 
5719     attn_reg_arr = qed_get_block_attn_regs(p_hwfn,
5720                            block_id,
5721                            attn_type, &num_attn_regs);
5722 
5723     for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
5724         const struct dbg_attn_reg *reg_data = &attn_reg_arr[reg_idx];
5725         struct dbg_attn_reg_result *reg_result;
5726         u32 sts_addr, sts_val;
5727         u16 modes_buf_offset;
5728         bool eval_mode;
5729 
5730         /* Check mode */
5731         eval_mode = GET_FIELD(reg_data->mode.data,
5732                       DBG_MODE_HDR_EVAL_MODE) > 0;
5733         modes_buf_offset = GET_FIELD(reg_data->mode.data,
5734                          DBG_MODE_HDR_MODES_BUF_OFFSET);
5735         if (eval_mode && !qed_is_mode_match(p_hwfn, &modes_buf_offset))
5736             continue;
5737 
5738         /* Mode match - read attention status register */
5739         sts_addr = DWORDS_TO_BYTES(clear_status ?
5740                        reg_data->sts_clr_address :
5741                        GET_FIELD(reg_data->data,
5742                              DBG_ATTN_REG_STS_ADDRESS));
5743         sts_val = qed_rd(p_hwfn, p_ptt, sts_addr);
5744         if (!sts_val)
5745             continue;
5746 
5747         /* Non-zero attention status - add to results */
5748         reg_result = &results->reg_results[num_result_regs];
5749         SET_FIELD(reg_result->data,
5750               DBG_ATTN_REG_RESULT_STS_ADDRESS, sts_addr);
5751         SET_FIELD(reg_result->data,
5752               DBG_ATTN_REG_RESULT_NUM_REG_ATTN,
5753               GET_FIELD(reg_data->data, DBG_ATTN_REG_NUM_REG_ATTN));
5754         reg_result->block_attn_offset = reg_data->block_attn_offset;
5755         reg_result->sts_val = sts_val;
5756         reg_result->mask_val = qed_rd(p_hwfn,
5757                           p_ptt,
5758                           DWORDS_TO_BYTES
5759                           (reg_data->mask_address));
5760         num_result_regs++;
5761     }
5762 
5763     results->block_id = (u8)block_id;
5764     results->names_offset =
5765         qed_get_block_attn_data(p_hwfn, block_id, attn_type)->names_offset;
5766     SET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE, attn_type);
5767     SET_FIELD(results->data,
5768           DBG_ATTN_BLOCK_RESULT_NUM_REGS, num_result_regs);
5769 
5770     return DBG_STATUS_OK;
5771 }
5772 
5773 /******************************* Data Types **********************************/
5774 
5775 /* REG fifo element */
5776 struct reg_fifo_element {
5777     u64 data;
5778 #define REG_FIFO_ELEMENT_ADDRESS_SHIFT      0
5779 #define REG_FIFO_ELEMENT_ADDRESS_MASK       0x7fffff
5780 #define REG_FIFO_ELEMENT_ACCESS_SHIFT       23
5781 #define REG_FIFO_ELEMENT_ACCESS_MASK        0x1
5782 #define REG_FIFO_ELEMENT_PF_SHIFT       24
5783 #define REG_FIFO_ELEMENT_PF_MASK        0xf
5784 #define REG_FIFO_ELEMENT_VF_SHIFT       28
5785 #define REG_FIFO_ELEMENT_VF_MASK        0xff
5786 #define REG_FIFO_ELEMENT_PORT_SHIFT     36
5787 #define REG_FIFO_ELEMENT_PORT_MASK      0x3
5788 #define REG_FIFO_ELEMENT_PRIVILEGE_SHIFT    38
5789 #define REG_FIFO_ELEMENT_PRIVILEGE_MASK     0x3
5790 #define REG_FIFO_ELEMENT_PROTECTION_SHIFT   40
5791 #define REG_FIFO_ELEMENT_PROTECTION_MASK    0x7
5792 #define REG_FIFO_ELEMENT_MASTER_SHIFT       43
5793 #define REG_FIFO_ELEMENT_MASTER_MASK        0xf
5794 #define REG_FIFO_ELEMENT_ERROR_SHIFT        47
5795 #define REG_FIFO_ELEMENT_ERROR_MASK     0x1f
5796 };
5797 
5798 /* REG fifo error element */
5799 struct reg_fifo_err {
5800     u32 err_code;
5801     const char *err_msg;
5802 };
5803 
5804 /* IGU fifo element */
5805 struct igu_fifo_element {
5806     u32 dword0;
5807 #define IGU_FIFO_ELEMENT_DWORD0_FID_SHIFT       0
5808 #define IGU_FIFO_ELEMENT_DWORD0_FID_MASK        0xff
5809 #define IGU_FIFO_ELEMENT_DWORD0_IS_PF_SHIFT     8
5810 #define IGU_FIFO_ELEMENT_DWORD0_IS_PF_MASK      0x1
5811 #define IGU_FIFO_ELEMENT_DWORD0_SOURCE_SHIFT        9
5812 #define IGU_FIFO_ELEMENT_DWORD0_SOURCE_MASK     0xf
5813 #define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_SHIFT      13
5814 #define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_MASK       0xf
5815 #define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_SHIFT      17
5816 #define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_MASK       0x7fff
5817     u32 dword1;
5818     u32 dword2;
5819 #define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_SHIFT    0
5820 #define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_MASK     0x1
5821 #define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_SHIFT      1
5822 #define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_MASK       0xffffffff
5823     u32 reserved;
5824 };
5825 
5826 struct igu_fifo_wr_data {
5827     u32 data;
5828 #define IGU_FIFO_WR_DATA_PROD_CONS_SHIFT        0
5829 #define IGU_FIFO_WR_DATA_PROD_CONS_MASK         0xffffff
5830 #define IGU_FIFO_WR_DATA_UPDATE_FLAG_SHIFT      24
5831 #define IGU_FIFO_WR_DATA_UPDATE_FLAG_MASK       0x1
5832 #define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_SHIFT    25
5833 #define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_MASK     0x3
5834 #define IGU_FIFO_WR_DATA_SEGMENT_SHIFT          27
5835 #define IGU_FIFO_WR_DATA_SEGMENT_MASK           0x1
5836 #define IGU_FIFO_WR_DATA_TIMER_MASK_SHIFT       28
5837 #define IGU_FIFO_WR_DATA_TIMER_MASK_MASK        0x1
5838 #define IGU_FIFO_WR_DATA_CMD_TYPE_SHIFT         31
5839 #define IGU_FIFO_WR_DATA_CMD_TYPE_MASK          0x1
5840 };
5841 
5842 struct igu_fifo_cleanup_wr_data {
5843     u32 data;
5844 #define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_SHIFT     0
5845 #define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_MASK      0x7ffffff
5846 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_SHIFT  27
5847 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_MASK   0x1
5848 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_SHIFT 28
5849 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_MASK  0x7
5850 #define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_SHIFT     31
5851 #define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_MASK      0x1
5852 };
5853 
5854 /* Protection override element */
5855 struct protection_override_element {
5856     u64 data;
5857 #define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_SHIFT       0
5858 #define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_MASK        0x7fffff
5859 #define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_SHIFT       23
5860 #define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_MASK        0xffffff
5861 #define PROTECTION_OVERRIDE_ELEMENT_READ_SHIFT          47
5862 #define PROTECTION_OVERRIDE_ELEMENT_READ_MASK           0x1
5863 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_SHIFT         48
5864 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_MASK          0x1
5865 #define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_SHIFT   49
5866 #define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_MASK    0x7
5867 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_SHIFT  52
5868 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_MASK   0x7
5869 };
5870 
5871 enum igu_fifo_sources {
5872     IGU_SRC_PXP0,
5873     IGU_SRC_PXP1,
5874     IGU_SRC_PXP2,
5875     IGU_SRC_PXP3,
5876     IGU_SRC_PXP4,
5877     IGU_SRC_PXP5,
5878     IGU_SRC_PXP6,
5879     IGU_SRC_PXP7,
5880     IGU_SRC_CAU,
5881     IGU_SRC_ATTN,
5882     IGU_SRC_GRC
5883 };
5884 
5885 enum igu_fifo_addr_types {
5886     IGU_ADDR_TYPE_MSIX_MEM,
5887     IGU_ADDR_TYPE_WRITE_PBA,
5888     IGU_ADDR_TYPE_WRITE_INT_ACK,
5889     IGU_ADDR_TYPE_WRITE_ATTN_BITS,
5890     IGU_ADDR_TYPE_READ_INT,
5891     IGU_ADDR_TYPE_WRITE_PROD_UPDATE,
5892     IGU_ADDR_TYPE_RESERVED
5893 };
5894 
5895 struct igu_fifo_addr_data {
5896     u16 start_addr;
5897     u16 end_addr;
5898     char *desc;
5899     char *vf_desc;
5900     enum igu_fifo_addr_types type;
5901 };
5902 
5903 /******************************** Constants **********************************/
5904 
5905 #define MAX_MSG_LEN             1024
5906 
5907 #define MCP_TRACE_MAX_MODULE_LEN        8
5908 #define MCP_TRACE_FORMAT_MAX_PARAMS     3
5909 #define MCP_TRACE_FORMAT_PARAM_WIDTH \
5910     (MCP_TRACE_FORMAT_P2_SIZE_OFFSET - MCP_TRACE_FORMAT_P1_SIZE_OFFSET)
5911 
5912 #define REG_FIFO_ELEMENT_ADDR_FACTOR        4
5913 #define REG_FIFO_ELEMENT_IS_PF_VF_VAL       127
5914 
5915 #define PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR 4
5916 
5917 /***************************** Constant Arrays *******************************/
5918 
5919 /* Status string array */
5920 static const char * const s_status_str[] = {
5921     /* DBG_STATUS_OK */
5922     "Operation completed successfully",
5923 
5924     /* DBG_STATUS_APP_VERSION_NOT_SET */
5925     "Debug application version wasn't set",
5926 
5927     /* DBG_STATUS_UNSUPPORTED_APP_VERSION */
5928     "Unsupported debug application version",
5929 
5930     /* DBG_STATUS_DBG_BLOCK_NOT_RESET */
5931     "The debug block wasn't reset since the last recording",
5932 
5933     /* DBG_STATUS_INVALID_ARGS */
5934     "Invalid arguments",
5935 
5936     /* DBG_STATUS_OUTPUT_ALREADY_SET */
5937     "The debug output was already set",
5938 
5939     /* DBG_STATUS_INVALID_PCI_BUF_SIZE */
5940     "Invalid PCI buffer size",
5941 
5942     /* DBG_STATUS_PCI_BUF_ALLOC_FAILED */
5943     "PCI buffer allocation failed",
5944 
5945     /* DBG_STATUS_PCI_BUF_NOT_ALLOCATED */
5946     "A PCI buffer wasn't allocated",
5947 
5948     /* DBG_STATUS_INVALID_FILTER_TRIGGER_DWORDS */
5949     "The filter/trigger constraint dword offsets are not enabled for recording",
5950     /* DBG_STATUS_NO_MATCHING_FRAMING_MODE */
5951     "No matching framing mode",
5952 
5953     /* DBG_STATUS_VFC_READ_ERROR */
5954     "Error reading from VFC",
5955 
5956     /* DBG_STATUS_STORM_ALREADY_ENABLED */
5957     "The Storm was already enabled",
5958 
5959     /* DBG_STATUS_STORM_NOT_ENABLED */
5960     "The specified Storm wasn't enabled",
5961 
5962     /* DBG_STATUS_BLOCK_ALREADY_ENABLED */
5963     "The block was already enabled",
5964 
5965     /* DBG_STATUS_BLOCK_NOT_ENABLED */
5966     "The specified block wasn't enabled",
5967 
5968     /* DBG_STATUS_NO_INPUT_ENABLED */
5969     "No input was enabled for recording",
5970 
5971     /* DBG_STATUS_NO_FILTER_TRIGGER_256B */
5972     "Filters and triggers are not allowed in E4 256-bit mode",
5973 
5974     /* DBG_STATUS_FILTER_ALREADY_ENABLED */
5975     "The filter was already enabled",
5976 
5977     /* DBG_STATUS_TRIGGER_ALREADY_ENABLED */
5978     "The trigger was already enabled",
5979 
5980     /* DBG_STATUS_TRIGGER_NOT_ENABLED */
5981     "The trigger wasn't enabled",
5982 
5983     /* DBG_STATUS_CANT_ADD_CONSTRAINT */
5984     "A constraint can be added only after a filter was enabled or a trigger state was added",
5985 
5986     /* DBG_STATUS_TOO_MANY_TRIGGER_STATES */
5987     "Cannot add more than 3 trigger states",
5988 
5989     /* DBG_STATUS_TOO_MANY_CONSTRAINTS */
5990     "Cannot add more than 4 constraints per filter or trigger state",
5991 
5992     /* DBG_STATUS_RECORDING_NOT_STARTED */
5993     "The recording wasn't started",
5994 
5995     /* DBG_STATUS_DATA_DIDNT_TRIGGER */
5996     "A trigger was configured, but it didn't trigger",
5997 
5998     /* DBG_STATUS_NO_DATA_RECORDED */
5999     "No data was recorded",
6000 
6001     /* DBG_STATUS_DUMP_BUF_TOO_SMALL */
6002     "Dump buffer is too small",
6003 
6004     /* DBG_STATUS_DUMP_NOT_CHUNK_ALIGNED */
6005     "Dumped data is not aligned to chunks",
6006 
6007     /* DBG_STATUS_UNKNOWN_CHIP */
6008     "Unknown chip",
6009 
6010     /* DBG_STATUS_VIRT_MEM_ALLOC_FAILED */
6011     "Failed allocating virtual memory",
6012 
6013     /* DBG_STATUS_BLOCK_IN_RESET */
6014     "The input block is in reset",
6015 
6016     /* DBG_STATUS_INVALID_TRACE_SIGNATURE */
6017     "Invalid MCP trace signature found in NVRAM",
6018 
6019     /* DBG_STATUS_INVALID_NVRAM_BUNDLE */
6020     "Invalid bundle ID found in NVRAM",
6021 
6022     /* DBG_STATUS_NVRAM_GET_IMAGE_FAILED */
6023     "Failed getting NVRAM image",
6024 
6025     /* DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE */
6026     "NVRAM image is not dword-aligned",
6027 
6028     /* DBG_STATUS_NVRAM_READ_FAILED */
6029     "Failed reading from NVRAM",
6030 
6031     /* DBG_STATUS_IDLE_CHK_PARSE_FAILED */
6032     "Idle check parsing failed",
6033 
6034     /* DBG_STATUS_MCP_TRACE_BAD_DATA */
6035     "MCP Trace data is corrupt",
6036 
6037     /* DBG_STATUS_MCP_TRACE_NO_META */
6038     "Dump doesn't contain meta data - it must be provided in image file",
6039 
6040     /* DBG_STATUS_MCP_COULD_NOT_HALT */
6041     "Failed to halt MCP",
6042 
6043     /* DBG_STATUS_MCP_COULD_NOT_RESUME */
6044     "Failed to resume MCP after halt",
6045 
6046     /* DBG_STATUS_RESERVED0 */
6047     "",
6048 
6049     /* DBG_STATUS_SEMI_FIFO_NOT_EMPTY */
6050     "Failed to empty SEMI sync FIFO",
6051 
6052     /* DBG_STATUS_IGU_FIFO_BAD_DATA */
6053     "IGU FIFO data is corrupt",
6054 
6055     /* DBG_STATUS_MCP_COULD_NOT_MASK_PRTY */
6056     "MCP failed to mask parities",
6057 
6058     /* DBG_STATUS_FW_ASSERTS_PARSE_FAILED */
6059     "FW Asserts parsing failed",
6060 
6061     /* DBG_STATUS_REG_FIFO_BAD_DATA */
6062     "GRC FIFO data is corrupt",
6063 
6064     /* DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA */
6065     "Protection Override data is corrupt",
6066 
6067     /* DBG_STATUS_DBG_ARRAY_NOT_SET */
6068     "Debug arrays were not set (when using binary files, dbg_set_bin_ptr must be called)",
6069 
6070     /* DBG_STATUS_RESERVED1 */
6071     "",
6072 
6073     /* DBG_STATUS_NON_MATCHING_LINES */
6074     "Non-matching debug lines - in E4, all lines must be of the same type (either 128b or 256b)",
6075 
6076     /* DBG_STATUS_INSUFFICIENT_HW_IDS */
6077     "Insufficient HW IDs. Try to record less Storms/blocks",
6078 
6079     /* DBG_STATUS_DBG_BUS_IN_USE */
6080     "The debug bus is in use",
6081 
6082     /* DBG_STATUS_INVALID_STORM_DBG_MODE */
6083     "The storm debug mode is not supported in the current chip",
6084 
6085     /* DBG_STATUS_OTHER_ENGINE_BB_ONLY */
6086     "Other engine is supported only in BB",
6087 
6088     /* DBG_STATUS_FILTER_SINGLE_HW_ID */
6089     "The configured filter mode requires a single Storm/block input",
6090 
6091     /* DBG_STATUS_TRIGGER_SINGLE_HW_ID */
6092     "The configured filter mode requires that all the constraints of a single trigger state will be defined on a single Storm/block input",
6093 
6094     /* DBG_STATUS_MISSING_TRIGGER_STATE_STORM */
6095     "When triggering on Storm data, the Storm to trigger on must be specified",
6096 
6097     /* DBG_STATUS_MDUMP2_FAILED_TO_REQUEST_OFFSIZE */
6098     "Failed to request MDUMP2 Offsize",
6099 
6100     /* DBG_STATUS_MDUMP2_FAILED_VALIDATION_OF_DATA_CRC */
6101     "Expected CRC (part of the MDUMP2 data) is different than the calculated CRC over that data",
6102 
6103     /* DBG_STATUS_MDUMP2_INVALID_SIGNATURE */
6104     "Invalid Signature found at start of MDUMP2",
6105 
6106     /* DBG_STATUS_MDUMP2_INVALID_LOG_SIZE */
6107     "Invalid Log Size of MDUMP2",
6108 
6109     /* DBG_STATUS_MDUMP2_INVALID_LOG_HDR */
6110     "Invalid Log Header of MDUMP2",
6111 
6112     /* DBG_STATUS_MDUMP2_INVALID_LOG_DATA */
6113     "Invalid Log Data of MDUMP2",
6114 
6115     /* DBG_STATUS_MDUMP2_ERROR_EXTRACTING_NUM_PORTS */
6116     "Could not extract number of ports from regval buf of MDUMP2",
6117 
6118     /* DBG_STATUS_MDUMP2_ERROR_EXTRACTING_MFW_STATUS */
6119     "Could not extract MFW (link) status from regval buf of MDUMP2",
6120 
6121     /* DBG_STATUS_MDUMP2_ERROR_DISPLAYING_LINKDUMP */
6122     "Could not display linkdump of MDUMP2",
6123 
6124     /* DBG_STATUS_MDUMP2_ERROR_READING_PHY_CFG */
6125     "Could not read PHY CFG of MDUMP2",
6126 
6127     /* DBG_STATUS_MDUMP2_ERROR_READING_PLL_MODE */
6128     "Could not read PLL Mode of MDUMP2",
6129 
6130     /* DBG_STATUS_MDUMP2_ERROR_READING_LANE_REGS */
6131     "Could not read TSCF/TSCE Lane Regs of MDUMP2",
6132 
6133     /* DBG_STATUS_MDUMP2_ERROR_ALLOCATING_BUF */
6134     "Could not allocate MDUMP2 reg-val internal buffer"
6135 };
6136 
6137 /* Idle check severity names array */
6138 static const char * const s_idle_chk_severity_str[] = {
6139     "Error",
6140     "Error if no traffic",
6141     "Warning"
6142 };
6143 
6144 /* MCP Trace level names array */
6145 static const char * const s_mcp_trace_level_str[] = {
6146     "ERROR",
6147     "TRACE",
6148     "DEBUG"
6149 };
6150 
6151 /* Access type names array */
6152 static const char * const s_access_strs[] = {
6153     "read",
6154     "write"
6155 };
6156 
6157 /* Privilege type names array */
6158 static const char * const s_privilege_strs[] = {
6159     "VF",
6160     "PDA",
6161     "HV",
6162     "UA"
6163 };
6164 
6165 /* Protection type names array */
6166 static const char * const s_protection_strs[] = {
6167     "(default)",
6168     "(default)",
6169     "(default)",
6170     "(default)",
6171     "override VF",
6172     "override PDA",
6173     "override HV",
6174     "override UA"
6175 };
6176 
6177 /* Master type names array */
6178 static const char * const s_master_strs[] = {
6179     "???",
6180     "pxp",
6181     "mcp",
6182     "msdm",
6183     "psdm",
6184     "ysdm",
6185     "usdm",
6186     "tsdm",
6187     "xsdm",
6188     "dbu",
6189     "dmae",
6190     "jdap",
6191     "???",
6192     "???",
6193     "???",
6194     "???"
6195 };
6196 
6197 /* REG FIFO error messages array */
6198 static struct reg_fifo_err s_reg_fifo_errors[] = {
6199     {1, "grc timeout"},
6200     {2, "address doesn't belong to any block"},
6201     {4, "reserved address in block or write to read-only address"},
6202     {8, "privilege/protection mismatch"},
6203     {16, "path isolation error"},
6204     {17, "RSL error"}
6205 };
6206 
6207 /* IGU FIFO sources array */
6208 static const char * const s_igu_fifo_source_strs[] = {
6209     "TSTORM",
6210     "MSTORM",
6211     "USTORM",
6212     "XSTORM",
6213     "YSTORM",
6214     "PSTORM",
6215     "PCIE",
6216     "NIG_QM_PBF",
6217     "CAU",
6218     "ATTN",
6219     "GRC",
6220 };
6221 
6222 /* IGU FIFO error messages */
6223 static const char * const s_igu_fifo_error_strs[] = {
6224     "no error",
6225     "length error",
6226     "function disabled",
6227     "VF sent command to attention address",
6228     "host sent prod update command",
6229     "read of during interrupt register while in MIMD mode",
6230     "access to PXP BAR reserved address",
6231     "producer update command to attention index",
6232     "unknown error",
6233     "SB index not valid",
6234     "SB relative index and FID not found",
6235     "FID not match",
6236     "command with error flag asserted (PCI error or CAU discard)",
6237     "VF sent cleanup and RF cleanup is disabled",
6238     "cleanup command on type bigger than 4"
6239 };
6240 
6241 /* IGU FIFO address data */
6242 static const struct igu_fifo_addr_data s_igu_fifo_addr_data[] = {
6243     {0x0, 0x101, "MSI-X Memory", NULL,
6244      IGU_ADDR_TYPE_MSIX_MEM},
6245     {0x102, 0x1ff, "reserved", NULL,
6246      IGU_ADDR_TYPE_RESERVED},
6247     {0x200, 0x200, "Write PBA[0:63]", NULL,
6248      IGU_ADDR_TYPE_WRITE_PBA},
6249     {0x201, 0x201, "Write PBA[64:127]", "reserved",
6250      IGU_ADDR_TYPE_WRITE_PBA},
6251     {0x202, 0x202, "Write PBA[128]", "reserved",
6252      IGU_ADDR_TYPE_WRITE_PBA},
6253     {0x203, 0x3ff, "reserved", NULL,
6254      IGU_ADDR_TYPE_RESERVED},
6255     {0x400, 0x5ef, "Write interrupt acknowledgment", NULL,
6256      IGU_ADDR_TYPE_WRITE_INT_ACK},
6257     {0x5f0, 0x5f0, "Attention bits update", NULL,
6258      IGU_ADDR_TYPE_WRITE_ATTN_BITS},
6259     {0x5f1, 0x5f1, "Attention bits set", NULL,
6260      IGU_ADDR_TYPE_WRITE_ATTN_BITS},
6261     {0x5f2, 0x5f2, "Attention bits clear", NULL,
6262      IGU_ADDR_TYPE_WRITE_ATTN_BITS},
6263     {0x5f3, 0x5f3, "Read interrupt 0:63 with mask", NULL,
6264      IGU_ADDR_TYPE_READ_INT},
6265     {0x5f4, 0x5f4, "Read interrupt 0:31 with mask", NULL,
6266      IGU_ADDR_TYPE_READ_INT},
6267     {0x5f5, 0x5f5, "Read interrupt 32:63 with mask", NULL,
6268      IGU_ADDR_TYPE_READ_INT},
6269     {0x5f6, 0x5f6, "Read interrupt 0:63 without mask", NULL,
6270      IGU_ADDR_TYPE_READ_INT},
6271     {0x5f7, 0x5ff, "reserved", NULL,
6272      IGU_ADDR_TYPE_RESERVED},
6273     {0x600, 0x7ff, "Producer update", NULL,
6274      IGU_ADDR_TYPE_WRITE_PROD_UPDATE}
6275 };
6276 
6277 /******************************** Variables **********************************/
6278 
6279 /* Temporary buffer, used for print size calculations */
6280 static char s_temp_buf[MAX_MSG_LEN];
6281 
6282 /**************************** Private Functions ******************************/
6283 
6284 static void qed_user_static_asserts(void)
6285 {
6286 }
6287 
6288 static u32 qed_cyclic_add(u32 a, u32 b, u32 size)
6289 {
6290     return (a + b) % size;
6291 }
6292 
6293 static u32 qed_cyclic_sub(u32 a, u32 b, u32 size)
6294 {
6295     return (size + a - b) % size;
6296 }
6297 
6298 /* Reads the specified number of bytes from the specified cyclic buffer (up to 4
6299  * bytes) and returns them as a dword value. the specified buffer offset is
6300  * updated.
6301  */
6302 static u32 qed_read_from_cyclic_buf(void *buf,
6303                     u32 *offset,
6304                     u32 buf_size, u8 num_bytes_to_read)
6305 {
6306     u8 i, *val_ptr, *bytes_buf = (u8 *)buf;
6307     u32 val = 0;
6308 
6309     val_ptr = (u8 *)&val;
6310 
6311     /* Assume running on a LITTLE ENDIAN and the buffer is network order
6312      * (BIG ENDIAN), as high order bytes are placed in lower memory address.
6313      */
6314     for (i = 0; i < num_bytes_to_read; i++) {
6315         val_ptr[i] = bytes_buf[*offset];
6316         *offset = qed_cyclic_add(*offset, 1, buf_size);
6317     }
6318 
6319     return val;
6320 }
6321 
6322 /* Reads and returns the next byte from the specified buffer.
6323  * The specified buffer offset is updated.
6324  */
6325 static u8 qed_read_byte_from_buf(void *buf, u32 *offset)
6326 {
6327     return ((u8 *)buf)[(*offset)++];
6328 }
6329 
6330 /* Reads and returns the next dword from the specified buffer.
6331  * The specified buffer offset is updated.
6332  */
6333 static u32 qed_read_dword_from_buf(void *buf, u32 *offset)
6334 {
6335     u32 dword_val = *(u32 *)&((u8 *)buf)[*offset];
6336 
6337     *offset += 4;
6338 
6339     return dword_val;
6340 }
6341 
6342 /* Reads the next string from the specified buffer, and copies it to the
6343  * specified pointer. The specified buffer offset is updated.
6344  */
6345 static void qed_read_str_from_buf(void *buf, u32 *offset, u32 size, char *dest)
6346 {
6347     const char *source_str = &((const char *)buf)[*offset];
6348 
6349     strncpy(dest, source_str, size);
6350     dest[size - 1] = '\0';
6351     *offset += size;
6352 }
6353 
6354 /* Returns a pointer to the specified offset (in bytes) of the specified buffer.
6355  * If the specified buffer in NULL, a temporary buffer pointer is returned.
6356  */
6357 static char *qed_get_buf_ptr(void *buf, u32 offset)
6358 {
6359     return buf ? (char *)buf + offset : s_temp_buf;
6360 }
6361 
6362 /* Reads a param from the specified buffer. Returns the number of dwords read.
6363  * If the returned str_param is NULL, the param is numeric and its value is
6364  * returned in num_param.
6365  * Otheriwise, the param is a string and its pointer is returned in str_param.
6366  */
6367 static u32 qed_read_param(u32 *dump_buf,
6368               const char **param_name,
6369               const char **param_str_val, u32 *param_num_val)
6370 {
6371     char *char_buf = (char *)dump_buf;
6372     size_t offset = 0;
6373 
6374     /* Extract param name */
6375     *param_name = char_buf;
6376     offset += strlen(*param_name) + 1;
6377 
6378     /* Check param type */
6379     if (*(char_buf + offset++)) {
6380         /* String param */
6381         *param_str_val = char_buf + offset;
6382         *param_num_val = 0;
6383         offset += strlen(*param_str_val) + 1;
6384         if (offset & 0x3)
6385             offset += (4 - (offset & 0x3));
6386     } else {
6387         /* Numeric param */
6388         *param_str_val = NULL;
6389         if (offset & 0x3)
6390             offset += (4 - (offset & 0x3));
6391         *param_num_val = *(u32 *)(char_buf + offset);
6392         offset += 4;
6393     }
6394 
6395     return (u32)offset / 4;
6396 }
6397 
6398 /* Reads a section header from the specified buffer.
6399  * Returns the number of dwords read.
6400  */
6401 static u32 qed_read_section_hdr(u32 *dump_buf,
6402                 const char **section_name,
6403                 u32 *num_section_params)
6404 {
6405     const char *param_str_val;
6406 
6407     return qed_read_param(dump_buf,
6408                   section_name, &param_str_val, num_section_params);
6409 }
6410 
6411 /* Reads section params from the specified buffer and prints them to the results
6412  * buffer. Returns the number of dwords read.
6413  */
6414 static u32 qed_print_section_params(u32 *dump_buf,
6415                     u32 num_section_params,
6416                     char *results_buf, u32 *num_chars_printed)
6417 {
6418     u32 i, dump_offset = 0, results_offset = 0;
6419 
6420     for (i = 0; i < num_section_params; i++) {
6421         const char *param_name, *param_str_val;
6422         u32 param_num_val = 0;
6423 
6424         dump_offset += qed_read_param(dump_buf + dump_offset,
6425                           &param_name,
6426                           &param_str_val, &param_num_val);
6427 
6428         if (param_str_val)
6429             results_offset +=
6430                 sprintf(qed_get_buf_ptr(results_buf,
6431                             results_offset),
6432                     "%s: %s\n", param_name, param_str_val);
6433         else if (strcmp(param_name, "fw-timestamp"))
6434             results_offset +=
6435                 sprintf(qed_get_buf_ptr(results_buf,
6436                             results_offset),
6437                     "%s: %d\n", param_name, param_num_val);
6438     }
6439 
6440     results_offset += sprintf(qed_get_buf_ptr(results_buf, results_offset),
6441                   "\n");
6442 
6443     *num_chars_printed = results_offset;
6444 
6445     return dump_offset;
6446 }
6447 
6448 /* Returns the block name that matches the specified block ID,
6449  * or NULL if not found.
6450  */
6451 static const char *qed_dbg_get_block_name(struct qed_hwfn *p_hwfn,
6452                       enum block_id block_id)
6453 {
6454     const struct dbg_block_user *block =
6455         (const struct dbg_block_user *)
6456         p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS_USER_DATA].ptr + block_id;
6457 
6458     return (const char *)block->name;
6459 }
6460 
6461 static struct dbg_tools_user_data *qed_dbg_get_user_data(struct qed_hwfn
6462                              *p_hwfn)
6463 {
6464     return (struct dbg_tools_user_data *)p_hwfn->dbg_user_info;
6465 }
6466 
6467 /* Parses the idle check rules and returns the number of characters printed.
6468  * In case of parsing error, returns 0.
6469  */
6470 static u32 qed_parse_idle_chk_dump_rules(struct qed_hwfn *p_hwfn,
6471                      u32 *dump_buf,
6472                      u32 *dump_buf_end,
6473                      u32 num_rules,
6474                      bool print_fw_idle_chk,
6475                      char *results_buf,
6476                      u32 *num_errors, u32 *num_warnings)
6477 {
6478     /* Offset in results_buf in bytes */
6479     u32 results_offset = 0;
6480 
6481     u32 rule_idx;
6482     u16 i, j;
6483 
6484     *num_errors = 0;
6485     *num_warnings = 0;
6486 
6487     /* Go over dumped results */
6488     for (rule_idx = 0; rule_idx < num_rules && dump_buf < dump_buf_end;
6489          rule_idx++) {
6490         const struct dbg_idle_chk_rule_parsing_data *rule_parsing_data;
6491         struct dbg_idle_chk_result_hdr *hdr;
6492         const char *parsing_str, *lsi_msg;
6493         u32 parsing_str_offset;
6494         bool has_fw_msg;
6495         u8 curr_reg_id;
6496 
6497         hdr = (struct dbg_idle_chk_result_hdr *)dump_buf;
6498         rule_parsing_data =
6499             (const struct dbg_idle_chk_rule_parsing_data *)
6500             p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr +
6501             hdr->rule_id;
6502         parsing_str_offset =
6503             GET_FIELD(rule_parsing_data->data,
6504                   DBG_IDLE_CHK_RULE_PARSING_DATA_STR_OFFSET);
6505         has_fw_msg =
6506             GET_FIELD(rule_parsing_data->data,
6507                   DBG_IDLE_CHK_RULE_PARSING_DATA_HAS_FW_MSG) > 0;
6508         parsing_str = (const char *)
6509             p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr +
6510             parsing_str_offset;
6511         lsi_msg = parsing_str;
6512         curr_reg_id = 0;
6513 
6514         if (hdr->severity >= MAX_DBG_IDLE_CHK_SEVERITY_TYPES)
6515             return 0;
6516 
6517         /* Skip rule header */
6518         dump_buf += BYTES_TO_DWORDS(sizeof(*hdr));
6519 
6520         /* Update errors/warnings count */
6521         if (hdr->severity == IDLE_CHK_SEVERITY_ERROR ||
6522             hdr->severity == IDLE_CHK_SEVERITY_ERROR_NO_TRAFFIC)
6523             (*num_errors)++;
6524         else
6525             (*num_warnings)++;
6526 
6527         /* Print rule severity */
6528         results_offset +=
6529             sprintf(qed_get_buf_ptr(results_buf,
6530                         results_offset), "%s: ",
6531                 s_idle_chk_severity_str[hdr->severity]);
6532 
6533         /* Print rule message */
6534         if (has_fw_msg)
6535             parsing_str += strlen(parsing_str) + 1;
6536         results_offset +=
6537             sprintf(qed_get_buf_ptr(results_buf,
6538                         results_offset), "%s.",
6539                 has_fw_msg &&
6540                 print_fw_idle_chk ? parsing_str : lsi_msg);
6541         parsing_str += strlen(parsing_str) + 1;
6542 
6543         /* Print register values */
6544         results_offset +=
6545             sprintf(qed_get_buf_ptr(results_buf,
6546                         results_offset), " Registers:");
6547         for (i = 0;
6548              i < hdr->num_dumped_cond_regs + hdr->num_dumped_info_regs;
6549              i++) {
6550             struct dbg_idle_chk_result_reg_hdr *reg_hdr;
6551             bool is_mem;
6552             u8 reg_id;
6553 
6554             reg_hdr =
6555                 (struct dbg_idle_chk_result_reg_hdr *)dump_buf;
6556             is_mem = GET_FIELD(reg_hdr->data,
6557                        DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM);
6558             reg_id = GET_FIELD(reg_hdr->data,
6559                        DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID);
6560 
6561             /* Skip reg header */
6562             dump_buf += BYTES_TO_DWORDS(sizeof(*reg_hdr));
6563 
6564             /* Skip register names until the required reg_id is
6565              * reached.
6566              */
6567             for (; reg_id > curr_reg_id; curr_reg_id++)
6568                 parsing_str += strlen(parsing_str) + 1;
6569 
6570             results_offset +=
6571                 sprintf(qed_get_buf_ptr(results_buf,
6572                             results_offset), " %s",
6573                     parsing_str);
6574             if (i < hdr->num_dumped_cond_regs && is_mem)
6575                 results_offset +=
6576                     sprintf(qed_get_buf_ptr(results_buf,
6577                                 results_offset),
6578                         "[%d]", hdr->mem_entry_id +
6579                         reg_hdr->start_entry);
6580             results_offset +=
6581                 sprintf(qed_get_buf_ptr(results_buf,
6582                             results_offset), "=");
6583             for (j = 0; j < reg_hdr->size; j++, dump_buf++) {
6584                 results_offset +=
6585                     sprintf(qed_get_buf_ptr(results_buf,
6586                                 results_offset),
6587                         "0x%x", *dump_buf);
6588                 if (j < reg_hdr->size - 1)
6589                     results_offset +=
6590                         sprintf(qed_get_buf_ptr
6591                             (results_buf,
6592                              results_offset), ",");
6593             }
6594         }
6595 
6596         results_offset +=
6597             sprintf(qed_get_buf_ptr(results_buf, results_offset), "\n");
6598     }
6599 
6600     /* Check if end of dump buffer was exceeded */
6601     if (dump_buf > dump_buf_end)
6602         return 0;
6603 
6604     return results_offset;
6605 }
6606 
6607 /* Parses an idle check dump buffer.
6608  * If result_buf is not NULL, the idle check results are printed to it.
6609  * In any case, the required results buffer size is assigned to
6610  * parsed_results_bytes.
6611  * The parsing status is returned.
6612  */
6613 static enum dbg_status qed_parse_idle_chk_dump(struct qed_hwfn *p_hwfn,
6614                            u32 *dump_buf,
6615                            u32 num_dumped_dwords,
6616                            char *results_buf,
6617                            u32 *parsed_results_bytes,
6618                            u32 *num_errors,
6619                            u32 *num_warnings)
6620 {
6621     u32 num_section_params = 0, num_rules, num_rules_not_dumped;
6622     const char *section_name, *param_name, *param_str_val;
6623     u32 *dump_buf_end = dump_buf + num_dumped_dwords;
6624 
6625     /* Offset in results_buf in bytes */
6626     u32 results_offset = 0;
6627 
6628     *parsed_results_bytes = 0;
6629     *num_errors = 0;
6630     *num_warnings = 0;
6631 
6632     if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr ||
6633         !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr)
6634         return DBG_STATUS_DBG_ARRAY_NOT_SET;
6635 
6636     /* Read global_params section */
6637     dump_buf += qed_read_section_hdr(dump_buf,
6638                      &section_name, &num_section_params);
6639     if (strcmp(section_name, "global_params"))
6640         return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6641 
6642     /* Print global params */
6643     dump_buf += qed_print_section_params(dump_buf,
6644                          num_section_params,
6645                          results_buf, &results_offset);
6646 
6647     /* Read idle_chk section
6648      * There may be 1 or 2 idle_chk section parameters:
6649      * - 1st is "num_rules"
6650      * - 2nd is "num_rules_not_dumped" (optional)
6651      */
6652 
6653     dump_buf += qed_read_section_hdr(dump_buf,
6654                      &section_name, &num_section_params);
6655     if (strcmp(section_name, "idle_chk") ||
6656         (num_section_params != 2 && num_section_params != 1))
6657         return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6658     dump_buf += qed_read_param(dump_buf,
6659                    &param_name, &param_str_val, &num_rules);
6660     if (strcmp(param_name, "num_rules"))
6661         return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6662     if (num_section_params > 1) {
6663         dump_buf += qed_read_param(dump_buf,
6664                        &param_name,
6665                        &param_str_val,
6666                        &num_rules_not_dumped);
6667         if (strcmp(param_name, "num_rules_not_dumped"))
6668             return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6669     } else {
6670         num_rules_not_dumped = 0;
6671     }
6672 
6673     if (num_rules) {
6674         u32 rules_print_size;
6675 
6676         /* Print FW output */
6677         results_offset +=
6678             sprintf(qed_get_buf_ptr(results_buf,
6679                         results_offset),
6680                 "FW_IDLE_CHECK:\n");
6681         rules_print_size =
6682             qed_parse_idle_chk_dump_rules(p_hwfn,
6683                               dump_buf,
6684                               dump_buf_end,
6685                               num_rules,
6686                               true,
6687                               results_buf ?
6688                               results_buf +
6689                               results_offset :
6690                               NULL,
6691                               num_errors,
6692                               num_warnings);
6693         results_offset += rules_print_size;
6694         if (!rules_print_size)
6695             return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6696 
6697         /* Print LSI output */
6698         results_offset +=
6699             sprintf(qed_get_buf_ptr(results_buf,
6700                         results_offset),
6701                 "\nLSI_IDLE_CHECK:\n");
6702         rules_print_size =
6703             qed_parse_idle_chk_dump_rules(p_hwfn,
6704                               dump_buf,
6705                               dump_buf_end,
6706                               num_rules,
6707                               false,
6708                               results_buf ?
6709                               results_buf +
6710                               results_offset :
6711                               NULL,
6712                               num_errors,
6713                               num_warnings);
6714         results_offset += rules_print_size;
6715         if (!rules_print_size)
6716             return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6717     }
6718 
6719     /* Print errors/warnings count */
6720     if (*num_errors)
6721         results_offset +=
6722             sprintf(qed_get_buf_ptr(results_buf,
6723                         results_offset),
6724                 "\nIdle Check failed!!! (with %d errors and %d warnings)\n",
6725                 *num_errors, *num_warnings);
6726     else if (*num_warnings)
6727         results_offset +=
6728             sprintf(qed_get_buf_ptr(results_buf,
6729                         results_offset),
6730                 "\nIdle Check completed successfully (with %d warnings)\n",
6731                 *num_warnings);
6732     else
6733         results_offset +=
6734             sprintf(qed_get_buf_ptr(results_buf,
6735                         results_offset),
6736                 "\nIdle Check completed successfully\n");
6737 
6738     if (num_rules_not_dumped)
6739         results_offset +=
6740             sprintf(qed_get_buf_ptr(results_buf,
6741                         results_offset),
6742                 "\nIdle Check Partially dumped : num_rules_not_dumped = %d\n",
6743                 num_rules_not_dumped);
6744 
6745     /* Add 1 for string NULL termination */
6746     *parsed_results_bytes = results_offset + 1;
6747 
6748     return DBG_STATUS_OK;
6749 }
6750 
6751 /* Allocates and fills MCP Trace meta data based on the specified meta data
6752  * dump buffer.
6753  * Returns debug status code.
6754  */
6755 static enum dbg_status
6756 qed_mcp_trace_alloc_meta_data(struct qed_hwfn *p_hwfn,
6757                   const u32 *meta_buf)
6758 {
6759     struct dbg_tools_user_data *dev_user_data;
6760     u32 offset = 0, signature, i;
6761     struct mcp_trace_meta *meta;
6762     u8 *meta_buf_bytes;
6763 
6764     dev_user_data = qed_dbg_get_user_data(p_hwfn);
6765     meta = &dev_user_data->mcp_trace_meta;
6766     meta_buf_bytes = (u8 *)meta_buf;
6767 
6768     /* Free the previous meta before loading a new one. */
6769     if (meta->is_allocated)
6770         qed_mcp_trace_free_meta_data(p_hwfn);
6771 
6772     memset(meta, 0, sizeof(*meta));
6773 
6774     /* Read first signature */
6775     signature = qed_read_dword_from_buf(meta_buf_bytes, &offset);
6776     if (signature != NVM_MAGIC_VALUE)
6777         return DBG_STATUS_INVALID_TRACE_SIGNATURE;
6778 
6779     /* Read no. of modules and allocate memory for their pointers */
6780     meta->modules_num = qed_read_byte_from_buf(meta_buf_bytes, &offset);
6781     meta->modules = kcalloc(meta->modules_num, sizeof(char *),
6782                 GFP_KERNEL);
6783     if (!meta->modules)
6784         return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6785 
6786     /* Allocate and read all module strings */
6787     for (i = 0; i < meta->modules_num; i++) {
6788         u8 module_len = qed_read_byte_from_buf(meta_buf_bytes, &offset);
6789 
6790         *(meta->modules + i) = kzalloc(module_len, GFP_KERNEL);
6791         if (!(*(meta->modules + i))) {
6792             /* Update number of modules to be released */
6793             meta->modules_num = i ? i - 1 : 0;
6794             return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6795         }
6796 
6797         qed_read_str_from_buf(meta_buf_bytes, &offset, module_len,
6798                       *(meta->modules + i));
6799         if (module_len > MCP_TRACE_MAX_MODULE_LEN)
6800             (*(meta->modules + i))[MCP_TRACE_MAX_MODULE_LEN] = '\0';
6801     }
6802 
6803     /* Read second signature */
6804     signature = qed_read_dword_from_buf(meta_buf_bytes, &offset);
6805     if (signature != NVM_MAGIC_VALUE)
6806         return DBG_STATUS_INVALID_TRACE_SIGNATURE;
6807 
6808     /* Read number of formats and allocate memory for all formats */
6809     meta->formats_num = qed_read_dword_from_buf(meta_buf_bytes, &offset);
6810     meta->formats = kcalloc(meta->formats_num,
6811                 sizeof(struct mcp_trace_format),
6812                 GFP_KERNEL);
6813     if (!meta->formats)
6814         return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6815 
6816     /* Allocate and read all strings */
6817     for (i = 0; i < meta->formats_num; i++) {
6818         struct mcp_trace_format *format_ptr = &meta->formats[i];
6819         u8 format_len;
6820 
6821         format_ptr->data = qed_read_dword_from_buf(meta_buf_bytes,
6822                                &offset);
6823         format_len = GET_MFW_FIELD(format_ptr->data,
6824                        MCP_TRACE_FORMAT_LEN);
6825         format_ptr->format_str = kzalloc(format_len, GFP_KERNEL);
6826         if (!format_ptr->format_str) {
6827             /* Update number of modules to be released */
6828             meta->formats_num = i ? i - 1 : 0;
6829             return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6830         }
6831 
6832         qed_read_str_from_buf(meta_buf_bytes,
6833                       &offset,
6834                       format_len, format_ptr->format_str);
6835     }
6836 
6837     meta->is_allocated = true;
6838     return DBG_STATUS_OK;
6839 }
6840 
6841 /* Parses an MCP trace buffer. If result_buf is not NULL, the MCP Trace results
6842  * are printed to it. The parsing status is returned.
6843  * Arguments:
6844  * trace_buf - MCP trace cyclic buffer
6845  * trace_buf_size - MCP trace cyclic buffer size in bytes
6846  * data_offset - offset in bytes of the data to parse in the MCP trace cyclic
6847  *       buffer.
6848  * data_size - size in bytes of data to parse.
6849  * parsed_buf - destination buffer for parsed data.
6850  * parsed_results_bytes - size of parsed data in bytes.
6851  */
6852 static enum dbg_status qed_parse_mcp_trace_buf(struct qed_hwfn *p_hwfn,
6853                            u8 *trace_buf,
6854                            u32 trace_buf_size,
6855                            u32 data_offset,
6856                            u32 data_size,
6857                            char *parsed_buf,
6858                            u32 *parsed_results_bytes)
6859 {
6860     struct dbg_tools_user_data *dev_user_data;
6861     struct mcp_trace_meta *meta;
6862     u32 param_mask, param_shift;
6863     enum dbg_status status;
6864 
6865     dev_user_data = qed_dbg_get_user_data(p_hwfn);
6866     meta = &dev_user_data->mcp_trace_meta;
6867     *parsed_results_bytes = 0;
6868 
6869     if (!meta->is_allocated)
6870         return DBG_STATUS_MCP_TRACE_BAD_DATA;
6871 
6872     status = DBG_STATUS_OK;
6873 
6874     while (data_size) {
6875         struct mcp_trace_format *format_ptr;
6876         u8 format_level, format_module;
6877         u32 params[3] = { 0, 0, 0 };
6878         u32 header, format_idx, i;
6879 
6880         if (data_size < MFW_TRACE_ENTRY_SIZE)
6881             return DBG_STATUS_MCP_TRACE_BAD_DATA;
6882 
6883         header = qed_read_from_cyclic_buf(trace_buf,
6884                           &data_offset,
6885                           trace_buf_size,
6886                           MFW_TRACE_ENTRY_SIZE);
6887         data_size -= MFW_TRACE_ENTRY_SIZE;
6888         format_idx = header & MFW_TRACE_EVENTID_MASK;
6889 
6890         /* Skip message if its index doesn't exist in the meta data */
6891         if (format_idx >= meta->formats_num) {
6892             u8 format_size = (u8)GET_MFW_FIELD(header,
6893                                MFW_TRACE_PRM_SIZE);
6894 
6895             if (data_size < format_size)
6896                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6897 
6898             data_offset = qed_cyclic_add(data_offset,
6899                              format_size,
6900                              trace_buf_size);
6901             data_size -= format_size;
6902             continue;
6903         }
6904 
6905         format_ptr = &meta->formats[format_idx];
6906 
6907         for (i = 0,
6908              param_mask = MCP_TRACE_FORMAT_P1_SIZE_MASK, param_shift =
6909              MCP_TRACE_FORMAT_P1_SIZE_OFFSET;
6910              i < MCP_TRACE_FORMAT_MAX_PARAMS;
6911              i++, param_mask <<= MCP_TRACE_FORMAT_PARAM_WIDTH,
6912              param_shift += MCP_TRACE_FORMAT_PARAM_WIDTH) {
6913             /* Extract param size (0..3) */
6914             u8 param_size = (u8)((format_ptr->data & param_mask) >>
6915                          param_shift);
6916 
6917             /* If the param size is zero, there are no other
6918              * parameters.
6919              */
6920             if (!param_size)
6921                 break;
6922 
6923             /* Size is encoded using 2 bits, where 3 is used to
6924              * encode 4.
6925              */
6926             if (param_size == 3)
6927                 param_size = 4;
6928 
6929             if (data_size < param_size)
6930                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6931 
6932             params[i] = qed_read_from_cyclic_buf(trace_buf,
6933                                  &data_offset,
6934                                  trace_buf_size,
6935                                  param_size);
6936             data_size -= param_size;
6937         }
6938 
6939         format_level = (u8)GET_MFW_FIELD(format_ptr->data,
6940                          MCP_TRACE_FORMAT_LEVEL);
6941         format_module = (u8)GET_MFW_FIELD(format_ptr->data,
6942                           MCP_TRACE_FORMAT_MODULE);
6943         if (format_level >= ARRAY_SIZE(s_mcp_trace_level_str))
6944             return DBG_STATUS_MCP_TRACE_BAD_DATA;
6945 
6946         /* Print current message to results buffer */
6947         *parsed_results_bytes +=
6948             sprintf(qed_get_buf_ptr(parsed_buf,
6949                         *parsed_results_bytes),
6950                 "%s %-8s: ",
6951                 s_mcp_trace_level_str[format_level],
6952                 meta->modules[format_module]);
6953         *parsed_results_bytes +=
6954             sprintf(qed_get_buf_ptr(parsed_buf, *parsed_results_bytes),
6955                 format_ptr->format_str,
6956                 params[0], params[1], params[2]);
6957     }
6958 
6959     /* Add string NULL terminator */
6960     (*parsed_results_bytes)++;
6961 
6962     return status;
6963 }
6964 
6965 /* Parses an MCP Trace dump buffer.
6966  * If result_buf is not NULL, the MCP Trace results are printed to it.
6967  * In any case, the required results buffer size is assigned to
6968  * parsed_results_bytes.
6969  * The parsing status is returned.
6970  */
6971 static enum dbg_status qed_parse_mcp_trace_dump(struct qed_hwfn *p_hwfn,
6972                         u32 *dump_buf,
6973                         char *results_buf,
6974                         u32 *parsed_results_bytes,
6975                         bool free_meta_data)
6976 {
6977     const char *section_name, *param_name, *param_str_val;
6978     u32 data_size, trace_data_dwords, trace_meta_dwords;
6979     u32 offset, results_offset, results_buf_bytes;
6980     u32 param_num_val, num_section_params;
6981     struct mcp_trace *trace;
6982     enum dbg_status status;
6983     const u32 *meta_buf;
6984     u8 *trace_buf;
6985 
6986     *parsed_results_bytes = 0;
6987 
6988     /* Read global_params section */
6989     dump_buf += qed_read_section_hdr(dump_buf,
6990                      &section_name, &num_section_params);
6991     if (strcmp(section_name, "global_params"))
6992         return DBG_STATUS_MCP_TRACE_BAD_DATA;
6993 
6994     /* Print global params */
6995     dump_buf += qed_print_section_params(dump_buf,
6996                          num_section_params,
6997                          results_buf, &results_offset);
6998 
6999     /* Read trace_data section */
7000     dump_buf += qed_read_section_hdr(dump_buf,
7001                      &section_name, &num_section_params);
7002     if (strcmp(section_name, "mcp_trace_data") || num_section_params != 1)
7003         return DBG_STATUS_MCP_TRACE_BAD_DATA;
7004     dump_buf += qed_read_param(dump_buf,
7005                    &param_name, &param_str_val, &param_num_val);
7006     if (strcmp(param_name, "size"))
7007         return DBG_STATUS_MCP_TRACE_BAD_DATA;
7008     trace_data_dwords = param_num_val;
7009 
7010     /* Prepare trace info */
7011     trace = (struct mcp_trace *)dump_buf;
7012     if (trace->signature != MFW_TRACE_SIGNATURE || !trace->size)
7013         return DBG_STATUS_MCP_TRACE_BAD_DATA;
7014 
7015     trace_buf = (u8 *)dump_buf + sizeof(*trace);
7016     offset = trace->trace_oldest;
7017     data_size = qed_cyclic_sub(trace->trace_prod, offset, trace->size);
7018     dump_buf += trace_data_dwords;
7019 
7020     /* Read meta_data section */
7021     dump_buf += qed_read_section_hdr(dump_buf,
7022                      &section_name, &num_section_params);
7023     if (strcmp(section_name, "mcp_trace_meta"))
7024         return DBG_STATUS_MCP_TRACE_BAD_DATA;
7025     dump_buf += qed_read_param(dump_buf,
7026                    &param_name, &param_str_val, &param_num_val);
7027     if (strcmp(param_name, "size"))
7028         return DBG_STATUS_MCP_TRACE_BAD_DATA;
7029     trace_meta_dwords = param_num_val;
7030 
7031     /* Choose meta data buffer */
7032     if (!trace_meta_dwords) {
7033         /* Dump doesn't include meta data */
7034         struct dbg_tools_user_data *dev_user_data =
7035             qed_dbg_get_user_data(p_hwfn);
7036 
7037         if (!dev_user_data->mcp_trace_user_meta_buf)
7038             return DBG_STATUS_MCP_TRACE_NO_META;
7039 
7040         meta_buf = dev_user_data->mcp_trace_user_meta_buf;
7041     } else {
7042         /* Dump includes meta data */
7043         meta_buf = dump_buf;
7044     }
7045 
7046     /* Allocate meta data memory */
7047     status = qed_mcp_trace_alloc_meta_data(p_hwfn, meta_buf);
7048     if (status != DBG_STATUS_OK)
7049         return status;
7050 
7051     status = qed_parse_mcp_trace_buf(p_hwfn,
7052                      trace_buf,
7053                      trace->size,
7054                      offset,
7055                      data_size,
7056                      results_buf ?
7057                      results_buf + results_offset :
7058                      NULL,
7059                      &results_buf_bytes);
7060     if (status != DBG_STATUS_OK)
7061         return status;
7062 
7063     if (free_meta_data)
7064         qed_mcp_trace_free_meta_data(p_hwfn);
7065 
7066     *parsed_results_bytes = results_offset + results_buf_bytes;
7067 
7068     return DBG_STATUS_OK;
7069 }
7070 
7071 /* Parses a Reg FIFO dump buffer.
7072  * If result_buf is not NULL, the Reg FIFO results are printed to it.
7073  * In any case, the required results buffer size is assigned to
7074  * parsed_results_bytes.
7075  * The parsing status is returned.
7076  */
7077 static enum dbg_status qed_parse_reg_fifo_dump(u32 *dump_buf,
7078                            char *results_buf,
7079                            u32 *parsed_results_bytes)
7080 {
7081     const char *section_name, *param_name, *param_str_val;
7082     u32 param_num_val, num_section_params, num_elements;
7083     struct reg_fifo_element *elements;
7084     u8 i, j, err_code, vf_val;
7085     u32 results_offset = 0;
7086     char vf_str[4];
7087 
7088     /* Read global_params section */
7089     dump_buf += qed_read_section_hdr(dump_buf,
7090                      &section_name, &num_section_params);
7091     if (strcmp(section_name, "global_params"))
7092         return DBG_STATUS_REG_FIFO_BAD_DATA;
7093 
7094     /* Print global params */
7095     dump_buf += qed_print_section_params(dump_buf,
7096                          num_section_params,
7097                          results_buf, &results_offset);
7098 
7099     /* Read reg_fifo_data section */
7100     dump_buf += qed_read_section_hdr(dump_buf,
7101                      &section_name, &num_section_params);
7102     if (strcmp(section_name, "reg_fifo_data"))
7103         return DBG_STATUS_REG_FIFO_BAD_DATA;
7104     dump_buf += qed_read_param(dump_buf,
7105                    &param_name, &param_str_val, &param_num_val);
7106     if (strcmp(param_name, "size"))
7107         return DBG_STATUS_REG_FIFO_BAD_DATA;
7108     if (param_num_val % REG_FIFO_ELEMENT_DWORDS)
7109         return DBG_STATUS_REG_FIFO_BAD_DATA;
7110     num_elements = param_num_val / REG_FIFO_ELEMENT_DWORDS;
7111     elements = (struct reg_fifo_element *)dump_buf;
7112 
7113     /* Decode elements */
7114     for (i = 0; i < num_elements; i++) {
7115         const char *err_msg = NULL;
7116 
7117         /* Discover if element belongs to a VF or a PF */
7118         vf_val = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_VF);
7119         if (vf_val == REG_FIFO_ELEMENT_IS_PF_VF_VAL)
7120             sprintf(vf_str, "%s", "N/A");
7121         else
7122             sprintf(vf_str, "%d", vf_val);
7123 
7124         /* Find error message */
7125         err_code = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_ERROR);
7126         for (j = 0; j < ARRAY_SIZE(s_reg_fifo_errors) && !err_msg; j++)
7127             if (err_code == s_reg_fifo_errors[j].err_code)
7128                 err_msg = s_reg_fifo_errors[j].err_msg;
7129 
7130         /* Add parsed element to parsed buffer */
7131         results_offset +=
7132             sprintf(qed_get_buf_ptr(results_buf,
7133                         results_offset),
7134                 "raw: 0x%016llx, address: 0x%07x, access: %-5s, pf: %2d, vf: %s, port: %d, privilege: %-3s, protection: %-12s, master: %-4s, error: %s\n",
7135                 elements[i].data,
7136                 (u32)GET_FIELD(elements[i].data,
7137                        REG_FIFO_ELEMENT_ADDRESS) *
7138                 REG_FIFO_ELEMENT_ADDR_FACTOR,
7139                 s_access_strs[GET_FIELD(elements[i].data,
7140                             REG_FIFO_ELEMENT_ACCESS)],
7141                 (u32)GET_FIELD(elements[i].data,
7142                        REG_FIFO_ELEMENT_PF),
7143                 vf_str,
7144                 (u32)GET_FIELD(elements[i].data,
7145                        REG_FIFO_ELEMENT_PORT),
7146                 s_privilege_strs[GET_FIELD(elements[i].data,
7147                         REG_FIFO_ELEMENT_PRIVILEGE)],
7148                 s_protection_strs[GET_FIELD(elements[i].data,
7149                         REG_FIFO_ELEMENT_PROTECTION)],
7150                 s_master_strs[GET_FIELD(elements[i].data,
7151                             REG_FIFO_ELEMENT_MASTER)],
7152                 err_msg ? err_msg : "unknown error code");
7153     }
7154 
7155     results_offset += sprintf(qed_get_buf_ptr(results_buf,
7156                           results_offset),
7157                   "fifo contained %d elements", num_elements);
7158 
7159     /* Add 1 for string NULL termination */
7160     *parsed_results_bytes = results_offset + 1;
7161 
7162     return DBG_STATUS_OK;
7163 }
7164 
7165 static enum dbg_status qed_parse_igu_fifo_element(struct igu_fifo_element
7166                           *element, char
7167                           *results_buf,
7168                           u32 *results_offset)
7169 {
7170     const struct igu_fifo_addr_data *found_addr = NULL;
7171     u8 source, err_type, i, is_cleanup;
7172     char parsed_addr_data[32];
7173     char parsed_wr_data[256];
7174     u32 wr_data, prod_cons;
7175     bool is_wr_cmd, is_pf;
7176     u16 cmd_addr;
7177     u64 dword12;
7178 
7179     /* Dword12 (dword index 1 and 2) contains bits 32..95 of the
7180      * FIFO element.
7181      */
7182     dword12 = ((u64)element->dword2 << 32) | element->dword1;
7183     is_wr_cmd = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD);
7184     is_pf = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_IS_PF);
7185     cmd_addr = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR);
7186     source = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_SOURCE);
7187     err_type = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE);
7188 
7189     if (source >= ARRAY_SIZE(s_igu_fifo_source_strs))
7190         return DBG_STATUS_IGU_FIFO_BAD_DATA;
7191     if (err_type >= ARRAY_SIZE(s_igu_fifo_error_strs))
7192         return DBG_STATUS_IGU_FIFO_BAD_DATA;
7193 
7194     /* Find address data */
7195     for (i = 0; i < ARRAY_SIZE(s_igu_fifo_addr_data) && !found_addr; i++) {
7196         const struct igu_fifo_addr_data *curr_addr =
7197             &s_igu_fifo_addr_data[i];
7198 
7199         if (cmd_addr >= curr_addr->start_addr && cmd_addr <=
7200             curr_addr->end_addr)
7201             found_addr = curr_addr;
7202     }
7203 
7204     if (!found_addr)
7205         return DBG_STATUS_IGU_FIFO_BAD_DATA;
7206 
7207     /* Prepare parsed address data */
7208     switch (found_addr->type) {
7209     case IGU_ADDR_TYPE_MSIX_MEM:
7210         sprintf(parsed_addr_data, " vector_num = 0x%x", cmd_addr / 2);
7211         break;
7212     case IGU_ADDR_TYPE_WRITE_INT_ACK:
7213     case IGU_ADDR_TYPE_WRITE_PROD_UPDATE:
7214         sprintf(parsed_addr_data,
7215             " SB = 0x%x", cmd_addr - found_addr->start_addr);
7216         break;
7217     default:
7218         parsed_addr_data[0] = '\0';
7219     }
7220 
7221     if (!is_wr_cmd) {
7222         parsed_wr_data[0] = '\0';
7223         goto out;
7224     }
7225 
7226     /* Prepare parsed write data */
7227     wr_data = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_WR_DATA);
7228     prod_cons = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_PROD_CONS);
7229     is_cleanup = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_CMD_TYPE);
7230 
7231     if (source == IGU_SRC_ATTN) {
7232         sprintf(parsed_wr_data, "prod: 0x%x, ", prod_cons);
7233     } else {
7234         if (is_cleanup) {
7235             u8 cleanup_val, cleanup_type;
7236 
7237             cleanup_val =
7238                 GET_FIELD(wr_data,
7239                       IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL);
7240             cleanup_type =
7241                 GET_FIELD(wr_data,
7242                       IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE);
7243 
7244             sprintf(parsed_wr_data,
7245                 "cmd_type: cleanup, cleanup_val: %s, cleanup_type : %d, ",
7246                 cleanup_val ? "set" : "clear",
7247                 cleanup_type);
7248         } else {
7249             u8 update_flag, en_dis_int_for_sb, segment;
7250             u8 timer_mask;
7251 
7252             update_flag = GET_FIELD(wr_data,
7253                         IGU_FIFO_WR_DATA_UPDATE_FLAG);
7254             en_dis_int_for_sb =
7255                 GET_FIELD(wr_data,
7256                       IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB);
7257             segment = GET_FIELD(wr_data,
7258                         IGU_FIFO_WR_DATA_SEGMENT);
7259             timer_mask = GET_FIELD(wr_data,
7260                            IGU_FIFO_WR_DATA_TIMER_MASK);
7261 
7262             sprintf(parsed_wr_data,
7263                 "cmd_type: prod/cons update, prod/cons: 0x%x, update_flag: %s, en_dis_int_for_sb : %s, segment : %s, timer_mask = %d, ",
7264                 prod_cons,
7265                 update_flag ? "update" : "nop",
7266                 en_dis_int_for_sb ?
7267                 (en_dis_int_for_sb == 1 ? "disable" : "nop") :
7268                 "enable",
7269                 segment ? "attn" : "regular",
7270                 timer_mask);
7271         }
7272     }
7273 out:
7274     /* Add parsed element to parsed buffer */
7275     *results_offset += sprintf(qed_get_buf_ptr(results_buf,
7276                            *results_offset),
7277                    "raw: 0x%01x%08x%08x, %s: %d, source : %s, type : %s, cmd_addr : 0x%x(%s%s), %serror: %s\n",
7278                    element->dword2, element->dword1,
7279                    element->dword0,
7280                    is_pf ? "pf" : "vf",
7281                    GET_FIELD(element->dword0,
7282                          IGU_FIFO_ELEMENT_DWORD0_FID),
7283                    s_igu_fifo_source_strs[source],
7284                    is_wr_cmd ? "wr" : "rd",
7285                    cmd_addr,
7286                    (!is_pf && found_addr->vf_desc)
7287                    ? found_addr->vf_desc
7288                    : found_addr->desc,
7289                    parsed_addr_data,
7290                    parsed_wr_data,
7291                    s_igu_fifo_error_strs[err_type]);
7292 
7293     return DBG_STATUS_OK;
7294 }
7295 
7296 /* Parses an IGU FIFO dump buffer.
7297  * If result_buf is not NULL, the IGU FIFO results are printed to it.
7298  * In any case, the required results buffer size is assigned to
7299  * parsed_results_bytes.
7300  * The parsing status is returned.
7301  */
7302 static enum dbg_status qed_parse_igu_fifo_dump(u32 *dump_buf,
7303                            char *results_buf,
7304                            u32 *parsed_results_bytes)
7305 {
7306     const char *section_name, *param_name, *param_str_val;
7307     u32 param_num_val, num_section_params, num_elements;
7308     struct igu_fifo_element *elements;
7309     enum dbg_status status;
7310     u32 results_offset = 0;
7311     u8 i;
7312 
7313     /* Read global_params section */
7314     dump_buf += qed_read_section_hdr(dump_buf,
7315                      &section_name, &num_section_params);
7316     if (strcmp(section_name, "global_params"))
7317         return DBG_STATUS_IGU_FIFO_BAD_DATA;
7318 
7319     /* Print global params */
7320     dump_buf += qed_print_section_params(dump_buf,
7321                          num_section_params,
7322                          results_buf, &results_offset);
7323 
7324     /* Read igu_fifo_data section */
7325     dump_buf += qed_read_section_hdr(dump_buf,
7326                      &section_name, &num_section_params);
7327     if (strcmp(section_name, "igu_fifo_data"))
7328         return DBG_STATUS_IGU_FIFO_BAD_DATA;
7329     dump_buf += qed_read_param(dump_buf,
7330                    &param_name, &param_str_val, &param_num_val);
7331     if (strcmp(param_name, "size"))
7332         return DBG_STATUS_IGU_FIFO_BAD_DATA;
7333     if (param_num_val % IGU_FIFO_ELEMENT_DWORDS)
7334         return DBG_STATUS_IGU_FIFO_BAD_DATA;
7335     num_elements = param_num_val / IGU_FIFO_ELEMENT_DWORDS;
7336     elements = (struct igu_fifo_element *)dump_buf;
7337 
7338     /* Decode elements */
7339     for (i = 0; i < num_elements; i++) {
7340         status = qed_parse_igu_fifo_element(&elements[i],
7341                             results_buf,
7342                             &results_offset);
7343         if (status != DBG_STATUS_OK)
7344             return status;
7345     }
7346 
7347     results_offset += sprintf(qed_get_buf_ptr(results_buf,
7348                           results_offset),
7349                   "fifo contained %d elements", num_elements);
7350 
7351     /* Add 1 for string NULL termination */
7352     *parsed_results_bytes = results_offset + 1;
7353 
7354     return DBG_STATUS_OK;
7355 }
7356 
7357 static enum dbg_status
7358 qed_parse_protection_override_dump(u32 *dump_buf,
7359                    char *results_buf,
7360                    u32 *parsed_results_bytes)
7361 {
7362     const char *section_name, *param_name, *param_str_val;
7363     u32 param_num_val, num_section_params, num_elements;
7364     struct protection_override_element *elements;
7365     u32 results_offset = 0;
7366     u8 i;
7367 
7368     /* Read global_params section */
7369     dump_buf += qed_read_section_hdr(dump_buf,
7370                      &section_name, &num_section_params);
7371     if (strcmp(section_name, "global_params"))
7372         return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7373 
7374     /* Print global params */
7375     dump_buf += qed_print_section_params(dump_buf,
7376                          num_section_params,
7377                          results_buf, &results_offset);
7378 
7379     /* Read protection_override_data section */
7380     dump_buf += qed_read_section_hdr(dump_buf,
7381                      &section_name, &num_section_params);
7382     if (strcmp(section_name, "protection_override_data"))
7383         return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7384     dump_buf += qed_read_param(dump_buf,
7385                    &param_name, &param_str_val, &param_num_val);
7386     if (strcmp(param_name, "size"))
7387         return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7388     if (param_num_val % PROTECTION_OVERRIDE_ELEMENT_DWORDS)
7389         return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7390     num_elements = param_num_val / PROTECTION_OVERRIDE_ELEMENT_DWORDS;
7391     elements = (struct protection_override_element *)dump_buf;
7392 
7393     /* Decode elements */
7394     for (i = 0; i < num_elements; i++) {
7395         u32 address = GET_FIELD(elements[i].data,
7396                     PROTECTION_OVERRIDE_ELEMENT_ADDRESS) *
7397                   PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR;
7398 
7399         results_offset +=
7400             sprintf(qed_get_buf_ptr(results_buf,
7401                         results_offset),
7402                 "window %2d, address: 0x%07x, size: %7d regs, read: %d, write: %d, read protection: %-12s, write protection: %-12s\n",
7403                 i, address,
7404                 (u32)GET_FIELD(elements[i].data,
7405                       PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE),
7406                 (u32)GET_FIELD(elements[i].data,
7407                       PROTECTION_OVERRIDE_ELEMENT_READ),
7408                 (u32)GET_FIELD(elements[i].data,
7409                       PROTECTION_OVERRIDE_ELEMENT_WRITE),
7410                 s_protection_strs[GET_FIELD(elements[i].data,
7411                 PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION)],
7412                 s_protection_strs[GET_FIELD(elements[i].data,
7413                 PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION)]);
7414     }
7415 
7416     results_offset += sprintf(qed_get_buf_ptr(results_buf,
7417                           results_offset),
7418                   "protection override contained %d elements",
7419                   num_elements);
7420 
7421     /* Add 1 for string NULL termination */
7422     *parsed_results_bytes = results_offset + 1;
7423 
7424     return DBG_STATUS_OK;
7425 }
7426 
7427 /* Parses a FW Asserts dump buffer.
7428  * If result_buf is not NULL, the FW Asserts results are printed to it.
7429  * In any case, the required results buffer size is assigned to
7430  * parsed_results_bytes.
7431  * The parsing status is returned.
7432  */
7433 static enum dbg_status qed_parse_fw_asserts_dump(u32 *dump_buf,
7434                          char *results_buf,
7435                          u32 *parsed_results_bytes)
7436 {
7437     u32 num_section_params, param_num_val, i, results_offset = 0;
7438     const char *param_name, *param_str_val, *section_name;
7439     bool last_section_found = false;
7440 
7441     *parsed_results_bytes = 0;
7442 
7443     /* Read global_params section */
7444     dump_buf += qed_read_section_hdr(dump_buf,
7445                      &section_name, &num_section_params);
7446     if (strcmp(section_name, "global_params"))
7447         return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7448 
7449     /* Print global params */
7450     dump_buf += qed_print_section_params(dump_buf,
7451                          num_section_params,
7452                          results_buf, &results_offset);
7453 
7454     while (!last_section_found) {
7455         dump_buf += qed_read_section_hdr(dump_buf,
7456                          &section_name,
7457                          &num_section_params);
7458         if (!strcmp(section_name, "fw_asserts")) {
7459             /* Extract params */
7460             const char *storm_letter = NULL;
7461             u32 storm_dump_size = 0;
7462 
7463             for (i = 0; i < num_section_params; i++) {
7464                 dump_buf += qed_read_param(dump_buf,
7465                                &param_name,
7466                                &param_str_val,
7467                                &param_num_val);
7468                 if (!strcmp(param_name, "storm"))
7469                     storm_letter = param_str_val;
7470                 else if (!strcmp(param_name, "size"))
7471                     storm_dump_size = param_num_val;
7472                 else
7473                     return
7474                         DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7475             }
7476 
7477             if (!storm_letter || !storm_dump_size)
7478                 return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7479 
7480             /* Print data */
7481             results_offset +=
7482                 sprintf(qed_get_buf_ptr(results_buf,
7483                             results_offset),
7484                     "\n%sSTORM_ASSERT: size=%d\n",
7485                     storm_letter, storm_dump_size);
7486             for (i = 0; i < storm_dump_size; i++, dump_buf++)
7487                 results_offset +=
7488                     sprintf(qed_get_buf_ptr(results_buf,
7489                                 results_offset),
7490                         "%08x\n", *dump_buf);
7491         } else if (!strcmp(section_name, "last")) {
7492             last_section_found = true;
7493         } else {
7494             return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7495         }
7496     }
7497 
7498     /* Add 1 for string NULL termination */
7499     *parsed_results_bytes = results_offset + 1;
7500 
7501     return DBG_STATUS_OK;
7502 }
7503 
7504 /***************************** Public Functions *******************************/
7505 
7506 enum dbg_status qed_dbg_user_set_bin_ptr(struct qed_hwfn *p_hwfn,
7507                      const u8 * const bin_ptr)
7508 {
7509     struct bin_buffer_hdr *buf_hdrs = (struct bin_buffer_hdr *)bin_ptr;
7510     u8 buf_id;
7511 
7512     /* Convert binary data to debug arrays */
7513     for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++)
7514         qed_set_dbg_bin_buf(p_hwfn,
7515                     (enum bin_dbg_buffer_type)buf_id,
7516                     (u32 *)(bin_ptr + buf_hdrs[buf_id].offset),
7517                     buf_hdrs[buf_id].length);
7518 
7519     return DBG_STATUS_OK;
7520 }
7521 
7522 enum dbg_status qed_dbg_alloc_user_data(struct qed_hwfn *p_hwfn,
7523                     void **user_data_ptr)
7524 {
7525     *user_data_ptr = kzalloc(sizeof(struct dbg_tools_user_data),
7526                  GFP_KERNEL);
7527     if (!(*user_data_ptr))
7528         return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
7529 
7530     return DBG_STATUS_OK;
7531 }
7532 
7533 const char *qed_dbg_get_status_str(enum dbg_status status)
7534 {
7535     return (status <
7536         MAX_DBG_STATUS) ? s_status_str[status] : "Invalid debug status";
7537 }
7538 
7539 enum dbg_status qed_get_idle_chk_results_buf_size(struct qed_hwfn *p_hwfn,
7540                           u32 *dump_buf,
7541                           u32 num_dumped_dwords,
7542                           u32 *results_buf_size)
7543 {
7544     u32 num_errors, num_warnings;
7545 
7546     return qed_parse_idle_chk_dump(p_hwfn,
7547                        dump_buf,
7548                        num_dumped_dwords,
7549                        NULL,
7550                        results_buf_size,
7551                        &num_errors, &num_warnings);
7552 }
7553 
7554 enum dbg_status qed_print_idle_chk_results(struct qed_hwfn *p_hwfn,
7555                        u32 *dump_buf,
7556                        u32 num_dumped_dwords,
7557                        char *results_buf,
7558                        u32 *num_errors,
7559                        u32 *num_warnings)
7560 {
7561     u32 parsed_buf_size;
7562 
7563     return qed_parse_idle_chk_dump(p_hwfn,
7564                        dump_buf,
7565                        num_dumped_dwords,
7566                        results_buf,
7567                        &parsed_buf_size,
7568                        num_errors, num_warnings);
7569 }
7570 
7571 void qed_dbg_mcp_trace_set_meta_data(struct qed_hwfn *p_hwfn,
7572                      const u32 *meta_buf)
7573 {
7574     struct dbg_tools_user_data *dev_user_data =
7575         qed_dbg_get_user_data(p_hwfn);
7576 
7577     dev_user_data->mcp_trace_user_meta_buf = meta_buf;
7578 }
7579 
7580 enum dbg_status qed_get_mcp_trace_results_buf_size(struct qed_hwfn *p_hwfn,
7581                            u32 *dump_buf,
7582                            u32 num_dumped_dwords,
7583                            u32 *results_buf_size)
7584 {
7585     return qed_parse_mcp_trace_dump(p_hwfn,
7586                     dump_buf, NULL, results_buf_size, true);
7587 }
7588 
7589 enum dbg_status qed_print_mcp_trace_results(struct qed_hwfn *p_hwfn,
7590                         u32 *dump_buf,
7591                         u32 num_dumped_dwords,
7592                         char *results_buf)
7593 {
7594     u32 parsed_buf_size;
7595 
7596     /* Doesn't do anything, needed for compile time asserts */
7597     qed_user_static_asserts();
7598 
7599     return qed_parse_mcp_trace_dump(p_hwfn,
7600                     dump_buf,
7601                     results_buf, &parsed_buf_size, true);
7602 }
7603 
7604 enum dbg_status qed_print_mcp_trace_results_cont(struct qed_hwfn *p_hwfn,
7605                          u32 *dump_buf,
7606                          char *results_buf)
7607 {
7608     u32 parsed_buf_size;
7609 
7610     return qed_parse_mcp_trace_dump(p_hwfn, dump_buf, results_buf,
7611                     &parsed_buf_size, false);
7612 }
7613 
7614 enum dbg_status qed_print_mcp_trace_line(struct qed_hwfn *p_hwfn,
7615                      u8 *dump_buf,
7616                      u32 num_dumped_bytes,
7617                      char *results_buf)
7618 {
7619     u32 parsed_results_bytes;
7620 
7621     return qed_parse_mcp_trace_buf(p_hwfn,
7622                        dump_buf,
7623                        num_dumped_bytes,
7624                        0,
7625                        num_dumped_bytes,
7626                        results_buf, &parsed_results_bytes);
7627 }
7628 
7629 /* Frees the specified MCP Trace meta data */
7630 void qed_mcp_trace_free_meta_data(struct qed_hwfn *p_hwfn)
7631 {
7632     struct dbg_tools_user_data *dev_user_data;
7633     struct mcp_trace_meta *meta;
7634     u32 i;
7635 
7636     dev_user_data = qed_dbg_get_user_data(p_hwfn);
7637     meta = &dev_user_data->mcp_trace_meta;
7638     if (!meta->is_allocated)
7639         return;
7640 
7641     /* Release modules */
7642     if (meta->modules) {
7643         for (i = 0; i < meta->modules_num; i++)
7644             kfree(meta->modules[i]);
7645         kfree(meta->modules);
7646     }
7647 
7648     /* Release formats */
7649     if (meta->formats) {
7650         for (i = 0; i < meta->formats_num; i++)
7651             kfree(meta->formats[i].format_str);
7652         kfree(meta->formats);
7653     }
7654 
7655     meta->is_allocated = false;
7656 }
7657 
7658 enum dbg_status qed_get_reg_fifo_results_buf_size(struct qed_hwfn *p_hwfn,
7659                           u32 *dump_buf,
7660                           u32 num_dumped_dwords,
7661                           u32 *results_buf_size)
7662 {
7663     return qed_parse_reg_fifo_dump(dump_buf, NULL, results_buf_size);
7664 }
7665 
7666 enum dbg_status qed_print_reg_fifo_results(struct qed_hwfn *p_hwfn,
7667                        u32 *dump_buf,
7668                        u32 num_dumped_dwords,
7669                        char *results_buf)
7670 {
7671     u32 parsed_buf_size;
7672 
7673     return qed_parse_reg_fifo_dump(dump_buf, results_buf, &parsed_buf_size);
7674 }
7675 
7676 enum dbg_status qed_get_igu_fifo_results_buf_size(struct qed_hwfn *p_hwfn,
7677                           u32 *dump_buf,
7678                           u32 num_dumped_dwords,
7679                           u32 *results_buf_size)
7680 {
7681     return qed_parse_igu_fifo_dump(dump_buf, NULL, results_buf_size);
7682 }
7683 
7684 enum dbg_status qed_print_igu_fifo_results(struct qed_hwfn *p_hwfn,
7685                        u32 *dump_buf,
7686                        u32 num_dumped_dwords,
7687                        char *results_buf)
7688 {
7689     u32 parsed_buf_size;
7690 
7691     return qed_parse_igu_fifo_dump(dump_buf, results_buf, &parsed_buf_size);
7692 }
7693 
7694 enum dbg_status
7695 qed_get_protection_override_results_buf_size(struct qed_hwfn *p_hwfn,
7696                          u32 *dump_buf,
7697                          u32 num_dumped_dwords,
7698                          u32 *results_buf_size)
7699 {
7700     return qed_parse_protection_override_dump(dump_buf,
7701                           NULL, results_buf_size);
7702 }
7703 
7704 enum dbg_status qed_print_protection_override_results(struct qed_hwfn *p_hwfn,
7705                               u32 *dump_buf,
7706                               u32 num_dumped_dwords,
7707                               char *results_buf)
7708 {
7709     u32 parsed_buf_size;
7710 
7711     return qed_parse_protection_override_dump(dump_buf,
7712                           results_buf,
7713                           &parsed_buf_size);
7714 }
7715 
7716 enum dbg_status qed_get_fw_asserts_results_buf_size(struct qed_hwfn *p_hwfn,
7717                             u32 *dump_buf,
7718                             u32 num_dumped_dwords,
7719                             u32 *results_buf_size)
7720 {
7721     return qed_parse_fw_asserts_dump(dump_buf, NULL, results_buf_size);
7722 }
7723 
7724 enum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn,
7725                          u32 *dump_buf,
7726                          u32 num_dumped_dwords,
7727                          char *results_buf)
7728 {
7729     u32 parsed_buf_size;
7730 
7731     return qed_parse_fw_asserts_dump(dump_buf,
7732                      results_buf, &parsed_buf_size);
7733 }
7734 
7735 enum dbg_status qed_dbg_parse_attn(struct qed_hwfn *p_hwfn,
7736                    struct dbg_attn_block_result *results)
7737 {
7738     const u32 *block_attn_name_offsets;
7739     const char *attn_name_base;
7740     const char *block_name;
7741     enum dbg_attn_type attn_type;
7742     u8 num_regs, i, j;
7743 
7744     num_regs = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_NUM_REGS);
7745     attn_type = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE);
7746     block_name = qed_dbg_get_block_name(p_hwfn, results->block_id);
7747     if (!block_name)
7748         return DBG_STATUS_INVALID_ARGS;
7749 
7750     if (!p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr ||
7751         !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr ||
7752         !p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr)
7753         return DBG_STATUS_DBG_ARRAY_NOT_SET;
7754 
7755     block_attn_name_offsets =
7756         (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr +
7757         results->names_offset;
7758 
7759     attn_name_base = p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr;
7760 
7761     /* Go over registers with a non-zero attention status */
7762     for (i = 0; i < num_regs; i++) {
7763         struct dbg_attn_bit_mapping *bit_mapping;
7764         struct dbg_attn_reg_result *reg_result;
7765         u8 num_reg_attn, bit_idx = 0;
7766 
7767         reg_result = &results->reg_results[i];
7768         num_reg_attn = GET_FIELD(reg_result->data,
7769                      DBG_ATTN_REG_RESULT_NUM_REG_ATTN);
7770         bit_mapping = (struct dbg_attn_bit_mapping *)
7771             p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr +
7772             reg_result->block_attn_offset;
7773 
7774         /* Go over attention status bits */
7775         for (j = 0; j < num_reg_attn; j++) {
7776             u16 attn_idx_val = GET_FIELD(bit_mapping[j].data,
7777                              DBG_ATTN_BIT_MAPPING_VAL);
7778             const char *attn_name, *attn_type_str, *masked_str;
7779             u32 attn_name_offset;
7780             u32 sts_addr;
7781 
7782             /* Check if bit mask should be advanced (due to unused
7783              * bits).
7784              */
7785             if (GET_FIELD(bit_mapping[j].data,
7786                       DBG_ATTN_BIT_MAPPING_IS_UNUSED_BIT_CNT)) {
7787                 bit_idx += (u8)attn_idx_val;
7788                 continue;
7789             }
7790 
7791             /* Check current bit index */
7792             if (reg_result->sts_val & BIT(bit_idx)) {
7793                 /* An attention bit with value=1 was found
7794                  * Find attention name
7795                  */
7796                 attn_name_offset =
7797                     block_attn_name_offsets[attn_idx_val];
7798                 attn_name = attn_name_base + attn_name_offset;
7799                 attn_type_str =
7800                     (attn_type ==
7801                      ATTN_TYPE_INTERRUPT ? "Interrupt" :
7802                      "Parity");
7803                 masked_str = reg_result->mask_val &
7804                          BIT(bit_idx) ?
7805                          " [masked]" : "";
7806                 sts_addr =
7807                 GET_FIELD(reg_result->data,
7808                       DBG_ATTN_REG_RESULT_STS_ADDRESS);
7809                 DP_NOTICE(p_hwfn,
7810                       "%s (%s) : %s [address 0x%08x, bit %d]%s\n",
7811                       block_name, attn_type_str, attn_name,
7812                       sts_addr * 4, bit_idx, masked_str);
7813             }
7814 
7815             bit_idx++;
7816         }
7817     }
7818 
7819     return DBG_STATUS_OK;
7820 }
7821 
7822 /* Wrapper for unifying the idle_chk and mcp_trace api */
7823 static enum dbg_status
7824 qed_print_idle_chk_results_wrapper(struct qed_hwfn *p_hwfn,
7825                    u32 *dump_buf,
7826                    u32 num_dumped_dwords,
7827                    char *results_buf)
7828 {
7829     u32 num_errors, num_warnnings;
7830 
7831     return qed_print_idle_chk_results(p_hwfn, dump_buf, num_dumped_dwords,
7832                       results_buf, &num_errors,
7833                       &num_warnnings);
7834 }
7835 
7836 static DEFINE_MUTEX(qed_dbg_lock);
7837 
7838 #define MAX_PHY_RESULT_BUFFER 9000
7839 
7840 /******************************** Feature Meta data section ******************/
7841 
7842 #define GRC_NUM_STR_FUNCS 2
7843 #define IDLE_CHK_NUM_STR_FUNCS 1
7844 #define MCP_TRACE_NUM_STR_FUNCS 1
7845 #define REG_FIFO_NUM_STR_FUNCS 1
7846 #define IGU_FIFO_NUM_STR_FUNCS 1
7847 #define PROTECTION_OVERRIDE_NUM_STR_FUNCS 1
7848 #define FW_ASSERTS_NUM_STR_FUNCS 1
7849 #define ILT_NUM_STR_FUNCS 1
7850 #define PHY_NUM_STR_FUNCS 20
7851 
7852 /* Feature meta data lookup table */
7853 static struct {
7854     char *name;
7855     u32 num_funcs;
7856     enum dbg_status (*get_size)(struct qed_hwfn *p_hwfn,
7857                     struct qed_ptt *p_ptt, u32 *size);
7858     enum dbg_status (*perform_dump)(struct qed_hwfn *p_hwfn,
7859                     struct qed_ptt *p_ptt, u32 *dump_buf,
7860                     u32 buf_size, u32 *dumped_dwords);
7861     enum dbg_status (*print_results)(struct qed_hwfn *p_hwfn,
7862                      u32 *dump_buf, u32 num_dumped_dwords,
7863                      char *results_buf);
7864     enum dbg_status (*results_buf_size)(struct qed_hwfn *p_hwfn,
7865                         u32 *dump_buf,
7866                         u32 num_dumped_dwords,
7867                         u32 *results_buf_size);
7868     const struct qed_func_lookup *hsi_func_lookup;
7869 } qed_features_lookup[] = {
7870     {
7871     "grc", GRC_NUM_STR_FUNCS, qed_dbg_grc_get_dump_buf_size,
7872             qed_dbg_grc_dump, NULL, NULL, NULL}, {
7873     "idle_chk", IDLE_CHK_NUM_STR_FUNCS,
7874             qed_dbg_idle_chk_get_dump_buf_size,
7875             qed_dbg_idle_chk_dump,
7876             qed_print_idle_chk_results_wrapper,
7877             qed_get_idle_chk_results_buf_size,
7878             NULL}, {
7879     "mcp_trace", MCP_TRACE_NUM_STR_FUNCS,
7880             qed_dbg_mcp_trace_get_dump_buf_size,
7881             qed_dbg_mcp_trace_dump, qed_print_mcp_trace_results,
7882             qed_get_mcp_trace_results_buf_size,
7883             NULL}, {
7884     "reg_fifo", REG_FIFO_NUM_STR_FUNCS,
7885             qed_dbg_reg_fifo_get_dump_buf_size,
7886             qed_dbg_reg_fifo_dump, qed_print_reg_fifo_results,
7887             qed_get_reg_fifo_results_buf_size,
7888             NULL}, {
7889     "igu_fifo", IGU_FIFO_NUM_STR_FUNCS,
7890             qed_dbg_igu_fifo_get_dump_buf_size,
7891             qed_dbg_igu_fifo_dump, qed_print_igu_fifo_results,
7892             qed_get_igu_fifo_results_buf_size,
7893             NULL}, {
7894     "protection_override", PROTECTION_OVERRIDE_NUM_STR_FUNCS,
7895             qed_dbg_protection_override_get_dump_buf_size,
7896             qed_dbg_protection_override_dump,
7897             qed_print_protection_override_results,
7898             qed_get_protection_override_results_buf_size,
7899             NULL}, {
7900     "fw_asserts", FW_ASSERTS_NUM_STR_FUNCS,
7901             qed_dbg_fw_asserts_get_dump_buf_size,
7902             qed_dbg_fw_asserts_dump,
7903             qed_print_fw_asserts_results,
7904             qed_get_fw_asserts_results_buf_size,
7905             NULL}, {
7906     "ilt", ILT_NUM_STR_FUNCS, qed_dbg_ilt_get_dump_buf_size,
7907             qed_dbg_ilt_dump, NULL, NULL, NULL},};
7908 
7909 static void qed_dbg_print_feature(u8 *p_text_buf, u32 text_size)
7910 {
7911     u32 i, precision = 80;
7912 
7913     if (!p_text_buf)
7914         return;
7915 
7916     pr_notice("\n%.*s", precision, p_text_buf);
7917     for (i = precision; i < text_size; i += precision)
7918         pr_cont("%.*s", precision, p_text_buf + i);
7919     pr_cont("\n");
7920 }
7921 
7922 #define QED_RESULTS_BUF_MIN_SIZE 16
7923 /* Generic function for decoding debug feature info */
7924 static enum dbg_status format_feature(struct qed_hwfn *p_hwfn,
7925                       enum qed_dbg_features feature_idx)
7926 {
7927     struct qed_dbg_feature *feature =
7928         &p_hwfn->cdev->dbg_features[feature_idx];
7929     u32 txt_size_bytes, null_char_pos, i;
7930     u32 *dbuf, dwords;
7931     enum dbg_status rc;
7932     char *text_buf;
7933 
7934     /* Check if feature supports formatting capability */
7935     if (!qed_features_lookup[feature_idx].results_buf_size)
7936         return DBG_STATUS_OK;
7937 
7938     dbuf = (u32 *)feature->dump_buf;
7939     dwords = feature->dumped_dwords;
7940 
7941     /* Obtain size of formatted output */
7942     rc = qed_features_lookup[feature_idx].results_buf_size(p_hwfn,
7943                                    dbuf,
7944                                    dwords,
7945                                    &txt_size_bytes);
7946     if (rc != DBG_STATUS_OK)
7947         return rc;
7948 
7949     /* Make sure that the allocated size is a multiple of dword
7950      * (4 bytes).
7951      */
7952     null_char_pos = txt_size_bytes - 1;
7953     txt_size_bytes = (txt_size_bytes + 3) & ~0x3;
7954 
7955     if (txt_size_bytes < QED_RESULTS_BUF_MIN_SIZE) {
7956         DP_NOTICE(p_hwfn->cdev,
7957               "formatted size of feature was too small %d. Aborting\n",
7958               txt_size_bytes);
7959         return DBG_STATUS_INVALID_ARGS;
7960     }
7961 
7962     /* allocate temp text buf */
7963     text_buf = vzalloc(txt_size_bytes);
7964     if (!text_buf) {
7965         DP_NOTICE(p_hwfn->cdev,
7966               "failed to allocate text buffer. Aborting\n");
7967         return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
7968     }
7969 
7970     /* Decode feature opcodes to string on temp buf */
7971     rc = qed_features_lookup[feature_idx].print_results(p_hwfn,
7972                                 dbuf,
7973                                 dwords,
7974                                 text_buf);
7975     if (rc != DBG_STATUS_OK) {
7976         vfree(text_buf);
7977         return rc;
7978     }
7979 
7980     /* Replace the original null character with a '\n' character.
7981      * The bytes that were added as a result of the dword alignment are also
7982      * padded with '\n' characters.
7983      */
7984     for (i = null_char_pos; i < txt_size_bytes; i++)
7985         text_buf[i] = '\n';
7986 
7987     /* Dump printable feature to log */
7988     if (p_hwfn->cdev->print_dbg_data)
7989         qed_dbg_print_feature(text_buf, txt_size_bytes);
7990 
7991     /* Dump binary data as is to the output file */
7992     if (p_hwfn->cdev->dbg_bin_dump) {
7993         vfree(text_buf);
7994         return rc;
7995     }
7996 
7997     /* Free the old dump_buf and point the dump_buf to the newly allocated
7998      * and formatted text buffer.
7999      */
8000     vfree(feature->dump_buf);
8001     feature->dump_buf = text_buf;
8002     feature->buf_size = txt_size_bytes;
8003     feature->dumped_dwords = txt_size_bytes / 4;
8004 
8005     return rc;
8006 }
8007 
8008 #define MAX_DBG_FEATURE_SIZE_DWORDS 0x3FFFFFFF
8009 
8010 /* Generic function for performing the dump of a debug feature. */
8011 static enum dbg_status qed_dbg_dump(struct qed_hwfn *p_hwfn,
8012                     struct qed_ptt *p_ptt,
8013                     enum qed_dbg_features feature_idx)
8014 {
8015     struct qed_dbg_feature *feature =
8016         &p_hwfn->cdev->dbg_features[feature_idx];
8017     u32 buf_size_dwords, *dbuf, *dwords;
8018     enum dbg_status rc;
8019 
8020     DP_NOTICE(p_hwfn->cdev, "Collecting a debug feature [\"%s\"]\n",
8021           qed_features_lookup[feature_idx].name);
8022 
8023     /* Dump_buf was already allocated need to free (this can happen if dump
8024      * was called but file was never read).
8025      * We can't use the buffer as is since size may have changed.
8026      */
8027     if (feature->dump_buf) {
8028         vfree(feature->dump_buf);
8029         feature->dump_buf = NULL;
8030     }
8031 
8032     /* Get buffer size from hsi, allocate accordingly, and perform the
8033      * dump.
8034      */
8035     rc = qed_features_lookup[feature_idx].get_size(p_hwfn, p_ptt,
8036                                &buf_size_dwords);
8037     if (rc != DBG_STATUS_OK && rc != DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
8038         return rc;
8039 
8040     if (buf_size_dwords > MAX_DBG_FEATURE_SIZE_DWORDS) {
8041         feature->buf_size = 0;
8042         DP_NOTICE(p_hwfn->cdev,
8043               "Debug feature [\"%s\"] size (0x%x dwords) exceeds maximum size (0x%x dwords)\n",
8044               qed_features_lookup[feature_idx].name,
8045               buf_size_dwords, MAX_DBG_FEATURE_SIZE_DWORDS);
8046 
8047         return DBG_STATUS_OK;
8048     }
8049 
8050     feature->buf_size = buf_size_dwords * sizeof(u32);
8051     feature->dump_buf = vmalloc(feature->buf_size);
8052     if (!feature->dump_buf)
8053         return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
8054 
8055     dbuf = (u32 *)feature->dump_buf;
8056     dwords = &feature->dumped_dwords;
8057     rc = qed_features_lookup[feature_idx].perform_dump(p_hwfn, p_ptt,
8058                                dbuf,
8059                                feature->buf_size /
8060                                sizeof(u32),
8061                                dwords);
8062 
8063     /* If mcp is stuck we get DBG_STATUS_NVRAM_GET_IMAGE_FAILED error.
8064      * In this case the buffer holds valid binary data, but we won't able
8065      * to parse it (since parsing relies on data in NVRAM which is only
8066      * accessible when MFW is responsive). skip the formatting but return
8067      * success so that binary data is provided.
8068      */
8069     if (rc == DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
8070         return DBG_STATUS_OK;
8071 
8072     if (rc != DBG_STATUS_OK)
8073         return rc;
8074 
8075     /* Format output */
8076     rc = format_feature(p_hwfn, feature_idx);
8077     return rc;
8078 }
8079 
8080 int qed_dbg_grc(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
8081 {
8082     return qed_dbg_feature(cdev, buffer, DBG_FEATURE_GRC, num_dumped_bytes);
8083 }
8084 
8085 int qed_dbg_grc_size(struct qed_dev *cdev)
8086 {
8087     return qed_dbg_feature_size(cdev, DBG_FEATURE_GRC);
8088 }
8089 
8090 int qed_dbg_idle_chk(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
8091 {
8092     return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IDLE_CHK,
8093                    num_dumped_bytes);
8094 }
8095 
8096 int qed_dbg_idle_chk_size(struct qed_dev *cdev)
8097 {
8098     return qed_dbg_feature_size(cdev, DBG_FEATURE_IDLE_CHK);
8099 }
8100 
8101 int qed_dbg_reg_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
8102 {
8103     return qed_dbg_feature(cdev, buffer, DBG_FEATURE_REG_FIFO,
8104                    num_dumped_bytes);
8105 }
8106 
8107 int qed_dbg_reg_fifo_size(struct qed_dev *cdev)
8108 {
8109     return qed_dbg_feature_size(cdev, DBG_FEATURE_REG_FIFO);
8110 }
8111 
8112 int qed_dbg_igu_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
8113 {
8114     return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IGU_FIFO,
8115                    num_dumped_bytes);
8116 }
8117 
8118 int qed_dbg_igu_fifo_size(struct qed_dev *cdev)
8119 {
8120     return qed_dbg_feature_size(cdev, DBG_FEATURE_IGU_FIFO);
8121 }
8122 
8123 static int qed_dbg_nvm_image_length(struct qed_hwfn *p_hwfn,
8124                     enum qed_nvm_images image_id, u32 *length)
8125 {
8126     struct qed_nvm_image_att image_att;
8127     int rc;
8128 
8129     *length = 0;
8130     rc = qed_mcp_get_nvm_image_att(p_hwfn, image_id, &image_att);
8131     if (rc)
8132         return rc;
8133 
8134     *length = image_att.length;
8135 
8136     return rc;
8137 }
8138 
8139 static int qed_dbg_nvm_image(struct qed_dev *cdev, void *buffer,
8140                  u32 *num_dumped_bytes,
8141                  enum qed_nvm_images image_id)
8142 {
8143     struct qed_hwfn *p_hwfn =
8144         &cdev->hwfns[cdev->engine_for_debug];
8145     u32 len_rounded;
8146     int rc;
8147 
8148     *num_dumped_bytes = 0;
8149     rc = qed_dbg_nvm_image_length(p_hwfn, image_id, &len_rounded);
8150     if (rc)
8151         return rc;
8152 
8153     DP_NOTICE(p_hwfn->cdev,
8154           "Collecting a debug feature [\"nvram image %d\"]\n",
8155           image_id);
8156 
8157     len_rounded = roundup(len_rounded, sizeof(u32));
8158     rc = qed_mcp_get_nvm_image(p_hwfn, image_id, buffer, len_rounded);
8159     if (rc)
8160         return rc;
8161 
8162     /* QED_NVM_IMAGE_NVM_META image is not swapped like other images */
8163     if (image_id != QED_NVM_IMAGE_NVM_META)
8164         cpu_to_be32_array((__force __be32 *)buffer,
8165                   (const u32 *)buffer,
8166                   len_rounded / sizeof(u32));
8167 
8168     *num_dumped_bytes = len_rounded;
8169 
8170     return rc;
8171 }
8172 
8173 int qed_dbg_protection_override(struct qed_dev *cdev, void *buffer,
8174                 u32 *num_dumped_bytes)
8175 {
8176     return qed_dbg_feature(cdev, buffer, DBG_FEATURE_PROTECTION_OVERRIDE,
8177                    num_dumped_bytes);
8178 }
8179 
8180 int qed_dbg_protection_override_size(struct qed_dev *cdev)
8181 {
8182     return qed_dbg_feature_size(cdev, DBG_FEATURE_PROTECTION_OVERRIDE);
8183 }
8184 
8185 int qed_dbg_fw_asserts(struct qed_dev *cdev, void *buffer,
8186                u32 *num_dumped_bytes)
8187 {
8188     return qed_dbg_feature(cdev, buffer, DBG_FEATURE_FW_ASSERTS,
8189                    num_dumped_bytes);
8190 }
8191 
8192 int qed_dbg_fw_asserts_size(struct qed_dev *cdev)
8193 {
8194     return qed_dbg_feature_size(cdev, DBG_FEATURE_FW_ASSERTS);
8195 }
8196 
8197 int qed_dbg_ilt(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
8198 {
8199     return qed_dbg_feature(cdev, buffer, DBG_FEATURE_ILT, num_dumped_bytes);
8200 }
8201 
8202 int qed_dbg_ilt_size(struct qed_dev *cdev)
8203 {
8204     return qed_dbg_feature_size(cdev, DBG_FEATURE_ILT);
8205 }
8206 
8207 int qed_dbg_mcp_trace(struct qed_dev *cdev, void *buffer,
8208               u32 *num_dumped_bytes)
8209 {
8210     return qed_dbg_feature(cdev, buffer, DBG_FEATURE_MCP_TRACE,
8211                    num_dumped_bytes);
8212 }
8213 
8214 int qed_dbg_mcp_trace_size(struct qed_dev *cdev)
8215 {
8216     return qed_dbg_feature_size(cdev, DBG_FEATURE_MCP_TRACE);
8217 }
8218 
8219 /* Defines the amount of bytes allocated for recording the length of debugfs
8220  * feature buffer.
8221  */
8222 #define REGDUMP_HEADER_SIZE         sizeof(u32)
8223 #define REGDUMP_HEADER_SIZE_SHIFT       0
8224 #define REGDUMP_HEADER_SIZE_MASK        0xffffff
8225 #define REGDUMP_HEADER_FEATURE_SHIFT        24
8226 #define REGDUMP_HEADER_FEATURE_MASK     0x1f
8227 #define REGDUMP_HEADER_BIN_DUMP_SHIFT       29
8228 #define REGDUMP_HEADER_BIN_DUMP_MASK        0x1
8229 #define REGDUMP_HEADER_OMIT_ENGINE_SHIFT    30
8230 #define REGDUMP_HEADER_OMIT_ENGINE_MASK     0x1
8231 #define REGDUMP_HEADER_ENGINE_SHIFT     31
8232 #define REGDUMP_HEADER_ENGINE_MASK      0x1
8233 #define REGDUMP_MAX_SIZE            0x1000000
8234 #define ILT_DUMP_MAX_SIZE           (1024 * 1024 * 15)
8235 
8236 enum debug_print_features {
8237     OLD_MODE = 0,
8238     IDLE_CHK = 1,
8239     GRC_DUMP = 2,
8240     MCP_TRACE = 3,
8241     REG_FIFO = 4,
8242     PROTECTION_OVERRIDE = 5,
8243     IGU_FIFO = 6,
8244     PHY = 7,
8245     FW_ASSERTS = 8,
8246     NVM_CFG1 = 9,
8247     DEFAULT_CFG = 10,
8248     NVM_META = 11,
8249     MDUMP = 12,
8250     ILT_DUMP = 13,
8251 };
8252 
8253 static u32 qed_calc_regdump_header(struct qed_dev *cdev,
8254                    enum debug_print_features feature,
8255                    int engine, u32 feature_size,
8256                    u8 omit_engine, u8 dbg_bin_dump)
8257 {
8258     u32 res = 0;
8259 
8260     SET_FIELD(res, REGDUMP_HEADER_SIZE, feature_size);
8261     if (res != feature_size)
8262         DP_NOTICE(cdev,
8263               "Feature %d is too large (size 0x%x) and will corrupt the dump\n",
8264               feature, feature_size);
8265 
8266     SET_FIELD(res, REGDUMP_HEADER_FEATURE, feature);
8267     SET_FIELD(res, REGDUMP_HEADER_BIN_DUMP, dbg_bin_dump);
8268     SET_FIELD(res, REGDUMP_HEADER_OMIT_ENGINE, omit_engine);
8269     SET_FIELD(res, REGDUMP_HEADER_ENGINE, engine);
8270 
8271     return res;
8272 }
8273 
8274 int qed_dbg_all_data(struct qed_dev *cdev, void *buffer)
8275 {
8276     u8 cur_engine, omit_engine = 0, org_engine;
8277     struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug];
8278     struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
8279     int grc_params[MAX_DBG_GRC_PARAMS], rc, i;
8280     u32 offset = 0, feature_size;
8281 
8282     for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
8283         grc_params[i] = dev_data->grc.param_val[i];
8284 
8285     if (!QED_IS_CMT(cdev))
8286         omit_engine = 1;
8287 
8288     cdev->dbg_bin_dump = 1;
8289     mutex_lock(&qed_dbg_lock);
8290 
8291     org_engine = qed_get_debug_engine(cdev);
8292     for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
8293         /* Collect idle_chks and grcDump for each hw function */
8294         DP_VERBOSE(cdev, QED_MSG_DEBUG,
8295                "obtaining idle_chk and grcdump for current engine\n");
8296         qed_set_debug_engine(cdev, cur_engine);
8297 
8298         /* First idle_chk */
8299         rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset +
8300                       REGDUMP_HEADER_SIZE, &feature_size);
8301         if (!rc) {
8302             *(u32 *)((u8 *)buffer + offset) =
8303                 qed_calc_regdump_header(cdev, IDLE_CHK,
8304                             cur_engine,
8305                             feature_size,
8306                             omit_engine,
8307                             cdev->dbg_bin_dump);
8308             offset += (feature_size + REGDUMP_HEADER_SIZE);
8309         } else {
8310             DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
8311         }
8312 
8313         /* Second idle_chk */
8314         rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset +
8315                       REGDUMP_HEADER_SIZE, &feature_size);
8316         if (!rc) {
8317             *(u32 *)((u8 *)buffer + offset) =
8318                 qed_calc_regdump_header(cdev, IDLE_CHK,
8319                             cur_engine,
8320                             feature_size,
8321                             omit_engine,
8322                             cdev->dbg_bin_dump);
8323             offset += (feature_size + REGDUMP_HEADER_SIZE);
8324         } else {
8325             DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
8326         }
8327 
8328         /* reg_fifo dump */
8329         rc = qed_dbg_reg_fifo(cdev, (u8 *)buffer + offset +
8330                       REGDUMP_HEADER_SIZE, &feature_size);
8331         if (!rc) {
8332             *(u32 *)((u8 *)buffer + offset) =
8333                 qed_calc_regdump_header(cdev, REG_FIFO,
8334                             cur_engine,
8335                             feature_size,
8336                             omit_engine,
8337                             cdev->dbg_bin_dump);
8338             offset += (feature_size + REGDUMP_HEADER_SIZE);
8339         } else {
8340             DP_ERR(cdev, "qed_dbg_reg_fifo failed. rc = %d\n", rc);
8341         }
8342 
8343         /* igu_fifo dump */
8344         rc = qed_dbg_igu_fifo(cdev, (u8 *)buffer + offset +
8345                       REGDUMP_HEADER_SIZE, &feature_size);
8346         if (!rc) {
8347             *(u32 *)((u8 *)buffer + offset) =
8348                 qed_calc_regdump_header(cdev, IGU_FIFO,
8349                             cur_engine,
8350                             feature_size,
8351                             omit_engine,
8352                             cdev->dbg_bin_dump);
8353             offset += (feature_size + REGDUMP_HEADER_SIZE);
8354         } else {
8355             DP_ERR(cdev, "qed_dbg_igu_fifo failed. rc = %d", rc);
8356         }
8357 
8358         /* protection_override dump */
8359         rc = qed_dbg_protection_override(cdev, (u8 *)buffer + offset +
8360                          REGDUMP_HEADER_SIZE,
8361                          &feature_size);
8362         if (!rc) {
8363             *(u32 *)((u8 *)buffer + offset) =
8364                 qed_calc_regdump_header(cdev,
8365                             PROTECTION_OVERRIDE,
8366                             cur_engine,
8367                             feature_size,
8368                             omit_engine,
8369                             cdev->dbg_bin_dump);
8370             offset += (feature_size + REGDUMP_HEADER_SIZE);
8371         } else {
8372             DP_ERR(cdev,
8373                    "qed_dbg_protection_override failed. rc = %d\n",
8374                    rc);
8375         }
8376 
8377         /* fw_asserts dump */
8378         rc = qed_dbg_fw_asserts(cdev, (u8 *)buffer + offset +
8379                     REGDUMP_HEADER_SIZE, &feature_size);
8380         if (!rc) {
8381             *(u32 *)((u8 *)buffer + offset) =
8382                 qed_calc_regdump_header(cdev, FW_ASSERTS,
8383                             cur_engine,
8384                             feature_size,
8385                             omit_engine,
8386                             cdev->dbg_bin_dump);
8387             offset += (feature_size + REGDUMP_HEADER_SIZE);
8388         } else {
8389             DP_ERR(cdev, "qed_dbg_fw_asserts failed. rc = %d\n",
8390                    rc);
8391         }
8392 
8393         feature_size = qed_dbg_ilt_size(cdev);
8394         if (!cdev->disable_ilt_dump && feature_size <
8395             ILT_DUMP_MAX_SIZE) {
8396             rc = qed_dbg_ilt(cdev, (u8 *)buffer + offset +
8397                      REGDUMP_HEADER_SIZE, &feature_size);
8398             if (!rc) {
8399                 *(u32 *)((u8 *)buffer + offset) =
8400                     qed_calc_regdump_header(cdev, ILT_DUMP,
8401                                 cur_engine,
8402                                 feature_size,
8403                                 omit_engine,
8404                                 cdev->dbg_bin_dump);
8405                 offset += (feature_size + REGDUMP_HEADER_SIZE);
8406             } else {
8407                 DP_ERR(cdev, "qed_dbg_ilt failed. rc = %d\n",
8408                        rc);
8409             }
8410         }
8411 
8412         /* Grc dump - must be last because when mcp stuck it will
8413          * clutter idle_chk, reg_fifo, ...
8414          */
8415         for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
8416             dev_data->grc.param_val[i] = grc_params[i];
8417 
8418         rc = qed_dbg_grc(cdev, (u8 *)buffer + offset +
8419                  REGDUMP_HEADER_SIZE, &feature_size);
8420         if (!rc) {
8421             *(u32 *)((u8 *)buffer + offset) =
8422                 qed_calc_regdump_header(cdev, GRC_DUMP,
8423                             cur_engine,
8424                             feature_size,
8425                             omit_engine,
8426                             cdev->dbg_bin_dump);
8427             offset += (feature_size + REGDUMP_HEADER_SIZE);
8428         } else {
8429             DP_ERR(cdev, "qed_dbg_grc failed. rc = %d", rc);
8430         }
8431     }
8432 
8433     qed_set_debug_engine(cdev, org_engine);
8434 
8435     /* mcp_trace */
8436     rc = qed_dbg_mcp_trace(cdev, (u8 *)buffer + offset +
8437                    REGDUMP_HEADER_SIZE, &feature_size);
8438     if (!rc) {
8439         *(u32 *)((u8 *)buffer + offset) =
8440             qed_calc_regdump_header(cdev, MCP_TRACE, cur_engine,
8441                         feature_size, omit_engine,
8442                         cdev->dbg_bin_dump);
8443         offset += (feature_size + REGDUMP_HEADER_SIZE);
8444     } else {
8445         DP_ERR(cdev, "qed_dbg_mcp_trace failed. rc = %d\n", rc);
8446     }
8447 
8448     /* nvm cfg1 */
8449     rc = qed_dbg_nvm_image(cdev,
8450                    (u8 *)buffer + offset +
8451                    REGDUMP_HEADER_SIZE, &feature_size,
8452                    QED_NVM_IMAGE_NVM_CFG1);
8453     if (!rc) {
8454         *(u32 *)((u8 *)buffer + offset) =
8455             qed_calc_regdump_header(cdev, NVM_CFG1, cur_engine,
8456                         feature_size, omit_engine,
8457                         cdev->dbg_bin_dump);
8458         offset += (feature_size + REGDUMP_HEADER_SIZE);
8459     } else if (rc != -ENOENT) {
8460         DP_ERR(cdev,
8461                "qed_dbg_nvm_image failed for image  %d (%s), rc = %d\n",
8462                QED_NVM_IMAGE_NVM_CFG1, "QED_NVM_IMAGE_NVM_CFG1",
8463                rc);
8464     }
8465 
8466         /* nvm default */
8467     rc = qed_dbg_nvm_image(cdev,
8468                    (u8 *)buffer + offset +
8469                    REGDUMP_HEADER_SIZE, &feature_size,
8470                    QED_NVM_IMAGE_DEFAULT_CFG);
8471     if (!rc) {
8472         *(u32 *)((u8 *)buffer + offset) =
8473             qed_calc_regdump_header(cdev, DEFAULT_CFG,
8474                         cur_engine, feature_size,
8475                         omit_engine,
8476                         cdev->dbg_bin_dump);
8477         offset += (feature_size + REGDUMP_HEADER_SIZE);
8478     } else if (rc != -ENOENT) {
8479         DP_ERR(cdev,
8480                "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
8481                QED_NVM_IMAGE_DEFAULT_CFG,
8482                "QED_NVM_IMAGE_DEFAULT_CFG", rc);
8483     }
8484 
8485     /* nvm meta */
8486     rc = qed_dbg_nvm_image(cdev,
8487                    (u8 *)buffer + offset +
8488                    REGDUMP_HEADER_SIZE, &feature_size,
8489                    QED_NVM_IMAGE_NVM_META);
8490     if (!rc) {
8491         *(u32 *)((u8 *)buffer + offset) =
8492             qed_calc_regdump_header(cdev, NVM_META, cur_engine,
8493                         feature_size, omit_engine,
8494                         cdev->dbg_bin_dump);
8495         offset += (feature_size + REGDUMP_HEADER_SIZE);
8496     } else if (rc != -ENOENT) {
8497         DP_ERR(cdev,
8498                "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
8499                QED_NVM_IMAGE_NVM_META, "QED_NVM_IMAGE_NVM_META",
8500                rc);
8501     }
8502 
8503     /* nvm mdump */
8504     rc = qed_dbg_nvm_image(cdev, (u8 *)buffer + offset +
8505                    REGDUMP_HEADER_SIZE, &feature_size,
8506                    QED_NVM_IMAGE_MDUMP);
8507     if (!rc) {
8508         *(u32 *)((u8 *)buffer + offset) =
8509             qed_calc_regdump_header(cdev, MDUMP, cur_engine,
8510                         feature_size, omit_engine,
8511                         cdev->dbg_bin_dump);
8512         offset += (feature_size + REGDUMP_HEADER_SIZE);
8513     } else if (rc != -ENOENT) {
8514         DP_ERR(cdev,
8515                "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
8516                QED_NVM_IMAGE_MDUMP, "QED_NVM_IMAGE_MDUMP", rc);
8517     }
8518 
8519     mutex_unlock(&qed_dbg_lock);
8520     cdev->dbg_bin_dump = 0;
8521 
8522     return 0;
8523 }
8524 
8525 int qed_dbg_all_data_size(struct qed_dev *cdev)
8526 {
8527     u32 regs_len = 0, image_len = 0, ilt_len = 0, total_ilt_len = 0;
8528     struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug];
8529     u8 cur_engine, org_engine;
8530 
8531     cdev->disable_ilt_dump = false;
8532     org_engine = qed_get_debug_engine(cdev);
8533     for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
8534         /* Engine specific */
8535         DP_VERBOSE(cdev, QED_MSG_DEBUG,
8536                "calculating idle_chk and grcdump register length for current engine\n");
8537         qed_set_debug_engine(cdev, cur_engine);
8538         regs_len += REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
8539             REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
8540             REGDUMP_HEADER_SIZE + qed_dbg_grc_size(cdev) +
8541             REGDUMP_HEADER_SIZE + qed_dbg_reg_fifo_size(cdev) +
8542             REGDUMP_HEADER_SIZE + qed_dbg_igu_fifo_size(cdev) +
8543             REGDUMP_HEADER_SIZE +
8544             qed_dbg_protection_override_size(cdev) +
8545             REGDUMP_HEADER_SIZE + qed_dbg_fw_asserts_size(cdev);
8546         ilt_len = REGDUMP_HEADER_SIZE + qed_dbg_ilt_size(cdev);
8547         if (ilt_len < ILT_DUMP_MAX_SIZE) {
8548             total_ilt_len += ilt_len;
8549             regs_len += ilt_len;
8550         }
8551     }
8552 
8553     qed_set_debug_engine(cdev, org_engine);
8554 
8555     /* Engine common */
8556     regs_len += REGDUMP_HEADER_SIZE + qed_dbg_mcp_trace_size(cdev) +
8557         REGDUMP_HEADER_SIZE + qed_dbg_phy_size(cdev);
8558     qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_CFG1, &image_len);
8559     if (image_len)
8560         regs_len += REGDUMP_HEADER_SIZE + image_len;
8561     qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_DEFAULT_CFG, &image_len);
8562     if (image_len)
8563         regs_len += REGDUMP_HEADER_SIZE + image_len;
8564     qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_META, &image_len);
8565     if (image_len)
8566         regs_len += REGDUMP_HEADER_SIZE + image_len;
8567     qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_MDUMP, &image_len);
8568     if (image_len)
8569         regs_len += REGDUMP_HEADER_SIZE + image_len;
8570 
8571     if (regs_len > REGDUMP_MAX_SIZE) {
8572         DP_VERBOSE(cdev, QED_MSG_DEBUG,
8573                "Dump exceeds max size 0x%x, disable ILT dump\n",
8574                REGDUMP_MAX_SIZE);
8575         cdev->disable_ilt_dump = true;
8576         regs_len -= total_ilt_len;
8577     }
8578 
8579     return regs_len;
8580 }
8581 
8582 int qed_dbg_feature(struct qed_dev *cdev, void *buffer,
8583             enum qed_dbg_features feature, u32 *num_dumped_bytes)
8584 {
8585     struct qed_dbg_feature *qed_feature = &cdev->dbg_features[feature];
8586     struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug];
8587     enum dbg_status dbg_rc;
8588     struct qed_ptt *p_ptt;
8589     int rc = 0;
8590 
8591     /* Acquire ptt */
8592     p_ptt = qed_ptt_acquire(p_hwfn);
8593     if (!p_ptt)
8594         return -EINVAL;
8595 
8596     /* Get dump */
8597     dbg_rc = qed_dbg_dump(p_hwfn, p_ptt, feature);
8598     if (dbg_rc != DBG_STATUS_OK) {
8599         DP_VERBOSE(cdev, QED_MSG_DEBUG, "%s\n",
8600                qed_dbg_get_status_str(dbg_rc));
8601         *num_dumped_bytes = 0;
8602         rc = -EINVAL;
8603         goto out;
8604     }
8605 
8606     DP_VERBOSE(cdev, QED_MSG_DEBUG,
8607            "copying debugfs feature to external buffer\n");
8608     memcpy(buffer, qed_feature->dump_buf, qed_feature->buf_size);
8609     *num_dumped_bytes = cdev->dbg_features[feature].dumped_dwords *
8610                 4;
8611 
8612 out:
8613     qed_ptt_release(p_hwfn, p_ptt);
8614     return rc;
8615 }
8616 
8617 int qed_dbg_feature_size(struct qed_dev *cdev, enum qed_dbg_features feature)
8618 {
8619     struct qed_dbg_feature *qed_feature = &cdev->dbg_features[feature];
8620     struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug];
8621     struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
8622     u32 buf_size_dwords;
8623     enum dbg_status rc;
8624 
8625     if (!p_ptt)
8626         return -EINVAL;
8627 
8628     rc = qed_features_lookup[feature].get_size(p_hwfn, p_ptt,
8629                            &buf_size_dwords);
8630     if (rc != DBG_STATUS_OK)
8631         buf_size_dwords = 0;
8632 
8633     /* Feature will not be dumped if it exceeds maximum size */
8634     if (buf_size_dwords > MAX_DBG_FEATURE_SIZE_DWORDS)
8635         buf_size_dwords = 0;
8636 
8637     qed_ptt_release(p_hwfn, p_ptt);
8638     qed_feature->buf_size = buf_size_dwords * sizeof(u32);
8639     return qed_feature->buf_size;
8640 }
8641 
8642 int qed_dbg_phy_size(struct qed_dev *cdev)
8643 {
8644     /* return max size of phy info and
8645      * phy mac_stat multiplied by the number of ports
8646      */
8647     return MAX_PHY_RESULT_BUFFER * (1 + qed_device_num_ports(cdev));
8648 }
8649 
8650 u8 qed_get_debug_engine(struct qed_dev *cdev)
8651 {
8652     return cdev->engine_for_debug;
8653 }
8654 
8655 void qed_set_debug_engine(struct qed_dev *cdev, int engine_number)
8656 {
8657     DP_VERBOSE(cdev, QED_MSG_DEBUG, "set debug engine to %d\n",
8658            engine_number);
8659     cdev->engine_for_debug = engine_number;
8660 }
8661 
8662 void qed_dbg_pf_init(struct qed_dev *cdev)
8663 {
8664     const u8 *dbg_values = NULL;
8665     int i;
8666 
8667     /* Sync ver with debugbus qed code */
8668     qed_dbg_set_app_ver(TOOLS_VERSION);
8669 
8670     /* Debug values are after init values.
8671      * The offset is the first dword of the file.
8672      */
8673     dbg_values = cdev->firmware->data + *(u32 *)cdev->firmware->data;
8674 
8675     for_each_hwfn(cdev, i) {
8676         qed_dbg_set_bin_ptr(&cdev->hwfns[i], dbg_values);
8677         qed_dbg_user_set_bin_ptr(&cdev->hwfns[i], dbg_values);
8678     }
8679 
8680     /* Set the hwfn to be 0 as default */
8681     cdev->engine_for_debug = 0;
8682 }
8683 
8684 void qed_dbg_pf_exit(struct qed_dev *cdev)
8685 {
8686     struct qed_dbg_feature *feature = NULL;
8687     enum qed_dbg_features feature_idx;
8688 
8689     /* debug features' buffers may be allocated if debug feature was used
8690      * but dump wasn't called
8691      */
8692     for (feature_idx = 0; feature_idx < DBG_FEATURE_NUM; feature_idx++) {
8693         feature = &cdev->dbg_features[feature_idx];
8694         if (feature->dump_buf) {
8695             vfree(feature->dump_buf);
8696             feature->dump_buf = NULL;
8697         }
8698     }
8699 }