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