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