Show a patch.

GET /api/patches/73467/
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 73467,
    "url": "https://patches.dpdk.org/api/patches/73467/",
    "web_url": "https://patches.dpdk.org/patch/73467/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk"
    },
    "msgid": "<20200707201844.16111-4-rmody@marvell.com>",
    "date": "2020-07-07T20:18:43",
    "name": "[v3,3/4] net/qede: add infrastructure for debug data collection",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "f8c3ca6e99ad18b41872ecc9175f68e0121b9dde",
    "submitter": {
        "id": 1211,
        "url": "https://patches.dpdk.org/api/people/1211/",
        "name": "Rasesh Mody",
        "email": "rmody@marvell.com"
    },
    "delegate": {
        "id": 310,
        "url": "https://patches.dpdk.org/api/users/310/",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerin.jacob@caviumnetworks.com"
    },
    "mbox": "https://patches.dpdk.org/patch/73467/mbox/",
    "series": [
        {
            "id": 10681,
            "url": "https://patches.dpdk.org/api/series/10681/",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=10681",
            "date": "2020-06-30T08:32:11",
            "name": "net/qede: add FW debug data collection support",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/10681/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/73467/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/73467/checks/",
    "tags": {},
    "headers": {
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "Return-Path": "<dev-bounces@dpdk.org>",
        "To": "<jerinj@marvell.com>, <ferruh.yigit@intel.com>",
        "X-Mailer": "git-send-email 2.18.0",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-type; s=pfpt0818; bh=034V5kBg5saR9g3rHwmzxwezsksqsMIHDGkyh7eKYGQ=;\n b=ZiFVncCxj/m2Q6k6PfMOH6YSpQPON8X7UHvQzwCqKAHVlJfx9JydcsZY2bCWf2BzibRK\n t3P0orbBiOdKAYVw5s1ELzn/s6T6Wbh0tua6j3hhSuztK38/N+XN8utXH1C5HCCv6HYD\n rSfgIaDNkEXsFDFMAae+6xuBQfbUiTSAMenF834yGjGur+VBb7oJtJ1NbsBQVFt8O+fc\n SbKPSwMeplu1EKaVGvT27tmVLHVEgePyIeXm5XTDBMSqgJEsjt2dYEY/ybMoq1yD+rj3\n 9cW/9Ut4ykpaD1HAztDrElEXsVzkz0Um83ZXloh0kXVBWSxIRxwVV4xdKtD8JgNDhlLJ og==",
        "List-Post": "<mailto:dev@dpdk.org>",
        "Message-ID": "<20200707201844.16111-4-rmody@marvell.com>",
        "CC": "Rasesh Mody <rmody@marvell.com>, <dev@dpdk.org>,\n <GR-Everest-DPDK-Dev@marvell.com>, Igor Russkikh <irusskikh@marvell.com>",
        "X-BeenThere": "dev@dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id E38C2A00BE;\n\tTue,  7 Jul 2020 22:19:33 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 657D81DBD1;\n\tTue,  7 Jul 2020 22:19:29 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com\n [67.231.148.174]) by dpdk.org (Postfix) with ESMTP id 97B5E1D690\n for <dev@dpdk.org>; Tue,  7 Jul 2020 22:19:26 +0200 (CEST)",
            "from pps.filterd (m0045849.ppops.net [127.0.0.1])\n by mx0a-0016f401.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id\n 067K03Zj016249; Tue, 7 Jul 2020 13:19:25 -0700",
            "from sc-exch01.marvell.com ([199.233.58.181])\n by mx0a-0016f401.pphosted.com with ESMTP id 322q4pwhba-2\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT);\n Tue, 07 Jul 2020 13:19:24 -0700",
            "from DC5-EXCH01.marvell.com (10.69.176.38) by SC-EXCH01.marvell.com\n (10.93.176.81) with Microsoft SMTP Server (TLS) id 15.0.1497.2;\n Tue, 7 Jul 2020 13:19:23 -0700",
            "from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2;\n Tue, 7 Jul 2020 13:19:21 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.2 via Frontend\n Transport; Tue, 7 Jul 2020 13:19:21 -0700",
            "from irv1user08.caveonetworks.com (unknown [10.104.116.105])\n by maili.marvell.com (Postfix) with ESMTP id 5A5CE3F703F;\n Tue,  7 Jul 2020 13:19:21 -0700 (PDT)",
            "(from rmody@localhost)\n by irv1user08.caveonetworks.com (8.14.4/8.14.4/Submit) id 067KJLps016352;\n Tue, 7 Jul 2020 13:19:21 -0700"
        ],
        "Subject": "[dpdk-dev] [PATCH v3 3/4] net/qede: add infrastructure for debug\n\tdata collection",
        "In-Reply-To": "<20200630083215.13108-1-rmody@marvell.com>",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10434:6.0.235, 18.0.687\n definitions=2020-07-07_13:2020-07-07,\n 2020-07-07 signatures=0",
        "Date": "Tue, 7 Jul 2020 13:18:43 -0700",
        "Precedence": "list",
        "From": "Rasesh Mody <rmody@marvell.com>",
        "X-Authentication-Warning": "irv1user08.caveonetworks.com: rmody set sender to\n rmody@marvell.com using -f",
        "MIME-Version": "1.0",
        "References": "<20200630083215.13108-1-rmody@marvell.com>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>",
        "Errors-To": "dev-bounces@dpdk.org",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "Content-Type": "text/plain",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>"
    },
    "content": "The patch adds QEDE PMD ops and APIs to calculate the size and collect\nthe debug dump for various firmware components. The patch adds new files\nqede_debug.[ch] that has all the firmware debug data collection\ninfrastructure changes.\n\nSigned-off-by: Rasesh Mody <rmody@marvell.com>\nSigned-off-by: Igor Russkikh <irusskikh@marvell.com>\n---\n drivers/net/qede/Makefile        |    4 +-\n drivers/net/qede/base/bcm_osal.h |    5 +-\n drivers/net/qede/qede_debug.c    | 8120 ++++++++++++++++++++++++++++++\n drivers/net/qede/qede_debug.h    |  759 +++\n drivers/net/qede/qede_if.h       |   45 +\n drivers/net/qede/qede_main.c     |   39 +-\n 6 files changed, 8968 insertions(+), 4 deletions(-)\n create mode 100644 drivers/net/qede/qede_debug.c\n create mode 100644 drivers/net/qede/qede_debug.h",
    "diff": "diff --git a/drivers/net/qede/Makefile b/drivers/net/qede/Makefile\nindex 5810b4d49..3b00338ff 100644\n--- a/drivers/net/qede/Makefile\n+++ b/drivers/net/qede/Makefile\n@@ -11,7 +11,6 @@ include $(RTE_SDK)/mk/rte.vars.mk\n LIB = librte_pmd_qede.a\n \n CFLAGS += -O3\n-CFLAGS += $(WERROR_FLAGS)\n LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring\n LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs\n LDLIBS += -lrte_bus_pci\n@@ -37,7 +36,6 @@ CFLAGS_BASE_DRIVER += -Wno-missing-prototypes\n \n ifneq ($(CONFIG_RTE_TOOLCHAIN_ICC),y)\n CFLAGS_BASE_DRIVER += -Wno-unused-value\n-CFLAGS_BASE_DRIVER += -Wno-format-nonliteral\n ifeq ($(OS_TYPE),Linux)\n ifeq ($(shell clang -Wno-shift-negative-value -Werror -E - < /dev/null > /dev/null 2>&1; echo $$?),0)\n CFLAGS_BASE_DRIVER += -Wno-shift-negative-value\n@@ -48,6 +46,7 @@ endif\n ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y)\n ifeq ($(shell test $(GCC_VERSION) -ge 44 && echo 1), 1)\n CFLAGS_BASE_DRIVER += -Wno-unused-but-set-variable\n+CFLAGS += -Wno-format-nonliteral\n endif\n CFLAGS_BASE_DRIVER += -Wno-missing-declarations\n ifeq ($(shell test $(GCC_VERSION) -ge 46 && echo 1), 1)\n@@ -104,5 +103,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_ethdev.c\n SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_main.c\n SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_rxtx.c\n SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_filter.c\n+SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_debug.c\n \n include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/drivers/net/qede/base/bcm_osal.h b/drivers/net/qede/base/bcm_osal.h\nindex 6ea3e7dda..b4b94231b 100644\n--- a/drivers/net/qede/base/bcm_osal.h\n+++ b/drivers/net/qede/base/bcm_osal.h\n@@ -457,7 +457,10 @@ void qed_set_platform_str(struct ecore_hwfn *p_hwfn,\n #define OSAL_SET_PLATFORM_STR(p_hwfn, buf_str, buf_size) \\\n \tqed_set_platform_str(p_hwfn, buf_str, buf_size)\n #define OSAL_GET_EPOCH(p_hwfn) ((u32)time(NULL))\n-#define OSAL_DBG_ALLOC_USER_DATA(p_hwfn, user_data_ptr) (0)\n+enum dbg_status\tqed_dbg_alloc_user_data(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\tvoid **user_data_ptr);\n+#define OSAL_DBG_ALLOC_USER_DATA(p_hwfn, user_data_ptr) \\\n+\tqed_dbg_alloc_user_data(p_hwfn, user_data_ptr)\n #define OSAL_DB_REC_OCCURRED(p_hwfn) nothing\n \n #endif /* __BCM_OSAL_H */\ndiff --git a/drivers/net/qede/qede_debug.c b/drivers/net/qede/qede_debug.c\nnew file mode 100644\nindex 000000000..dd54e50be\n--- /dev/null\n+++ b/drivers/net/qede/qede_debug.c\n@@ -0,0 +1,8120 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2020 Marvell Semiconductor Inc.\n+ * All rights reserved.\n+ * www.marvell.com\n+ */\n+\n+#include <rte_common.h>\n+#include \"base/bcm_osal.h\"\n+#include \"base/ecore.h\"\n+#include \"base/ecore_cxt.h\"\n+#include \"base/ecore_hsi_common.h\"\n+#include \"base/ecore_hw.h\"\n+#include \"base/ecore_mcp.h\"\n+#include \"base/reg_addr.h\"\n+#include \"qede_debug.h\"\n+\n+/* Memory groups enum */\n+enum mem_groups {\n+\tMEM_GROUP_PXP_MEM,\n+\tMEM_GROUP_DMAE_MEM,\n+\tMEM_GROUP_CM_MEM,\n+\tMEM_GROUP_QM_MEM,\n+\tMEM_GROUP_DORQ_MEM,\n+\tMEM_GROUP_BRB_RAM,\n+\tMEM_GROUP_BRB_MEM,\n+\tMEM_GROUP_PRS_MEM,\n+\tMEM_GROUP_SDM_MEM,\n+\tMEM_GROUP_PBUF,\n+\tMEM_GROUP_IOR,\n+\tMEM_GROUP_RAM,\n+\tMEM_GROUP_BTB_RAM,\n+\tMEM_GROUP_RDIF_CTX,\n+\tMEM_GROUP_TDIF_CTX,\n+\tMEM_GROUP_CFC_MEM,\n+\tMEM_GROUP_CONN_CFC_MEM,\n+\tMEM_GROUP_CAU_PI,\n+\tMEM_GROUP_CAU_MEM,\n+\tMEM_GROUP_CAU_MEM_EXT,\n+\tMEM_GROUP_PXP_ILT,\n+\tMEM_GROUP_MULD_MEM,\n+\tMEM_GROUP_BTB_MEM,\n+\tMEM_GROUP_IGU_MEM,\n+\tMEM_GROUP_IGU_MSIX,\n+\tMEM_GROUP_CAU_SB,\n+\tMEM_GROUP_BMB_RAM,\n+\tMEM_GROUP_BMB_MEM,\n+\tMEM_GROUP_TM_MEM,\n+\tMEM_GROUP_TASK_CFC_MEM,\n+\tMEM_GROUPS_NUM\n+};\n+\n+/* Memory groups names */\n+static const char * const s_mem_group_names[] = {\n+\t\"PXP_MEM\",\n+\t\"DMAE_MEM\",\n+\t\"CM_MEM\",\n+\t\"QM_MEM\",\n+\t\"DORQ_MEM\",\n+\t\"BRB_RAM\",\n+\t\"BRB_MEM\",\n+\t\"PRS_MEM\",\n+\t\"SDM_MEM\",\n+\t\"PBUF\",\n+\t\"IOR\",\n+\t\"RAM\",\n+\t\"BTB_RAM\",\n+\t\"RDIF_CTX\",\n+\t\"TDIF_CTX\",\n+\t\"CFC_MEM\",\n+\t\"CONN_CFC_MEM\",\n+\t\"CAU_PI\",\n+\t\"CAU_MEM\",\n+\t\"CAU_MEM_EXT\",\n+\t\"PXP_ILT\",\n+\t\"MULD_MEM\",\n+\t\"BTB_MEM\",\n+\t\"IGU_MEM\",\n+\t\"IGU_MSIX\",\n+\t\"CAU_SB\",\n+\t\"BMB_RAM\",\n+\t\"BMB_MEM\",\n+\t\"TM_MEM\",\n+\t\"TASK_CFC_MEM\",\n+};\n+\n+/* Idle check conditions */\n+\n+static u32 cond5(const u32 *r, const u32 *imm)\n+{\n+\treturn ((r[0] & imm[0]) != imm[1]) && ((r[1] & imm[2]) != imm[3]);\n+}\n+\n+static u32 cond7(const u32 *r, const u32 *imm)\n+{\n+\treturn ((r[0] >> imm[0]) & imm[1]) != imm[2];\n+}\n+\n+static u32 cond6(const u32 *r, const u32 *imm)\n+{\n+\treturn (r[0] & imm[0]) != imm[1];\n+}\n+\n+static u32 cond9(const u32 *r, const u32 *imm)\n+{\n+\treturn ((r[0] & imm[0]) >> imm[1]) !=\n+\t\t(((r[0] & imm[2]) >> imm[3]) | ((r[1] & imm[4]) << imm[5]));\n+}\n+\n+static u32 cond10(const u32 *r, const u32 *imm)\n+{\n+\treturn ((r[0] & imm[0]) >> imm[1]) != (r[0] & imm[2]);\n+}\n+\n+static u32 cond4(const u32 *r, const u32 *imm)\n+{\n+\treturn (r[0] & ~imm[0]) != imm[1];\n+}\n+\n+static u32 cond0(const u32 *r, const u32 *imm)\n+{\n+\treturn (r[0] & ~r[1]) != imm[0];\n+}\n+\n+static u32 cond1(const u32 *r, const u32 *imm)\n+{\n+\treturn r[0] != imm[0];\n+}\n+\n+static u32 cond11(const u32 *r, const u32 *imm)\n+{\n+\treturn r[0] != r[1] && r[2] == imm[0];\n+}\n+\n+static u32 cond12(const u32 *r, const u32 *imm)\n+{\n+\treturn r[0] != r[1] && r[2] > imm[0];\n+}\n+\n+static u32 cond3(const u32 *r, const __rte_unused u32 *imm)\n+{\n+\treturn r[0] != r[1];\n+}\n+\n+static u32 cond13(const u32 *r, const u32 *imm)\n+{\n+\treturn r[0] & imm[0];\n+}\n+\n+static u32 cond8(const u32 *r, const u32 *imm)\n+{\n+\treturn r[0] < (r[1] - imm[0]);\n+}\n+\n+static u32 cond2(const u32 *r, const u32 *imm)\n+{\n+\treturn r[0] > imm[0];\n+}\n+\n+/* Array of Idle Check conditions */\n+static u32(*cond_arr[]) (const u32 *r, const u32 *imm) = {\n+\tcond0,\n+\tcond1,\n+\tcond2,\n+\tcond3,\n+\tcond4,\n+\tcond5,\n+\tcond6,\n+\tcond7,\n+\tcond8,\n+\tcond9,\n+\tcond10,\n+\tcond11,\n+\tcond12,\n+\tcond13,\n+};\n+\n+#define NUM_PHYS_BLOCKS 84\n+\n+#define NUM_DBG_RESET_REGS 8\n+\n+/******************************* Data Types **********************************/\n+\n+enum hw_types {\n+\tHW_TYPE_ASIC,\n+\tPLATFORM_RESERVED,\n+\tPLATFORM_RESERVED2,\n+\tPLATFORM_RESERVED3,\n+\tPLATFORM_RESERVED4,\n+\tMAX_HW_TYPES\n+};\n+\n+/* CM context types */\n+enum cm_ctx_types {\n+\tCM_CTX_CONN_AG,\n+\tCM_CTX_CONN_ST,\n+\tCM_CTX_TASK_AG,\n+\tCM_CTX_TASK_ST,\n+\tNUM_CM_CTX_TYPES\n+};\n+\n+/* Debug bus frame modes */\n+enum dbg_bus_frame_modes {\n+\tDBG_BUS_FRAME_MODE_4ST = 0,\t/* 4 Storm dwords (no HW) */\n+\tDBG_BUS_FRAME_MODE_2ST_2HW = 1,\t/* 2 Storm dwords, 2 HW dwords */\n+\tDBG_BUS_FRAME_MODE_1ST_3HW = 2,\t/* 1 Storm dwords, 3 HW dwords */\n+\tDBG_BUS_FRAME_MODE_4HW = 3,\t/* 4 HW dwords (no Storms) */\n+\tDBG_BUS_FRAME_MODE_8HW = 4,\t/* 8 HW dwords (no Storms) */\n+\tDBG_BUS_NUM_FRAME_MODES\n+};\n+\n+/* Chip constant definitions */\n+struct chip_defs {\n+\tconst char *name;\n+\tu32 num_ilt_pages;\n+};\n+\n+/* HW type constant definitions */\n+struct hw_type_defs {\n+\tconst char *name;\n+\tu32 delay_factor;\n+\tu32 dmae_thresh;\n+\tu32 log_thresh;\n+};\n+\n+/* RBC reset definitions */\n+struct rbc_reset_defs {\n+\tu32 reset_reg_addr;\n+\tu32 reset_val[MAX_CHIP_IDS];\n+};\n+\n+/* Storm constant definitions.\n+ * Addresses are in bytes, sizes are in quad-regs.\n+ */\n+struct storm_defs {\n+\tchar letter;\n+\tenum block_id sem_block_id;\n+\tenum dbg_bus_clients dbg_client_id[MAX_CHIP_IDS];\n+\tbool has_vfc;\n+\tu32 sem_fast_mem_addr;\n+\tu32 sem_frame_mode_addr;\n+\tu32 sem_slow_enable_addr;\n+\tu32 sem_slow_mode_addr;\n+\tu32 sem_slow_mode1_conf_addr;\n+\tu32 sem_sync_dbg_empty_addr;\n+\tu32 sem_gpre_vect_addr;\n+\tu32 cm_ctx_wr_addr;\n+\tu32 cm_ctx_rd_addr[NUM_CM_CTX_TYPES];\n+\tu32 cm_ctx_lid_sizes[MAX_CHIP_IDS][NUM_CM_CTX_TYPES];\n+};\n+\n+/* Debug Bus Constraint operation constant definitions */\n+struct dbg_bus_constraint_op_defs {\n+\tu8 hw_op_val;\n+\tbool is_cyclic;\n+};\n+\n+/* Storm Mode definitions */\n+struct storm_mode_defs {\n+\tconst char *name;\n+\tbool is_fast_dbg;\n+\tu8 id_in_hw;\n+\tu32 src_disable_reg_addr;\n+\tu32 src_enable_val;\n+\tbool exists[MAX_CHIP_IDS];\n+};\n+\n+struct grc_param_defs {\n+\tu32 default_val[MAX_CHIP_IDS];\n+\tu32 min;\n+\tu32 max;\n+\tbool is_preset;\n+\tbool is_persistent;\n+\tu32 exclude_all_preset_val;\n+\tu32 crash_preset_val[MAX_CHIP_IDS];\n+};\n+\n+/* Address is in 128b units. Width is in bits. */\n+struct rss_mem_defs {\n+\tconst char *mem_name;\n+\tconst char *type_name;\n+\tu32 addr;\n+\tu32 entry_width;\n+\tu32 num_entries[MAX_CHIP_IDS];\n+};\n+\n+struct vfc_ram_defs {\n+\tconst char *mem_name;\n+\tconst char *type_name;\n+\tu32 base_row;\n+\tu32 num_rows;\n+};\n+\n+struct big_ram_defs {\n+\tconst char *instance_name;\n+\tenum mem_groups mem_group_id;\n+\tenum mem_groups ram_mem_group_id;\n+\tenum dbg_grc_params grc_param;\n+\tu32 addr_reg_addr;\n+\tu32 data_reg_addr;\n+\tu32 is_256b_reg_addr;\n+\tu32 is_256b_bit_offset[MAX_CHIP_IDS];\n+\tu32 ram_size[MAX_CHIP_IDS]; /* In dwords */\n+};\n+\n+struct phy_defs {\n+\tconst char *phy_name;\n+\n+\t/* PHY base GRC address */\n+\tu32 base_addr;\n+\n+\t/* Relative address of indirect TBUS address register (bits 0..7) */\n+\tu32 tbus_addr_lo_addr;\n+\n+\t/* Relative address of indirect TBUS address register (bits 8..10) */\n+\tu32 tbus_addr_hi_addr;\n+\n+\t/* Relative address of indirect TBUS data register (bits 0..7) */\n+\tu32 tbus_data_lo_addr;\n+\n+\t/* Relative address of indirect TBUS data register (bits 8..11) */\n+\tu32 tbus_data_hi_addr;\n+};\n+\n+/* Split type definitions */\n+struct split_type_defs {\n+\tconst char *name;\n+};\n+\n+/******************************** Constants **********************************/\n+\n+#define BYTES_IN_DWORD\t\t\tsizeof(u32)\n+/* In the macros below, size and offset are specified in bits */\n+#define CEIL_DWORDS(size)\t\tDIV_ROUND_UP(size, 32)\n+#define FIELD_BIT_OFFSET(type, field)\ttype ## _ ## field ## _ ## OFFSET\n+#define FIELD_BIT_SIZE(type, field)\ttype ## _ ## field ## _ ## SIZE\n+#define FIELD_DWORD_OFFSET(type, field) \\\n+\t (int)(FIELD_BIT_OFFSET(type, field) / 32)\n+#define FIELD_DWORD_SHIFT(type, field)\t(FIELD_BIT_OFFSET(type, field) % 32)\n+#define FIELD_BIT_MASK(type, field) \\\n+\t(((1 << FIELD_BIT_SIZE(type, field)) - 1) << \\\n+\t FIELD_DWORD_SHIFT(type, field))\n+\n+#define SET_VAR_FIELD(var, type, field, val) \\\n+\tdo { \\\n+\t\tvar[FIELD_DWORD_OFFSET(type, field)] &=\t\\\n+\t\t(~FIELD_BIT_MASK(type, field));\t\\\n+\t\tvar[FIELD_DWORD_OFFSET(type, field)] |= \\\n+\t\t(val) << FIELD_DWORD_SHIFT(type, field); \\\n+\t} while (0)\n+\n+#define ARR_REG_WR(dev, ptt, addr, arr, arr_size) \\\n+\tdo { \\\n+\t\tfor (i = 0; i < (arr_size); i++) \\\n+\t\t\tecore_wr(dev, ptt, addr,\t(arr)[i]); \\\n+\t} while (0)\n+\n+#define DWORDS_TO_BYTES(dwords)\t\t((dwords) * BYTES_IN_DWORD)\n+#define BYTES_TO_DWORDS(bytes)\t\t((bytes) / BYTES_IN_DWORD)\n+\n+/* extra lines include a signature line + optional latency events line */\n+#define NUM_EXTRA_DBG_LINES(block) \\\n+\t(GET_FIELD((block)->flags, DBG_BLOCK_CHIP_HAS_LATENCY_EVENTS) ? 2 : 1)\n+#define NUM_DBG_LINES(block) \\\n+\t((block)->num_of_dbg_bus_lines + NUM_EXTRA_DBG_LINES(block))\n+\n+#define USE_DMAE\t\t\ttrue\n+#define PROTECT_WIDE_BUS\t\ttrue\n+\n+#define RAM_LINES_TO_DWORDS(lines)\t((lines) * 2)\n+#define RAM_LINES_TO_BYTES(lines) \\\n+\tDWORDS_TO_BYTES(RAM_LINES_TO_DWORDS(lines))\n+\n+#define REG_DUMP_LEN_SHIFT\t\t24\n+#define MEM_DUMP_ENTRY_SIZE_DWORDS \\\n+\tBYTES_TO_DWORDS(sizeof(struct dbg_dump_mem))\n+\n+#define IDLE_CHK_RULE_SIZE_DWORDS \\\n+\tBYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_rule))\n+\n+#define IDLE_CHK_RESULT_HDR_DWORDS \\\n+\tBYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_hdr))\n+\n+#define IDLE_CHK_RESULT_REG_HDR_DWORDS \\\n+\tBYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_reg_hdr))\n+\n+#define PAGE_MEM_DESC_SIZE_DWORDS \\\n+\tBYTES_TO_DWORDS(sizeof(struct phys_mem_desc))\n+\n+#define IDLE_CHK_MAX_ENTRIES_SIZE\t32\n+\n+/* The sizes and offsets below are specified in bits */\n+#define VFC_CAM_CMD_STRUCT_SIZE\t\t64\n+#define VFC_CAM_CMD_ROW_OFFSET\t\t48\n+#define VFC_CAM_CMD_ROW_SIZE\t\t9\n+#define VFC_CAM_ADDR_STRUCT_SIZE\t16\n+#define VFC_CAM_ADDR_OP_OFFSET\t\t0\n+#define VFC_CAM_ADDR_OP_SIZE\t\t4\n+#define VFC_CAM_RESP_STRUCT_SIZE\t256\n+#define VFC_RAM_ADDR_STRUCT_SIZE\t16\n+#define VFC_RAM_ADDR_OP_OFFSET\t\t0\n+#define VFC_RAM_ADDR_OP_SIZE\t\t2\n+#define VFC_RAM_ADDR_ROW_OFFSET\t\t2\n+#define VFC_RAM_ADDR_ROW_SIZE\t\t10\n+#define VFC_RAM_RESP_STRUCT_SIZE\t256\n+\n+#define VFC_CAM_CMD_DWORDS\t\tCEIL_DWORDS(VFC_CAM_CMD_STRUCT_SIZE)\n+#define VFC_CAM_ADDR_DWORDS\t\tCEIL_DWORDS(VFC_CAM_ADDR_STRUCT_SIZE)\n+#define VFC_CAM_RESP_DWORDS\t\tCEIL_DWORDS(VFC_CAM_RESP_STRUCT_SIZE)\n+#define VFC_RAM_CMD_DWORDS\t\tVFC_CAM_CMD_DWORDS\n+#define VFC_RAM_ADDR_DWORDS\t\tCEIL_DWORDS(VFC_RAM_ADDR_STRUCT_SIZE)\n+#define VFC_RAM_RESP_DWORDS\t\tCEIL_DWORDS(VFC_RAM_RESP_STRUCT_SIZE)\n+\n+#define NUM_VFC_RAM_TYPES\t\t4\n+\n+#define VFC_CAM_NUM_ROWS\t\t512\n+\n+#define VFC_OPCODE_CAM_RD\t\t14\n+#define VFC_OPCODE_RAM_RD\t\t0\n+\n+#define NUM_RSS_MEM_TYPES\t\t5\n+\n+#define NUM_BIG_RAM_TYPES\t\t3\n+#define BIG_RAM_NAME_LEN\t\t3\n+\n+#define NUM_PHY_TBUS_ADDRESSES\t\t2048\n+#define PHY_DUMP_SIZE_DWORDS\t\t(NUM_PHY_TBUS_ADDRESSES / 2)\n+\n+#define RESET_REG_UNRESET_OFFSET\t4\n+\n+#define STALL_DELAY_MS\t\t\t500\n+\n+#define STATIC_DEBUG_LINE_DWORDS\t9\n+\n+#define NUM_COMMON_GLOBAL_PARAMS\t11\n+\n+#define MAX_RECURSION_DEPTH\t\t10\n+\n+#define FW_IMG_MAIN\t\t\t1\n+\n+#define REG_FIFO_ELEMENT_DWORDS\t\t2\n+#define REG_FIFO_DEPTH_ELEMENTS\t\t32\n+#define REG_FIFO_DEPTH_DWORDS \\\n+\t(REG_FIFO_ELEMENT_DWORDS * REG_FIFO_DEPTH_ELEMENTS)\n+\n+#define IGU_FIFO_ELEMENT_DWORDS\t\t4\n+#define IGU_FIFO_DEPTH_ELEMENTS\t\t64\n+#define IGU_FIFO_DEPTH_DWORDS \\\n+\t(IGU_FIFO_ELEMENT_DWORDS * IGU_FIFO_DEPTH_ELEMENTS)\n+\n+#define PROTECTION_OVERRIDE_ELEMENT_DWORDS\t2\n+#define PROTECTION_OVERRIDE_DEPTH_ELEMENTS\t20\n+#define PROTECTION_OVERRIDE_DEPTH_DWORDS \\\n+\t(PROTECTION_OVERRIDE_DEPTH_ELEMENTS * \\\n+\t PROTECTION_OVERRIDE_ELEMENT_DWORDS)\n+\n+#define MCP_SPAD_TRACE_OFFSIZE_ADDR \\\n+\t(MCP_REG_SCRATCH + \\\n+\t offsetof(struct static_init, sections[SPAD_SECTION_TRACE]))\n+\n+#define MAX_SW_PLTAFORM_STR_SIZE\t64\n+\n+#define EMPTY_FW_VERSION_STR\t\t\"???_???_???_???\"\n+#define EMPTY_FW_IMAGE_STR\t\t\"???????????????\"\n+\n+/***************************** Constant Arrays *******************************/\n+\n+/* Chip constant definitions array */\n+static struct chip_defs s_chip_defs[MAX_CHIP_IDS] = {\n+\t{\"bb\", PSWRQ2_REG_ILT_MEMORY_SIZE_BB / 2},\n+\t{\"ah\", PSWRQ2_REG_ILT_MEMORY_SIZE_K2 / 2}\n+};\n+\n+/* Storm constant definitions array */\n+static struct storm_defs s_storm_defs[] = {\n+\t/* Tstorm */\n+\t{'T', BLOCK_TSEM,\n+\t\t{DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},\n+\t\ttrue,\n+\t\tTSEM_REG_FAST_MEMORY,\n+\t\tTSEM_REG_DBG_FRAME_MODE, TSEM_REG_SLOW_DBG_ACTIVE,\n+\t\tTSEM_REG_SLOW_DBG_MODE, TSEM_REG_DBG_MODE1_CFG,\n+\t\tTSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_DBG_GPRE_VECT,\n+\t\tTCM_REG_CTX_RBC_ACCS,\n+\t\t{TCM_REG_AGG_CON_CTX, TCM_REG_SM_CON_CTX, TCM_REG_AGG_TASK_CTX,\n+\t\t TCM_REG_SM_TASK_CTX},\n+\t\t{{4, 16, 2, 4}, {4, 16, 2, 4} } /* {bb} {k2} */\n+\t},\n+\n+\t/* Mstorm */\n+\t{'M', BLOCK_MSEM,\n+\t\t{DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},\n+\t\tfalse,\n+\t\tMSEM_REG_FAST_MEMORY,\n+\t\tMSEM_REG_DBG_FRAME_MODE,\n+\t\tMSEM_REG_SLOW_DBG_ACTIVE,\n+\t\tMSEM_REG_SLOW_DBG_MODE,\n+\t\tMSEM_REG_DBG_MODE1_CFG,\n+\t\tMSEM_REG_SYNC_DBG_EMPTY,\n+\t\tMSEM_REG_DBG_GPRE_VECT,\n+\t\tMCM_REG_CTX_RBC_ACCS,\n+\t\t{MCM_REG_AGG_CON_CTX, MCM_REG_SM_CON_CTX, MCM_REG_AGG_TASK_CTX,\n+\t\t MCM_REG_SM_TASK_CTX },\n+\t\t{{1, 10, 2, 7}, {1, 10, 2, 7} } /* {bb} {k2}*/\n+\t},\n+\n+\t/* Ustorm */\n+\t{'U', BLOCK_USEM,\n+\t\t{DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},\n+\t\tfalse,\n+\t\tUSEM_REG_FAST_MEMORY,\n+\t\tUSEM_REG_DBG_FRAME_MODE,\n+\t\tUSEM_REG_SLOW_DBG_ACTIVE,\n+\t\tUSEM_REG_SLOW_DBG_MODE,\n+\t\tUSEM_REG_DBG_MODE1_CFG,\n+\t\tUSEM_REG_SYNC_DBG_EMPTY,\n+\t\tUSEM_REG_DBG_GPRE_VECT,\n+\t\tUCM_REG_CTX_RBC_ACCS,\n+\t\t{UCM_REG_AGG_CON_CTX, UCM_REG_SM_CON_CTX, UCM_REG_AGG_TASK_CTX,\n+\t\t UCM_REG_SM_TASK_CTX},\n+\t\t{{2, 13, 3, 3}, {2, 13, 3, 3} } /* {bb} {k2} */\n+\t},\n+\n+\t/* Xstorm */\n+\t{'X', BLOCK_XSEM,\n+\t\t{DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},\n+\t\tfalse,\n+\t\tXSEM_REG_FAST_MEMORY,\n+\t\tXSEM_REG_DBG_FRAME_MODE,\n+\t\tXSEM_REG_SLOW_DBG_ACTIVE,\n+\t\tXSEM_REG_SLOW_DBG_MODE,\n+\t\tXSEM_REG_DBG_MODE1_CFG,\n+\t\tXSEM_REG_SYNC_DBG_EMPTY,\n+\t\tXSEM_REG_DBG_GPRE_VECT,\n+\t\tXCM_REG_CTX_RBC_ACCS,\n+\t\t{XCM_REG_AGG_CON_CTX, XCM_REG_SM_CON_CTX, 0, 0},\n+\t\t{{9, 15, 0, 0}, {9, 15,\t0, 0} } /* {bb} {k2} */\n+\t},\n+\n+\t/* Ystorm */\n+\t{'Y', BLOCK_YSEM,\n+\t\t{DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY},\n+\t\tfalse,\n+\t\tYSEM_REG_FAST_MEMORY,\n+\t\tYSEM_REG_DBG_FRAME_MODE,\n+\t\tYSEM_REG_SLOW_DBG_ACTIVE,\n+\t\tYSEM_REG_SLOW_DBG_MODE,\n+\t\tYSEM_REG_DBG_MODE1_CFG,\n+\t\tYSEM_REG_SYNC_DBG_EMPTY,\n+\t\tYSEM_REG_DBG_GPRE_VECT,\n+\t\tYCM_REG_CTX_RBC_ACCS,\n+\t\t{YCM_REG_AGG_CON_CTX, YCM_REG_SM_CON_CTX, YCM_REG_AGG_TASK_CTX,\n+\t\t YCM_REG_SM_TASK_CTX},\n+\t\t{{2, 3, 2, 12}, {2, 3, 2, 12} } /* {bb} {k2} */\n+\t},\n+\n+\t/* Pstorm */\n+\t{'P', BLOCK_PSEM,\n+\t\t{DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},\n+\t\ttrue,\n+\t\tPSEM_REG_FAST_MEMORY,\n+\t\tPSEM_REG_DBG_FRAME_MODE,\n+\t\tPSEM_REG_SLOW_DBG_ACTIVE,\n+\t\tPSEM_REG_SLOW_DBG_MODE,\n+\t\tPSEM_REG_DBG_MODE1_CFG,\n+\t\tPSEM_REG_SYNC_DBG_EMPTY,\n+\t\tPSEM_REG_DBG_GPRE_VECT,\n+\t\tPCM_REG_CTX_RBC_ACCS,\n+\t\t{0, PCM_REG_SM_CON_CTX, 0, 0},\n+\t\t{{0, 10, 0, 0}, {0, 10, 0, 0} } /* {bb} {k2} */\n+\t},\n+};\n+\n+static struct hw_type_defs s_hw_type_defs[] = {\n+\t/* HW_TYPE_ASIC */\n+\t{\"asic\", 1, 256, 32768},\n+\t{\"reserved\", 0, 0, 0},\n+\t{\"reserved2\", 0, 0, 0},\n+\t{\"reserved3\", 0, 0, 0}\n+};\n+\n+static struct grc_param_defs s_grc_param_defs[] = {\n+\t/* DBG_GRC_PARAM_DUMP_TSTORM */\n+\t{{1, 1}, 0, 1, false, false, 1, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_MSTORM */\n+\t{{1, 1}, 0, 1, false, false, 1, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_USTORM */\n+\t{{1, 1}, 0, 1, false, false, 1, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_XSTORM */\n+\t{{1, 1}, 0, 1, false, false, 1, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_YSTORM */\n+\t{{1, 1}, 0, 1, false, false, 1, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_PSTORM */\n+\t{{1, 1}, 0, 1, false, false, 1, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_REGS */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_RAM */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_PBUF */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_IOR */\n+\t{{0, 0}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_VFC */\n+\t{{0, 0}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_CM_CTX */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_ILT */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_RSS */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_CAU */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_QM */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_MCP */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_DORQ */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_CFC */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_IGU */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_BRB */\n+\t{{0, 0}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_BTB */\n+\t{{0, 0}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_BMB */\n+\t{{0, 0}, 0, 1, false, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_RESERVED1 */\n+\t{{0, 0}, 0, 1, false, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_MULD */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_PRS */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_DMAE */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_TM */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_SDM */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_DIF */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_STATIC */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_UNSTALL */\n+\t{{0, 0}, 0, 1, false, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_RESERVED2 */\n+\t{{0, 0}, 0, 1, false, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_MCP_TRACE_META_SIZE */\n+\t{{0, 0}, 1, 0xffffffff, false, true, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_EXCLUDE_ALL */\n+\t{{0, 0}, 0, 1, true, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_CRASH */\n+\t{{0, 0}, 0, 1, true, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_PARITY_SAFE */\n+\t{{0, 0}, 0, 1, false, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_CM */\n+\t{{1, 1}, 0, 1, false, false, 0, {1, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_PHY */\n+\t{{0, 0}, 0, 1, false, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_NO_MCP */\n+\t{{0, 0}, 0, 1, false, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_NO_FW_VER */\n+\t{{0, 0}, 0, 1, false, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_RESERVED3 */\n+\t{{0, 0}, 0, 1, false, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_MCP_HW_DUMP */\n+\t{{0, 1}, 0, 1, false, false, 0, {0, 1} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_ILT_CDUC */\n+\t{{1, 1}, 0, 1, false, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_ILT_CDUT */\n+\t{{1, 1}, 0, 1, false, false, 0, {0, 0} },\n+\n+\t/* DBG_GRC_PARAM_DUMP_CAU_EXT */\n+\t{{0, 0}, 0, 1, false, false, 0, {1, 1} }\n+};\n+\n+static struct rss_mem_defs s_rss_mem_defs[] = {\n+\t{\"rss_mem_cid\", \"rss_cid\", 0, 32,\n+\t {256, 320} },\n+\n+\t{\"rss_mem_key_msb\", \"rss_key\", 1024, 256,\n+\t {128, 208} },\n+\n+\t{\"rss_mem_key_lsb\", \"rss_key\", 2048, 64,\n+\t {128, 208} },\n+\n+\t{\"rss_mem_info\", \"rss_info\", 3072, 16,\n+\t {128, 208} },\n+\n+\t{\"rss_mem_ind\", \"rss_ind\", 4096, 16,\n+\t {16384, 26624} }\n+};\n+\n+static struct vfc_ram_defs s_vfc_ram_defs[] = {\n+\t{\"vfc_ram_tt1\", \"vfc_ram\", 0, 512},\n+\t{\"vfc_ram_mtt2\", \"vfc_ram\", 512, 128},\n+\t{\"vfc_ram_stt2\", \"vfc_ram\", 640, 32},\n+\t{\"vfc_ram_ro_vect\", \"vfc_ram\", 672, 32}\n+};\n+\n+static struct big_ram_defs s_big_ram_defs[] = {\n+\t{\"BRB\", MEM_GROUP_BRB_MEM, MEM_GROUP_BRB_RAM, DBG_GRC_PARAM_DUMP_BRB,\n+\t BRB_REG_BIG_RAM_ADDRESS, BRB_REG_BIG_RAM_DATA,\n+\t MISC_REG_BLOCK_256B_EN, {0, 0},\n+\t {153600, 180224} },\n+\n+\t{\"BTB\", MEM_GROUP_BTB_MEM, MEM_GROUP_BTB_RAM, DBG_GRC_PARAM_DUMP_BTB,\n+\t BTB_REG_BIG_RAM_ADDRESS, BTB_REG_BIG_RAM_DATA,\n+\t MISC_REG_BLOCK_256B_EN, {0, 1},\n+\t {92160, 117760} },\n+\n+\t{\"BMB\", MEM_GROUP_BMB_MEM, MEM_GROUP_BMB_RAM, DBG_GRC_PARAM_DUMP_BMB,\n+\t BMB_REG_BIG_RAM_ADDRESS, BMB_REG_BIG_RAM_DATA,\n+\t MISCS_REG_BLOCK_256B_EN, {0, 0},\n+\t {36864, 36864} }\n+};\n+\n+static struct rbc_reset_defs s_rbc_reset_defs[] = {\n+\t{MISCS_REG_RESET_PL_HV,\n+\t {0x0, 0x400} },\n+\t{MISC_REG_RESET_PL_PDA_VMAIN_1,\n+\t {0x4404040, 0x4404040} },\n+\t{MISC_REG_RESET_PL_PDA_VMAIN_2,\n+\t {0x7, 0x7c00007} },\n+\t{MISC_REG_RESET_PL_PDA_VAUX,\n+\t {0x2, 0x2} },\n+};\n+\n+static struct phy_defs s_phy_defs[] = {\n+\t{\"nw_phy\", NWS_REG_NWS_CMU_K2,\n+\t PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_7_0_K2,\n+\t PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_15_8_K2,\n+\t PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_7_0_K2,\n+\t PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_11_8_K2},\n+\t{\"sgmii_phy\", MS_REG_MS_CMU_K2,\n+\t PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X132_K2,\n+\t PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X133_K2,\n+\t PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X130_K2,\n+\t PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X131_K2},\n+\t{\"pcie_phy0\", PHY_PCIE_REG_PHY0_K2,\n+\t PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2,\n+\t PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2,\n+\t PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2,\n+\t PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2},\n+\t{\"pcie_phy1\", PHY_PCIE_REG_PHY1_K2,\n+\t PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2,\n+\t PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2,\n+\t PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2,\n+\t PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2},\n+};\n+\n+static struct split_type_defs s_split_type_defs[] = {\n+\t/* SPLIT_TYPE_NONE */\n+\t{\"eng\"},\n+\n+\t/* SPLIT_TYPE_PORT */\n+\t{\"port\"},\n+\n+\t/* SPLIT_TYPE_PF */\n+\t{\"pf\"},\n+\n+\t/* SPLIT_TYPE_PORT_PF */\n+\t{\"port\"},\n+\n+\t/* SPLIT_TYPE_VF */\n+\t{\"vf\"}\n+};\n+\n+/******************************** Variables *********************************/\n+\n+/**\n+ * The version of the calling app\n+ */\n+static u32 s_app_ver;\n+\n+/**************************** Private Functions ******************************/\n+\n+/* Reads and returns a single dword from the specified unaligned buffer */\n+static u32 qed_read_unaligned_dword(u8 *buf)\n+{\n+\tu32 dword;\n+\n+\tmemcpy((u8 *)&dword, buf, sizeof(dword));\n+\treturn dword;\n+}\n+\n+/* Sets the value of the specified GRC param */\n+static void qed_grc_set_param(struct ecore_hwfn *p_hwfn,\n+\t\t\t      enum dbg_grc_params grc_param, u32 val)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\n+\tdev_data->grc.param_val[grc_param] = val;\n+}\n+\n+/* Returns the value of the specified GRC param */\n+static u32 qed_grc_get_param(struct ecore_hwfn *p_hwfn,\n+\t\t\t     enum dbg_grc_params grc_param)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\n+\treturn dev_data->grc.param_val[grc_param];\n+}\n+\n+/* Initializes the GRC parameters */\n+static void qed_dbg_grc_init_params(struct ecore_hwfn *p_hwfn)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\n+\tif (!dev_data->grc.params_initialized) {\n+\t\tqed_dbg_grc_set_params_default(p_hwfn);\n+\t\tdev_data->grc.params_initialized = 1;\n+\t}\n+}\n+\n+/* Sets pointer and size for the specified binary buffer type */\n+static void qed_set_dbg_bin_buf(struct ecore_hwfn *p_hwfn,\n+\t\t\t\tenum bin_dbg_buffer_type buf_type,\n+\t\t\t\tconst u32 *ptr, u32 size)\n+{\n+\tstruct virt_mem_desc *buf = &p_hwfn->dbg_arrays[buf_type];\n+\n+\tbuf->ptr = (void *)(osal_uintptr_t)ptr;\n+\tbuf->size = size;\n+}\n+\n+/* Initializes debug data for the specified device */\n+static enum dbg_status qed_dbg_dev_init(struct ecore_hwfn *p_hwfn)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu8 num_pfs = 0, max_pfs_per_port = 0;\n+\n+\tif (dev_data->initialized)\n+\t\treturn DBG_STATUS_OK;\n+\n+\t/* Set chip */\n+\tif (ECORE_IS_K2(p_hwfn->p_dev)) {\n+\t\tdev_data->chip_id = CHIP_K2;\n+\t\tdev_data->mode_enable[MODE_K2] = 1;\n+\t\tdev_data->num_vfs = MAX_NUM_VFS_K2;\n+\t\tnum_pfs = MAX_NUM_PFS_K2;\n+\t\tmax_pfs_per_port = MAX_NUM_PFS_K2 / 2;\n+\t} else if (ECORE_IS_BB_B0(p_hwfn->p_dev)) {\n+\t\tdev_data->chip_id = CHIP_BB;\n+\t\tdev_data->mode_enable[MODE_BB] = 1;\n+\t\tdev_data->num_vfs = MAX_NUM_VFS_BB;\n+\t\tnum_pfs = MAX_NUM_PFS_BB;\n+\t\tmax_pfs_per_port = MAX_NUM_PFS_BB;\n+\t} else {\n+\t\treturn DBG_STATUS_UNKNOWN_CHIP;\n+\t}\n+\n+\t/* Set HW type */\n+\tdev_data->hw_type = HW_TYPE_ASIC;\n+\tdev_data->mode_enable[MODE_ASIC] = 1;\n+\n+\t/* Set port mode */\n+\tswitch (p_hwfn->p_dev->num_ports_in_engine) {\n+\tcase 1:\n+\t\tdev_data->mode_enable[MODE_PORTS_PER_ENG_1] = 1;\n+\t\tbreak;\n+\tcase 2:\n+\t\tdev_data->mode_enable[MODE_PORTS_PER_ENG_2] = 1;\n+\t\tbreak;\n+\tcase 4:\n+\t\tdev_data->mode_enable[MODE_PORTS_PER_ENG_4] = 1;\n+\t\tbreak;\n+\t}\n+\n+\t/* Set 100G mode */\n+\tif (ECORE_IS_CMT(p_hwfn->p_dev))\n+\t\tdev_data->mode_enable[MODE_100G] = 1;\n+\n+\t/* Set number of ports */\n+\tif (dev_data->mode_enable[MODE_PORTS_PER_ENG_1] ||\n+\t    dev_data->mode_enable[MODE_100G])\n+\t\tdev_data->num_ports = 1;\n+\telse if (dev_data->mode_enable[MODE_PORTS_PER_ENG_2])\n+\t\tdev_data->num_ports = 2;\n+\telse if (dev_data->mode_enable[MODE_PORTS_PER_ENG_4])\n+\t\tdev_data->num_ports = 4;\n+\n+\t/* Set number of PFs per port */\n+\tdev_data->num_pfs_per_port = OSAL_MIN_T(u32,\n+\t\t\t\t\t\tnum_pfs / dev_data->num_ports,\n+\t\t\t\t\t\tmax_pfs_per_port);\n+\n+\t/* Initializes the GRC parameters */\n+\tqed_dbg_grc_init_params(p_hwfn);\n+\n+\tdev_data->use_dmae = true;\n+\tdev_data->initialized = 1;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+static const struct dbg_block *get_dbg_block(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t     enum block_id block_id)\n+{\n+\tconst struct dbg_block *dbg_block;\n+\n+\tdbg_block = p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS].ptr;\n+\treturn dbg_block + block_id;\n+}\n+\n+static const struct dbg_block_chip *qed_get_dbg_block_per_chip(struct ecore_hwfn\n+\t\t\t\t\t\t\t       *p_hwfn,\n+\t\t\t\t\t\t\t       enum block_id\n+\t\t\t\t\t\t\t       block_id)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\n+\treturn (const struct dbg_block_chip *)\n+\t    p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS_CHIP_DATA].ptr +\n+\t    block_id * MAX_CHIP_IDS + dev_data->chip_id;\n+}\n+\n+static const struct dbg_reset_reg *qed_get_dbg_reset_reg(struct ecore_hwfn\n+\t\t\t\t\t\t\t *p_hwfn,\n+\t\t\t\t\t\t\t u8 reset_reg_id)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\n+\treturn (const struct dbg_reset_reg *)\n+\t    p_hwfn->dbg_arrays[BIN_BUF_DBG_RESET_REGS].ptr +\n+\t    reset_reg_id * MAX_CHIP_IDS + dev_data->chip_id;\n+}\n+\n+/* Reads the FW info structure for the specified Storm from the chip,\n+ * and writes it to the specified fw_info pointer.\n+ */\n+static void qed_read_storm_fw_info(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   struct ecore_ptt *p_ptt,\n+\t\t\t\t   u8 storm_id, struct fw_info *fw_info)\n+{\n+\tstruct storm_defs *storm = &s_storm_defs[storm_id];\n+\tstruct fw_info_location fw_info_location;\n+\tu32 addr, i, *dest;\n+\n+\tmemset(&fw_info_location, 0, sizeof(fw_info_location));\n+\tmemset(fw_info, 0, sizeof(*fw_info));\n+\n+\t/* Read first the address that points to fw_info location.\n+\t * The address is located in the last line of the Storm RAM.\n+\t */\n+\taddr = storm->sem_fast_mem_addr + SEM_FAST_REG_INT_RAM +\n+\t    DWORDS_TO_BYTES(SEM_FAST_REG_INT_RAM_SIZE) -\n+\t    sizeof(fw_info_location);\n+\n+\tdest = (u32 *)&fw_info_location;\n+\n+\tfor (i = 0; i < BYTES_TO_DWORDS(sizeof(fw_info_location));\n+\t     i++, addr += BYTES_IN_DWORD)\n+\t\tdest[i] = ecore_rd(p_hwfn, p_ptt, addr);\n+\n+\t/* Read FW version info from Storm RAM */\n+\tif (fw_info_location.size > 0 && fw_info_location.size <=\n+\t    sizeof(*fw_info)) {\n+\t\taddr = fw_info_location.grc_addr;\n+\t\tdest = (u32 *)fw_info;\n+\t\tfor (i = 0; i < BYTES_TO_DWORDS(fw_info_location.size);\n+\t\t     i++, addr += BYTES_IN_DWORD)\n+\t\t\tdest[i] = ecore_rd(p_hwfn, p_ptt, addr);\n+\t}\n+}\n+\n+/* Dumps the specified string to the specified buffer.\n+ * Returns the dumped size in bytes.\n+ */\n+static u32 qed_dump_str(char *dump_buf, bool dump, const char *str)\n+{\n+\tif (dump)\n+\t\tstrcpy(dump_buf, str);\n+\n+\treturn (u32)strlen(str) + 1;\n+}\n+\n+/* Dumps zeros to align the specified buffer to dwords.\n+ * Returns the dumped size in bytes.\n+ */\n+static u32 qed_dump_align(char *dump_buf, bool dump, u32 byte_offset)\n+{\n+\tu8 offset_in_dword, align_size;\n+\n+\toffset_in_dword = (u8)(byte_offset & 0x3);\n+\talign_size = offset_in_dword ? BYTES_IN_DWORD - offset_in_dword : 0;\n+\n+\tif (dump && align_size)\n+\t\tmemset(dump_buf, 0, align_size);\n+\n+\treturn align_size;\n+}\n+\n+/* Writes the specified string param to the specified buffer.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_dump_str_param(u32 *dump_buf,\n+\t\t\t      bool dump,\n+\t\t\t      const char *param_name, const char *param_val)\n+{\n+\tchar *char_buf = (char *)dump_buf;\n+\tu32 offset = 0;\n+\n+\t/* Dump param name */\n+\toffset += qed_dump_str(char_buf + offset, dump, param_name);\n+\n+\t/* Indicate a string param value */\n+\tif (dump)\n+\t\t*(char_buf + offset) = 1;\n+\toffset++;\n+\n+\t/* Dump param value */\n+\toffset += qed_dump_str(char_buf + offset, dump, param_val);\n+\n+\t/* Align buffer to next dword */\n+\toffset += qed_dump_align(char_buf + offset, dump, offset);\n+\n+\treturn BYTES_TO_DWORDS(offset);\n+}\n+\n+/* Writes the specified numeric param to the specified buffer.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_dump_num_param(u32 *dump_buf,\n+\t\t\t      bool dump, const char *param_name, u32 param_val)\n+{\n+\tchar *char_buf = (char *)dump_buf;\n+\tu32 offset = 0;\n+\n+\t/* Dump param name */\n+\toffset += qed_dump_str(char_buf + offset, dump, param_name);\n+\n+\t/* Indicate a numeric param value */\n+\tif (dump)\n+\t\t*(char_buf + offset) = 0;\n+\toffset++;\n+\n+\t/* Align buffer to next dword */\n+\toffset += qed_dump_align(char_buf + offset, dump, offset);\n+\n+\t/* Dump param value (and change offset from bytes to dwords) */\n+\toffset = BYTES_TO_DWORDS(offset);\n+\tif (dump)\n+\t\t*(dump_buf + offset) = param_val;\n+\toffset++;\n+\n+\treturn offset;\n+}\n+\n+/* Reads the FW version and writes it as a param to the specified buffer.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_dump_fw_ver_param(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t struct ecore_ptt *p_ptt,\n+\t\t\t\t u32 *dump_buf, bool dump)\n+{\n+\tchar fw_ver_str[16] = EMPTY_FW_VERSION_STR;\n+\tchar fw_img_str[16] = EMPTY_FW_IMAGE_STR;\n+\tstruct fw_info fw_info = { {0}, {0} };\n+\tu32 offset = 0;\n+\n+\tif (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {\n+\t\t/* Read FW info from chip */\n+\t\tqed_read_fw_info(p_hwfn, p_ptt, &fw_info);\n+\n+\t\t/* Create FW version/image strings */\n+\t\tif (snprintf(fw_ver_str, sizeof(fw_ver_str),\n+\t\t\t     \"%d_%d_%d_%d\", fw_info.ver.num.major,\n+\t\t\t     fw_info.ver.num.minor, fw_info.ver.num.rev,\n+\t\t\t     fw_info.ver.num.eng) < 0)\n+\t\t\tDP_NOTICE(p_hwfn, false,\n+\t\t\t\t  \"Unexpected debug error: invalid FW version string\\n\");\n+\t\tswitch (fw_info.ver.image_id) {\n+\t\tcase FW_IMG_MAIN:\n+\t\t\tstrcpy(fw_img_str, \"main\");\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tstrcpy(fw_img_str, \"unknown\");\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/* Dump FW version, image and timestamp */\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump, \"fw-version\", fw_ver_str);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump, \"fw-image\", fw_img_str);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"fw-timestamp\", fw_info.ver.timestamp);\n+\n+\treturn offset;\n+}\n+\n+/* Reads the MFW version and writes it as a param to the specified buffer.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_dump_mfw_ver_param(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t  struct ecore_ptt *p_ptt,\n+\t\t\t\t  u32 *dump_buf, bool dump)\n+{\n+\tchar mfw_ver_str[16] = EMPTY_FW_VERSION_STR;\n+\n+\tif (dump &&\n+\t    !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {\n+\t\tu32 global_section_offsize, global_section_addr, mfw_ver;\n+\t\tu32 public_data_addr, global_section_offsize_addr;\n+\n+\t\t/* Find MCP public data GRC address. Needs to be ORed with\n+\t\t * MCP_REG_SCRATCH due to a HW bug.\n+\t\t */\n+\t\tpublic_data_addr = ecore_rd(p_hwfn,\n+\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t  MISC_REG_SHARED_MEM_ADDR) |\n+\t\t\t\t   MCP_REG_SCRATCH;\n+\n+\t\t/* Find MCP public global section offset */\n+\t\tglobal_section_offsize_addr = public_data_addr +\n+\t\t\t\t\t      offsetof(struct mcp_public_data,\n+\t\t\t\t\t\t       sections) +\n+\t\t\t\t\t      sizeof(offsize_t) * PUBLIC_GLOBAL;\n+\t\tglobal_section_offsize = ecore_rd(p_hwfn, p_ptt,\n+\t\t\t\t\t\tglobal_section_offsize_addr);\n+\t\tglobal_section_addr =\n+\t\t\tMCP_REG_SCRATCH +\n+\t\t\t(global_section_offsize & OFFSIZE_OFFSET_MASK) * 4;\n+\n+\t\t/* Read MFW version from MCP public global section */\n+\t\tmfw_ver = ecore_rd(p_hwfn, p_ptt,\n+\t\t\t\t global_section_addr +\n+\t\t\t\t offsetof(struct public_global, mfw_ver));\n+\n+\t\t/* Dump MFW version param */\n+\t\tif (snprintf(mfw_ver_str, sizeof(mfw_ver_str), \"%d_%d_%d_%d\",\n+\t\t\t     (u8)(mfw_ver >> 24), (u8)(mfw_ver >> 16),\n+\t\t\t     (u8)(mfw_ver >> 8), (u8)mfw_ver) < 0)\n+\t\t\tDP_NOTICE(p_hwfn, false,\n+\t\t\t\t  \"Unexpected debug error: invalid MFW version string\\n\");\n+\t}\n+\n+\treturn qed_dump_str_param(dump_buf, dump, \"mfw-version\", mfw_ver_str);\n+}\n+\n+/* Reads the chip revision from the chip and writes it as a param to the\n+ * specified buffer. Returns the dumped size in dwords.\n+ */\n+static u32 qed_dump_chip_revision_param(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\tstruct ecore_ptt *p_ptt,\n+\t\t\t\t\tu32 *dump_buf, bool dump)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tchar param_str[3] = \"??\";\n+\n+\tif (dev_data->hw_type == HW_TYPE_ASIC) {\n+\t\tu32 chip_rev, chip_metal;\n+\n+\t\tchip_rev = ecore_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_REV);\n+\t\tchip_metal = ecore_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_METAL);\n+\n+\t\tparam_str[0] = 'a' + (u8)chip_rev;\n+\t\tparam_str[1] = '0' + (u8)chip_metal;\n+\t}\n+\n+\treturn qed_dump_str_param(dump_buf, dump, \"chip-revision\", param_str);\n+}\n+\n+/* Writes a section header to the specified buffer.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_dump_section_hdr(u32 *dump_buf,\n+\t\t\t\tbool dump, const char *name, u32 num_params)\n+{\n+\treturn qed_dump_num_param(dump_buf, dump, name, num_params);\n+}\n+\n+/* Writes the common global params to the specified buffer.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_dump_common_global_params(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t struct ecore_ptt *p_ptt,\n+\t\t\t\t\t u32 *dump_buf,\n+\t\t\t\t\t bool dump,\n+\t\t\t\t\t u8 num_specific_global_params)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tchar sw_platform_str[MAX_SW_PLTAFORM_STR_SIZE];\n+\tu32 offset = 0;\n+\tu8 num_params;\n+\n+\t/* Fill platform string */\n+\tecore_set_platform_str(p_hwfn, sw_platform_str,\n+\t\t\t       MAX_SW_PLTAFORM_STR_SIZE);\n+\n+\t/* Dump global params section header */\n+\tnum_params = NUM_COMMON_GLOBAL_PARAMS + num_specific_global_params +\n+\t\t(dev_data->chip_id == CHIP_BB ? 1 : 0);\n+\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t       dump, \"global_params\", num_params);\n+\n+\t/* Store params */\n+\toffset += qed_dump_fw_ver_param(p_hwfn, p_ptt, dump_buf + offset, dump);\n+\toffset += qed_dump_mfw_ver_param(p_hwfn,\n+\t\t\t\t\t p_ptt, dump_buf + offset, dump);\n+\toffset += qed_dump_chip_revision_param(p_hwfn,\n+\t\t\t\t\t       p_ptt, dump_buf + offset, dump);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump, \"tools-version\", TOOLS_VERSION);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"chip\",\n+\t\t\t\t     s_chip_defs[dev_data->chip_id].name);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"platform\",\n+\t\t\t\t     s_hw_type_defs[dev_data->hw_type].name);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump, \"sw-platform\", sw_platform_str);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump, \"pci-func\", p_hwfn->abs_pf_id);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump, \"epoch\", OSAL_GET_EPOCH(p_hwfn));\n+\tif (dev_data->chip_id == CHIP_BB)\n+\t\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t\t     dump, \"path\",\n+\t\t\t\t\t     ECORE_PATH_ID(p_hwfn));\n+\n+\treturn offset;\n+}\n+\n+/* Writes the \"last\" section (including CRC) to the specified buffer at the\n+ * given offset. Returns the dumped size in dwords.\n+ */\n+static u32 qed_dump_last_section(u32 *dump_buf, u32 offset, bool dump)\n+{\n+\tu32 start_offset = offset;\n+\n+\t/* Dump CRC section header */\n+\toffset += qed_dump_section_hdr(dump_buf + offset, dump, \"last\", 0);\n+\n+\t/* Calculate CRC32 and add it to the dword after the \"last\" section */\n+\tif (dump)\n+\t\t*(dump_buf + offset) = ~OSAL_CRC32(0xffffffff,\n+\t\t\t\t\t      (u8 *)dump_buf,\n+\t\t\t\t\t      DWORDS_TO_BYTES(offset));\n+\n+\toffset++;\n+\n+\treturn offset - start_offset;\n+}\n+\n+/* Update blocks reset state  */\n+static void qed_update_blocks_reset_state(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t  struct ecore_ptt *p_ptt)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu32 reg_val[NUM_DBG_RESET_REGS] = { 0 };\n+\tu8 rst_reg_id;\n+\tu32 blk_id;\n+\n+\t/* Read reset registers */\n+\tfor (rst_reg_id = 0; rst_reg_id < NUM_DBG_RESET_REGS; rst_reg_id++) {\n+\t\tconst struct dbg_reset_reg *rst_reg;\n+\t\tbool rst_reg_removed;\n+\t\tu32 rst_reg_addr;\n+\n+\t\trst_reg = qed_get_dbg_reset_reg(p_hwfn, rst_reg_id);\n+\t\trst_reg_removed = GET_FIELD(rst_reg->data,\n+\t\t\t\t\t    DBG_RESET_REG_IS_REMOVED);\n+\t\trst_reg_addr = DWORDS_TO_BYTES(GET_FIELD(rst_reg->data,\n+\t\t\t\t\t\t\t DBG_RESET_REG_ADDR));\n+\n+\t\tif (!rst_reg_removed)\n+\t\t\treg_val[rst_reg_id] = ecore_rd(p_hwfn, p_ptt,\n+\t\t\t\t\t\t     rst_reg_addr);\n+\t}\n+\n+\t/* Check if blocks are in reset */\n+\tfor (blk_id = 0; blk_id < NUM_PHYS_BLOCKS; blk_id++) {\n+\t\tconst struct dbg_block_chip *blk;\n+\t\tbool has_rst_reg;\n+\t\tbool is_removed;\n+\n+\t\tblk = qed_get_dbg_block_per_chip(p_hwfn, (enum block_id)blk_id);\n+\t\tis_removed = GET_FIELD(blk->flags, DBG_BLOCK_CHIP_IS_REMOVED);\n+\t\thas_rst_reg = GET_FIELD(blk->flags,\n+\t\t\t\t\tDBG_BLOCK_CHIP_HAS_RESET_REG);\n+\n+\t\tif (!is_removed && has_rst_reg)\n+\t\t\tdev_data->block_in_reset[blk_id] =\n+\t\t\t    !(reg_val[blk->reset_reg_id] &\n+\t\t\t      OSAL_BIT(blk->reset_reg_bit_offset));\n+\t}\n+}\n+\n+/* is_mode_match recursive function */\n+static bool qed_is_mode_match_rec(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t  u16 *modes_buf_offset, u8 rec_depth)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tconst u8 *dbg_array;\n+\tbool arg1, arg2;\n+\tu8 tree_val;\n+\n+\tif (rec_depth > MAX_RECURSION_DEPTH) {\n+\t\tDP_NOTICE(p_hwfn, false,\n+\t\t\t  \"Unexpected error: is_mode_match_rec exceeded the max recursion depth. This is probably due to a corrupt init/debug buffer.\\n\");\n+\t\treturn false;\n+\t}\n+\n+\t/* Get next element from modes tree buffer */\n+\tdbg_array = p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr;\n+\ttree_val = dbg_array[(*modes_buf_offset)++];\n+\n+\tswitch (tree_val) {\n+\tcase INIT_MODE_OP_NOT:\n+\t\treturn !qed_is_mode_match_rec(p_hwfn,\n+\t\t\t\t\t      modes_buf_offset, rec_depth + 1);\n+\tcase INIT_MODE_OP_OR:\n+\tcase INIT_MODE_OP_AND:\n+\t\targ1 = qed_is_mode_match_rec(p_hwfn,\n+\t\t\t\t\t     modes_buf_offset, rec_depth + 1);\n+\t\targ2 = qed_is_mode_match_rec(p_hwfn,\n+\t\t\t\t\t     modes_buf_offset, rec_depth + 1);\n+\t\treturn (tree_val == INIT_MODE_OP_OR) ? (arg1 ||\n+\t\t\t\t\t\t\targ2) : (arg1 && arg2);\n+\tdefault:\n+\t\treturn dev_data->mode_enable[tree_val - MAX_INIT_MODE_OPS] > 0;\n+\t}\n+}\n+\n+/* Returns true if the mode (specified using modes_buf_offset) is enabled */\n+static bool qed_is_mode_match(struct ecore_hwfn *p_hwfn, u16 *modes_buf_offset)\n+{\n+\treturn qed_is_mode_match_rec(p_hwfn, modes_buf_offset, 0);\n+}\n+\n+/* Enable / disable the Debug block */\n+static void qed_bus_enable_dbg_block(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t     struct ecore_ptt *p_ptt, bool enable)\n+{\n+\tecore_wr(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON, enable ? 1 : 0);\n+}\n+\n+/* Resets the Debug block */\n+static void qed_bus_reset_dbg_block(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t    struct ecore_ptt *p_ptt)\n+{\n+\tu32 reset_reg_addr, old_reset_reg_val, new_reset_reg_val;\n+\tconst struct dbg_reset_reg *reset_reg;\n+\tconst struct dbg_block_chip *block;\n+\n+\tblock = qed_get_dbg_block_per_chip(p_hwfn, BLOCK_DBG);\n+\treset_reg = qed_get_dbg_reset_reg(p_hwfn, block->reset_reg_id);\n+\treset_reg_addr =\n+\t    DWORDS_TO_BYTES(GET_FIELD(reset_reg->data, DBG_RESET_REG_ADDR));\n+\n+\told_reset_reg_val = ecore_rd(p_hwfn, p_ptt, reset_reg_addr);\n+\tnew_reset_reg_val =\n+\t    old_reset_reg_val & ~OSAL_BIT(block->reset_reg_bit_offset);\n+\n+\tecore_wr(p_hwfn, p_ptt, reset_reg_addr, new_reset_reg_val);\n+\tecore_wr(p_hwfn, p_ptt, reset_reg_addr, old_reset_reg_val);\n+}\n+\n+/* Enable / disable Debug Bus clients according to the specified mask\n+ * (1 = enable, 0 = disable).\n+ */\n+static void qed_bus_enable_clients(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   struct ecore_ptt *p_ptt, u32 client_mask)\n+{\n+\tecore_wr(p_hwfn, p_ptt, DBG_REG_CLIENT_ENABLE, client_mask);\n+}\n+\n+static void qed_bus_config_dbg_line(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t    struct ecore_ptt *p_ptt,\n+\t\t\t\t    enum block_id block_id,\n+\t\t\t\t    u8 line_id,\n+\t\t\t\t    u8 enable_mask,\n+\t\t\t\t    u8 right_shift,\n+\t\t\t\t    u8 force_valid_mask, u8 force_frame_mask)\n+{\n+\tconst struct dbg_block_chip *block =\n+\t\tqed_get_dbg_block_per_chip(p_hwfn, block_id);\n+\n+\tecore_wr(p_hwfn, p_ptt,\n+\t\t DWORDS_TO_BYTES(block->dbg_select_reg_addr),\n+\t\t line_id);\n+\tecore_wr(p_hwfn, p_ptt,\n+\t\t DWORDS_TO_BYTES(block->dbg_dword_enable_reg_addr),\n+\t\t enable_mask);\n+\tecore_wr(p_hwfn, p_ptt,\n+\t\t DWORDS_TO_BYTES(block->dbg_shift_reg_addr),\n+\t\t right_shift);\n+\tecore_wr(p_hwfn, p_ptt,\n+\t\t DWORDS_TO_BYTES(block->dbg_force_valid_reg_addr),\n+\t\t force_valid_mask);\n+\tecore_wr(p_hwfn, p_ptt,\n+\t\t DWORDS_TO_BYTES(block->dbg_force_frame_reg_addr),\n+\t\t force_frame_mask);\n+}\n+\n+/* Disable debug bus in all blocks */\n+static void qed_bus_disable_blocks(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   struct ecore_ptt *p_ptt)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu32 block_id;\n+\n+\t/* Disable all blocks */\n+\tfor (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {\n+\t\tconst struct dbg_block_chip *block_per_chip =\n+\t\t    qed_get_dbg_block_per_chip(p_hwfn,\n+\t\t\t\t\t       (enum block_id)block_id);\n+\n+\t\tif (GET_FIELD(block_per_chip->flags,\n+\t\t\t      DBG_BLOCK_CHIP_IS_REMOVED) ||\n+\t\t    dev_data->block_in_reset[block_id])\n+\t\t\tcontinue;\n+\n+\t\t/* Disable debug bus */\n+\t\tif (GET_FIELD(block_per_chip->flags,\n+\t\t\t      DBG_BLOCK_CHIP_HAS_DBG_BUS)) {\n+\t\t\tu32 dbg_en_addr =\n+\t\t\t\tblock_per_chip->dbg_dword_enable_reg_addr;\n+\t\t\tu16 modes_buf_offset =\n+\t\t\t    GET_FIELD(block_per_chip->dbg_bus_mode.data,\n+\t\t\t\t      DBG_MODE_HDR_MODES_BUF_OFFSET);\n+\t\t\tbool eval_mode =\n+\t\t\t    GET_FIELD(block_per_chip->dbg_bus_mode.data,\n+\t\t\t\t      DBG_MODE_HDR_EVAL_MODE) > 0;\n+\n+\t\t\tif (!eval_mode ||\n+\t\t\t    qed_is_mode_match(p_hwfn, &modes_buf_offset))\n+\t\t\t\tecore_wr(p_hwfn, p_ptt,\n+\t\t\t\t       DWORDS_TO_BYTES(dbg_en_addr),\n+\t\t\t\t       0);\n+\t\t}\n+\t}\n+}\n+\n+/* Returns true if the specified entity (indicated by GRC param) should be\n+ * included in the dump, false otherwise.\n+ */\n+static bool qed_grc_is_included(struct ecore_hwfn *p_hwfn,\n+\t\t\t\tenum dbg_grc_params grc_param)\n+{\n+\treturn qed_grc_get_param(p_hwfn, grc_param) > 0;\n+}\n+\n+/* Returns the storm_id that matches the specified Storm letter,\n+ * or MAX_DBG_STORMS if invalid storm letter.\n+ */\n+static enum dbg_storms qed_get_id_from_letter(char storm_letter)\n+{\n+\tu8 storm_id;\n+\n+\tfor (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++)\n+\t\tif (s_storm_defs[storm_id].letter == storm_letter)\n+\t\t\treturn (enum dbg_storms)storm_id;\n+\n+\treturn MAX_DBG_STORMS;\n+}\n+\n+/* Returns true of the specified Storm should be included in the dump, false\n+ * otherwise.\n+ */\n+static bool qed_grc_is_storm_included(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      enum dbg_storms storm)\n+{\n+\treturn qed_grc_get_param(p_hwfn, (enum dbg_grc_params)storm) > 0;\n+}\n+\n+/* Returns true if the specified memory should be included in the dump, false\n+ * otherwise.\n+ */\n+static bool qed_grc_is_mem_included(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t    enum block_id block_id, u8 mem_group_id)\n+{\n+\tconst struct dbg_block *block;\n+\tu8 i;\n+\n+\tblock = get_dbg_block(p_hwfn, block_id);\n+\n+\t/* If the block is associated with a Storm, check Storm match */\n+\tif (block->associated_storm_letter) {\n+\t\tenum dbg_storms associated_storm_id =\n+\t\t    qed_get_id_from_letter(block->associated_storm_letter);\n+\n+\t\tif (associated_storm_id == MAX_DBG_STORMS ||\n+\t\t    !qed_grc_is_storm_included(p_hwfn, associated_storm_id))\n+\t\t\treturn false;\n+\t}\n+\n+\tfor (i = 0; i < NUM_BIG_RAM_TYPES; i++) {\n+\t\tstruct big_ram_defs *big_ram = &s_big_ram_defs[i];\n+\n+\t\tif (mem_group_id == big_ram->mem_group_id ||\n+\t\t    mem_group_id == big_ram->ram_mem_group_id)\n+\t\t\treturn qed_grc_is_included(p_hwfn, big_ram->grc_param);\n+\t}\n+\n+\tswitch (mem_group_id) {\n+\tcase MEM_GROUP_PXP_ILT:\n+\tcase MEM_GROUP_PXP_MEM:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PXP);\n+\tcase MEM_GROUP_RAM:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RAM);\n+\tcase MEM_GROUP_PBUF:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PBUF);\n+\tcase MEM_GROUP_CAU_MEM:\n+\tcase MEM_GROUP_CAU_SB:\n+\tcase MEM_GROUP_CAU_PI:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU);\n+\tcase MEM_GROUP_CAU_MEM_EXT:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU_EXT);\n+\tcase MEM_GROUP_QM_MEM:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_QM);\n+\tcase MEM_GROUP_CFC_MEM:\n+\tcase MEM_GROUP_CONN_CFC_MEM:\n+\tcase MEM_GROUP_TASK_CFC_MEM:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CFC) ||\n+\t\t       qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX);\n+\tcase MEM_GROUP_DORQ_MEM:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DORQ);\n+\tcase MEM_GROUP_IGU_MEM:\n+\tcase MEM_GROUP_IGU_MSIX:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IGU);\n+\tcase MEM_GROUP_MULD_MEM:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MULD);\n+\tcase MEM_GROUP_PRS_MEM:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PRS);\n+\tcase MEM_GROUP_DMAE_MEM:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DMAE);\n+\tcase MEM_GROUP_TM_MEM:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_TM);\n+\tcase MEM_GROUP_SDM_MEM:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_SDM);\n+\tcase MEM_GROUP_TDIF_CTX:\n+\tcase MEM_GROUP_RDIF_CTX:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DIF);\n+\tcase MEM_GROUP_CM_MEM:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM);\n+\tcase MEM_GROUP_IOR:\n+\t\treturn qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IOR);\n+\tdefault:\n+\t\treturn true;\n+\t}\n+}\n+\n+/* Stalls all Storms */\n+static void qed_grc_stall_storms(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t struct ecore_ptt *p_ptt, bool stall)\n+{\n+\tu32 reg_addr;\n+\tu8 storm_id;\n+\n+\tfor (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {\n+\t\tif (!qed_grc_is_storm_included(p_hwfn,\n+\t\t\t\t\t       (enum dbg_storms)storm_id))\n+\t\t\tcontinue;\n+\n+\t\treg_addr = s_storm_defs[storm_id].sem_fast_mem_addr +\n+\t\t    SEM_FAST_REG_STALL_0;\n+\t\tecore_wr(p_hwfn, p_ptt, reg_addr, stall ? 1 : 0);\n+\t}\n+\n+\tOSAL_MSLEEP(STALL_DELAY_MS);\n+}\n+\n+/* Takes all blocks out of reset. If rbc_only is true, only RBC clients are\n+ * taken out of reset.\n+ */\n+static void qed_grc_unreset_blocks(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   struct ecore_ptt *p_ptt, bool rbc_only)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu8 chip_id = dev_data->chip_id;\n+\tu32 i;\n+\n+\t/* Take RBCs out of reset */\n+\tfor (i = 0; i < OSAL_ARRAY_SIZE(s_rbc_reset_defs); i++)\n+\t\tif (s_rbc_reset_defs[i].reset_val[dev_data->chip_id])\n+\t\t\tecore_wr(p_hwfn,\n+\t\t\t       p_ptt,\n+\t\t\t       s_rbc_reset_defs[i].reset_reg_addr +\n+\t\t\t       RESET_REG_UNRESET_OFFSET,\n+\t\t\t       s_rbc_reset_defs[i].reset_val[chip_id]);\n+\n+\tif (!rbc_only) {\n+\t\tu32 reg_val[NUM_DBG_RESET_REGS] = { 0 };\n+\t\tu8 reset_reg_id;\n+\t\tu32 block_id;\n+\n+\t\t/* Fill reset regs values */\n+\t\tfor (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) {\n+\t\t\tbool is_removed, has_reset_reg, unreset_before_dump;\n+\t\t\tconst struct dbg_block_chip *block;\n+\n+\t\t\tblock = qed_get_dbg_block_per_chip(p_hwfn,\n+\t\t\t\t\t\t\t   (enum block_id)\n+\t\t\t\t\t\t\t   block_id);\n+\t\t\tis_removed =\n+\t\t\t    GET_FIELD(block->flags, DBG_BLOCK_CHIP_IS_REMOVED);\n+\t\t\thas_reset_reg =\n+\t\t\t    GET_FIELD(block->flags,\n+\t\t\t\t      DBG_BLOCK_CHIP_HAS_RESET_REG);\n+\t\t\tunreset_before_dump =\n+\t\t\t    GET_FIELD(block->flags,\n+\t\t\t\t      DBG_BLOCK_CHIP_UNRESET_BEFORE_DUMP);\n+\n+\t\t\tif (!is_removed && has_reset_reg && unreset_before_dump)\n+\t\t\t\treg_val[block->reset_reg_id] |=\n+\t\t\t\t    OSAL_BIT(block->reset_reg_bit_offset);\n+\t\t}\n+\n+\t\t/* Write reset registers */\n+\t\tfor (reset_reg_id = 0; reset_reg_id < NUM_DBG_RESET_REGS;\n+\t\t     reset_reg_id++) {\n+\t\t\tconst struct dbg_reset_reg *reset_reg;\n+\t\t\tu32 reset_reg_addr;\n+\n+\t\t\treset_reg = qed_get_dbg_reset_reg(p_hwfn, reset_reg_id);\n+\n+\t\t\tif (GET_FIELD\n+\t\t\t    (reset_reg->data, DBG_RESET_REG_IS_REMOVED))\n+\t\t\t\tcontinue;\n+\n+\t\t\tif (reg_val[reset_reg_id]) {\n+\t\t\t\treset_reg_addr =\n+\t\t\t\t    GET_FIELD(reset_reg->data,\n+\t\t\t\t\t      DBG_RESET_REG_ADDR);\n+\t\t\t\tecore_wr(p_hwfn,\n+\t\t\t\t       p_ptt,\n+\t\t\t\t       DWORDS_TO_BYTES(reset_reg_addr) +\n+\t\t\t\t       RESET_REG_UNRESET_OFFSET,\n+\t\t\t\t       reg_val[reset_reg_id]);\n+\t\t\t}\n+\t\t}\n+\t}\n+}\n+\n+/* Returns the attention block data of the specified block */\n+static const struct dbg_attn_block_type_data *\n+qed_get_block_attn_data(struct ecore_hwfn *p_hwfn,\n+\t\t\tenum block_id block_id, enum dbg_attn_type attn_type)\n+{\n+\tconst struct dbg_attn_block *base_attn_block_arr =\n+\t    (const struct dbg_attn_block *)\n+\t    p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr;\n+\n+\treturn &base_attn_block_arr[block_id].per_type_data[attn_type];\n+}\n+\n+/* Returns the attention registers of the specified block */\n+static const struct dbg_attn_reg *\n+qed_get_block_attn_regs(struct ecore_hwfn *p_hwfn,\n+\t\t\tenum block_id block_id, enum dbg_attn_type attn_type,\n+\t\t\tu8 *num_attn_regs)\n+{\n+\tconst struct dbg_attn_block_type_data *block_type_data =\n+\t    qed_get_block_attn_data(p_hwfn, block_id, attn_type);\n+\n+\t*num_attn_regs = block_type_data->num_regs;\n+\n+\treturn (const struct dbg_attn_reg *)\n+\t\tp_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr +\n+\t\tblock_type_data->regs_offset;\n+}\n+\n+/* For each block, clear the status of all parities */\n+static void qed_grc_clear_all_prty(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   struct ecore_ptt *p_ptt)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tconst struct dbg_attn_reg *attn_reg_arr;\n+\tu8 reg_idx, num_attn_regs;\n+\tu32 block_id;\n+\n+\tfor (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) {\n+\t\tif (dev_data->block_in_reset[block_id])\n+\t\t\tcontinue;\n+\n+\t\tattn_reg_arr = qed_get_block_attn_regs(p_hwfn,\n+\t\t\t\t\t\t       (enum block_id)block_id,\n+\t\t\t\t\t\t       ATTN_TYPE_PARITY,\n+\t\t\t\t\t\t       &num_attn_regs);\n+\n+\t\tfor (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {\n+\t\t\tconst struct dbg_attn_reg *reg_data =\n+\t\t\t\t&attn_reg_arr[reg_idx];\n+\t\t\tu16 modes_buf_offset;\n+\t\t\tbool eval_mode;\n+\n+\t\t\t/* Check mode */\n+\t\t\teval_mode = GET_FIELD(reg_data->mode.data,\n+\t\t\t\t\t      DBG_MODE_HDR_EVAL_MODE) > 0;\n+\t\t\tmodes_buf_offset =\n+\t\t\t\tGET_FIELD(reg_data->mode.data,\n+\t\t\t\t\t  DBG_MODE_HDR_MODES_BUF_OFFSET);\n+\n+\t\t\t/* If Mode match: clear parity status */\n+\t\t\tif (!eval_mode ||\n+\t\t\t    qed_is_mode_match(p_hwfn, &modes_buf_offset))\n+\t\t\t\tecore_rd(p_hwfn, p_ptt,\n+\t\t\t\t    DWORDS_TO_BYTES(reg_data->sts_clr_address));\n+\t\t}\n+\t}\n+}\n+\n+/* Dumps GRC registers section header. Returns the dumped size in dwords.\n+ * the following parameters are dumped:\n+ * - count: no. of dumped entries\n+ * - split_type: split type\n+ * - split_id: split ID (dumped only if split_id != SPLIT_TYPE_NONE)\n+ * - reg_type_name: register type name (dumped only if reg_type_name != NULL)\n+ */\n+static u32 qed_grc_dump_regs_hdr(u32 *dump_buf,\n+\t\t\t\t bool dump,\n+\t\t\t\t u32 num_reg_entries,\n+\t\t\t\t enum init_split_types split_type,\n+\t\t\t\t u8 split_id, const char *reg_type_name)\n+{\n+\tu8 num_params = 2 +\n+\t    (split_type != SPLIT_TYPE_NONE ? 1 : 0) + (reg_type_name ? 1 : 0);\n+\tu32 offset = 0;\n+\n+\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t       dump, \"grc_regs\", num_params);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump, \"count\", num_reg_entries);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump, \"split\",\n+\t\t\t\t     s_split_type_defs[split_type].name);\n+\tif (split_type != SPLIT_TYPE_NONE)\n+\t\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t\t     dump, \"id\", split_id);\n+\tif (reg_type_name)\n+\t\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t\t     dump, \"type\", reg_type_name);\n+\n+\treturn offset;\n+}\n+\n+/* Reads the specified registers into the specified buffer.\n+ * The addr and len arguments are specified in dwords.\n+ */\n+void qed_read_regs(struct ecore_hwfn *p_hwfn,\n+\t\t   struct ecore_ptt *p_ptt, u32 *buf, u32 addr, u32 len)\n+{\n+\tu32 i;\n+\n+\tfor (i = 0; i < len; i++)\n+\t\tbuf[i] = ecore_rd(p_hwfn, p_ptt, DWORDS_TO_BYTES(addr + i));\n+}\n+\n+/* Dumps the GRC registers in the specified address range.\n+ * Returns the dumped size in dwords.\n+ * The addr and len arguments are specified in dwords.\n+ */\n+static u32 qed_grc_dump_addr_range(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   struct ecore_ptt *p_ptt,\n+\t\t\t\t   u32 *dump_buf,\n+\t\t\t\t   bool dump, u32 addr, u32 len, bool wide_bus,\n+\t\t\t\t   enum init_split_types split_type,\n+\t\t\t\t   u8 split_id)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu8 port_id = 0, pf_id = 0, vf_id = 0, fid = 0;\n+\tbool read_using_dmae = false;\n+\tu32 thresh;\n+\n+\tif (!dump)\n+\t\treturn len;\n+\n+\tswitch (split_type) {\n+\tcase SPLIT_TYPE_PORT:\n+\t\tport_id = split_id;\n+\t\tbreak;\n+\tcase SPLIT_TYPE_PF:\n+\t\tpf_id = split_id;\n+\t\tbreak;\n+\tcase SPLIT_TYPE_PORT_PF:\n+\t\tport_id = split_id / dev_data->num_pfs_per_port;\n+\t\tpf_id = port_id + dev_data->num_ports *\n+\t\t    (split_id % dev_data->num_pfs_per_port);\n+\t\tbreak;\n+\tcase SPLIT_TYPE_VF:\n+\t\tvf_id = split_id;\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\t/* Try reading using DMAE */\n+\tif (dev_data->use_dmae && split_type != SPLIT_TYPE_VF &&\n+\t    (len >= s_hw_type_defs[dev_data->hw_type].dmae_thresh ||\n+\t     (PROTECT_WIDE_BUS && wide_bus))) {\n+\t\tstruct dmae_params dmae_params;\n+\n+\t\t/* Set DMAE params */\n+\t\tmemset(&dmae_params, 0, sizeof(dmae_params));\n+\t\tSET_FIELD(dmae_params.flags, DMAE_PARAMS_COMPLETION_DST, 1);\n+\t\tswitch (split_type) {\n+\t\tcase SPLIT_TYPE_PORT:\n+\t\t\tSET_FIELD(dmae_params.flags, DMAE_PARAMS_PORT_VALID,\n+\t\t\t\t  1);\n+\t\t\tdmae_params.port_id = port_id;\n+\t\t\tbreak;\n+\t\tcase SPLIT_TYPE_PF:\n+\t\t\tSET_FIELD(dmae_params.flags,\n+\t\t\t\t  DMAE_PARAMS_SRC_PF_VALID, 1);\n+\t\t\tdmae_params.src_pf_id = pf_id;\n+\t\t\tbreak;\n+\t\tcase SPLIT_TYPE_PORT_PF:\n+\t\t\tSET_FIELD(dmae_params.flags, DMAE_PARAMS_PORT_VALID,\n+\t\t\t\t  1);\n+\t\t\tSET_FIELD(dmae_params.flags,\n+\t\t\t\t  DMAE_PARAMS_SRC_PF_VALID, 1);\n+\t\t\tdmae_params.port_id = port_id;\n+\t\t\tdmae_params.src_pf_id = pf_id;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\t/* Execute DMAE command */\n+\t\tread_using_dmae = !ecore_dmae_grc2host(p_hwfn,\n+\t\t\t\t\t\t     p_ptt,\n+\t\t\t\t\t\t     DWORDS_TO_BYTES(addr),\n+\t\t\t\t\t\t     (u64)(uintptr_t)(dump_buf),\n+\t\t\t\t\t\t     len, &dmae_params);\n+\t\tif (!read_using_dmae) {\n+\t\t\tdev_data->use_dmae = 0;\n+\t\t\tDP_VERBOSE(p_hwfn->p_dev,\n+\t\t\t\t   ECORE_MSG_DEBUG,\n+\t\t\t\t   \"Failed reading from chip using DMAE, using GRC instead\\n\");\n+\t\t}\n+\t}\n+\n+\tif (read_using_dmae)\n+\t\tgoto print_log;\n+\n+\t/* If not read using DMAE, read using GRC */\n+\n+\t/* Set pretend */\n+\tif (split_type != dev_data->pretend.split_type ||\n+\t    split_id != dev_data->pretend.split_id) {\n+\t\tswitch (split_type) {\n+\t\tcase SPLIT_TYPE_PORT:\n+\t\t\tecore_port_pretend(p_hwfn, p_ptt, port_id);\n+\t\t\tbreak;\n+\t\tcase SPLIT_TYPE_PF:\n+\t\t\tfid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID,\n+\t\t\t\t\t  pf_id);\n+\t\t\tecore_fid_pretend(p_hwfn, p_ptt, fid);\n+\t\t\tbreak;\n+\t\tcase SPLIT_TYPE_PORT_PF:\n+\t\t\tfid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID,\n+\t\t\t\t\t  pf_id);\n+\t\t\tecore_port_fid_pretend(p_hwfn, p_ptt, port_id, fid);\n+\t\t\tbreak;\n+\t\tcase SPLIT_TYPE_VF:\n+\t\t\tfid = FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFVALID, 1)\n+\t\t\t      | FIELD_VALUE(PXP_PRETEND_CONCRETE_FID_VFID,\n+\t\t\t\t\t  vf_id);\n+\t\t\tecore_fid_pretend(p_hwfn, p_ptt, fid);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tdev_data->pretend.split_type = (u8)split_type;\n+\t\tdev_data->pretend.split_id = split_id;\n+\t}\n+\n+\t/* Read registers using GRC */\n+\tqed_read_regs(p_hwfn, p_ptt, dump_buf, addr, len);\n+\n+print_log:\n+\t/* Print log */\n+\tdev_data->num_regs_read += len;\n+\tthresh = s_hw_type_defs[dev_data->hw_type].log_thresh;\n+\tif ((dev_data->num_regs_read / thresh) >\n+\t    ((dev_data->num_regs_read - len) / thresh))\n+\t\tDP_VERBOSE(p_hwfn->p_dev,\n+\t\t\t   ECORE_MSG_DEBUG,\n+\t\t\t   \"Dumped %d registers...\\n\", dev_data->num_regs_read);\n+\n+\treturn len;\n+}\n+\n+/* Dumps GRC registers sequence header. Returns the dumped size in dwords.\n+ * The addr and len arguments are specified in dwords.\n+ */\n+static u32 qed_grc_dump_reg_entry_hdr(u32 *dump_buf,\n+\t\t\t\t      bool dump, u32 addr, u32 len)\n+{\n+\tif (dump)\n+\t\t*dump_buf = addr | (len << REG_DUMP_LEN_SHIFT);\n+\n+\treturn 1;\n+}\n+\n+/* Dumps GRC registers sequence. Returns the dumped size in dwords.\n+ * The addr and len arguments are specified in dwords.\n+ */\n+static u32 qed_grc_dump_reg_entry(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t  struct ecore_ptt *p_ptt,\n+\t\t\t\t  u32 *dump_buf,\n+\t\t\t\t  bool dump, u32 addr, u32 len, bool wide_bus,\n+\t\t\t\t  enum init_split_types split_type, u8 split_id)\n+{\n+\tu32 offset = 0;\n+\n+\toffset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, len);\n+\toffset += qed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t  dump, addr, len, wide_bus,\n+\t\t\t\t\t  split_type, split_id);\n+\n+\treturn offset;\n+}\n+\n+/* Dumps GRC registers sequence with skip cycle.\n+ * Returns the dumped size in dwords.\n+ * - addr:\tstart GRC address in dwords\n+ * - total_len:\ttotal no. of dwords to dump\n+ * - read_len:\tno. consecutive dwords to read\n+ * - skip_len:\tno. of dwords to skip (and fill with zeros)\n+ */\n+static u32 qed_grc_dump_reg_entry_skip(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t       struct ecore_ptt *p_ptt,\n+\t\t\t\t       u32 *dump_buf,\n+\t\t\t\t       bool dump,\n+\t\t\t\t       u32 addr,\n+\t\t\t\t       u32 total_len,\n+\t\t\t\t       u32 read_len, u32 skip_len)\n+{\n+\tu32 offset = 0, reg_offset = 0;\n+\n+\toffset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, total_len);\n+\n+\tif (!dump)\n+\t\treturn offset + total_len;\n+\n+\twhile (reg_offset < total_len) {\n+\t\tu32 curr_len = OSAL_MIN_T(u32, read_len,\n+\t\t\t\t\t  total_len - reg_offset);\n+\n+\t\toffset += qed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t\t  dump,  addr, curr_len, false,\n+\t\t\t\t\t\t  SPLIT_TYPE_NONE, 0);\n+\t\treg_offset += curr_len;\n+\t\taddr += curr_len;\n+\n+\t\tif (reg_offset < total_len) {\n+\t\t\tcurr_len = OSAL_MIN_T(u32, skip_len,\n+\t\t\t\t\t      total_len - skip_len);\n+\t\t\tmemset(dump_buf + offset, 0, DWORDS_TO_BYTES(curr_len));\n+\t\t\toffset += curr_len;\n+\t\t\treg_offset += curr_len;\n+\t\t\taddr += curr_len;\n+\t\t}\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dumps GRC registers entries. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_regs_entries(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t     struct ecore_ptt *p_ptt,\n+\t\t\t\t     struct virt_mem_desc input_regs_arr,\n+\t\t\t\t     u32 *dump_buf,\n+\t\t\t\t     bool dump,\n+\t\t\t\t     enum init_split_types split_type,\n+\t\t\t\t     u8 split_id,\n+\t\t\t\t     bool block_enable[MAX_BLOCK_ID],\n+\t\t\t\t     u32 *num_dumped_reg_entries)\n+{\n+\tu32 i, offset = 0, input_offset = 0;\n+\tbool mode_match = true;\n+\n+\t*num_dumped_reg_entries = 0;\n+\n+\twhile (input_offset < BYTES_TO_DWORDS(input_regs_arr.size)) {\n+\t\tconst struct dbg_dump_cond_hdr *cond_hdr =\n+\t\t    (const struct dbg_dump_cond_hdr *)\n+\t\t    input_regs_arr.ptr + input_offset++;\n+\t\tu16 modes_buf_offset;\n+\t\tbool eval_mode;\n+\n+\t\t/* Check mode/block */\n+\t\teval_mode = GET_FIELD(cond_hdr->mode.data,\n+\t\t\t\t      DBG_MODE_HDR_EVAL_MODE) > 0;\n+\t\tif (eval_mode) {\n+\t\t\tmodes_buf_offset =\n+\t\t\t\tGET_FIELD(cond_hdr->mode.data,\n+\t\t\t\t\t  DBG_MODE_HDR_MODES_BUF_OFFSET);\n+\t\t\tmode_match = qed_is_mode_match(p_hwfn,\n+\t\t\t\t\t\t       &modes_buf_offset);\n+\t\t}\n+\n+\t\tif (!mode_match || !block_enable[cond_hdr->block_id]) {\n+\t\t\tinput_offset += cond_hdr->data_size;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tfor (i = 0; i < cond_hdr->data_size; i++, input_offset++) {\n+\t\t\tconst struct dbg_dump_reg *reg =\n+\t\t\t    (const struct dbg_dump_reg *)\n+\t\t\t    input_regs_arr.ptr + input_offset;\n+\t\t\tu32 addr, len;\n+\t\t\tbool wide_bus;\n+\n+\t\t\taddr = GET_FIELD(reg->data, DBG_DUMP_REG_ADDRESS);\n+\t\t\tlen = GET_FIELD(reg->data, DBG_DUMP_REG_LENGTH);\n+\t\t\twide_bus = GET_FIELD(reg->data, DBG_DUMP_REG_WIDE_BUS);\n+\t\t\toffset += qed_grc_dump_reg_entry(p_hwfn,\n+\t\t\t\t\t\t\t p_ptt,\n+\t\t\t\t\t\t\t dump_buf + offset,\n+\t\t\t\t\t\t\t dump,\n+\t\t\t\t\t\t\t addr,\n+\t\t\t\t\t\t\t len,\n+\t\t\t\t\t\t\t wide_bus,\n+\t\t\t\t\t\t\t split_type, split_id);\n+\t\t\t(*num_dumped_reg_entries)++;\n+\t\t}\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dumps GRC registers entries. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_split_data(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   struct ecore_ptt *p_ptt,\n+\t\t\t\t   struct virt_mem_desc input_regs_arr,\n+\t\t\t\t   u32 *dump_buf,\n+\t\t\t\t   bool dump,\n+\t\t\t\t   bool block_enable[MAX_BLOCK_ID],\n+\t\t\t\t   enum init_split_types split_type,\n+\t\t\t\t   u8 split_id, const char *reg_type_name)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tenum init_split_types hdr_split_type = split_type;\n+\tu32 num_dumped_reg_entries, offset;\n+\tu8 hdr_split_id = split_id;\n+\n+\t/* In PORT_PF split type, print a port split header */\n+\tif (split_type == SPLIT_TYPE_PORT_PF) {\n+\t\thdr_split_type = SPLIT_TYPE_PORT;\n+\t\thdr_split_id = split_id / dev_data->num_pfs_per_port;\n+\t}\n+\n+\t/* Calculate register dump header size (and skip it for now) */\n+\toffset = qed_grc_dump_regs_hdr(dump_buf,\n+\t\t\t\t       false,\n+\t\t\t\t       0,\n+\t\t\t\t       hdr_split_type,\n+\t\t\t\t       hdr_split_id, reg_type_name);\n+\n+\t/* Dump registers */\n+\toffset += qed_grc_dump_regs_entries(p_hwfn,\n+\t\t\t\t\t    p_ptt,\n+\t\t\t\t\t    input_regs_arr,\n+\t\t\t\t\t    dump_buf + offset,\n+\t\t\t\t\t    dump,\n+\t\t\t\t\t    split_type,\n+\t\t\t\t\t    split_id,\n+\t\t\t\t\t    block_enable,\n+\t\t\t\t\t    &num_dumped_reg_entries);\n+\n+\t/* Write register dump header */\n+\tif (dump && num_dumped_reg_entries > 0)\n+\t\tqed_grc_dump_regs_hdr(dump_buf,\n+\t\t\t\t      dump,\n+\t\t\t\t      num_dumped_reg_entries,\n+\t\t\t\t      hdr_split_type,\n+\t\t\t\t      hdr_split_id, reg_type_name);\n+\n+\treturn num_dumped_reg_entries > 0 ? offset : 0;\n+}\n+\n+/* Dumps registers according to the input registers array. Returns the dumped\n+ * size in dwords.\n+ */\n+static u32 qed_grc_dump_registers(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t  struct ecore_ptt *p_ptt,\n+\t\t\t\t  u32 *dump_buf,\n+\t\t\t\t  bool dump,\n+\t\t\t\t  bool block_enable[MAX_BLOCK_ID],\n+\t\t\t\t  const char *reg_type_name)\n+{\n+\tstruct virt_mem_desc *dbg_buf =\n+\t    &p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG];\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu32 offset = 0, input_offset = 0;\n+\n+\twhile (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) {\n+\t\tconst struct dbg_dump_split_hdr *split_hdr;\n+\t\tstruct virt_mem_desc curr_input_regs_arr;\n+\t\tenum init_split_types split_type;\n+\t\tu16 split_count = 0;\n+\t\tu32 split_data_size;\n+\t\tu8 split_id;\n+\n+\t\tsplit_hdr =\n+\t\t    (const struct dbg_dump_split_hdr *)\n+\t\t    dbg_buf->ptr + input_offset++;\n+\t\tsplit_type =\n+\t\t    GET_FIELD(split_hdr->hdr,\n+\t\t\t      DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);\n+\t\tsplit_data_size = GET_FIELD(split_hdr->hdr,\n+\t\t\t\t\t    DBG_DUMP_SPLIT_HDR_DATA_SIZE);\n+\t\tcurr_input_regs_arr.ptr =\n+\t\t    (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr +\n+\t\t    input_offset;\n+\t\tcurr_input_regs_arr.size = DWORDS_TO_BYTES(split_data_size);\n+\n+\t\tswitch (split_type) {\n+\t\tcase SPLIT_TYPE_NONE:\n+\t\t\tsplit_count = 1;\n+\t\t\tbreak;\n+\t\tcase SPLIT_TYPE_PORT:\n+\t\t\tsplit_count = dev_data->num_ports;\n+\t\t\tbreak;\n+\t\tcase SPLIT_TYPE_PF:\n+\t\tcase SPLIT_TYPE_PORT_PF:\n+\t\t\tsplit_count = dev_data->num_ports *\n+\t\t\t    dev_data->num_pfs_per_port;\n+\t\t\tbreak;\n+\t\tcase SPLIT_TYPE_VF:\n+\t\t\tsplit_count = dev_data->num_vfs;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\tfor (split_id = 0; split_id < split_count; split_id++)\n+\t\t\toffset += qed_grc_dump_split_data(p_hwfn, p_ptt,\n+\t\t\t\t\t\t\t  curr_input_regs_arr,\n+\t\t\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t\t\t  dump, block_enable,\n+\t\t\t\t\t\t\t  split_type,\n+\t\t\t\t\t\t\t  split_id,\n+\t\t\t\t\t\t\t  reg_type_name);\n+\n+\t\tinput_offset += split_data_size;\n+\t}\n+\n+\t/* Cancel pretends (pretend to original PF) */\n+\tif (dump) {\n+\t\tecore_fid_pretend(p_hwfn, p_ptt,\n+\t\t\t\tFIELD_VALUE(PXP_PRETEND_CONCRETE_FID_PFID,\n+\t\t\t\t\t    p_hwfn->rel_pf_id));\n+\t\tdev_data->pretend.split_type = SPLIT_TYPE_NONE;\n+\t\tdev_data->pretend.split_id = 0;\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dump reset registers. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_reset_regs(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   struct ecore_ptt *p_ptt,\n+\t\t\t\t   u32 *dump_buf, bool dump)\n+{\n+\tu32 offset = 0, num_regs = 0;\n+\tu8 reset_reg_id;\n+\n+\t/* Calculate header size */\n+\toffset += qed_grc_dump_regs_hdr(dump_buf,\n+\t\t\t\t\tfalse,\n+\t\t\t\t\t0, SPLIT_TYPE_NONE, 0, \"RESET_REGS\");\n+\n+\t/* Write reset registers */\n+\tfor (reset_reg_id = 0; reset_reg_id < NUM_DBG_RESET_REGS;\n+\t     reset_reg_id++) {\n+\t\tconst struct dbg_reset_reg *reset_reg;\n+\t\tu32 reset_reg_addr;\n+\n+\t\treset_reg = qed_get_dbg_reset_reg(p_hwfn, reset_reg_id);\n+\n+\t\tif (GET_FIELD(reset_reg->data, DBG_RESET_REG_IS_REMOVED))\n+\t\t\tcontinue;\n+\n+\t\treset_reg_addr = GET_FIELD(reset_reg->data, DBG_RESET_REG_ADDR);\n+\t\toffset += qed_grc_dump_reg_entry(p_hwfn,\n+\t\t\t\t\t\t p_ptt,\n+\t\t\t\t\t\t dump_buf + offset,\n+\t\t\t\t\t\t dump,\n+\t\t\t\t\t\t reset_reg_addr,\n+\t\t\t\t\t\t 1, false, SPLIT_TYPE_NONE, 0);\n+\t\tnum_regs++;\n+\t}\n+\n+\t/* Write header */\n+\tif (dump)\n+\t\tqed_grc_dump_regs_hdr(dump_buf,\n+\t\t\t\t      true, num_regs, SPLIT_TYPE_NONE,\n+\t\t\t\t      0, \"RESET_REGS\");\n+\n+\treturn offset;\n+}\n+\n+/* Dump registers that are modified during GRC Dump and therefore must be\n+ * dumped first. Returns the dumped size in dwords.\n+ */\n+static u32 qed_grc_dump_modified_regs(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t      u32 *dump_buf, bool dump)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu32 block_id, offset = 0, stall_regs_offset;\n+\tconst struct dbg_attn_reg *attn_reg_arr;\n+\tu8 storm_id, reg_idx, num_attn_regs;\n+\tu32 num_reg_entries = 0;\n+\n+\t/* Write empty header for attention registers */\n+\toffset += qed_grc_dump_regs_hdr(dump_buf,\n+\t\t\t\t\tfalse,\n+\t\t\t\t\t0, SPLIT_TYPE_NONE, 0, \"ATTN_REGS\");\n+\n+\t/* Write parity registers */\n+\tfor (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) {\n+\t\tif (dev_data->block_in_reset[block_id] && dump)\n+\t\t\tcontinue;\n+\n+\t\tattn_reg_arr = qed_get_block_attn_regs(p_hwfn,\n+\t\t\t\t\t\t       (enum block_id)block_id,\n+\t\t\t\t\t\t       ATTN_TYPE_PARITY,\n+\t\t\t\t\t\t       &num_attn_regs);\n+\n+\t\tfor (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {\n+\t\t\tconst struct dbg_attn_reg *reg_data =\n+\t\t\t\t&attn_reg_arr[reg_idx];\n+\t\t\tu16 modes_buf_offset;\n+\t\t\tbool eval_mode;\n+\t\t\tu32 addr;\n+\n+\t\t\t/* Check mode */\n+\t\t\teval_mode = GET_FIELD(reg_data->mode.data,\n+\t\t\t\t\t      DBG_MODE_HDR_EVAL_MODE) > 0;\n+\t\t\tmodes_buf_offset =\n+\t\t\t\tGET_FIELD(reg_data->mode.data,\n+\t\t\t\t\t  DBG_MODE_HDR_MODES_BUF_OFFSET);\n+\t\t\tif (eval_mode &&\n+\t\t\t    !qed_is_mode_match(p_hwfn, &modes_buf_offset))\n+\t\t\t\tcontinue;\n+\n+\t\t\t/* Mode match: read & dump registers */\n+\t\t\taddr = reg_data->mask_address;\n+\t\t\toffset += qed_grc_dump_reg_entry(p_hwfn,\n+\t\t\t\t\t\t\t p_ptt,\n+\t\t\t\t\t\t\t dump_buf + offset,\n+\t\t\t\t\t\t\t dump,\n+\t\t\t\t\t\t\t addr,\n+\t\t\t\t\t\t\t 1, false,\n+\t\t\t\t\t\t\t SPLIT_TYPE_NONE, 0);\n+\t\t\taddr = GET_FIELD(reg_data->data,\n+\t\t\t\t\t DBG_ATTN_REG_STS_ADDRESS);\n+\t\t\toffset += qed_grc_dump_reg_entry(p_hwfn,\n+\t\t\t\t\t\t\t p_ptt,\n+\t\t\t\t\t\t\t dump_buf + offset,\n+\t\t\t\t\t\t\t dump,\n+\t\t\t\t\t\t\t addr,\n+\t\t\t\t\t\t\t 1, false,\n+\t\t\t\t\t\t\t SPLIT_TYPE_NONE, 0);\n+\t\t\tnum_reg_entries += 2;\n+\t\t}\n+\t}\n+\n+\t/* Overwrite header for attention registers */\n+\tif (dump)\n+\t\tqed_grc_dump_regs_hdr(dump_buf,\n+\t\t\t\t      true,\n+\t\t\t\t      num_reg_entries,\n+\t\t\t\t      SPLIT_TYPE_NONE, 0, \"ATTN_REGS\");\n+\n+\t/* Write empty header for stall registers */\n+\tstall_regs_offset = offset;\n+\toffset += qed_grc_dump_regs_hdr(dump_buf,\n+\t\t\t\t\tfalse, 0, SPLIT_TYPE_NONE, 0, \"REGS\");\n+\n+\t/* Write Storm stall status registers */\n+\tfor (storm_id = 0, num_reg_entries = 0; storm_id < MAX_DBG_STORMS;\n+\t     storm_id++) {\n+\t\tstruct storm_defs *storm = &s_storm_defs[storm_id];\n+\t\tu32 addr;\n+\n+\t\tif (dev_data->block_in_reset[storm->sem_block_id] && dump)\n+\t\t\tcontinue;\n+\n+\t\taddr =\n+\t\t    BYTES_TO_DWORDS(storm->sem_fast_mem_addr +\n+\t\t\t\t    SEM_FAST_REG_STALLED);\n+\t\toffset += qed_grc_dump_reg_entry(p_hwfn,\n+\t\t\t\t\t\t p_ptt,\n+\t\t\t\t\t\t dump_buf + offset,\n+\t\t\t\t\t\t dump,\n+\t\t\t\t\t\t addr,\n+\t\t\t\t\t\t 1,\n+\t\t\t\t\t\t false, SPLIT_TYPE_NONE, 0);\n+\t\tnum_reg_entries++;\n+\t}\n+\n+\t/* Overwrite header for stall registers */\n+\tif (dump)\n+\t\tqed_grc_dump_regs_hdr(dump_buf + stall_regs_offset,\n+\t\t\t\t      true,\n+\t\t\t\t      num_reg_entries,\n+\t\t\t\t      SPLIT_TYPE_NONE, 0, \"REGS\");\n+\n+\treturn offset;\n+}\n+\n+/* Dumps registers that can't be represented in the debug arrays */\n+static u32 qed_grc_dump_special_regs(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t     struct ecore_ptt *p_ptt,\n+\t\t\t\t     u32 *dump_buf, bool dump)\n+{\n+\tu32 offset = 0, addr;\n+\n+\toffset += qed_grc_dump_regs_hdr(dump_buf,\n+\t\t\t\t\tdump, 2, SPLIT_TYPE_NONE, 0, \"REGS\");\n+\n+\t/* Dump R/TDIF_REG_DEBUG_ERROR_INFO_SIZE (every 8'th register should be\n+\t * skipped).\n+\t */\n+\taddr = BYTES_TO_DWORDS(RDIF_REG_DEBUG_ERROR_INFO);\n+\toffset += qed_grc_dump_reg_entry_skip(p_hwfn,\n+\t\t\t\t\t      p_ptt,\n+\t\t\t\t\t      dump_buf + offset,\n+\t\t\t\t\t      dump,\n+\t\t\t\t\t      addr,\n+\t\t\t\t\t      RDIF_REG_DEBUG_ERROR_INFO_SIZE,\n+\t\t\t\t\t      7,\n+\t\t\t\t\t      1);\n+\taddr = BYTES_TO_DWORDS(TDIF_REG_DEBUG_ERROR_INFO);\n+\toffset +=\n+\t    qed_grc_dump_reg_entry_skip(p_hwfn,\n+\t\t\t\t\tp_ptt,\n+\t\t\t\t\tdump_buf + offset,\n+\t\t\t\t\tdump,\n+\t\t\t\t\taddr,\n+\t\t\t\t\tTDIF_REG_DEBUG_ERROR_INFO_SIZE,\n+\t\t\t\t\t7,\n+\t\t\t\t\t1);\n+\n+\treturn offset;\n+}\n+\n+/* Dumps a GRC memory header (section and params). Returns the dumped size in\n+ * dwords. The following parameters are dumped:\n+ * - name:\t   dumped only if it's not NULL.\n+ * - addr:\t   in dwords, dumped only if name is NULL.\n+ * - len:\t   in dwords, always dumped.\n+ * - width:\t   dumped if it's not zero.\n+ * - packed:\t   dumped only if it's not false.\n+ * - mem_group:\t   always dumped.\n+ * - is_storm:\t   true only if the memory is related to a Storm.\n+ * - storm_letter: valid only if is_storm is true.\n+ *\n+ */\n+static u32 qed_grc_dump_mem_hdr(struct ecore_hwfn *p_hwfn,\n+\t\t\t\tu32 *dump_buf,\n+\t\t\t\tbool dump,\n+\t\t\t\tconst char *name,\n+\t\t\t\tu32 addr,\n+\t\t\t\tu32 len,\n+\t\t\t\tu32 bit_width,\n+\t\t\t\tbool packed,\n+\t\t\t\tconst char *mem_group, char storm_letter)\n+{\n+\tu8 num_params = 3;\n+\tu32 offset = 0;\n+\tchar buf[64];\n+\n+\tif (!len)\n+\t\tDP_NOTICE(p_hwfn, false,\n+\t\t\t  \"Unexpected GRC Dump error: dumped memory size must be non-zero\\n\");\n+\n+\tif (bit_width)\n+\t\tnum_params++;\n+\tif (packed)\n+\t\tnum_params++;\n+\n+\t/* Dump section header */\n+\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t       dump, \"grc_mem\", num_params);\n+\n+\tif (name) {\n+\t\t/* Dump name */\n+\t\tif (storm_letter) {\n+\t\t\tstrcpy(buf, \"?STORM_\");\n+\t\t\tbuf[0] = storm_letter;\n+\t\t\tstrcpy(buf + strlen(buf), name);\n+\t\t} else {\n+\t\t\tstrcpy(buf, name);\n+\t\t}\n+\n+\t\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t\t     dump, \"name\", buf);\n+\t} else {\n+\t\t/* Dump address */\n+\t\tu32 addr_in_bytes = DWORDS_TO_BYTES(addr);\n+\n+\t\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t\t     dump, \"addr\", addr_in_bytes);\n+\t}\n+\n+\t/* Dump len */\n+\toffset += qed_dump_num_param(dump_buf + offset, dump, \"len\", len);\n+\n+\t/* Dump bit width */\n+\tif (bit_width)\n+\t\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t\t     dump, \"width\", bit_width);\n+\n+\t/* Dump packed */\n+\tif (packed)\n+\t\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t\t     dump, \"packed\", 1);\n+\n+\t/* Dump reg type */\n+\tif (storm_letter) {\n+\t\tstrcpy(buf, \"?STORM_\");\n+\t\tbuf[0] = storm_letter;\n+\t\tstrcpy(buf + strlen(buf), mem_group);\n+\t} else {\n+\t\tstrcpy(buf, mem_group);\n+\t}\n+\n+\toffset += qed_dump_str_param(dump_buf + offset, dump, \"type\", buf);\n+\n+\treturn offset;\n+}\n+\n+/* Dumps a single GRC memory. If name is NULL, the memory is stored by address.\n+ * Returns the dumped size in dwords.\n+ * The addr and len arguments are specified in dwords.\n+ */\n+static u32 qed_grc_dump_mem(struct ecore_hwfn *p_hwfn,\n+\t\t\t    struct ecore_ptt *p_ptt,\n+\t\t\t    u32 *dump_buf,\n+\t\t\t    bool dump,\n+\t\t\t    const char *name,\n+\t\t\t    u32 addr,\n+\t\t\t    u32 len,\n+\t\t\t    bool wide_bus,\n+\t\t\t    u32 bit_width,\n+\t\t\t    bool packed,\n+\t\t\t    const char *mem_group, char storm_letter)\n+{\n+\tu32 offset = 0;\n+\n+\toffset += qed_grc_dump_mem_hdr(p_hwfn,\n+\t\t\t\t       dump_buf + offset,\n+\t\t\t\t       dump,\n+\t\t\t\t       name,\n+\t\t\t\t       addr,\n+\t\t\t\t       len,\n+\t\t\t\t       bit_width,\n+\t\t\t\t       packed, mem_group, storm_letter);\n+\toffset += qed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t  dump, addr, len, wide_bus,\n+\t\t\t\t\t  SPLIT_TYPE_NONE, 0);\n+\n+\treturn offset;\n+}\n+\n+/* Dumps GRC memories entries. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_mem_entries(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t    struct ecore_ptt *p_ptt,\n+\t\t\t\t    struct virt_mem_desc input_mems_arr,\n+\t\t\t\t    u32 *dump_buf, bool dump)\n+{\n+\tu32 i, offset = 0, input_offset = 0;\n+\tbool mode_match = true;\n+\n+\twhile (input_offset < BYTES_TO_DWORDS(input_mems_arr.size)) {\n+\t\tconst struct dbg_dump_cond_hdr *cond_hdr;\n+\t\tu16 modes_buf_offset;\n+\t\tu32 num_entries;\n+\t\tbool eval_mode;\n+\n+\t\tcond_hdr =\n+\t\t    (const struct dbg_dump_cond_hdr *)input_mems_arr.ptr +\n+\t\t    input_offset++;\n+\t\tnum_entries = cond_hdr->data_size / MEM_DUMP_ENTRY_SIZE_DWORDS;\n+\n+\t\t/* Check required mode */\n+\t\teval_mode = GET_FIELD(cond_hdr->mode.data,\n+\t\t\t\t      DBG_MODE_HDR_EVAL_MODE) > 0;\n+\t\tif (eval_mode) {\n+\t\t\tmodes_buf_offset =\n+\t\t\t\tGET_FIELD(cond_hdr->mode.data,\n+\t\t\t\t\t  DBG_MODE_HDR_MODES_BUF_OFFSET);\n+\t\t\tmode_match = qed_is_mode_match(p_hwfn,\n+\t\t\t\t\t\t       &modes_buf_offset);\n+\t\t}\n+\n+\t\tif (!mode_match) {\n+\t\t\tinput_offset += cond_hdr->data_size;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tfor (i = 0; i < num_entries;\n+\t\t     i++, input_offset += MEM_DUMP_ENTRY_SIZE_DWORDS) {\n+\t\t\tconst struct dbg_dump_mem *mem =\n+\t\t\t    (const struct dbg_dump_mem *)((u32 *)\n+\t\t\t\t\t\t\t  input_mems_arr.ptr\n+\t\t\t\t\t\t\t  + input_offset);\n+\t\t\tconst struct dbg_block *block;\n+\t\t\tchar storm_letter = 0;\n+\t\t\tu32 mem_addr, mem_len;\n+\t\t\tbool mem_wide_bus;\n+\t\t\tu8 mem_group_id;\n+\n+\t\t\tmem_group_id = GET_FIELD(mem->dword0,\n+\t\t\t\t\t\t DBG_DUMP_MEM_MEM_GROUP_ID);\n+\t\t\tif (mem_group_id >= MEM_GROUPS_NUM) {\n+\t\t\t\tDP_NOTICE(p_hwfn, false, \"Invalid mem_group_id\\n\");\n+\t\t\t\treturn 0;\n+\t\t\t}\n+\n+\t\t\tif (!qed_grc_is_mem_included(p_hwfn,\n+\t\t\t\t\t\t     (enum block_id)\n+\t\t\t\t\t\t     cond_hdr->block_id,\n+\t\t\t\t\t\t     mem_group_id))\n+\t\t\t\tcontinue;\n+\n+\t\t\tmem_addr = GET_FIELD(mem->dword0, DBG_DUMP_MEM_ADDRESS);\n+\t\t\tmem_len = GET_FIELD(mem->dword1, DBG_DUMP_MEM_LENGTH);\n+\t\t\tmem_wide_bus = GET_FIELD(mem->dword1,\n+\t\t\t\t\t\t DBG_DUMP_MEM_WIDE_BUS);\n+\n+\t\t\tblock = get_dbg_block(p_hwfn,\n+\t\t\t\t\t      cond_hdr->block_id);\n+\n+\t\t\t/* If memory is associated with Storm,\n+\t\t\t * update storm details\n+\t\t\t */\n+\t\t\tif (block->associated_storm_letter)\n+\t\t\t\tstorm_letter = block->associated_storm_letter;\n+\n+\t\t\t/* Dump memory */\n+\t\t\toffset += qed_grc_dump_mem(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\tdump_buf + offset,\n+\t\t\t\t\t\tdump,\n+\t\t\t\t\t\tNULL,\n+\t\t\t\t\t\tmem_addr,\n+\t\t\t\t\t\tmem_len,\n+\t\t\t\t\t\tmem_wide_bus,\n+\t\t\t\t\t\t0,\n+\t\t\t\t\t\tfalse,\n+\t\t\t\t\t\ts_mem_group_names[mem_group_id],\n+\t\t\t\t\t\tstorm_letter);\n+\t\t}\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dumps GRC memories according to the input array dump_mem.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_grc_dump_memories(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t struct ecore_ptt *p_ptt,\n+\t\t\t\t u32 *dump_buf, bool dump)\n+{\n+\tstruct virt_mem_desc *dbg_buf =\n+\t    &p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_MEM];\n+\tu32 offset = 0, input_offset = 0;\n+\n+\twhile (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) {\n+\t\tconst struct dbg_dump_split_hdr *split_hdr;\n+\t\tstruct virt_mem_desc curr_input_mems_arr;\n+\t\tenum init_split_types split_type;\n+\t\tu32 split_data_size;\n+\n+\t\tsplit_hdr =\n+\t\t    (const struct dbg_dump_split_hdr *)dbg_buf->ptr +\n+\t\t    input_offset++;\n+\t\tsplit_type = GET_FIELD(split_hdr->hdr,\n+\t\t\t\t       DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);\n+\t\tsplit_data_size = GET_FIELD(split_hdr->hdr,\n+\t\t\t\t\t    DBG_DUMP_SPLIT_HDR_DATA_SIZE);\n+\t\tcurr_input_mems_arr.ptr = (u32 *)dbg_buf->ptr + input_offset;\n+\t\tcurr_input_mems_arr.size = DWORDS_TO_BYTES(split_data_size);\n+\n+\t\tif (split_type == SPLIT_TYPE_NONE)\n+\t\t\toffset += qed_grc_dump_mem_entries(p_hwfn,\n+\t\t\t\t\t\t\t   p_ptt,\n+\t\t\t\t\t\t\t   curr_input_mems_arr,\n+\t\t\t\t\t\t\t   dump_buf + offset,\n+\t\t\t\t\t\t\t   dump);\n+\t\telse\n+\t\t\tDP_NOTICE(p_hwfn, false,\n+\t\t\t\t  \"Dumping split memories is currently not supported\\n\");\n+\n+\t\tinput_offset += split_data_size;\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dumps GRC context data for the specified Storm.\n+ * Returns the dumped size in dwords.\n+ * The lid_size argument is specified in quad-regs.\n+ */\n+static u32 qed_grc_dump_ctx_data(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t struct ecore_ptt *p_ptt,\n+\t\t\t\t u32 *dump_buf,\n+\t\t\t\t bool dump,\n+\t\t\t\t const char *name,\n+\t\t\t\t u32 num_lids,\n+\t\t\t\t enum cm_ctx_types ctx_type, u8 storm_id)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tstruct storm_defs *storm = &s_storm_defs[storm_id];\n+\tu32 i, lid, lid_size, total_size;\n+\tu32 rd_reg_addr, offset = 0;\n+\n+\t/* Convert quad-regs to dwords */\n+\tlid_size = storm->cm_ctx_lid_sizes[dev_data->chip_id][ctx_type] * 4;\n+\n+\tif (!lid_size)\n+\t\treturn 0;\n+\n+\ttotal_size = num_lids * lid_size;\n+\n+\toffset += qed_grc_dump_mem_hdr(p_hwfn,\n+\t\t\t\t       dump_buf + offset,\n+\t\t\t\t       dump,\n+\t\t\t\t       name,\n+\t\t\t\t       0,\n+\t\t\t\t       total_size,\n+\t\t\t\t       lid_size * 32,\n+\t\t\t\t       false, name, storm->letter);\n+\n+\tif (!dump)\n+\t\treturn offset + total_size;\n+\n+\trd_reg_addr = BYTES_TO_DWORDS(storm->cm_ctx_rd_addr[ctx_type]);\n+\n+\t/* Dump context data */\n+\tfor (lid = 0; lid < num_lids; lid++) {\n+\t\tfor (i = 0; i < lid_size; i++) {\n+\t\t\tecore_wr(p_hwfn,\n+\t\t\t       p_ptt, storm->cm_ctx_wr_addr, (i << 9) | lid);\n+\t\t\toffset += qed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t\t\t  dump,\n+\t\t\t\t\t\t\t  rd_reg_addr,\n+\t\t\t\t\t\t\t  1,\n+\t\t\t\t\t\t\t  false,\n+\t\t\t\t\t\t\t  SPLIT_TYPE_NONE, 0);\n+\t\t}\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dumps GRC contexts. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_ctx(struct ecore_hwfn *p_hwfn,\n+\t\t\t    struct ecore_ptt *p_ptt, u32 *dump_buf, bool dump)\n+{\n+\tu32 offset = 0;\n+\tu8 storm_id;\n+\n+\tfor (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {\n+\t\tif (!qed_grc_is_storm_included(p_hwfn,\n+\t\t\t\t\t       (enum dbg_storms)storm_id))\n+\t\t\tcontinue;\n+\n+\t\t/* Dump Conn AG context size */\n+\t\toffset += qed_grc_dump_ctx_data(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\tdump_buf + offset,\n+\t\t\t\t\t\tdump,\n+\t\t\t\t\t\t\"CONN_AG_CTX\",\n+\t\t\t\t\t\tNUM_OF_LCIDS,\n+\t\t\t\t\t\tCM_CTX_CONN_AG, storm_id);\n+\n+\t\t/* Dump Conn ST context size */\n+\t\toffset += qed_grc_dump_ctx_data(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\tdump_buf + offset,\n+\t\t\t\t\t\tdump,\n+\t\t\t\t\t\t\"CONN_ST_CTX\",\n+\t\t\t\t\t\tNUM_OF_LCIDS,\n+\t\t\t\t\t\tCM_CTX_CONN_ST, storm_id);\n+\n+\t\t/* Dump Task AG context size */\n+\t\toffset += qed_grc_dump_ctx_data(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\tdump_buf + offset,\n+\t\t\t\t\t\tdump,\n+\t\t\t\t\t\t\"TASK_AG_CTX\",\n+\t\t\t\t\t\tNUM_OF_LTIDS,\n+\t\t\t\t\t\tCM_CTX_TASK_AG, storm_id);\n+\n+\t\t/* Dump Task ST context size */\n+\t\toffset += qed_grc_dump_ctx_data(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\tdump_buf + offset,\n+\t\t\t\t\t\tdump,\n+\t\t\t\t\t\t\"TASK_ST_CTX\",\n+\t\t\t\t\t\tNUM_OF_LTIDS,\n+\t\t\t\t\t\tCM_CTX_TASK_ST, storm_id);\n+\t}\n+\n+\treturn offset;\n+}\n+\n+#define VFC_STATUS_RESP_READY_BIT\t0\n+#define VFC_STATUS_BUSY_BIT\t\t1\n+#define VFC_STATUS_SENDING_CMD_BIT\t2\n+\n+#define VFC_POLLING_DELAY_MS\t1\n+#define VFC_POLLING_COUNT\t\t20\n+\n+/* Reads data from VFC. Returns the number of dwords read (0 on error).\n+ * Sizes are specified in dwords.\n+ */\n+static u32 qed_grc_dump_read_from_vfc(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t      struct storm_defs *storm,\n+\t\t\t\t      u32 *cmd_data,\n+\t\t\t\t      u32 cmd_size,\n+\t\t\t\t      u32 *addr_data,\n+\t\t\t\t      u32 addr_size,\n+\t\t\t\t      u32 resp_size, u32 *dump_buf)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu32 vfc_status, polling_ms, polling_count = 0, i;\n+\tu32 reg_addr, sem_base;\n+\tbool is_ready = false;\n+\n+\tsem_base = storm->sem_fast_mem_addr;\n+\tpolling_ms = VFC_POLLING_DELAY_MS *\n+\t    s_hw_type_defs[dev_data->hw_type].delay_factor;\n+\n+\t/* Write VFC command */\n+\tARR_REG_WR(p_hwfn,\n+\t\t   p_ptt,\n+\t\t   sem_base + SEM_FAST_REG_VFC_DATA_WR,\n+\t\t   cmd_data, cmd_size);\n+\n+\t/* Write VFC address */\n+\tARR_REG_WR(p_hwfn,\n+\t\t   p_ptt,\n+\t\t   sem_base + SEM_FAST_REG_VFC_ADDR,\n+\t\t   addr_data, addr_size);\n+\n+\t/* Read response */\n+\tfor (i = 0; i < resp_size; i++) {\n+\t\t/* Poll until ready */\n+\t\tdo {\n+\t\t\treg_addr = sem_base + SEM_FAST_REG_VFC_STATUS;\n+\t\t\tqed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\t&vfc_status,\n+\t\t\t\t\t\ttrue,\n+\t\t\t\t\t\tBYTES_TO_DWORDS(reg_addr),\n+\t\t\t\t\t\t1,\n+\t\t\t\t\t\tfalse, SPLIT_TYPE_NONE, 0);\n+\t\t\tis_ready = vfc_status &\n+\t\t\t\t   OSAL_BIT(VFC_STATUS_RESP_READY_BIT);\n+\n+\t\t\tif (!is_ready) {\n+\t\t\t\tif (polling_count++ == VFC_POLLING_COUNT)\n+\t\t\t\t\treturn 0;\n+\n+\t\t\t\tOSAL_MSLEEP(polling_ms);\n+\t\t\t}\n+\t\t} while (!is_ready);\n+\n+\t\treg_addr = sem_base + SEM_FAST_REG_VFC_DATA_RD;\n+\t\tqed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\tp_ptt,\n+\t\t\t\t\tdump_buf + i,\n+\t\t\t\t\ttrue,\n+\t\t\t\t\tBYTES_TO_DWORDS(reg_addr),\n+\t\t\t\t\t1, false, SPLIT_TYPE_NONE, 0);\n+\t}\n+\n+\treturn resp_size;\n+}\n+\n+/* Dump VFC CAM. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_vfc_cam(struct ecore_hwfn *p_hwfn,\n+\t\t\t\tstruct ecore_ptt *p_ptt,\n+\t\t\t\tu32 *dump_buf, bool dump, u8 storm_id)\n+{\n+\tu32 total_size = VFC_CAM_NUM_ROWS * VFC_CAM_RESP_DWORDS;\n+\tstruct storm_defs *storm = &s_storm_defs[storm_id];\n+\tu32 cam_addr[VFC_CAM_ADDR_DWORDS] = { 0 };\n+\tu32 cam_cmd[VFC_CAM_CMD_DWORDS] = { 0 };\n+\tu32 row, offset = 0;\n+\n+\toffset += qed_grc_dump_mem_hdr(p_hwfn,\n+\t\t\t\t       dump_buf + offset,\n+\t\t\t\t       dump,\n+\t\t\t\t       \"vfc_cam\",\n+\t\t\t\t       0,\n+\t\t\t\t       total_size,\n+\t\t\t\t       256,\n+\t\t\t\t       false, \"vfc_cam\", storm->letter);\n+\n+\tif (!dump)\n+\t\treturn offset + total_size;\n+\n+\t/* Prepare CAM address */\n+\tSET_VAR_FIELD(cam_addr, VFC_CAM_ADDR, OP, VFC_OPCODE_CAM_RD);\n+\n+\t/* Read VFC CAM data */\n+\tfor (row = 0; row < VFC_CAM_NUM_ROWS; row++) {\n+\t\tSET_VAR_FIELD(cam_cmd, VFC_CAM_CMD, ROW, row);\n+\t\toffset += qed_grc_dump_read_from_vfc(p_hwfn,\n+\t\t\t\t\t\t     p_ptt,\n+\t\t\t\t\t\t     storm,\n+\t\t\t\t\t\t     cam_cmd,\n+\t\t\t\t\t\t     VFC_CAM_CMD_DWORDS,\n+\t\t\t\t\t\t     cam_addr,\n+\t\t\t\t\t\t     VFC_CAM_ADDR_DWORDS,\n+\t\t\t\t\t\t     VFC_CAM_RESP_DWORDS,\n+\t\t\t\t\t\t     dump_buf + offset);\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dump VFC RAM. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_vfc_ram(struct ecore_hwfn *p_hwfn,\n+\t\t\t\tstruct ecore_ptt *p_ptt,\n+\t\t\t\tu32 *dump_buf,\n+\t\t\t\tbool dump,\n+\t\t\t\tu8 storm_id, struct vfc_ram_defs *ram_defs)\n+{\n+\tu32 total_size = ram_defs->num_rows * VFC_RAM_RESP_DWORDS;\n+\tstruct storm_defs *storm = &s_storm_defs[storm_id];\n+\tu32 ram_addr[VFC_RAM_ADDR_DWORDS] = { 0 };\n+\tu32 ram_cmd[VFC_RAM_CMD_DWORDS] = { 0 };\n+\tu32 row, offset = 0;\n+\n+\toffset += qed_grc_dump_mem_hdr(p_hwfn,\n+\t\t\t\t       dump_buf + offset,\n+\t\t\t\t       dump,\n+\t\t\t\t       ram_defs->mem_name,\n+\t\t\t\t       0,\n+\t\t\t\t       total_size,\n+\t\t\t\t       256,\n+\t\t\t\t       false,\n+\t\t\t\t       ram_defs->type_name,\n+\t\t\t\t       storm->letter);\n+\n+\tif (!dump)\n+\t\treturn offset + total_size;\n+\n+\t/* Prepare RAM address */\n+\tSET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, OP, VFC_OPCODE_RAM_RD);\n+\n+\t/* Read VFC RAM data */\n+\tfor (row = ram_defs->base_row;\n+\t     row < ram_defs->base_row + ram_defs->num_rows; row++) {\n+\t\tSET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, ROW, row);\n+\t\toffset += qed_grc_dump_read_from_vfc(p_hwfn,\n+\t\t\t\t\t\t     p_ptt,\n+\t\t\t\t\t\t     storm,\n+\t\t\t\t\t\t     ram_cmd,\n+\t\t\t\t\t\t     VFC_RAM_CMD_DWORDS,\n+\t\t\t\t\t\t     ram_addr,\n+\t\t\t\t\t\t     VFC_RAM_ADDR_DWORDS,\n+\t\t\t\t\t\t     VFC_RAM_RESP_DWORDS,\n+\t\t\t\t\t\t     dump_buf + offset);\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dumps GRC VFC data. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_vfc(struct ecore_hwfn *p_hwfn,\n+\t\t\t    struct ecore_ptt *p_ptt, u32 *dump_buf, bool dump)\n+{\n+\tu8 storm_id, i;\n+\tu32 offset = 0;\n+\n+\tfor (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {\n+\t\tif (!qed_grc_is_storm_included(p_hwfn,\n+\t\t\t\t\t       (enum dbg_storms)storm_id) ||\n+\t\t    !s_storm_defs[storm_id].has_vfc)\n+\t\t\tcontinue;\n+\n+\t\t/* Read CAM */\n+\t\toffset += qed_grc_dump_vfc_cam(p_hwfn,\n+\t\t\t\t\t       p_ptt,\n+\t\t\t\t\t       dump_buf + offset,\n+\t\t\t\t\t       dump, storm_id);\n+\n+\t\t/* Read RAM */\n+\t\tfor (i = 0; i < NUM_VFC_RAM_TYPES; i++)\n+\t\t\toffset += qed_grc_dump_vfc_ram(p_hwfn,\n+\t\t\t\t\t\t       p_ptt,\n+\t\t\t\t\t\t       dump_buf + offset,\n+\t\t\t\t\t\t       dump,\n+\t\t\t\t\t\t       storm_id,\n+\t\t\t\t\t\t       &s_vfc_ram_defs[i]);\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dumps GRC RSS data. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_rss(struct ecore_hwfn *p_hwfn,\n+\t\t\t    struct ecore_ptt *p_ptt, u32 *dump_buf, bool dump)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu32 offset = 0;\n+\tu8 rss_mem_id;\n+\n+\tfor (rss_mem_id = 0; rss_mem_id < NUM_RSS_MEM_TYPES; rss_mem_id++) {\n+\t\tu32 rss_addr, num_entries, total_dwords;\n+\t\tstruct rss_mem_defs *rss_defs;\n+\t\tu32 addr, num_dwords_to_read;\n+\t\tbool packed;\n+\n+\t\trss_defs = &s_rss_mem_defs[rss_mem_id];\n+\t\trss_addr = rss_defs->addr;\n+\t\tnum_entries = rss_defs->num_entries[dev_data->chip_id];\n+\t\ttotal_dwords = (num_entries * rss_defs->entry_width) / 32;\n+\t\tpacked = (rss_defs->entry_width == 16);\n+\n+\t\toffset += qed_grc_dump_mem_hdr(p_hwfn,\n+\t\t\t\t\t       dump_buf + offset,\n+\t\t\t\t\t       dump,\n+\t\t\t\t\t       rss_defs->mem_name,\n+\t\t\t\t\t       0,\n+\t\t\t\t\t       total_dwords,\n+\t\t\t\t\t       rss_defs->entry_width,\n+\t\t\t\t\t       packed,\n+\t\t\t\t\t       rss_defs->type_name, 0);\n+\n+\t\t/* Dump RSS data */\n+\t\tif (!dump) {\n+\t\t\toffset += total_dwords;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\taddr = BYTES_TO_DWORDS(RSS_REG_RSS_RAM_DATA);\n+\t\twhile (total_dwords) {\n+\t\t\tnum_dwords_to_read = OSAL_MIN_T(u32,\n+\t\t\t\t\t\t      RSS_REG_RSS_RAM_DATA_SIZE,\n+\t\t\t\t\t\t      total_dwords);\n+\t\t\tecore_wr(p_hwfn, p_ptt, RSS_REG_RSS_RAM_ADDR, rss_addr);\n+\t\t\toffset += qed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t\t\t  dump,\n+\t\t\t\t\t\t\t  addr,\n+\t\t\t\t\t\t\t  num_dwords_to_read,\n+\t\t\t\t\t\t\t  false,\n+\t\t\t\t\t\t\t  SPLIT_TYPE_NONE, 0);\n+\t\t\ttotal_dwords -= num_dwords_to_read;\n+\t\t\trss_addr++;\n+\t\t}\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dumps GRC Big RAM. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_big_ram(struct ecore_hwfn *p_hwfn,\n+\t\t\t\tstruct ecore_ptt *p_ptt,\n+\t\t\t\tu32 *dump_buf, bool dump, u8 big_ram_id)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu32 block_size, ram_size, offset = 0, reg_val, i;\n+\tchar mem_name[12] = \"???_BIG_RAM\";\n+\tchar type_name[8] = \"???_RAM\";\n+\tstruct big_ram_defs *big_ram;\n+\n+\tbig_ram = &s_big_ram_defs[big_ram_id];\n+\tram_size = big_ram->ram_size[dev_data->chip_id];\n+\n+\treg_val = ecore_rd(p_hwfn, p_ptt, big_ram->is_256b_reg_addr);\n+\tblock_size = reg_val &\n+\t\t     OSAL_BIT(big_ram->is_256b_bit_offset[dev_data->chip_id]) ?\n+\t\t\t\t\t\t\t\t     256 : 128;\n+\n+\tstrncpy(type_name, big_ram->instance_name, BIG_RAM_NAME_LEN);\n+\tstrncpy(mem_name, big_ram->instance_name, BIG_RAM_NAME_LEN);\n+\n+\t/* Dump memory header */\n+\toffset += qed_grc_dump_mem_hdr(p_hwfn,\n+\t\t\t\t       dump_buf + offset,\n+\t\t\t\t       dump,\n+\t\t\t\t       mem_name,\n+\t\t\t\t       0,\n+\t\t\t\t       ram_size,\n+\t\t\t\t       block_size * 8,\n+\t\t\t\t       false, type_name, 0);\n+\n+\t/* Read and dump Big RAM data */\n+\tif (!dump)\n+\t\treturn offset + ram_size;\n+\n+\t/* Dump Big RAM */\n+\tfor (i = 0; i < DIV_ROUND_UP(ram_size, BRB_REG_BIG_RAM_DATA_SIZE);\n+\t     i++) {\n+\t\tu32 addr, len;\n+\n+\t\tecore_wr(p_hwfn, p_ptt, big_ram->addr_reg_addr, i);\n+\t\taddr = BYTES_TO_DWORDS(big_ram->data_reg_addr);\n+\t\tlen = BRB_REG_BIG_RAM_DATA_SIZE;\n+\t\toffset += qed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t\t  dump,\n+\t\t\t\t\t\t  addr,\n+\t\t\t\t\t\t  len,\n+\t\t\t\t\t\t  false, SPLIT_TYPE_NONE, 0);\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dumps MCP scratchpad. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_mcp(struct ecore_hwfn *p_hwfn,\n+\t\t\t    struct ecore_ptt *p_ptt, u32 *dump_buf, bool dump)\n+{\n+\tbool block_enable[MAX_BLOCK_ID] = { 0 };\n+\tu32 offset = 0, addr;\n+\tbool halted = false;\n+\n+\t/* Halt MCP */\n+\tif (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {\n+\t\thalted = !ecore_mcp_halt(p_hwfn, p_ptt);\n+\t\tif (!halted)\n+\t\t\tDP_NOTICE(p_hwfn, false, \"MCP halt failed!\\n\");\n+\t}\n+\n+\t/* Dump MCP scratchpad */\n+\toffset += qed_grc_dump_mem(p_hwfn,\n+\t\t\t\t   p_ptt,\n+\t\t\t\t   dump_buf + offset,\n+\t\t\t\t   dump,\n+\t\t\t\t   NULL,\n+\t\t\t\t   BYTES_TO_DWORDS(MCP_REG_SCRATCH),\n+\t\t\t\t   MCP_REG_SCRATCH_SIZE,\n+\t\t\t\t   false, 0, false, \"MCP\", 0);\n+\n+\t/* Dump MCP cpu_reg_file */\n+\toffset += qed_grc_dump_mem(p_hwfn,\n+\t\t\t\t   p_ptt,\n+\t\t\t\t   dump_buf + offset,\n+\t\t\t\t   dump,\n+\t\t\t\t   NULL,\n+\t\t\t\t   BYTES_TO_DWORDS(MCP_REG_CPU_REG_FILE),\n+\t\t\t\t   MCP_REG_CPU_REG_FILE_SIZE,\n+\t\t\t\t   false, 0, false, \"MCP\", 0);\n+\n+\t/* Dump MCP registers */\n+\tblock_enable[BLOCK_MCP] = true;\n+\toffset += qed_grc_dump_registers(p_hwfn,\n+\t\t\t\t\t p_ptt,\n+\t\t\t\t\t dump_buf + offset,\n+\t\t\t\t\t dump, block_enable, \"MCP\");\n+\n+\t/* Dump required non-MCP registers */\n+\toffset += qed_grc_dump_regs_hdr(dump_buf + offset,\n+\t\t\t\t\tdump, 1, SPLIT_TYPE_NONE, 0,\n+\t\t\t\t\t\"MCP\");\n+\taddr = BYTES_TO_DWORDS(MISC_REG_SHARED_MEM_ADDR);\n+\toffset += qed_grc_dump_reg_entry(p_hwfn,\n+\t\t\t\t\t p_ptt,\n+\t\t\t\t\t dump_buf + offset,\n+\t\t\t\t\t dump,\n+\t\t\t\t\t addr,\n+\t\t\t\t\t 1,\n+\t\t\t\t\t false, SPLIT_TYPE_NONE, 0);\n+\n+\t/* Release MCP */\n+\tif (halted && ecore_mcp_resume(p_hwfn, p_ptt))\n+\t\tDP_NOTICE(p_hwfn, false, \"Failed to resume MCP after halt!\\n\");\n+\n+\treturn offset;\n+}\n+\n+/* Dumps the tbus indirect memory for all PHYs.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_grc_dump_phy(struct ecore_hwfn *p_hwfn,\n+\t\t\t    struct ecore_ptt *p_ptt, u32 *dump_buf, bool dump)\n+{\n+\tu32 offset = 0, tbus_lo_offset, tbus_hi_offset;\n+\tchar mem_name[32];\n+\tu8 phy_id;\n+\n+\tfor (phy_id = 0; phy_id < OSAL_ARRAY_SIZE(s_phy_defs); phy_id++) {\n+\t\tu32 addr_lo_addr, addr_hi_addr, data_lo_addr, data_hi_addr;\n+\t\tstruct phy_defs *phy_defs;\n+\t\tu8 *bytes_buf;\n+\n+\t\tphy_defs = &s_phy_defs[phy_id];\n+\t\taddr_lo_addr = phy_defs->base_addr +\n+\t\t\t       phy_defs->tbus_addr_lo_addr;\n+\t\taddr_hi_addr = phy_defs->base_addr +\n+\t\t\t       phy_defs->tbus_addr_hi_addr;\n+\t\tdata_lo_addr = phy_defs->base_addr +\n+\t\t\t       phy_defs->tbus_data_lo_addr;\n+\t\tdata_hi_addr = phy_defs->base_addr +\n+\t\t\t       phy_defs->tbus_data_hi_addr;\n+\n+\t\tif (snprintf(mem_name, sizeof(mem_name), \"tbus_%s\",\n+\t\t\t     phy_defs->phy_name) < 0)\n+\t\t\tDP_NOTICE(p_hwfn, false,\n+\t\t\t\t  \"Unexpected debug error: invalid PHY memory name\\n\");\n+\n+\t\toffset += qed_grc_dump_mem_hdr(p_hwfn,\n+\t\t\t\t\t       dump_buf + offset,\n+\t\t\t\t\t       dump,\n+\t\t\t\t\t       mem_name,\n+\t\t\t\t\t       0,\n+\t\t\t\t\t       PHY_DUMP_SIZE_DWORDS,\n+\t\t\t\t\t       16, true, mem_name, 0);\n+\n+\t\tif (!dump) {\n+\t\t\toffset += PHY_DUMP_SIZE_DWORDS;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tbytes_buf = (u8 *)(dump_buf + offset);\n+\t\tfor (tbus_hi_offset = 0;\n+\t\t     tbus_hi_offset < (NUM_PHY_TBUS_ADDRESSES >> 8);\n+\t\t     tbus_hi_offset++) {\n+\t\t\tecore_wr(p_hwfn, p_ptt, addr_hi_addr, tbus_hi_offset);\n+\t\t\tfor (tbus_lo_offset = 0; tbus_lo_offset < 256;\n+\t\t\t     tbus_lo_offset++) {\n+\t\t\t\tecore_wr(p_hwfn,\n+\t\t\t\t       p_ptt, addr_lo_addr, tbus_lo_offset);\n+\t\t\t\t*(bytes_buf++) = (u8)ecore_rd(p_hwfn,\n+\t\t\t\t\t\t\t    p_ptt,\n+\t\t\t\t\t\t\t    data_lo_addr);\n+\t\t\t\t*(bytes_buf++) = (u8)ecore_rd(p_hwfn,\n+\t\t\t\t\t\t\t    p_ptt,\n+\t\t\t\t\t\t\t    data_hi_addr);\n+\t\t\t}\n+\t\t}\n+\n+\t\toffset += PHY_DUMP_SIZE_DWORDS;\n+\t}\n+\n+\treturn offset;\n+}\n+\n+static enum dbg_status qed_find_nvram_image(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t    struct ecore_ptt *p_ptt,\n+\t\t\t\t\t    u32 image_type,\n+\t\t\t\t\t    u32 *nvram_offset_bytes,\n+\t\t\t\t\t    u32 *nvram_size_bytes);\n+\n+static enum dbg_status qed_nvram_read(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t      u32 nvram_offset_bytes,\n+\t\t\t\t      u32 nvram_size_bytes, u32 *ret_buf);\n+\n+/* Dumps the MCP HW dump from NVRAM. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_mcp_hw_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t    struct ecore_ptt *p_ptt,\n+\t\t\t\t    u32 *dump_buf, bool dump)\n+{\n+\tu32 hw_dump_offset_bytes = 0, hw_dump_size_bytes = 0;\n+\tu32 hw_dump_size_dwords = 0, offset = 0;\n+\tenum dbg_status status;\n+\n+\t/* Read HW dump image from NVRAM */\n+\tstatus = qed_find_nvram_image(p_hwfn,\n+\t\t\t\t      p_ptt,\n+\t\t\t\t      NVM_TYPE_HW_DUMP_OUT,\n+\t\t\t\t      &hw_dump_offset_bytes,\n+\t\t\t\t      &hw_dump_size_bytes);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn 0;\n+\n+\thw_dump_size_dwords = BYTES_TO_DWORDS(hw_dump_size_bytes);\n+\n+\t/* Dump HW dump image section */\n+\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t       dump, \"mcp_hw_dump\", 1);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump, \"size\", hw_dump_size_dwords);\n+\n+\t/* Read MCP HW dump image into dump buffer */\n+\tif (dump && hw_dump_size_dwords) {\n+\t\tstatus = qed_nvram_read(p_hwfn,\n+\t\t\t\t\tp_ptt,\n+\t\t\t\t\thw_dump_offset_bytes,\n+\t\t\t\t\thw_dump_size_bytes, dump_buf + offset);\n+\t\tif (status != DBG_STATUS_OK) {\n+\t\t\tDP_NOTICE(p_hwfn, false,\n+\t\t\t\t  \"Failed to read MCP HW Dump image from NVRAM\\n\");\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\toffset += hw_dump_size_dwords;\n+\n+\treturn offset;\n+}\n+\n+/* Dumps Static Debug data. Returns the dumped size in dwords. */\n+static u32 qed_grc_dump_static_debug(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t     struct ecore_ptt *p_ptt,\n+\t\t\t\t     u32 *dump_buf, bool dump)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu32 block_id, line_id, offset = 0, addr, len;\n+\n+\t/* Don't dump static debug if a debug bus recording is in progress */\n+\tif (dump && ecore_rd(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON))\n+\t\treturn 0;\n+\n+\tif (dump) {\n+\t\t/* Disable debug bus in all blocks */\n+\t\tqed_bus_disable_blocks(p_hwfn, p_ptt);\n+\n+\t\tqed_bus_reset_dbg_block(p_hwfn, p_ptt);\n+\t\tecore_wr(p_hwfn,\n+\t\t       p_ptt, DBG_REG_FRAMING_MODE, DBG_BUS_FRAME_MODE_8HW);\n+\t\tecore_wr(p_hwfn,\n+\t\t       p_ptt, DBG_REG_DEBUG_TARGET, DBG_BUS_TARGET_ID_INT_BUF);\n+\t\tecore_wr(p_hwfn, p_ptt, DBG_REG_FULL_MODE, 1);\n+\t\tqed_bus_enable_dbg_block(p_hwfn, p_ptt, true);\n+\t}\n+\n+\t/* Dump all static debug lines for each relevant block */\n+\tfor (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {\n+\t\tconst struct dbg_block_chip *block_per_chip;\n+\t\tconst struct dbg_block *block;\n+\t\tbool is_removed, has_dbg_bus;\n+\t\tu16 modes_buf_offset;\n+\t\tu32 block_dwords;\n+\n+\t\tblock_per_chip =\n+\t\t    qed_get_dbg_block_per_chip(p_hwfn, (enum block_id)block_id);\n+\t\tis_removed = GET_FIELD(block_per_chip->flags,\n+\t\t\t\t       DBG_BLOCK_CHIP_IS_REMOVED);\n+\t\thas_dbg_bus = GET_FIELD(block_per_chip->flags,\n+\t\t\t\t\tDBG_BLOCK_CHIP_HAS_DBG_BUS);\n+\n+\t\t/* read+clear for NWS parity is not working, skip NWS block */\n+\t\tif (block_id == BLOCK_NWS)\n+\t\t\tcontinue;\n+\n+\t\tif (!is_removed && has_dbg_bus &&\n+\t\t    GET_FIELD(block_per_chip->dbg_bus_mode.data,\n+\t\t\t      DBG_MODE_HDR_EVAL_MODE) > 0) {\n+\t\t\tmodes_buf_offset =\n+\t\t\t    GET_FIELD(block_per_chip->dbg_bus_mode.data,\n+\t\t\t\t      DBG_MODE_HDR_MODES_BUF_OFFSET);\n+\t\t\tif (!qed_is_mode_match(p_hwfn, &modes_buf_offset))\n+\t\t\t\thas_dbg_bus = false;\n+\t\t}\n+\n+\t\tif (is_removed || !has_dbg_bus)\n+\t\t\tcontinue;\n+\n+\t\tblock_dwords = NUM_DBG_LINES(block_per_chip) *\n+\t\t\t       STATIC_DEBUG_LINE_DWORDS;\n+\n+\t\t/* Dump static section params */\n+\t\tblock = get_dbg_block(p_hwfn, (enum block_id)block_id);\n+\t\toffset += qed_grc_dump_mem_hdr(p_hwfn,\n+\t\t\t\t\t       dump_buf + offset,\n+\t\t\t\t\t       dump,\n+\t\t\t\t\t       (const char *)block->name,\n+\t\t\t\t\t       0,\n+\t\t\t\t\t       block_dwords,\n+\t\t\t\t\t       32, false, \"STATIC\", 0);\n+\n+\t\tif (!dump) {\n+\t\t\toffset += block_dwords;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* If all lines are invalid - dump zeros */\n+\t\tif (dev_data->block_in_reset[block_id]) {\n+\t\t\tmemset(dump_buf + offset, 0,\n+\t\t\t       DWORDS_TO_BYTES(block_dwords));\n+\t\t\toffset += block_dwords;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* Enable block's client */\n+\t\tqed_bus_enable_clients(p_hwfn,\n+\t\t\t\t       p_ptt,\n+\t\t\t\t       OSAL_BIT(block_per_chip->dbg_client_id));\n+\n+\t\taddr = BYTES_TO_DWORDS(DBG_REG_CALENDAR_OUT_DATA);\n+\t\tlen = STATIC_DEBUG_LINE_DWORDS;\n+\t\tfor (line_id = 0; line_id < (u32)NUM_DBG_LINES(block_per_chip);\n+\t\t     line_id++) {\n+\t\t\t/* Configure debug line ID */\n+\t\t\tqed_bus_config_dbg_line(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\t(enum block_id)block_id,\n+\t\t\t\t\t\t(u8)line_id, 0xf, 0, 0, 0);\n+\n+\t\t\t/* Read debug line info */\n+\t\t\toffset += qed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t\t\t  dump,\n+\t\t\t\t\t\t\t  addr,\n+\t\t\t\t\t\t\t  len,\n+\t\t\t\t\t\t\t  true, SPLIT_TYPE_NONE,\n+\t\t\t\t\t\t\t  0);\n+\t\t}\n+\n+\t\t/* Disable block's client and debug output */\n+\t\tqed_bus_enable_clients(p_hwfn, p_ptt, 0);\n+\t\tqed_bus_config_dbg_line(p_hwfn, p_ptt,\n+\t\t\t\t\t(enum block_id)block_id, 0, 0, 0, 0, 0);\n+\t}\n+\n+\tif (dump) {\n+\t\tqed_bus_enable_dbg_block(p_hwfn, p_ptt, false);\n+\t\tqed_bus_enable_clients(p_hwfn, p_ptt, 0);\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Performs GRC Dump to the specified buffer.\n+ * Returns the dumped size in dwords.\n+ */\n+static enum dbg_status qed_grc_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t    struct ecore_ptt *p_ptt,\n+\t\t\t\t    u32 *dump_buf,\n+\t\t\t\t    bool dump, u32 *num_dumped_dwords)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu32 dwords_read, offset = 0;\n+\tbool parities_masked = false;\n+\tu8 i;\n+\n+\t*num_dumped_dwords = 0;\n+\tdev_data->num_regs_read = 0;\n+\n+\t/* Update reset state */\n+\tif (dump)\n+\t\tqed_update_blocks_reset_state(p_hwfn, p_ptt);\n+\n+\t/* Dump global params */\n+\toffset += qed_dump_common_global_params(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\tdump_buf + offset, dump, 4);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump, \"dump-type\", \"grc-dump\");\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"num-lcids\",\n+\t\t\t\t     NUM_OF_LCIDS);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"num-ltids\",\n+\t\t\t\t     NUM_OF_LTIDS);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump, \"num-ports\", dev_data->num_ports);\n+\n+\t/* Dump reset registers (dumped before taking blocks out of reset ) */\n+\tif (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))\n+\t\toffset += qed_grc_dump_reset_regs(p_hwfn,\n+\t\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t\t  dump_buf + offset, dump);\n+\n+\t/* Take all blocks out of reset (using reset registers) */\n+\tif (dump) {\n+\t\tqed_grc_unreset_blocks(p_hwfn, p_ptt, false);\n+\t\tqed_update_blocks_reset_state(p_hwfn, p_ptt);\n+\t}\n+\n+\t/* Disable all parities using MFW command */\n+\tif (dump &&\n+\t    !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {\n+\t\tparities_masked = !ecore_mcp_mask_parities(p_hwfn, p_ptt, 1);\n+\t\tif (!parities_masked) {\n+\t\t\tDP_NOTICE(p_hwfn, false,\n+\t\t\t\t  \"Failed to mask parities using MFW\\n\");\n+\t\t\tif (qed_grc_get_param\n+\t\t\t    (p_hwfn, DBG_GRC_PARAM_PARITY_SAFE))\n+\t\t\t\treturn DBG_STATUS_MCP_COULD_NOT_MASK_PRTY;\n+\t\t}\n+\t}\n+\n+\t/* Dump modified registers (dumped before modifying them) */\n+\tif (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))\n+\t\toffset += qed_grc_dump_modified_regs(p_hwfn,\n+\t\t\t\t\t\t     p_ptt,\n+\t\t\t\t\t\t     dump_buf + offset, dump);\n+\n+\t/* Stall storms */\n+\tif (dump &&\n+\t    (qed_grc_is_included(p_hwfn,\n+\t\t\t\t DBG_GRC_PARAM_DUMP_IOR) ||\n+\t     qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)))\n+\t\tqed_grc_stall_storms(p_hwfn, p_ptt, true);\n+\n+\t/* Dump all regs  */\n+\tif (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS)) {\n+\t\tbool block_enable[MAX_BLOCK_ID];\n+\n+\t\t/* Dump all blocks except MCP */\n+\t\tfor (i = 0; i < MAX_BLOCK_ID; i++)\n+\t\t\tblock_enable[i] = true;\n+\t\tblock_enable[BLOCK_MCP] = false;\n+\t\toffset += qed_grc_dump_registers(p_hwfn,\n+\t\t\t\t\t\t p_ptt,\n+\t\t\t\t\t\t dump_buf +\n+\t\t\t\t\t\t offset,\n+\t\t\t\t\t\t dump,\n+\t\t\t\t\t\t block_enable, NULL);\n+\n+\t\t/* Dump special registers */\n+\t\toffset += qed_grc_dump_special_regs(p_hwfn,\n+\t\t\t\t\t\t    p_ptt,\n+\t\t\t\t\t\t    dump_buf + offset, dump);\n+\t}\n+\n+\t/* Dump memories */\n+\toffset += qed_grc_dump_memories(p_hwfn, p_ptt, dump_buf + offset, dump);\n+\n+\t/* Dump MCP */\n+\tif (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP))\n+\t\toffset += qed_grc_dump_mcp(p_hwfn,\n+\t\t\t\t\t   p_ptt, dump_buf + offset, dump);\n+\n+\t/* Dump context */\n+\tif (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX))\n+\t\toffset += qed_grc_dump_ctx(p_hwfn,\n+\t\t\t\t\t   p_ptt, dump_buf + offset, dump);\n+\n+\t/* Dump RSS memories */\n+\tif (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RSS))\n+\t\toffset += qed_grc_dump_rss(p_hwfn,\n+\t\t\t\t\t   p_ptt, dump_buf + offset, dump);\n+\n+\t/* Dump Big RAM */\n+\tfor (i = 0; i < NUM_BIG_RAM_TYPES; i++)\n+\t\tif (qed_grc_is_included(p_hwfn, s_big_ram_defs[i].grc_param))\n+\t\t\toffset += qed_grc_dump_big_ram(p_hwfn,\n+\t\t\t\t\t\t       p_ptt,\n+\t\t\t\t\t\t       dump_buf + offset,\n+\t\t\t\t\t\t       dump, i);\n+\n+\t/* Dump VFC */\n+\tif (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)) {\n+\t\tdwords_read = qed_grc_dump_vfc(p_hwfn,\n+\t\t\t\t\t       p_ptt, dump_buf + offset, dump);\n+\t\toffset += dwords_read;\n+\t\tif (!dwords_read)\n+\t\t\treturn DBG_STATUS_VFC_READ_ERROR;\n+\t}\n+\n+\t/* Dump PHY tbus */\n+\tif (qed_grc_is_included(p_hwfn,\n+\t\t\t\tDBG_GRC_PARAM_DUMP_PHY) && dev_data->chip_id ==\n+\t    CHIP_K2 && dev_data->hw_type == HW_TYPE_ASIC)\n+\t\toffset += qed_grc_dump_phy(p_hwfn,\n+\t\t\t\t\t   p_ptt, dump_buf + offset, dump);\n+\n+\t/* Dump MCP HW Dump */\n+\tif (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP_HW_DUMP) &&\n+\t    !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP) && 1)\n+\t\toffset += qed_grc_dump_mcp_hw_dump(p_hwfn,\n+\t\t\t\t\t\t   p_ptt,\n+\t\t\t\t\t\t   dump_buf + offset, dump);\n+\n+\t/* Dump static debug data (only if not during debug bus recording) */\n+\tif (qed_grc_is_included(p_hwfn,\n+\t\t\t\tDBG_GRC_PARAM_DUMP_STATIC) &&\n+\t    (!dump || dev_data->bus.state == DBG_BUS_STATE_IDLE))\n+\t\toffset += qed_grc_dump_static_debug(p_hwfn,\n+\t\t\t\t\t\t    p_ptt,\n+\t\t\t\t\t\t    dump_buf + offset, dump);\n+\n+\t/* Dump last section */\n+\toffset += qed_dump_last_section(dump_buf, offset, dump);\n+\n+\tif (dump) {\n+\t\t/* Unstall storms */\n+\t\tif (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_UNSTALL))\n+\t\t\tqed_grc_stall_storms(p_hwfn, p_ptt, false);\n+\n+\t\t/* Clear parity status */\n+\t\tqed_grc_clear_all_prty(p_hwfn, p_ptt);\n+\n+\t\t/* Enable all parities using MFW command */\n+\t\tif (parities_masked)\n+\t\t\tecore_mcp_mask_parities(p_hwfn, p_ptt, 0);\n+\t}\n+\n+\t*num_dumped_dwords = offset;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Writes the specified failing Idle Check rule to the specified buffer.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_idle_chk_dump_failure(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t     struct ecore_ptt *p_ptt,\n+\t\t\t\t     u32 *\n+\t\t\t\t     dump_buf,\n+\t\t\t\t     bool dump,\n+\t\t\t\t     u16 rule_id,\n+\t\t\t\t     const struct dbg_idle_chk_rule *rule,\n+\t\t\t\t     u16 fail_entry_id, u32 *cond_reg_values)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tconst struct dbg_idle_chk_cond_reg *cond_regs;\n+\tconst struct dbg_idle_chk_info_reg *info_regs;\n+\tu32 i, next_reg_offset = 0, offset = 0;\n+\tstruct dbg_idle_chk_result_hdr *hdr;\n+\tconst union dbg_idle_chk_reg *regs;\n+\tu8 reg_id;\n+\n+\thdr = (struct dbg_idle_chk_result_hdr *)dump_buf;\n+\tregs = (const union dbg_idle_chk_reg *)\n+\t\tp_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr +\n+\t\trule->reg_offset;\n+\tcond_regs = &regs[0].cond_reg;\n+\tinfo_regs = &regs[rule->num_cond_regs].info_reg;\n+\n+\t/* Dump rule data */\n+\tif (dump) {\n+\t\tmemset(hdr, 0, sizeof(*hdr));\n+\t\thdr->rule_id = rule_id;\n+\t\thdr->mem_entry_id = fail_entry_id;\n+\t\thdr->severity = rule->severity;\n+\t\thdr->num_dumped_cond_regs = rule->num_cond_regs;\n+\t}\n+\n+\toffset += IDLE_CHK_RESULT_HDR_DWORDS;\n+\n+\t/* Dump condition register values */\n+\tfor (reg_id = 0; reg_id < rule->num_cond_regs; reg_id++) {\n+\t\tconst struct dbg_idle_chk_cond_reg *reg = &cond_regs[reg_id];\n+\t\tstruct dbg_idle_chk_result_reg_hdr *reg_hdr;\n+\n+\t\treg_hdr =\n+\t\t    (struct dbg_idle_chk_result_reg_hdr *)(dump_buf + offset);\n+\n+\t\t/* Write register header */\n+\t\tif (!dump) {\n+\t\t\toffset += IDLE_CHK_RESULT_REG_HDR_DWORDS +\n+\t\t\t    reg->entry_size;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\toffset += IDLE_CHK_RESULT_REG_HDR_DWORDS;\n+\t\tmemset(reg_hdr, 0, sizeof(*reg_hdr));\n+\t\treg_hdr->start_entry = reg->start_entry;\n+\t\treg_hdr->size = reg->entry_size;\n+\t\tSET_FIELD(reg_hdr->data,\n+\t\t\t  DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM,\n+\t\t\t  reg->num_entries > 1 || reg->start_entry > 0 ? 1 : 0);\n+\t\tSET_FIELD(reg_hdr->data,\n+\t\t\t  DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID, reg_id);\n+\n+\t\t/* Write register values */\n+\t\tfor (i = 0; i < reg_hdr->size; i++, next_reg_offset++, offset++)\n+\t\t\tdump_buf[offset] = cond_reg_values[next_reg_offset];\n+\t}\n+\n+\t/* Dump info register values */\n+\tfor (reg_id = 0; reg_id < rule->num_info_regs; reg_id++) {\n+\t\tconst struct dbg_idle_chk_info_reg *reg = &info_regs[reg_id];\n+\t\tu32 block_id;\n+\n+\t\t/* Check if register's block is in reset */\n+\t\tif (!dump) {\n+\t\t\toffset += IDLE_CHK_RESULT_REG_HDR_DWORDS + reg->size;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tblock_id = GET_FIELD(reg->data, DBG_IDLE_CHK_INFO_REG_BLOCK_ID);\n+\t\tif (block_id >= MAX_BLOCK_ID) {\n+\t\t\tDP_NOTICE(p_hwfn, false, \"Invalid block_id\\n\");\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\tif (!dev_data->block_in_reset[block_id]) {\n+\t\t\tstruct dbg_idle_chk_result_reg_hdr *reg_hdr;\n+\t\t\tbool wide_bus, eval_mode, mode_match = true;\n+\t\t\tu16 modes_buf_offset;\n+\t\t\tu32 addr;\n+\n+\t\t\treg_hdr = (struct dbg_idle_chk_result_reg_hdr *)\n+\t\t\t\t  (dump_buf + offset);\n+\n+\t\t\t/* Check mode */\n+\t\t\teval_mode = GET_FIELD(reg->mode.data,\n+\t\t\t\t\t      DBG_MODE_HDR_EVAL_MODE) > 0;\n+\t\t\tif (eval_mode) {\n+\t\t\t\tmodes_buf_offset =\n+\t\t\t\t    GET_FIELD(reg->mode.data,\n+\t\t\t\t\t      DBG_MODE_HDR_MODES_BUF_OFFSET);\n+\t\t\t\tmode_match =\n+\t\t\t\t\tqed_is_mode_match(p_hwfn,\n+\t\t\t\t\t\t\t  &modes_buf_offset);\n+\t\t\t}\n+\n+\t\t\tif (!mode_match)\n+\t\t\t\tcontinue;\n+\n+\t\t\taddr = GET_FIELD(reg->data,\n+\t\t\t\t\t DBG_IDLE_CHK_INFO_REG_ADDRESS);\n+\t\t\twide_bus = GET_FIELD(reg->data,\n+\t\t\t\t\t     DBG_IDLE_CHK_INFO_REG_WIDE_BUS);\n+\n+\t\t\t/* Write register header */\n+\t\t\toffset += IDLE_CHK_RESULT_REG_HDR_DWORDS;\n+\t\t\thdr->num_dumped_info_regs++;\n+\t\t\tmemset(reg_hdr, 0, sizeof(*reg_hdr));\n+\t\t\treg_hdr->size = reg->size;\n+\t\t\tSET_FIELD(reg_hdr->data,\n+\t\t\t\t  DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID,\n+\t\t\t\t  rule->num_cond_regs + reg_id);\n+\n+\t\t\t/* Write register values */\n+\t\t\toffset += qed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t\t\t  dump,\n+\t\t\t\t\t\t\t  addr,\n+\t\t\t\t\t\t\t  reg->size, wide_bus,\n+\t\t\t\t\t\t\t  SPLIT_TYPE_NONE, 0);\n+\t\t}\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dumps idle check rule entries. Returns the dumped size in dwords. */\n+static u32\n+qed_idle_chk_dump_rule_entries(struct ecore_hwfn *p_hwfn,\n+\t\t\t       struct ecore_ptt *p_ptt,\n+\t\t\t       u32 *dump_buf, bool dump,\n+\t\t\t       const struct dbg_idle_chk_rule *input_rules,\n+\t\t\t       u32 num_input_rules, u32 *num_failing_rules)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu32 cond_reg_values[IDLE_CHK_MAX_ENTRIES_SIZE];\n+\tu32 i, offset = 0;\n+\tu16 entry_id;\n+\tu8 reg_id;\n+\n+\t*num_failing_rules = 0;\n+\n+\tfor (i = 0; i < num_input_rules; i++) {\n+\t\tconst struct dbg_idle_chk_cond_reg *cond_regs;\n+\t\tconst struct dbg_idle_chk_rule *rule;\n+\t\tconst union dbg_idle_chk_reg *regs;\n+\t\tu16 num_reg_entries = 1;\n+\t\tbool check_rule = true;\n+\t\tconst u32 *imm_values;\n+\n+\t\trule = &input_rules[i];\n+\t\tregs = (const union dbg_idle_chk_reg *)\n+\t\t\tp_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr +\n+\t\t\trule->reg_offset;\n+\t\tcond_regs = &regs[0].cond_reg;\n+\t\timm_values =\n+\t\t    (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr +\n+\t\t    rule->imm_offset;\n+\n+\t\t/* Check if all condition register blocks are out of reset, and\n+\t\t * find maximal number of entries (all condition registers that\n+\t\t * are memories must have the same size, which is > 1).\n+\t\t */\n+\t\tfor (reg_id = 0; reg_id < rule->num_cond_regs && check_rule;\n+\t\t     reg_id++) {\n+\t\t\tu32 block_id =\n+\t\t\t\tGET_FIELD(cond_regs[reg_id].data,\n+\t\t\t\t\t  DBG_IDLE_CHK_COND_REG_BLOCK_ID);\n+\n+\t\t\tif (block_id >= MAX_BLOCK_ID) {\n+\t\t\t\tDP_NOTICE(p_hwfn, false, \"Invalid block_id\\n\");\n+\t\t\t\treturn 0;\n+\t\t\t}\n+\n+\t\t\tcheck_rule = !dev_data->block_in_reset[block_id];\n+\t\t\tif (cond_regs[reg_id].num_entries > num_reg_entries)\n+\t\t\t\tnum_reg_entries = cond_regs[reg_id].num_entries;\n+\t\t}\n+\n+\t\tif (!check_rule && dump)\n+\t\t\tcontinue;\n+\n+\t\tif (!dump) {\n+\t\t\tu32 entry_dump_size =\n+\t\t\t\tqed_idle_chk_dump_failure(p_hwfn,\n+\t\t\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t\t\t  false,\n+\t\t\t\t\t\t\t  rule->rule_id,\n+\t\t\t\t\t\t\t  rule,\n+\t\t\t\t\t\t\t  0,\n+\t\t\t\t\t\t\t  NULL);\n+\n+\t\t\toffset += num_reg_entries * entry_dump_size;\n+\t\t\t(*num_failing_rules) += num_reg_entries;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* Go over all register entries (number of entries is the same\n+\t\t * for all condition registers).\n+\t\t */\n+\t\tfor (entry_id = 0; entry_id < num_reg_entries; entry_id++) {\n+\t\t\tu32 next_reg_offset = 0;\n+\n+\t\t\t/* Read current entry of all condition registers */\n+\t\t\tfor (reg_id = 0; reg_id < rule->num_cond_regs;\n+\t\t\t     reg_id++) {\n+\t\t\t\tconst struct dbg_idle_chk_cond_reg *reg =\n+\t\t\t\t\t&cond_regs[reg_id];\n+\t\t\t\tu32 padded_entry_size, addr;\n+\t\t\t\tbool wide_bus;\n+\n+\t\t\t\t/* Find GRC address (if it's a memory, the\n+\t\t\t\t * address of the specific entry is calculated).\n+\t\t\t\t */\n+\t\t\t\taddr = GET_FIELD(reg->data,\n+\t\t\t\t\t\t DBG_IDLE_CHK_COND_REG_ADDRESS);\n+\t\t\t\twide_bus =\n+\t\t\t\t    GET_FIELD(reg->data,\n+\t\t\t\t\t      DBG_IDLE_CHK_COND_REG_WIDE_BUS);\n+\t\t\t\tif (reg->num_entries > 1 ||\n+\t\t\t\t    reg->start_entry > 0) {\n+\t\t\t\t\tpadded_entry_size =\n+\t\t\t\t\t   reg->entry_size > 1 ?\n+\t\t\t\t\t   OSAL_ROUNDUP_POW_OF_TWO(reg->entry_size) :\n+\t\t\t\t\t   1;\n+\t\t\t\t\taddr += (reg->start_entry + entry_id) *\n+\t\t\t\t\t\tpadded_entry_size;\n+\t\t\t\t}\n+\n+\t\t\t\t/* Read registers */\n+\t\t\t\tif (next_reg_offset + reg->entry_size >=\n+\t\t\t\t    IDLE_CHK_MAX_ENTRIES_SIZE) {\n+\t\t\t\t\tDP_NOTICE(p_hwfn, false,\n+\t\t\t\t\t\t  \"idle check registers entry is too large\\n\");\n+\t\t\t\t\treturn 0;\n+\t\t\t\t}\n+\n+\t\t\t\tnext_reg_offset +=\n+\t\t\t\t    qed_grc_dump_addr_range(p_hwfn, p_ptt,\n+\t\t\t\t\t\t\t    cond_reg_values +\n+\t\t\t\t\t\t\t    next_reg_offset,\n+\t\t\t\t\t\t\t    dump, addr,\n+\t\t\t\t\t\t\t    reg->entry_size,\n+\t\t\t\t\t\t\t    wide_bus,\n+\t\t\t\t\t\t\t    SPLIT_TYPE_NONE, 0);\n+\t\t\t}\n+\n+\t\t\t/* Call rule condition function.\n+\t\t\t * If returns true, it's a failure.\n+\t\t\t */\n+\t\t\tif ((*cond_arr[rule->cond_id]) (cond_reg_values,\n+\t\t\t\t\t\t\timm_values)) {\n+\t\t\t\toffset += qed_idle_chk_dump_failure(p_hwfn,\n+\t\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\t\tdump_buf + offset,\n+\t\t\t\t\t\t\tdump,\n+\t\t\t\t\t\t\trule->rule_id,\n+\t\t\t\t\t\t\trule,\n+\t\t\t\t\t\t\tentry_id,\n+\t\t\t\t\t\t\tcond_reg_values);\n+\t\t\t\t(*num_failing_rules)++;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Performs Idle Check Dump to the specified buffer.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_idle_chk_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t     struct ecore_ptt *p_ptt, u32 *dump_buf, bool dump)\n+{\n+\tstruct virt_mem_desc *dbg_buf =\n+\t    &p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES];\n+\tu32 num_failing_rules_offset, offset = 0,\n+\t    input_offset = 0, num_failing_rules = 0;\n+\n+\t/* Dump global params  - 1 must match below amount of params */\n+\toffset += qed_dump_common_global_params(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\tdump_buf + offset, dump, 1);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump, \"dump-type\", \"idle-chk\");\n+\n+\t/* Dump idle check section header with a single parameter */\n+\toffset += qed_dump_section_hdr(dump_buf + offset, dump, \"idle_chk\", 1);\n+\tnum_failing_rules_offset = offset;\n+\toffset += qed_dump_num_param(dump_buf + offset, dump, \"num_rules\", 0);\n+\n+\twhile (input_offset < BYTES_TO_DWORDS(dbg_buf->size)) {\n+\t\tconst struct dbg_idle_chk_cond_hdr *cond_hdr =\n+\t\t    (const struct dbg_idle_chk_cond_hdr *)dbg_buf->ptr +\n+\t\t    input_offset++;\n+\t\tbool eval_mode, mode_match = true;\n+\t\tu32 curr_failing_rules;\n+\t\tu16 modes_buf_offset;\n+\n+\t\t/* Check mode */\n+\t\teval_mode = GET_FIELD(cond_hdr->mode.data,\n+\t\t\t\t      DBG_MODE_HDR_EVAL_MODE) > 0;\n+\t\tif (eval_mode) {\n+\t\t\tmodes_buf_offset =\n+\t\t\t\tGET_FIELD(cond_hdr->mode.data,\n+\t\t\t\t\t  DBG_MODE_HDR_MODES_BUF_OFFSET);\n+\t\t\tmode_match = qed_is_mode_match(p_hwfn,\n+\t\t\t\t\t\t       &modes_buf_offset);\n+\t\t}\n+\n+\t\tif (mode_match) {\n+\t\t\tconst struct dbg_idle_chk_rule *rule =\n+\t\t\t    (const struct dbg_idle_chk_rule *)((u32 *)\n+\t\t\t\t\t\t\t       dbg_buf->ptr\n+\t\t\t\t\t\t\t       + input_offset);\n+\t\t\tu32 num_input_rules =\n+\t\t\t\tcond_hdr->data_size / IDLE_CHK_RULE_SIZE_DWORDS;\n+\t\t\toffset +=\n+\t\t\t    qed_idle_chk_dump_rule_entries(p_hwfn,\n+\t\t\t\t\t\t\t   p_ptt,\n+\t\t\t\t\t\t\t   dump_buf +\n+\t\t\t\t\t\t\t   offset,\n+\t\t\t\t\t\t\t   dump,\n+\t\t\t\t\t\t\t   rule,\n+\t\t\t\t\t\t\t   num_input_rules,\n+\t\t\t\t\t\t\t   &curr_failing_rules);\n+\t\t\tnum_failing_rules += curr_failing_rules;\n+\t\t}\n+\n+\t\tinput_offset += cond_hdr->data_size;\n+\t}\n+\n+\t/* Overwrite num_rules parameter */\n+\tif (dump)\n+\t\tqed_dump_num_param(dump_buf + num_failing_rules_offset,\n+\t\t\t\t   dump, \"num_rules\", num_failing_rules);\n+\n+\t/* Dump last section */\n+\toffset += qed_dump_last_section(dump_buf, offset, dump);\n+\n+\treturn offset;\n+}\n+\n+/* Finds the meta data image in NVRAM */\n+static enum dbg_status qed_find_nvram_image(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t    struct ecore_ptt *p_ptt,\n+\t\t\t\t\t    u32 image_type,\n+\t\t\t\t\t    u32 *nvram_offset_bytes,\n+\t\t\t\t\t    u32 *nvram_size_bytes)\n+{\n+\tu32 ret_mcp_resp, ret_mcp_param, ret_txn_size;\n+\tstruct mcp_file_att file_att;\n+\tint nvm_result;\n+\n+\t/* Call NVRAM get file command */\n+\tnvm_result = ecore_mcp_nvm_rd_cmd(p_hwfn,\n+\t\t\t\t\tp_ptt,\n+\t\t\t\t\tDRV_MSG_CODE_NVM_GET_FILE_ATT,\n+\t\t\t\t\timage_type,\n+\t\t\t\t\t&ret_mcp_resp,\n+\t\t\t\t\t&ret_mcp_param,\n+\t\t\t\t\t&ret_txn_size, (u32 *)&file_att);\n+\n+\t/* Check response */\n+\tif (nvm_result ||\n+\t    (ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)\n+\t\treturn DBG_STATUS_NVRAM_GET_IMAGE_FAILED;\n+\n+\t/* Update return values */\n+\t*nvram_offset_bytes = file_att.nvm_start_addr;\n+\t*nvram_size_bytes = file_att.len;\n+\n+\tDP_VERBOSE(p_hwfn->p_dev,\n+\t\t   ECORE_MSG_DEBUG,\n+\t\t   \"find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\\n\",\n+\t\t   image_type, *nvram_offset_bytes, *nvram_size_bytes);\n+\n+\t/* Check alignment */\n+\tif (*nvram_size_bytes & 0x3)\n+\t\treturn DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Reads data from NVRAM */\n+static enum dbg_status qed_nvram_read(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t      u32 nvram_offset_bytes,\n+\t\t\t\t      u32 nvram_size_bytes, u32 *ret_buf)\n+{\n+\tu32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy;\n+\ts32 bytes_left = nvram_size_bytes;\n+\tu32 read_offset = 0, param = 0;\n+\n+\tDP_NOTICE(p_hwfn->p_dev, false,\n+\t\t   \"nvram_read: reading image of size %d bytes from NVRAM\\n\",\n+\t\t   nvram_size_bytes);\n+\n+\tdo {\n+\t\tbytes_to_copy =\n+\t\t    (bytes_left >\n+\t\t     MCP_DRV_NVM_BUF_LEN) ? MCP_DRV_NVM_BUF_LEN : bytes_left;\n+\n+\t\t/* Call NVRAM read command */\n+\t\tSET_MFW_FIELD(param,\n+\t\t\t      DRV_MB_PARAM_NVM_OFFSET,\n+\t\t\t      nvram_offset_bytes + read_offset);\n+\t\tSET_MFW_FIELD(param, DRV_MB_PARAM_NVM_LEN, bytes_to_copy);\n+\t\tif (ecore_mcp_nvm_rd_cmd(p_hwfn, p_ptt,\n+\t\t\t\t\t DRV_MSG_CODE_NVM_READ_NVRAM, param,\n+\t\t\t\t\t &ret_mcp_resp,\n+\t\t\t\t\t &ret_mcp_param, &ret_read_size,\n+\t\t\t\t\t (u32 *)((u8 *)ret_buf +\n+\t\t\t\t\t\t read_offset))) {\n+\t\t\tDP_NOTICE(p_hwfn->p_dev, false, \"rc = DBG_STATUS_NVRAM_READ_FAILED\\n\");\n+\t\t\treturn DBG_STATUS_NVRAM_READ_FAILED;\n+\t\t}\n+\n+\t\t/* Check response */\n+\t\tif ((ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK) {\n+\t\t\tDP_NOTICE(p_hwfn->p_dev, false, \"rc = DBG_STATUS_NVRAM_READ_FAILED\\n\");\n+\t\t\treturn DBG_STATUS_NVRAM_READ_FAILED;\n+\t\t}\n+\n+\t\t/* Update read offset */\n+\t\tread_offset += ret_read_size;\n+\t\tbytes_left -= ret_read_size;\n+\t} while (bytes_left > 0);\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Get info on the MCP Trace data in the scratchpad:\n+ * - trace_data_grc_addr (OUT): trace data GRC address in bytes\n+ * - trace_data_size (OUT): trace data size in bytes (without the header)\n+ */\n+static enum dbg_status qed_mcp_trace_get_data_info(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t   struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t   u32 *trace_data_grc_addr,\n+\t\t\t\t\t\t   u32 *trace_data_size)\n+{\n+\tu32 spad_trace_offsize, signature;\n+\n+\t/* Read trace section offsize structure from MCP scratchpad */\n+\tspad_trace_offsize = ecore_rd(p_hwfn, p_ptt,\n+\t\t\t\t      MCP_SPAD_TRACE_OFFSIZE_ADDR);\n+\n+\t/* Extract trace section address from offsize (in scratchpad) */\n+\t*trace_data_grc_addr =\n+\t\tMCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize);\n+\n+\t/* Read signature from MCP trace section */\n+\tsignature = ecore_rd(p_hwfn, p_ptt,\n+\t\t\t   *trace_data_grc_addr +\n+\t\t\t   offsetof(struct mcp_trace, signature));\n+\n+\tif (signature != MFW_TRACE_SIGNATURE)\n+\t\treturn DBG_STATUS_INVALID_TRACE_SIGNATURE;\n+\n+\t/* Read trace size from MCP trace section */\n+\t*trace_data_size = ecore_rd(p_hwfn,\n+\t\t\t\t  p_ptt,\n+\t\t\t\t  *trace_data_grc_addr +\n+\t\t\t\t  offsetof(struct mcp_trace, size));\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Reads MCP trace meta data image from NVRAM\n+ * - running_bundle_id (OUT): running bundle ID (invalid when loaded from file)\n+ * - trace_meta_offset (OUT): trace meta offset in NVRAM in bytes (invalid when\n+ *\t\t\t      loaded from file).\n+ * - trace_meta_size (OUT):   size in bytes of the trace meta data.\n+ */\n+static enum dbg_status qed_mcp_trace_get_meta_info(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t   struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t   u32 trace_data_size_bytes,\n+\t\t\t\t\t\t   u32 *running_bundle_id,\n+\t\t\t\t\t\t   u32 *trace_meta_offset,\n+\t\t\t\t\t\t   u32 *trace_meta_size)\n+{\n+\tu32 spad_trace_offsize, nvram_image_type, running_mfw_addr;\n+\n+\t/* Read MCP trace section offsize structure from MCP scratchpad */\n+\tspad_trace_offsize = ecore_rd(p_hwfn, p_ptt,\n+\t\t\t\t      MCP_SPAD_TRACE_OFFSIZE_ADDR);\n+\n+\t/* Find running bundle ID */\n+\trunning_mfw_addr =\n+\t\tMCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize) +\n+\t\tSECTION_SIZE(spad_trace_offsize) + trace_data_size_bytes;\n+\t*running_bundle_id = ecore_rd(p_hwfn, p_ptt, running_mfw_addr);\n+\tif (*running_bundle_id > 1)\n+\t\treturn DBG_STATUS_INVALID_NVRAM_BUNDLE;\n+\n+\t/* Find image in NVRAM */\n+\tnvram_image_type =\n+\t    (*running_bundle_id ==\n+\t     DIR_ID_1) ? NVM_TYPE_MFW_TRACE1 : NVM_TYPE_MFW_TRACE2;\n+\treturn qed_find_nvram_image(p_hwfn,\n+\t\t\t\t    p_ptt,\n+\t\t\t\t    nvram_image_type,\n+\t\t\t\t    trace_meta_offset, trace_meta_size);\n+}\n+\n+/* Reads the MCP Trace meta data from NVRAM into the specified buffer */\n+static enum dbg_status qed_mcp_trace_read_meta(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t       struct ecore_ptt *p_ptt,\n+\t\t\t\t\t       u32 nvram_offset_in_bytes,\n+\t\t\t\t\t       u32 size_in_bytes, u32 *buf)\n+{\n+\tu8 modules_num, module_len, i, *byte_buf = (u8 *)buf;\n+\tenum dbg_status status;\n+\tu32 signature;\n+\n+\t/* Read meta data from NVRAM */\n+\tstatus = qed_nvram_read(p_hwfn,\n+\t\t\t\tp_ptt,\n+\t\t\t\tnvram_offset_in_bytes, size_in_bytes, buf);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\t/* Extract and check first signature */\n+\tsignature = qed_read_unaligned_dword(byte_buf);\n+\tbyte_buf += sizeof(signature);\n+\tif (signature != NVM_MAGIC_VALUE)\n+\t\treturn DBG_STATUS_INVALID_TRACE_SIGNATURE;\n+\n+\t/* Extract number of modules */\n+\tmodules_num = *(byte_buf++);\n+\n+\t/* Skip all modules */\n+\tfor (i = 0; i < modules_num; i++) {\n+\t\tmodule_len = *(byte_buf++);\n+\t\tbyte_buf += module_len;\n+\t}\n+\n+\t/* Extract and check second signature */\n+\tsignature = qed_read_unaligned_dword(byte_buf);\n+\tbyte_buf += sizeof(signature);\n+\tif (signature != NVM_MAGIC_VALUE)\n+\t\treturn DBG_STATUS_INVALID_TRACE_SIGNATURE;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Dump MCP Trace */\n+static enum dbg_status qed_mcp_trace_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t  struct ecore_ptt *p_ptt,\n+\t\t\t\t\t  u32 *dump_buf,\n+\t\t\t\t\t  bool dump, u32 *num_dumped_dwords)\n+{\n+\tu32 trace_data_grc_addr, trace_data_size_bytes, trace_data_size_dwords;\n+\tu32 trace_meta_size_dwords = 0, running_bundle_id, offset = 0;\n+\tu32 trace_meta_offset_bytes = 0, trace_meta_size_bytes = 0;\n+\tenum dbg_status status;\n+\tint halted = 0;\n+\tbool use_mfw;\n+\n+\t*num_dumped_dwords = 0;\n+\n+\tuse_mfw = !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP);\n+\n+\t/* Get trace data info */\n+\tstatus = qed_mcp_trace_get_data_info(p_hwfn,\n+\t\t\t\t\t     p_ptt,\n+\t\t\t\t\t     &trace_data_grc_addr,\n+\t\t\t\t\t     &trace_data_size_bytes);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\t/* Dump global params */\n+\toffset += qed_dump_common_global_params(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\tdump_buf + offset, dump, 1);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump, \"dump-type\", \"mcp-trace\");\n+\n+\t/* Halt MCP while reading from scratchpad so the read data will be\n+\t * consistent. if halt fails, MCP trace is taken anyway, with a small\n+\t * risk that it may be corrupt.\n+\t */\n+\tif (dump && use_mfw) {\n+\t\thalted = !ecore_mcp_halt(p_hwfn, p_ptt);\n+\t\tif (!halted)\n+\t\t\tDP_NOTICE(p_hwfn, false, \"MCP halt failed!\\n\");\n+\t}\n+\n+\t/* Find trace data size */\n+\ttrace_data_size_dwords =\n+\t    DIV_ROUND_UP(trace_data_size_bytes + sizeof(struct mcp_trace),\n+\t\t\t BYTES_IN_DWORD);\n+\n+\t/* Dump trace data section header and param */\n+\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t       dump, \"mcp_trace_data\", 1);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump, \"size\", trace_data_size_dwords);\n+\n+\t/* Read trace data from scratchpad into dump buffer */\n+\toffset += qed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t  dump,\n+\t\t\t\t\t  BYTES_TO_DWORDS(trace_data_grc_addr),\n+\t\t\t\t\t  trace_data_size_dwords, false,\n+\t\t\t\t\t  SPLIT_TYPE_NONE, 0);\n+\n+\t/* Resume MCP (only if halt succeeded) */\n+\tif (halted && ecore_mcp_resume(p_hwfn, p_ptt))\n+\t\tDP_NOTICE(p_hwfn, false, \"Failed to resume MCP after halt!\\n\");\n+\n+\t/* Dump trace meta section header */\n+\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t       dump, \"mcp_trace_meta\", 1);\n+\n+\t/* If MCP Trace meta size parameter was set, use it.\n+\t * Otherwise, read trace meta.\n+\t * trace_meta_size_bytes is dword-aligned.\n+\t */\n+\ttrace_meta_size_bytes =\n+\t\tqed_grc_get_param(p_hwfn, DBG_GRC_PARAM_MCP_TRACE_META_SIZE);\n+\tif ((!trace_meta_size_bytes || dump) && use_mfw)\n+\t\tstatus = qed_mcp_trace_get_meta_info(p_hwfn,\n+\t\t\t\t\t\t     p_ptt,\n+\t\t\t\t\t\t     trace_data_size_bytes,\n+\t\t\t\t\t\t     &running_bundle_id,\n+\t\t\t\t\t\t     &trace_meta_offset_bytes,\n+\t\t\t\t\t\t     &trace_meta_size_bytes);\n+\tif (status == DBG_STATUS_OK)\n+\t\ttrace_meta_size_dwords = BYTES_TO_DWORDS(trace_meta_size_bytes);\n+\n+\t/* Dump trace meta size param */\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump, \"size\", trace_meta_size_dwords);\n+\n+\t/* Read trace meta image into dump buffer */\n+\tif (dump && trace_meta_size_dwords)\n+\t\tstatus = qed_mcp_trace_read_meta(p_hwfn,\n+\t\t\t\t\t\t p_ptt,\n+\t\t\t\t\t\t trace_meta_offset_bytes,\n+\t\t\t\t\t\t trace_meta_size_bytes,\n+\t\t\t\t\t\t dump_buf + offset);\n+\tif (status == DBG_STATUS_OK)\n+\t\toffset += trace_meta_size_dwords;\n+\n+\t/* Dump last section */\n+\toffset += qed_dump_last_section(dump_buf, offset, dump);\n+\n+\t*num_dumped_dwords = offset;\n+\n+\t/* If no mcp access, indicate that the dump doesn't contain the meta\n+\t * data from NVRAM.\n+\t */\n+\treturn use_mfw ? status : DBG_STATUS_NVRAM_GET_IMAGE_FAILED;\n+}\n+\n+/* Dump GRC FIFO */\n+static enum dbg_status qed_reg_fifo_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t struct ecore_ptt *p_ptt,\n+\t\t\t\t\t u32 *dump_buf,\n+\t\t\t\t\t bool dump, u32 *num_dumped_dwords)\n+{\n+\tu32 dwords_read, size_param_offset, offset = 0, addr, len;\n+\tbool fifo_has_data;\n+\n+\t*num_dumped_dwords = 0;\n+\n+\t/* Dump global params */\n+\toffset += qed_dump_common_global_params(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\tdump_buf + offset, dump, 1);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump, \"dump-type\", \"reg-fifo\");\n+\n+\t/* Dump fifo data section header and param. The size param is 0 for\n+\t * now, and is overwritten after reading the FIFO.\n+\t */\n+\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t       dump, \"reg_fifo_data\", 1);\n+\tsize_param_offset = offset;\n+\toffset += qed_dump_num_param(dump_buf + offset, dump, \"size\", 0);\n+\n+\tif (!dump) {\n+\t\t/* FIFO max size is REG_FIFO_DEPTH_DWORDS. There is no way to\n+\t\t * test how much data is available, except for reading it.\n+\t\t */\n+\t\toffset += REG_FIFO_DEPTH_DWORDS;\n+\t\tgoto out;\n+\t}\n+\n+\tfifo_has_data = ecore_rd(p_hwfn, p_ptt,\n+\t\t\t       GRC_REG_TRACE_FIFO_VALID_DATA) > 0;\n+\n+\t/* Pull available data from fifo. Use DMAE since this is widebus memory\n+\t * and must be accessed atomically. Test for dwords_read not passing\n+\t * buffer size since more entries could be added to the buffer as we are\n+\t * emptying it.\n+\t */\n+\taddr = BYTES_TO_DWORDS(GRC_REG_TRACE_FIFO);\n+\tlen = REG_FIFO_ELEMENT_DWORDS;\n+\tfor (dwords_read = 0;\n+\t     fifo_has_data && dwords_read < REG_FIFO_DEPTH_DWORDS;\n+\t     dwords_read += REG_FIFO_ELEMENT_DWORDS) {\n+\t\toffset += qed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t\t  true,\n+\t\t\t\t\t\t  addr,\n+\t\t\t\t\t\t  len,\n+\t\t\t\t\t\t  true, SPLIT_TYPE_NONE,\n+\t\t\t\t\t\t  0);\n+\t\tfifo_has_data = ecore_rd(p_hwfn, p_ptt,\n+\t\t\t\t       GRC_REG_TRACE_FIFO_VALID_DATA) > 0;\n+\t}\n+\n+\tqed_dump_num_param(dump_buf + size_param_offset, dump, \"size\",\n+\t\t\t   dwords_read);\n+out:\n+\t/* Dump last section */\n+\toffset += qed_dump_last_section(dump_buf, offset, dump);\n+\n+\t*num_dumped_dwords = offset;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Dump IGU FIFO */\n+static enum dbg_status qed_igu_fifo_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t struct ecore_ptt *p_ptt,\n+\t\t\t\t\t u32 *dump_buf,\n+\t\t\t\t\t bool dump, u32 *num_dumped_dwords)\n+{\n+\tu32 dwords_read, size_param_offset, offset = 0, addr, len;\n+\tbool fifo_has_data;\n+\n+\t*num_dumped_dwords = 0;\n+\n+\t/* Dump global params */\n+\toffset += qed_dump_common_global_params(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\tdump_buf + offset, dump, 1);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump, \"dump-type\", \"igu-fifo\");\n+\n+\t/* Dump fifo data section header and param. The size param is 0 for\n+\t * now, and is overwritten after reading the FIFO.\n+\t */\n+\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t       dump, \"igu_fifo_data\", 1);\n+\tsize_param_offset = offset;\n+\toffset += qed_dump_num_param(dump_buf + offset, dump, \"size\", 0);\n+\n+\tif (!dump) {\n+\t\t/* FIFO max size is IGU_FIFO_DEPTH_DWORDS. There is no way to\n+\t\t * test how much data is available, except for reading it.\n+\t\t */\n+\t\toffset += IGU_FIFO_DEPTH_DWORDS;\n+\t\tgoto out;\n+\t}\n+\n+\tfifo_has_data = ecore_rd(p_hwfn, p_ptt,\n+\t\t\t       IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;\n+\n+\t/* Pull available data from fifo. Use DMAE since this is widebus memory\n+\t * and must be accessed atomically. Test for dwords_read not passing\n+\t * buffer size since more entries could be added to the buffer as we are\n+\t * emptying it.\n+\t */\n+\taddr = BYTES_TO_DWORDS(IGU_REG_ERROR_HANDLING_MEMORY);\n+\tlen = IGU_FIFO_ELEMENT_DWORDS;\n+\tfor (dwords_read = 0;\n+\t     fifo_has_data && dwords_read < IGU_FIFO_DEPTH_DWORDS;\n+\t     dwords_read += IGU_FIFO_ELEMENT_DWORDS) {\n+\t\toffset += qed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t\t  true,\n+\t\t\t\t\t\t  addr,\n+\t\t\t\t\t\t  len,\n+\t\t\t\t\t\t  true, SPLIT_TYPE_NONE,\n+\t\t\t\t\t\t  0);\n+\t\tfifo_has_data = ecore_rd(p_hwfn, p_ptt,\n+\t\t\t\t       IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;\n+\t}\n+\n+\tqed_dump_num_param(dump_buf + size_param_offset, dump, \"size\",\n+\t\t\t   dwords_read);\n+out:\n+\t/* Dump last section */\n+\toffset += qed_dump_last_section(dump_buf, offset, dump);\n+\n+\t*num_dumped_dwords = offset;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Protection Override dump */\n+static enum dbg_status qed_protection_override_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t    struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t    u32 *dump_buf,\n+\t\t\t\t\t\t    bool dump,\n+\t\t\t\t\t\t    u32 *num_dumped_dwords)\n+{\n+\tu32 size_param_offset, override_window_dwords, offset = 0, addr;\n+\n+\t*num_dumped_dwords = 0;\n+\n+\t/* Dump global params */\n+\toffset += qed_dump_common_global_params(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\tdump_buf + offset, dump, 1);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump, \"dump-type\", \"protection-override\");\n+\n+\t/* Dump data section header and param. The size param is 0 for now,\n+\t * and is overwritten after reading the data.\n+\t */\n+\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t       dump, \"protection_override_data\", 1);\n+\tsize_param_offset = offset;\n+\toffset += qed_dump_num_param(dump_buf + offset, dump, \"size\", 0);\n+\n+\tif (!dump) {\n+\t\toffset += PROTECTION_OVERRIDE_DEPTH_DWORDS;\n+\t\tgoto out;\n+\t}\n+\n+\t/* Add override window info to buffer */\n+\toverride_window_dwords =\n+\t\tecore_rd(p_hwfn, p_ptt, GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW) *\n+\t\tPROTECTION_OVERRIDE_ELEMENT_DWORDS;\n+\tif (override_window_dwords) {\n+\t\taddr = BYTES_TO_DWORDS(GRC_REG_PROTECTION_OVERRIDE_WINDOW);\n+\t\toffset += qed_grc_dump_addr_range(p_hwfn,\n+\t\t\t\t\t\t  p_ptt,\n+\t\t\t\t\t\t  dump_buf + offset,\n+\t\t\t\t\t\t  true,\n+\t\t\t\t\t\t  addr,\n+\t\t\t\t\t\t  override_window_dwords,\n+\t\t\t\t\t\t  true, SPLIT_TYPE_NONE, 0);\n+\t\tqed_dump_num_param(dump_buf + size_param_offset, dump, \"size\",\n+\t\t\t\t   override_window_dwords);\n+\t}\n+out:\n+\t/* Dump last section */\n+\toffset += qed_dump_last_section(dump_buf, offset, dump);\n+\n+\t*num_dumped_dwords = offset;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Performs FW Asserts Dump to the specified buffer.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_fw_asserts_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t       struct ecore_ptt *p_ptt, u32 *dump_buf,\n+\t\t\t       bool dump)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tstruct fw_asserts_ram_section *asserts;\n+\tchar storm_letter_str[2] = \"?\";\n+\tstruct fw_info fw_info;\n+\tu32 offset = 0;\n+\tu8 storm_id;\n+\n+\t/* Dump global params */\n+\toffset += qed_dump_common_global_params(p_hwfn,\n+\t\t\t\t\t\tp_ptt,\n+\t\t\t\t\t\tdump_buf + offset, dump, 1);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump, \"dump-type\", \"fw-asserts\");\n+\n+\t/* Find Storm dump size */\n+\tfor (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {\n+\t\tu32 fw_asserts_section_addr, next_list_idx_addr, next_list_idx;\n+\t\tstruct storm_defs *storm = &s_storm_defs[storm_id];\n+\t\tu32 last_list_idx, addr;\n+\n+\t\tif (dev_data->block_in_reset[storm->sem_block_id])\n+\t\t\tcontinue;\n+\n+\t\t/* Read FW info for the current Storm */\n+\t\tqed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, &fw_info);\n+\n+\t\tasserts = &fw_info.fw_asserts_section;\n+\n+\t\t/* Dump FW Asserts section header and params */\n+\t\tstorm_letter_str[0] = storm->letter;\n+\t\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t\t       dump, \"fw_asserts\", 2);\n+\t\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t\t     dump, \"storm\", storm_letter_str);\n+\t\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t\t     dump,\n+\t\t\t\t\t     \"size\",\n+\t\t\t\t\t     asserts->list_element_dword_size);\n+\n+\t\t/* Read and dump FW Asserts data */\n+\t\tif (!dump) {\n+\t\t\toffset += asserts->list_element_dword_size;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tfw_asserts_section_addr = storm->sem_fast_mem_addr +\n+\t\t\tSEM_FAST_REG_INT_RAM +\n+\t\t\tRAM_LINES_TO_BYTES(asserts->section_ram_line_offset);\n+\t\tnext_list_idx_addr = fw_asserts_section_addr +\n+\t\t\tDWORDS_TO_BYTES(asserts->list_next_index_dword_offset);\n+\t\tnext_list_idx = ecore_rd(p_hwfn, p_ptt, next_list_idx_addr);\n+\t\tlast_list_idx = (next_list_idx > 0 ?\n+\t\t\t\t next_list_idx :\n+\t\t\t\t asserts->list_num_elements) - 1;\n+\t\taddr = BYTES_TO_DWORDS(fw_asserts_section_addr) +\n+\t\t       asserts->list_dword_offset +\n+\t\t       last_list_idx * asserts->list_element_dword_size;\n+\t\toffset +=\n+\t\t    qed_grc_dump_addr_range(p_hwfn, p_ptt,\n+\t\t\t\t\t    dump_buf + offset,\n+\t\t\t\t\t    dump, addr,\n+\t\t\t\t\t    asserts->list_element_dword_size,\n+\t\t\t\t\t\t  false, SPLIT_TYPE_NONE, 0);\n+\t}\n+\n+\t/* Dump last section */\n+\toffset += qed_dump_last_section(dump_buf, offset, dump);\n+\n+\treturn offset;\n+}\n+\n+/* Dumps the specified ILT pages to the specified buffer.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_ilt_dump_pages_range(u32 *dump_buf,\n+\t\t\t\t    bool dump,\n+\t\t\t\t    u32 start_page_id,\n+\t\t\t\t    u32 num_pages,\n+\t\t\t\t    struct phys_mem_desc *ilt_pages,\n+\t\t\t\t    bool dump_page_ids)\n+{\n+\tu32 page_id, end_page_id, offset = 0;\n+\n+\tif (num_pages == 0)\n+\t\treturn offset;\n+\n+\tend_page_id = start_page_id + num_pages - 1;\n+\n+\tfor (page_id = start_page_id; page_id <= end_page_id; page_id++) {\n+\t\tstruct phys_mem_desc *mem_desc = &ilt_pages[page_id];\n+\n+\t\t/**\n+\t\t *\n+\t\t * if (page_id >= ->p_cxt_mngr->ilt_shadow_size)\n+\t\t *     break;\n+\t\t */\n+\n+\t\tif (!ilt_pages[page_id].virt_addr)\n+\t\t\tcontinue;\n+\n+\t\tif (dump_page_ids) {\n+\t\t\t/* Copy page ID to dump buffer */\n+\t\t\tif (dump)\n+\t\t\t\t*(dump_buf + offset) = page_id;\n+\t\t\toffset++;\n+\t\t} else {\n+\t\t\t/* Copy page memory to dump buffer */\n+\t\t\tif (dump)\n+\t\t\t\tmemcpy(dump_buf + offset,\n+\t\t\t\t       mem_desc->virt_addr, mem_desc->size);\n+\t\t\toffset += BYTES_TO_DWORDS(mem_desc->size);\n+\t\t}\n+\t}\n+\n+\treturn offset;\n+}\n+\n+/* Dumps a section containing the dumped ILT pages.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_ilt_dump_pages_section(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      u32 *dump_buf,\n+\t\t\t\t      bool dump,\n+\t\t\t\t      u32 valid_conn_pf_pages,\n+\t\t\t\t      u32 valid_conn_vf_pages,\n+\t\t\t\t      struct phys_mem_desc *ilt_pages,\n+\t\t\t\t      bool dump_page_ids)\n+{\n+\tstruct ecore_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;\n+\tu32 pf_start_line, start_page_id, offset = 0;\n+\tu32 cdut_pf_init_pages, cdut_vf_init_pages;\n+\tu32 cdut_pf_work_pages, cdut_vf_work_pages;\n+\tu32 base_data_offset, size_param_offset;\n+\tu32 cdut_pf_pages, cdut_vf_pages;\n+\tconst char *section_name;\n+\tu8 i;\n+\n+\tsection_name = dump_page_ids ? \"ilt_page_ids\" : \"ilt_page_mem\";\n+\tcdut_pf_init_pages = ecore_get_cdut_num_pf_init_pages(p_hwfn);\n+\tcdut_vf_init_pages = ecore_get_cdut_num_vf_init_pages(p_hwfn);\n+\tcdut_pf_work_pages = ecore_get_cdut_num_pf_work_pages(p_hwfn);\n+\tcdut_vf_work_pages = ecore_get_cdut_num_vf_work_pages(p_hwfn);\n+\tcdut_pf_pages = cdut_pf_init_pages + cdut_pf_work_pages;\n+\tcdut_vf_pages = cdut_vf_init_pages + cdut_vf_work_pages;\n+\tpf_start_line = p_hwfn->p_cxt_mngr->pf_start_line;\n+\n+\toffset +=\n+\t    qed_dump_section_hdr(dump_buf + offset, dump, section_name, 1);\n+\n+\t/* Dump size parameter (0 for now, overwritten with real size later) */\n+\tsize_param_offset = offset;\n+\toffset += qed_dump_num_param(dump_buf + offset, dump, \"size\", 0);\n+\tbase_data_offset = offset;\n+\n+\t/* CDUC pages are ordered as follows:\n+\t * - PF pages - valid section (included in PF connection type mapping)\n+\t * - PF pages - invalid section (not dumped)\n+\t * - For each VF in the PF:\n+\t *   - VF pages - valid section (included in VF connection type mapping)\n+\t *   - VF pages - invalid section (not dumped)\n+\t */\n+\tif (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUC)) {\n+\t\t/* Dump connection PF pages */\n+\t\tstart_page_id = clients[ILT_CLI_CDUC].first.val - pf_start_line;\n+\t\toffset += qed_ilt_dump_pages_range(dump_buf + offset,\n+\t\t\t\t\t\t   dump,\n+\t\t\t\t\t\t   start_page_id,\n+\t\t\t\t\t\t   valid_conn_pf_pages,\n+\t\t\t\t\t\t   ilt_pages, dump_page_ids);\n+\n+\t\t/* Dump connection VF pages */\n+\t\tstart_page_id += clients[ILT_CLI_CDUC].pf_total_lines;\n+\t\tfor (i = 0; i < p_hwfn->p_cxt_mngr->vf_count;\n+\t\t     i++, start_page_id += clients[ILT_CLI_CDUC].vf_total_lines)\n+\t\t\toffset += qed_ilt_dump_pages_range(dump_buf + offset,\n+\t\t\t\t\t\t\t   dump,\n+\t\t\t\t\t\t\t   start_page_id,\n+\t\t\t\t\t\t\t   valid_conn_vf_pages,\n+\t\t\t\t\t\t\t   ilt_pages,\n+\t\t\t\t\t\t\t   dump_page_ids);\n+\t}\n+\n+\t/* CDUT pages are ordered as follows:\n+\t * - PF init pages (not dumped)\n+\t * - PF work pages\n+\t * - For each VF in the PF:\n+\t *   - VF init pages (not dumped)\n+\t *   - VF work pages\n+\t */\n+\tif (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUT)) {\n+\t\t/* Dump task PF pages */\n+\t\tstart_page_id = clients[ILT_CLI_CDUT].first.val +\n+\t\t    cdut_pf_init_pages - pf_start_line;\n+\t\toffset += qed_ilt_dump_pages_range(dump_buf + offset,\n+\t\t\t\t\t\t   dump,\n+\t\t\t\t\t\t   start_page_id,\n+\t\t\t\t\t\t   cdut_pf_work_pages,\n+\t\t\t\t\t\t   ilt_pages, dump_page_ids);\n+\n+\t\t/* Dump task VF pages */\n+\t\tstart_page_id = clients[ILT_CLI_CDUT].first.val +\n+\t\t    cdut_pf_pages + cdut_vf_init_pages - pf_start_line;\n+\t\tfor (i = 0; i < p_hwfn->p_cxt_mngr->vf_count;\n+\t\t     i++, start_page_id += cdut_vf_pages)\n+\t\t\toffset += qed_ilt_dump_pages_range(dump_buf + offset,\n+\t\t\t\t\t\t\t   dump,\n+\t\t\t\t\t\t\t   start_page_id,\n+\t\t\t\t\t\t\t   cdut_vf_work_pages,\n+\t\t\t\t\t\t\t   ilt_pages,\n+\t\t\t\t\t\t\t   dump_page_ids);\n+\t}\n+\n+\t/* Overwrite size param */\n+\tif (dump)\n+\t\tqed_dump_num_param(dump_buf + size_param_offset,\n+\t\t\t\t   dump, \"size\", offset - base_data_offset);\n+\n+\treturn offset;\n+}\n+\n+/* Performs ILT Dump to the specified buffer.\n+ * Returns the dumped size in dwords.\n+ */\n+static u32 qed_ilt_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\tstruct ecore_ptt *p_ptt, u32 *dump_buf, bool dump)\n+{\n+\tstruct ecore_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;\n+\tu32 valid_conn_vf_cids, valid_conn_vf_pages, offset = 0;\n+\tu32 valid_conn_pf_cids, valid_conn_pf_pages, num_pages;\n+\tu32 num_cids_per_page, conn_ctx_size;\n+\tu32 cduc_page_size, cdut_page_size;\n+\tstruct phys_mem_desc *ilt_pages;\n+\tu8 conn_type;\n+\n+\tcduc_page_size = 1 <<\n+\t    (clients[ILT_CLI_CDUC].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN);\n+\tcdut_page_size = 1 <<\n+\t    (clients[ILT_CLI_CDUT].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN);\n+\tconn_ctx_size = p_hwfn->p_cxt_mngr->conn_ctx_size;\n+\tnum_cids_per_page = (int)(cduc_page_size / conn_ctx_size);\n+\tilt_pages = p_hwfn->p_cxt_mngr->ilt_shadow;\n+\n+\t/* Dump global params - 22 must match number of params below */\n+\toffset += qed_dump_common_global_params(p_hwfn, p_ptt,\n+\t\t\t\t\t\tdump_buf + offset, dump, 22);\n+\toffset += qed_dump_str_param(dump_buf + offset,\n+\t\t\t\t     dump, \"dump-type\", \"ilt-dump\");\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"cduc-page-size\", cduc_page_size);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"cduc-first-page-id\",\n+\t\t\t\t     clients[ILT_CLI_CDUC].first.val);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"cduc-last-page-id\",\n+\t\t\t\t     clients[ILT_CLI_CDUC].last.val);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"cduc-num-pf-pages\",\n+\t\t\t\t     clients\n+\t\t\t\t     [ILT_CLI_CDUC].pf_total_lines);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"cduc-num-vf-pages\",\n+\t\t\t\t     clients\n+\t\t\t\t     [ILT_CLI_CDUC].vf_total_lines);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"max-conn-ctx-size\",\n+\t\t\t\t     conn_ctx_size);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"cdut-page-size\", cdut_page_size);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"cdut-first-page-id\",\n+\t\t\t\t     clients[ILT_CLI_CDUT].first.val);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"cdut-last-page-id\",\n+\t\t\t\t     clients[ILT_CLI_CDUT].last.val);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"cdut-num-pf-init-pages\",\n+\t\t\t\t     ecore_get_cdut_num_pf_init_pages(p_hwfn));\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"cdut-num-vf-init-pages\",\n+\t\t\t\t     ecore_get_cdut_num_vf_init_pages(p_hwfn));\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"cdut-num-pf-work-pages\",\n+\t\t\t\t     ecore_get_cdut_num_pf_work_pages(p_hwfn));\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"cdut-num-vf-work-pages\",\n+\t\t\t\t     ecore_get_cdut_num_vf_work_pages(p_hwfn));\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"max-task-ctx-size\",\n+\t\t\t\t     p_hwfn->p_cxt_mngr->task_ctx_size);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"task-type-id\",\n+\t\t\t\t     p_hwfn->p_cxt_mngr->task_type_id);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"first-vf-id-in-pf\",\n+\t\t\t\t     p_hwfn->p_cxt_mngr->first_vf_in_pf);\n+\toffset += /* 18 */ qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t\t      dump,\n+\t\t\t\t\t      \"num-vfs-in-pf\",\n+\t\t\t\t\t      p_hwfn->p_cxt_mngr->vf_count);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"ptr-size-bytes\", sizeof(void *));\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"pf-start-line\",\n+\t\t\t\t     p_hwfn->p_cxt_mngr->pf_start_line);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"page-mem-desc-size-dwords\",\n+\t\t\t\t     PAGE_MEM_DESC_SIZE_DWORDS);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"ilt-shadow-size\",\n+\t\t\t\t     p_hwfn->p_cxt_mngr->ilt_shadow_size);\n+\t/* Additional/Less parameters require matching of number in call to\n+\t * dump_common_global_params()\n+\t */\n+\n+\t/* Dump section containing number of PF CIDs per connection type */\n+\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t       dump, \"num_pf_cids_per_conn_type\", 1);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump, \"size\", NUM_OF_CONNECTION_TYPES);\n+\tfor (conn_type = 0, valid_conn_pf_cids = 0;\n+\t     conn_type < NUM_OF_CONNECTION_TYPES; conn_type++, offset++) {\n+\t\tu32 num_pf_cids =\n+\t\t    p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cid_count;\n+\n+\t\tif (dump)\n+\t\t\t*(dump_buf + offset) = num_pf_cids;\n+\t\tvalid_conn_pf_cids += num_pf_cids;\n+\t}\n+\n+\t/* Dump section containing number of VF CIDs per connection type */\n+\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t       dump, \"num_vf_cids_per_conn_type\", 1);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump, \"size\", NUM_OF_CONNECTION_TYPES);\n+\tfor (conn_type = 0, valid_conn_vf_cids = 0;\n+\t     conn_type < NUM_OF_CONNECTION_TYPES; conn_type++, offset++) {\n+\t\tu32 num_vf_cids =\n+\t\t    p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cids_per_vf;\n+\n+\t\tif (dump)\n+\t\t\t*(dump_buf + offset) = num_vf_cids;\n+\t\tvalid_conn_vf_cids += num_vf_cids;\n+\t}\n+\n+\t/* Dump section containing physical memory descs for each ILT page */\n+\tnum_pages = p_hwfn->p_cxt_mngr->ilt_shadow_size;\n+\toffset += qed_dump_section_hdr(dump_buf + offset,\n+\t\t\t\t       dump, \"ilt_page_desc\", 1);\n+\toffset += qed_dump_num_param(dump_buf + offset,\n+\t\t\t\t     dump,\n+\t\t\t\t     \"size\",\n+\t\t\t\t     num_pages * PAGE_MEM_DESC_SIZE_DWORDS);\n+\n+\t/* Copy memory descriptors to dump buffer */\n+\tif (dump) {\n+\t\tu32 page_id;\n+\n+\t\tfor (page_id = 0; page_id < num_pages;\n+\t\t     page_id++, offset += PAGE_MEM_DESC_SIZE_DWORDS)\n+\t\t\tmemcpy(dump_buf + offset,\n+\t\t\t       &ilt_pages[page_id],\n+\t\t\t       DWORDS_TO_BYTES(PAGE_MEM_DESC_SIZE_DWORDS));\n+\t} else {\n+\t\toffset += num_pages * PAGE_MEM_DESC_SIZE_DWORDS;\n+\t}\n+\n+\tvalid_conn_pf_pages = DIV_ROUND_UP(valid_conn_pf_cids,\n+\t\t\t\t\t   num_cids_per_page);\n+\tvalid_conn_vf_pages = DIV_ROUND_UP(valid_conn_vf_cids,\n+\t\t\t\t\t   num_cids_per_page);\n+\n+\t/* Dump ILT pages IDs */\n+\toffset += qed_ilt_dump_pages_section(p_hwfn,\n+\t\t\t\t\t     dump_buf + offset,\n+\t\t\t\t\t     dump,\n+\t\t\t\t\t     valid_conn_pf_pages,\n+\t\t\t\t\t     valid_conn_vf_pages,\n+\t\t\t\t\t     ilt_pages, true);\n+\n+\t/* Dump ILT pages memory */\n+\toffset += qed_ilt_dump_pages_section(p_hwfn,\n+\t\t\t\t\t     dump_buf + offset,\n+\t\t\t\t\t     dump,\n+\t\t\t\t\t     valid_conn_pf_pages,\n+\t\t\t\t\t     valid_conn_vf_pages,\n+\t\t\t\t\t     ilt_pages, false);\n+\n+\t/* Dump last section */\n+\toffset += qed_dump_last_section(dump_buf, offset, dump);\n+\n+\treturn offset;\n+}\n+\n+/***************************** Public Functions *******************************/\n+\n+enum dbg_status qed_dbg_set_bin_ptr(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t    const u8 * const bin_ptr)\n+{\n+\tstruct bin_buffer_hdr *buf_hdrs =\n+\t\t\t(struct bin_buffer_hdr *)(osal_uintptr_t)bin_ptr;\n+\tu8 buf_id;\n+\n+\t/* Convert binary data to debug arrays */\n+\tfor (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++)\n+\t\tqed_set_dbg_bin_buf(p_hwfn,\n+\t\t\t\t    buf_id,\n+\t\t\t\t    (const u32 *)(bin_ptr +\n+\t\t\t\t\t\t  buf_hdrs[buf_id].offset),\n+\t\t\t\t\t\t  buf_hdrs[buf_id].length);\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+enum dbg_status qed_dbg_set_app_ver(u32 ver)\n+{\n+\tif (ver < TOOLS_VERSION)\n+\t\treturn DBG_STATUS_UNSUPPORTED_APP_VERSION;\n+\n+\ts_app_ver = ver;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+bool qed_read_fw_info(struct ecore_hwfn *p_hwfn,\n+\t\t      struct ecore_ptt *p_ptt, struct fw_info *fw_info)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu8 storm_id;\n+\n+\tfor (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {\n+\t\tstruct storm_defs *storm = &s_storm_defs[storm_id];\n+\n+\t\t/* Skip Storm if it's in reset */\n+\t\tif (dev_data->block_in_reset[storm->sem_block_id])\n+\t\t\tcontinue;\n+\n+\t\t/* Read FW info for the current Storm */\n+\t\tqed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, fw_info);\n+\n+\t\treturn true;\n+\t}\n+\n+\treturn false;\n+}\n+\n+enum dbg_status qed_dbg_grc_config(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   enum dbg_grc_params grc_param, u32 val)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tenum dbg_status status;\n+\tint i;\n+\n+\tDP_VERBOSE(p_hwfn->p_dev,\n+\t\t   ECORE_MSG_DEBUG,\n+\t\t   \"dbg_grc_config: paramId = %d, val = %d\\n\", grc_param, val);\n+\n+\tstatus = qed_dbg_dev_init(p_hwfn);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\t/* Initializes the GRC parameters (if not initialized). Needed in order\n+\t * to set the default parameter values for the first time.\n+\t */\n+\tqed_dbg_grc_init_params(p_hwfn);\n+\n+\tif (grc_param >= MAX_DBG_GRC_PARAMS)\n+\t\treturn DBG_STATUS_INVALID_ARGS;\n+\tif (val < s_grc_param_defs[grc_param].min ||\n+\t    val > s_grc_param_defs[grc_param].max)\n+\t\treturn DBG_STATUS_INVALID_ARGS;\n+\n+\tif (s_grc_param_defs[grc_param].is_preset) {\n+\t\t/* Preset param */\n+\n+\t\t/* Disabling a preset is not allowed. Call\n+\t\t * dbg_grc_set_params_default instead.\n+\t\t */\n+\t\tif (!val)\n+\t\t\treturn DBG_STATUS_INVALID_ARGS;\n+\n+\t\t/* Update all params with the preset values */\n+\t\tfor (i = 0; i < MAX_DBG_GRC_PARAMS; i++) {\n+\t\t\tstruct grc_param_defs *defs = &s_grc_param_defs[i];\n+\t\t\tu32 preset_val;\n+\t\t\t/* Skip persistent params */\n+\t\t\tif (defs->is_persistent)\n+\t\t\t\tcontinue;\n+\n+\t\t\t/* Find preset value */\n+\t\t\tif (grc_param == DBG_GRC_PARAM_EXCLUDE_ALL)\n+\t\t\t\tpreset_val =\n+\t\t\t\t    defs->exclude_all_preset_val;\n+\t\t\telse if (grc_param == DBG_GRC_PARAM_CRASH)\n+\t\t\t\tpreset_val =\n+\t\t\t\t    defs->crash_preset_val[dev_data->chip_id];\n+\t\t\telse\n+\t\t\t\treturn DBG_STATUS_INVALID_ARGS;\n+\n+\t\t\tqed_grc_set_param(p_hwfn, i, preset_val);\n+\t\t}\n+\t} else {\n+\t\t/* Regular param - set its value */\n+\t\tqed_grc_set_param(p_hwfn, grc_param, val);\n+\t}\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Assign default GRC param values */\n+void qed_dbg_grc_set_params_default(struct ecore_hwfn *p_hwfn)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tu32 i;\n+\n+\tfor (i = 0; i < MAX_DBG_GRC_PARAMS; i++)\n+\t\tif (!s_grc_param_defs[i].is_persistent)\n+\t\t\tdev_data->grc.param_val[i] =\n+\t\t\t    s_grc_param_defs[i].default_val[dev_data->chip_id];\n+}\n+\n+enum dbg_status qed_dbg_grc_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t\t      u32 *buf_size)\n+{\n+\tenum dbg_status status = qed_dbg_dev_init(p_hwfn);\n+\n+\t*buf_size = 0;\n+\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\tif (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||\n+\t    !p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr ||\n+\t    !p_hwfn->dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr ||\n+\t    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||\n+\t    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)\n+\t\treturn DBG_STATUS_DBG_ARRAY_NOT_SET;\n+\n+\treturn qed_grc_dump(p_hwfn, p_ptt, NULL, false, buf_size);\n+}\n+\n+enum dbg_status qed_dbg_grc_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t struct ecore_ptt *p_ptt,\n+\t\t\t\t u32 *dump_buf,\n+\t\t\t\t u32 buf_size_in_dwords,\n+\t\t\t\t u32 *num_dumped_dwords)\n+{\n+\tu32 needed_buf_size_in_dwords;\n+\tenum dbg_status status;\n+\n+\t*num_dumped_dwords = 0;\n+\n+\tstatus = qed_dbg_grc_get_dump_buf_size(p_hwfn,\n+\t\t\t\t\t       p_ptt,\n+\t\t\t\t\t       &needed_buf_size_in_dwords);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\tif (buf_size_in_dwords < needed_buf_size_in_dwords)\n+\t\treturn DBG_STATUS_DUMP_BUF_TOO_SMALL;\n+\n+\t/* GRC Dump */\n+\tstatus = qed_grc_dump(p_hwfn, p_ptt, dump_buf, true, num_dumped_dwords);\n+\n+\t/* Revert GRC params to their default */\n+\tqed_dbg_grc_set_params_default(p_hwfn);\n+\n+\treturn status;\n+}\n+\n+enum dbg_status qed_dbg_idle_chk_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t   struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t   u32 *buf_size)\n+{\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tstruct idle_chk_data *idle_chk = &dev_data->idle_chk;\n+\tenum dbg_status status;\n+\n+\t*buf_size = 0;\n+\n+\tstatus = qed_dbg_dev_init(p_hwfn);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\tif (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||\n+\t    !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr ||\n+\t    !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr ||\n+\t    !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr)\n+\t\treturn DBG_STATUS_DBG_ARRAY_NOT_SET;\n+\n+\tif (!idle_chk->buf_size_set) {\n+\t\tidle_chk->buf_size = qed_idle_chk_dump(p_hwfn,\n+\t\t\t\t\t\t       p_ptt, NULL, false);\n+\t\tidle_chk->buf_size_set = true;\n+\t}\n+\n+\t*buf_size = idle_chk->buf_size;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+enum dbg_status qed_dbg_idle_chk_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t      u32 *dump_buf,\n+\t\t\t\t      u32 buf_size_in_dwords,\n+\t\t\t\t      u32 *num_dumped_dwords)\n+{\n+\tu32 needed_buf_size_in_dwords;\n+\tenum dbg_status status;\n+\n+\t*num_dumped_dwords = 0;\n+\n+\tstatus = qed_dbg_idle_chk_get_dump_buf_size(p_hwfn,\n+\t\t\t\t\t\t    p_ptt,\n+\t\t\t\t\t\t    &needed_buf_size_in_dwords);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\tif (buf_size_in_dwords < needed_buf_size_in_dwords)\n+\t\treturn DBG_STATUS_DUMP_BUF_TOO_SMALL;\n+\n+\t/* Update reset state */\n+\tqed_grc_unreset_blocks(p_hwfn, p_ptt, true);\n+\tqed_update_blocks_reset_state(p_hwfn, p_ptt);\n+\n+\t/* Idle Check Dump */\n+\t*num_dumped_dwords = qed_idle_chk_dump(p_hwfn, p_ptt, dump_buf, true);\n+\n+\t/* Revert GRC params to their default */\n+\tqed_dbg_grc_set_params_default(p_hwfn);\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+enum dbg_status qed_dbg_mcp_trace_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t    struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t    u32 *buf_size)\n+{\n+\tenum dbg_status status = qed_dbg_dev_init(p_hwfn);\n+\n+\t*buf_size = 0;\n+\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\treturn qed_mcp_trace_dump(p_hwfn, p_ptt, NULL, false, buf_size);\n+}\n+\n+enum dbg_status qed_dbg_mcp_trace_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t       struct ecore_ptt *p_ptt,\n+\t\t\t\t       u32 *dump_buf,\n+\t\t\t\t       u32 buf_size_in_dwords,\n+\t\t\t\t       u32 *num_dumped_dwords)\n+{\n+\tu32 needed_buf_size_in_dwords;\n+\tenum dbg_status status;\n+\n+\tstatus =\n+\t\tqed_dbg_mcp_trace_get_dump_buf_size(p_hwfn,\n+\t\t\t\t\t\t    p_ptt,\n+\t\t\t\t\t\t    &needed_buf_size_in_dwords);\n+\tif (status != DBG_STATUS_OK && status !=\n+\t    DBG_STATUS_NVRAM_GET_IMAGE_FAILED)\n+\t\treturn status;\n+\tif (buf_size_in_dwords < needed_buf_size_in_dwords)\n+\t\treturn DBG_STATUS_DUMP_BUF_TOO_SMALL;\n+\n+\t/* Update reset state */\n+\tqed_update_blocks_reset_state(p_hwfn, p_ptt);\n+\n+\t/* Perform dump */\n+\tstatus = qed_mcp_trace_dump(p_hwfn,\n+\t\t\t\t    p_ptt, dump_buf, true, num_dumped_dwords);\n+\n+\t/* Revert GRC params to their default */\n+\tqed_dbg_grc_set_params_default(p_hwfn);\n+\n+\treturn status;\n+}\n+\n+enum dbg_status qed_dbg_reg_fifo_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t   struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t   u32 *buf_size)\n+{\n+\tenum dbg_status status = qed_dbg_dev_init(p_hwfn);\n+\n+\t*buf_size = 0;\n+\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\treturn qed_reg_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);\n+}\n+\n+enum dbg_status qed_dbg_reg_fifo_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t      u32 *dump_buf,\n+\t\t\t\t      u32 buf_size_in_dwords,\n+\t\t\t\t      u32 *num_dumped_dwords)\n+{\n+\tu32 needed_buf_size_in_dwords;\n+\tenum dbg_status status;\n+\n+\t*num_dumped_dwords = 0;\n+\n+\tstatus = qed_dbg_reg_fifo_get_dump_buf_size(p_hwfn,\n+\t\t\t\t\t\t    p_ptt,\n+\t\t\t\t\t\t    &needed_buf_size_in_dwords);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\tif (buf_size_in_dwords < needed_buf_size_in_dwords)\n+\t\treturn DBG_STATUS_DUMP_BUF_TOO_SMALL;\n+\n+\t/* Update reset state */\n+\tqed_update_blocks_reset_state(p_hwfn, p_ptt);\n+\n+\tstatus = qed_reg_fifo_dump(p_hwfn,\n+\t\t\t\t   p_ptt, dump_buf, true, num_dumped_dwords);\n+\n+\t/* Revert GRC params to their default */\n+\tqed_dbg_grc_set_params_default(p_hwfn);\n+\n+\treturn status;\n+}\n+\n+enum dbg_status qed_dbg_igu_fifo_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t   struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t   u32 *buf_size)\n+{\n+\tenum dbg_status status = qed_dbg_dev_init(p_hwfn);\n+\n+\t*buf_size = 0;\n+\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\treturn qed_igu_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);\n+}\n+\n+enum dbg_status qed_dbg_igu_fifo_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t      u32 *dump_buf,\n+\t\t\t\t      u32 buf_size_in_dwords,\n+\t\t\t\t      u32 *num_dumped_dwords)\n+{\n+\tu32 needed_buf_size_in_dwords;\n+\tenum dbg_status status;\n+\n+\t*num_dumped_dwords = 0;\n+\n+\tstatus = qed_dbg_igu_fifo_get_dump_buf_size(p_hwfn,\n+\t\t\t\t\t\t    p_ptt,\n+\t\t\t\t\t\t    &needed_buf_size_in_dwords);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\tif (buf_size_in_dwords < needed_buf_size_in_dwords)\n+\t\treturn DBG_STATUS_DUMP_BUF_TOO_SMALL;\n+\n+\t/* Update reset state */\n+\tqed_update_blocks_reset_state(p_hwfn, p_ptt);\n+\n+\tstatus = qed_igu_fifo_dump(p_hwfn,\n+\t\t\t\t   p_ptt, dump_buf, true, num_dumped_dwords);\n+\t/* Revert GRC params to their default */\n+\tqed_dbg_grc_set_params_default(p_hwfn);\n+\n+\treturn status;\n+}\n+\n+enum dbg_status\n+qed_dbg_protection_override_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t\t      u32 *buf_size)\n+{\n+\tenum dbg_status status = qed_dbg_dev_init(p_hwfn);\n+\n+\t*buf_size = 0;\n+\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\treturn qed_protection_override_dump(p_hwfn,\n+\t\t\t\t\t    p_ptt, NULL, false, buf_size);\n+}\n+\n+enum dbg_status qed_dbg_protection_override_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t u32 *dump_buf,\n+\t\t\t\t\t\t u32 buf_size_in_dwords,\n+\t\t\t\t\t\t u32 *num_dumped_dwords)\n+{\n+\tu32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords;\n+\tenum dbg_status status;\n+\n+\t*num_dumped_dwords = 0;\n+\n+\tstatus =\n+\t\tqed_dbg_protection_override_get_dump_buf_size(p_hwfn,\n+\t\t\t\t\t\t\t      p_ptt,\n+\t\t\t\t\t\t\t      p_size);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\tif (buf_size_in_dwords < needed_buf_size_in_dwords)\n+\t\treturn DBG_STATUS_DUMP_BUF_TOO_SMALL;\n+\n+\t/* Update reset state */\n+\tqed_update_blocks_reset_state(p_hwfn, p_ptt);\n+\n+\tstatus = qed_protection_override_dump(p_hwfn,\n+\t\t\t\t\t      p_ptt,\n+\t\t\t\t\t      dump_buf,\n+\t\t\t\t\t      true, num_dumped_dwords);\n+\n+\t/* Revert GRC params to their default */\n+\tqed_dbg_grc_set_params_default(p_hwfn);\n+\n+\treturn status;\n+}\n+\n+enum dbg_status qed_dbg_fw_asserts_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t     struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t     u32 *buf_size)\n+{\n+\tenum dbg_status status = qed_dbg_dev_init(p_hwfn);\n+\n+\t*buf_size = 0;\n+\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\t/* Update reset state */\n+\tqed_update_blocks_reset_state(p_hwfn, p_ptt);\n+\n+\t*buf_size = qed_fw_asserts_dump(p_hwfn, p_ptt, NULL, false);\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+enum dbg_status qed_dbg_fw_asserts_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\tstruct ecore_ptt *p_ptt,\n+\t\t\t\t\tu32 *dump_buf,\n+\t\t\t\t\tu32 buf_size_in_dwords,\n+\t\t\t\t\tu32 *num_dumped_dwords)\n+{\n+\tu32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords;\n+\tenum dbg_status status;\n+\n+\t*num_dumped_dwords = 0;\n+\n+\tstatus =\n+\t\tqed_dbg_fw_asserts_get_dump_buf_size(p_hwfn,\n+\t\t\t\t\t\t     p_ptt,\n+\t\t\t\t\t\t     p_size);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\tif (buf_size_in_dwords < needed_buf_size_in_dwords)\n+\t\treturn DBG_STATUS_DUMP_BUF_TOO_SMALL;\n+\n+\t*num_dumped_dwords = qed_fw_asserts_dump(p_hwfn, p_ptt, dump_buf, true);\n+\n+\t/* Revert GRC params to their default */\n+\tqed_dbg_grc_set_params_default(p_hwfn);\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+static enum dbg_status qed_dbg_ilt_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t     struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t     u32 *buf_size)\n+{\n+\tenum dbg_status status = qed_dbg_dev_init(p_hwfn);\n+\n+\t*buf_size = 0;\n+\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\t*buf_size = qed_ilt_dump(p_hwfn, p_ptt, NULL, false);\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+static enum dbg_status qed_dbg_ilt_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\tstruct ecore_ptt *p_ptt,\n+\t\t\t\t\tu32 *dump_buf,\n+\t\t\t\t\tu32 buf_size_in_dwords,\n+\t\t\t\t\tu32 *num_dumped_dwords)\n+{\n+\tu32 needed_buf_size_in_dwords;\n+\tenum dbg_status status;\n+\n+\t*num_dumped_dwords = 0;\n+\n+\tstatus = qed_dbg_ilt_get_dump_buf_size(p_hwfn,\n+\t\t\t\t\t       p_ptt,\n+\t\t\t\t\t       &needed_buf_size_in_dwords);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\tif (buf_size_in_dwords < needed_buf_size_in_dwords)\n+\t\treturn DBG_STATUS_DUMP_BUF_TOO_SMALL;\n+\n+\t*num_dumped_dwords = qed_ilt_dump(p_hwfn, p_ptt, dump_buf, true);\n+\n+\t/* Reveret GRC params to their default */\n+\tqed_dbg_grc_set_params_default(p_hwfn);\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+enum dbg_status qed_dbg_read_attn(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t  struct ecore_ptt *p_ptt,\n+\t\t\t\t  enum block_id block_id,\n+\t\t\t\t  enum dbg_attn_type attn_type,\n+\t\t\t\t  bool clear_status,\n+\t\t\t\t  struct dbg_attn_block_result *results)\n+{\n+\tenum dbg_status status = qed_dbg_dev_init(p_hwfn);\n+\tu8 reg_idx, num_attn_regs, num_result_regs = 0;\n+\tconst struct dbg_attn_reg *attn_reg_arr;\n+\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\tif (!p_hwfn->dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||\n+\t    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||\n+\t    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)\n+\t\treturn DBG_STATUS_DBG_ARRAY_NOT_SET;\n+\n+\tattn_reg_arr = qed_get_block_attn_regs(p_hwfn,\n+\t\t\t\t\t       block_id,\n+\t\t\t\t\t       attn_type, &num_attn_regs);\n+\n+\tfor (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {\n+\t\tconst struct dbg_attn_reg *reg_data = &attn_reg_arr[reg_idx];\n+\t\tstruct dbg_attn_reg_result *reg_result;\n+\t\tu32 sts_addr, sts_val;\n+\t\tu16 modes_buf_offset;\n+\t\tbool eval_mode;\n+\n+\t\t/* Check mode */\n+\t\teval_mode = GET_FIELD(reg_data->mode.data,\n+\t\t\t\t      DBG_MODE_HDR_EVAL_MODE) > 0;\n+\t\tmodes_buf_offset = GET_FIELD(reg_data->mode.data,\n+\t\t\t\t\t     DBG_MODE_HDR_MODES_BUF_OFFSET);\n+\t\tif (eval_mode && !qed_is_mode_match(p_hwfn, &modes_buf_offset))\n+\t\t\tcontinue;\n+\n+\t\t/* Mode match - read attention status register */\n+\t\tsts_addr = DWORDS_TO_BYTES(clear_status ?\n+\t\t\t\t\t   reg_data->sts_clr_address :\n+\t\t\t\t\t   GET_FIELD(reg_data->data,\n+\t\t\t\t\t\t     DBG_ATTN_REG_STS_ADDRESS));\n+\t\tsts_val = ecore_rd(p_hwfn, p_ptt, sts_addr);\n+\t\tif (!sts_val)\n+\t\t\tcontinue;\n+\n+\t\t/* Non-zero attention status - add to results */\n+\t\treg_result = &results->reg_results[num_result_regs];\n+\t\tSET_FIELD(reg_result->data,\n+\t\t\t  DBG_ATTN_REG_RESULT_STS_ADDRESS, sts_addr);\n+\t\tSET_FIELD(reg_result->data,\n+\t\t\t  DBG_ATTN_REG_RESULT_NUM_REG_ATTN,\n+\t\t\t  GET_FIELD(reg_data->data, DBG_ATTN_REG_NUM_REG_ATTN));\n+\t\treg_result->block_attn_offset = reg_data->block_attn_offset;\n+\t\treg_result->sts_val = sts_val;\n+\t\treg_result->mask_val = ecore_rd(p_hwfn,\n+\t\t\t\t\t      p_ptt,\n+\t\t\t\t\t      DWORDS_TO_BYTES\n+\t\t\t\t\t      (reg_data->mask_address));\n+\t\tnum_result_regs++;\n+\t}\n+\n+\tresults->block_id = (u8)block_id;\n+\tresults->names_offset =\n+\t    qed_get_block_attn_data(p_hwfn, block_id, attn_type)->names_offset;\n+\tSET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE, attn_type);\n+\tSET_FIELD(results->data,\n+\t\t  DBG_ATTN_BLOCK_RESULT_NUM_REGS, num_result_regs);\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/******************************* Data Types **********************************/\n+\n+/* REG fifo element */\n+struct reg_fifo_element {\n+\tu64 data;\n+#define REG_FIFO_ELEMENT_ADDRESS_SHIFT\t\t0\n+#define REG_FIFO_ELEMENT_ADDRESS_MASK\t\t0x7fffff\n+#define REG_FIFO_ELEMENT_ACCESS_SHIFT\t\t23\n+#define REG_FIFO_ELEMENT_ACCESS_MASK\t\t0x1\n+#define REG_FIFO_ELEMENT_PF_SHIFT\t\t24\n+#define REG_FIFO_ELEMENT_PF_MASK\t\t0xf\n+#define REG_FIFO_ELEMENT_VF_SHIFT\t\t28\n+#define REG_FIFO_ELEMENT_VF_MASK\t\t0xff\n+#define REG_FIFO_ELEMENT_PORT_SHIFT\t\t36\n+#define REG_FIFO_ELEMENT_PORT_MASK\t\t0x3\n+#define REG_FIFO_ELEMENT_PRIVILEGE_SHIFT\t38\n+#define REG_FIFO_ELEMENT_PRIVILEGE_MASK\t\t0x3\n+#define REG_FIFO_ELEMENT_PROTECTION_SHIFT\t40\n+#define REG_FIFO_ELEMENT_PROTECTION_MASK\t0x7\n+#define REG_FIFO_ELEMENT_MASTER_SHIFT\t\t43\n+#define REG_FIFO_ELEMENT_MASTER_MASK\t\t0xf\n+#define REG_FIFO_ELEMENT_ERROR_SHIFT\t\t47\n+#define REG_FIFO_ELEMENT_ERROR_MASK\t\t0x1f\n+};\n+\n+/* REG fifo error element */\n+struct reg_fifo_err {\n+\tu32 err_code;\n+\tconst char *err_msg;\n+};\n+\n+/* IGU fifo element */\n+struct igu_fifo_element {\n+\tu32 dword0;\n+#define IGU_FIFO_ELEMENT_DWORD0_FID_SHIFT\t\t0\n+#define IGU_FIFO_ELEMENT_DWORD0_FID_MASK\t\t0xff\n+#define IGU_FIFO_ELEMENT_DWORD0_IS_PF_SHIFT\t\t8\n+#define IGU_FIFO_ELEMENT_DWORD0_IS_PF_MASK\t\t0x1\n+#define IGU_FIFO_ELEMENT_DWORD0_SOURCE_SHIFT\t\t9\n+#define IGU_FIFO_ELEMENT_DWORD0_SOURCE_MASK\t\t0xf\n+#define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_SHIFT\t\t13\n+#define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_MASK\t\t0xf\n+#define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_SHIFT\t\t17\n+#define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_MASK\t\t0x7fff\n+\tu32 dword1;\n+\tu32 dword2;\n+#define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_SHIFT\t0\n+#define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_MASK\t\t0x1\n+#define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_SHIFT\t\t1\n+#define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_MASK\t\t0xffffffff\n+\tu32 reserved;\n+};\n+\n+struct igu_fifo_wr_data {\n+\tu32 data;\n+#define IGU_FIFO_WR_DATA_PROD_CONS_SHIFT\t\t0\n+#define IGU_FIFO_WR_DATA_PROD_CONS_MASK\t\t\t0xffffff\n+#define IGU_FIFO_WR_DATA_UPDATE_FLAG_SHIFT\t\t24\n+#define IGU_FIFO_WR_DATA_UPDATE_FLAG_MASK\t\t0x1\n+#define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_SHIFT\t25\n+#define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_MASK\t\t0x3\n+#define IGU_FIFO_WR_DATA_SEGMENT_SHIFT\t\t\t27\n+#define IGU_FIFO_WR_DATA_SEGMENT_MASK\t\t\t0x1\n+#define IGU_FIFO_WR_DATA_TIMER_MASK_SHIFT\t\t28\n+#define IGU_FIFO_WR_DATA_TIMER_MASK_MASK\t\t0x1\n+#define IGU_FIFO_WR_DATA_CMD_TYPE_SHIFT\t\t\t31\n+#define IGU_FIFO_WR_DATA_CMD_TYPE_MASK\t\t\t0x1\n+};\n+\n+struct igu_fifo_cleanup_wr_data {\n+\tu32 data;\n+#define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_SHIFT\t\t0\n+#define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_MASK\t\t0x7ffffff\n+#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_SHIFT\t27\n+#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_MASK\t0x1\n+#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_SHIFT\t28\n+#define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_MASK\t0x7\n+#define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_SHIFT\t\t31\n+#define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_MASK\t\t0x1\n+};\n+\n+/* Protection override element */\n+struct protection_override_element {\n+\tu64 data;\n+#define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_SHIFT\t\t0\n+#define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_MASK\t\t0x7fffff\n+#define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_SHIFT\t\t23\n+#define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_MASK\t\t0xffffff\n+#define PROTECTION_OVERRIDE_ELEMENT_READ_SHIFT\t\t\t47\n+#define PROTECTION_OVERRIDE_ELEMENT_READ_MASK\t\t\t0x1\n+#define PROTECTION_OVERRIDE_ELEMENT_WRITE_SHIFT\t\t\t48\n+#define PROTECTION_OVERRIDE_ELEMENT_WRITE_MASK\t\t\t0x1\n+#define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_SHIFT\t49\n+#define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_MASK\t0x7\n+#define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_SHIFT\t52\n+#define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_MASK\t0x7\n+};\n+\n+enum igu_fifo_sources {\n+\tIGU_SRC_PXP0,\n+\tIGU_SRC_PXP1,\n+\tIGU_SRC_PXP2,\n+\tIGU_SRC_PXP3,\n+\tIGU_SRC_PXP4,\n+\tIGU_SRC_PXP5,\n+\tIGU_SRC_PXP6,\n+\tIGU_SRC_PXP7,\n+\tIGU_SRC_CAU,\n+\tIGU_SRC_ATTN,\n+\tIGU_SRC_GRC\n+};\n+\n+enum igu_fifo_addr_types {\n+\tIGU_ADDR_TYPE_MSIX_MEM,\n+\tIGU_ADDR_TYPE_WRITE_PBA,\n+\tIGU_ADDR_TYPE_WRITE_INT_ACK,\n+\tIGU_ADDR_TYPE_WRITE_ATTN_BITS,\n+\tIGU_ADDR_TYPE_READ_INT,\n+\tIGU_ADDR_TYPE_WRITE_PROD_UPDATE,\n+\tIGU_ADDR_TYPE_RESERVED\n+};\n+\n+struct igu_fifo_addr_data {\n+\tu16 start_addr;\n+\tu16 end_addr;\n+\tconst char *desc;\n+\tconst char *vf_desc;\n+\tenum igu_fifo_addr_types type;\n+};\n+\n+/******************************** Constants **********************************/\n+\n+#define MAX_MSG_LEN\t\t\t\t1024\n+\n+#define MCP_TRACE_MAX_MODULE_LEN\t\t8\n+#define MCP_TRACE_FORMAT_MAX_PARAMS\t\t3\n+#define MCP_TRACE_FORMAT_PARAM_WIDTH \\\n+\t(MCP_TRACE_FORMAT_P2_SIZE_OFFSET - MCP_TRACE_FORMAT_P1_SIZE_OFFSET)\n+\n+#define REG_FIFO_ELEMENT_ADDR_FACTOR\t\t4\n+#define REG_FIFO_ELEMENT_IS_PF_VF_VAL\t\t127\n+\n+#define PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR\t4\n+\n+/***************************** Constant Arrays *******************************/\n+\n+/* Status string array */\n+static const char * const s_status_str[] = {\n+\t/* DBG_STATUS_OK */\n+\t\"Operation completed successfully\",\n+\n+\t/* DBG_STATUS_APP_VERSION_NOT_SET */\n+\t\"Debug application version wasn't set\",\n+\n+\t/* DBG_STATUS_UNSUPPORTED_APP_VERSION */\n+\t\"Unsupported debug application version\",\n+\n+\t/* DBG_STATUS_DBG_BLOCK_NOT_RESET */\n+\t\"The debug block wasn't reset since the last recording\",\n+\n+\t/* DBG_STATUS_INVALID_ARGS */\n+\t\"Invalid arguments\",\n+\n+\t/* DBG_STATUS_OUTPUT_ALREADY_SET */\n+\t\"The debug output was already set\",\n+\n+\t/* DBG_STATUS_INVALID_PCI_BUF_SIZE */\n+\t\"Invalid PCI buffer size\",\n+\n+\t/* DBG_STATUS_PCI_BUF_ALLOC_FAILED */\n+\t\"PCI buffer allocation failed\",\n+\n+\t/* DBG_STATUS_PCI_BUF_NOT_ALLOCATED */\n+\t\"A PCI buffer wasn't allocated\",\n+\n+\t/* DBG_STATUS_INVALID_FILTER_TRIGGER_DWORDS */\n+\t\"The filter/trigger constraint dword offsets are not enabled for recording\",\n+\n+\n+\t/* DBG_STATUS_VFC_READ_ERROR */\n+\t\"Error reading from VFC\",\n+\n+\t/* DBG_STATUS_STORM_ALREADY_ENABLED */\n+\t\"The Storm was already enabled\",\n+\n+\t/* DBG_STATUS_STORM_NOT_ENABLED */\n+\t\"The specified Storm wasn't enabled\",\n+\n+\t/* DBG_STATUS_BLOCK_ALREADY_ENABLED */\n+\t\"The block was already enabled\",\n+\n+\t/* DBG_STATUS_BLOCK_NOT_ENABLED */\n+\t\"The specified block wasn't enabled\",\n+\n+\t/* DBG_STATUS_NO_INPUT_ENABLED */\n+\t\"No input was enabled for recording\",\n+\n+\t/* DBG_STATUS_NO_FILTER_TRIGGER_256B */\n+\t\"Filters and triggers are not allowed in E4 256-bit mode\",\n+\n+\t/* DBG_STATUS_FILTER_ALREADY_ENABLED */\n+\t\"The filter was already enabled\",\n+\n+\t/* DBG_STATUS_TRIGGER_ALREADY_ENABLED */\n+\t\"The trigger was already enabled\",\n+\n+\t/* DBG_STATUS_TRIGGER_NOT_ENABLED */\n+\t\"The trigger wasn't enabled\",\n+\n+\t/* DBG_STATUS_CANT_ADD_CONSTRAINT */\n+\t\"A constraint can be added only after a filter was enabled or a trigger state was added\",\n+\n+\t/* DBG_STATUS_TOO_MANY_TRIGGER_STATES */\n+\t\"Cannot add more than 3 trigger states\",\n+\n+\t/* DBG_STATUS_TOO_MANY_CONSTRAINTS */\n+\t\"Cannot add more than 4 constraints per filter or trigger state\",\n+\n+\t/* DBG_STATUS_RECORDING_NOT_STARTED */\n+\t\"The recording wasn't started\",\n+\n+\t/* DBG_STATUS_DATA_DID_NOT_TRIGGER */\n+\t\"A trigger was configured, but it didn't trigger\",\n+\n+\t/* DBG_STATUS_NO_DATA_RECORDED */\n+\t\"No data was recorded\",\n+\n+\t/* DBG_STATUS_DUMP_BUF_TOO_SMALL */\n+\t\"Dump buffer is too small\",\n+\n+\t/* DBG_STATUS_DUMP_NOT_CHUNK_ALIGNED */\n+\t\"Dumped data is not aligned to chunks\",\n+\n+\t/* DBG_STATUS_UNKNOWN_CHIP */\n+\t\"Unknown chip\",\n+\n+\t/* DBG_STATUS_VIRT_MEM_ALLOC_FAILED */\n+\t\"Failed allocating virtual memory\",\n+\n+\t/* DBG_STATUS_BLOCK_IN_RESET */\n+\t\"The input block is in reset\",\n+\n+\t/* DBG_STATUS_INVALID_TRACE_SIGNATURE */\n+\t\"Invalid MCP trace signature found in NVRAM\",\n+\n+\t/* DBG_STATUS_INVALID_NVRAM_BUNDLE */\n+\t\"Invalid bundle ID found in NVRAM\",\n+\n+\t/* DBG_STATUS_NVRAM_GET_IMAGE_FAILED */\n+\t\"Failed getting NVRAM image\",\n+\n+\t/* DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE */\n+\t\"NVRAM image is not dword-aligned\",\n+\n+\t/* DBG_STATUS_NVRAM_READ_FAILED */\n+\t\"Failed reading from NVRAM\",\n+\n+\t/* DBG_STATUS_IDLE_CHK_PARSE_FAILED */\n+\t\"Idle check parsing failed\",\n+\n+\t/* DBG_STATUS_MCP_TRACE_BAD_DATA */\n+\t\"MCP Trace data is corrupt\",\n+\n+\t/* DBG_STATUS_MCP_TRACE_NO_META */\n+\t\"Dump doesn't contain meta data - it must be provided in image file\",\n+\n+\t/* DBG_STATUS_MCP_COULD_NOT_HALT */\n+\t\"Failed to halt MCP\",\n+\n+\t/* DBG_STATUS_MCP_COULD_NOT_RESUME */\n+\t\"Failed to resume MCP after halt\",\n+\n+\t/* DBG_STATUS_RESERVED0 */\n+\t\"\",\n+\n+\t/* DBG_STATUS_SEMI_FIFO_NOT_EMPTY */\n+\t\"Failed to empty SEMI sync FIFO\",\n+\n+\t/* DBG_STATUS_IGU_FIFO_BAD_DATA */\n+\t\"IGU FIFO data is corrupt\",\n+\n+\t/* DBG_STATUS_MCP_COULD_NOT_MASK_PRTY */\n+\t\"MCP failed to mask parities\",\n+\n+\t/* DBG_STATUS_FW_ASSERTS_PARSE_FAILED */\n+\t\"FW Asserts parsing failed\",\n+\n+\t/* DBG_STATUS_REG_FIFO_BAD_DATA */\n+\t\"GRC FIFO data is corrupt\",\n+\n+\t/* DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA */\n+\t\"Protection Override data is corrupt\",\n+\n+\t/* DBG_STATUS_DBG_ARRAY_NOT_SET */\n+\t\"Debug arrays were not set (when using binary files, dbg_set_bin_ptr must be called)\",\n+\n+\t/* DBG_STATUS_RESERVED1 */\n+\t\"\",\n+\n+\t/* DBG_STATUS_NON_MATCHING_LINES */\n+\t\"Non-matching debug lines - in E4, all lines must be of the same type (either 128b or 256b)\",\n+\n+\t/* DBG_STATUS_INSUFFICIENT_HW_IDS */\n+\t\"Insufficient HW IDs. Try to record less Storms/blocks\",\n+\n+\t/* DBG_STATUS_DBG_BUS_IN_USE */\n+\t\"The debug bus is in use\",\n+\n+\t/* DBG_STATUS_INVALID_STORM_DBG_MODE */\n+\t\"The storm debug mode is not supported in the current chip\",\n+\n+\t/* DBG_STATUS_OTHER_ENGINE_BB_ONLY */\n+\t\"Other engine is supported only in BB\",\n+\n+\t/* DBG_STATUS_FILTER_SINGLE_HW_ID */\n+\t\"The configured filter mode requires a single Storm/block input\",\n+\n+\t/* DBG_STATUS_TRIGGER_SINGLE_HW_ID */\n+\t\"The configured filter mode requires that all the constraints of a single trigger state will be defined on a single Storm/block input\",\n+\n+\t/* DBG_STATUS_MISSING_TRIGGER_STATE_STORM */\n+\t\"When triggering on Storm data, the Storm to trigger on must be specified\"\n+};\n+\n+/* Idle check severity names array */\n+static const char * const s_idle_chk_severity_str[] = {\n+\t\"Error\",\n+\t\"Error if no traffic\",\n+\t\"Warning\"\n+};\n+\n+/* MCP Trace level names array */\n+static const char * const s_mcp_trace_level_str[] = {\n+\t\"ERROR\",\n+\t\"TRACE\",\n+\t\"DEBUG\"\n+};\n+\n+/* Access type names array */\n+static const char * const s_access_strs[] = {\n+\t\"read\",\n+\t\"write\"\n+};\n+\n+/* Privilege type names array */\n+static const char * const s_privilege_strs[] = {\n+\t\"VF\",\n+\t\"PDA\",\n+\t\"HV\",\n+\t\"UA\"\n+};\n+\n+/* Protection type names array */\n+static const char * const s_protection_strs[] = {\n+\t\"(default)\",\n+\t\"(default)\",\n+\t\"(default)\",\n+\t\"(default)\",\n+\t\"override VF\",\n+\t\"override PDA\",\n+\t\"override HV\",\n+\t\"override UA\"\n+};\n+\n+/* Master type names array */\n+static const char * const s_master_strs[] = {\n+\t\"???\",\n+\t\"pxp\",\n+\t\"mcp\",\n+\t\"msdm\",\n+\t\"psdm\",\n+\t\"ysdm\",\n+\t\"usdm\",\n+\t\"tsdm\",\n+\t\"xsdm\",\n+\t\"dbu\",\n+\t\"dmae\",\n+\t\"jdap\",\n+\t\"???\",\n+\t\"???\",\n+\t\"???\",\n+\t\"???\"\n+};\n+\n+/* REG FIFO error messages array */\n+static struct reg_fifo_err s_reg_fifo_errors[] = {\n+\t{1, \"grc timeout\"},\n+\t{2, \"address doesn't belong to any block\"},\n+\t{4, \"reserved address in block or write to read-only address\"},\n+\t{8, \"privilege/protection mismatch\"},\n+\t{16, \"path isolation error\"},\n+\t{17, \"RSL error\"}\n+};\n+\n+/* IGU FIFO sources array */\n+static const char * const s_igu_fifo_source_strs[] = {\n+\t\"TSTORM\",\n+\t\"MSTORM\",\n+\t\"USTORM\",\n+\t\"XSTORM\",\n+\t\"YSTORM\",\n+\t\"PSTORM\",\n+\t\"PCIE\",\n+\t\"NIG_QM_PBF\",\n+\t\"CAU\",\n+\t\"ATTN\",\n+\t\"GRC\",\n+};\n+\n+/* IGU FIFO error messages */\n+static const char * const s_igu_fifo_error_strs[] = {\n+\t\"no error\",\n+\t\"length error\",\n+\t\"function disabled\",\n+\t\"VF sent command to attention address\",\n+\t\"host sent prod update command\",\n+\t\"read of during interrupt register while in MIMD mode\",\n+\t\"access to PXP BAR reserved address\",\n+\t\"producer update command to attention index\",\n+\t\"unknown error\",\n+\t\"SB index not valid\",\n+\t\"SB relative index and FID not found\",\n+\t\"FID not match\",\n+\t\"command with error flag asserted (PCI error or CAU discard)\",\n+\t\"VF sent cleanup and RF cleanup is disabled\",\n+\t\"cleanup command on type bigger than 4\"\n+};\n+\n+/* IGU FIFO address data */\n+static const struct igu_fifo_addr_data s_igu_fifo_addr_data[] = {\n+\t{0x0, 0x101, \"MSI-X Memory\", NULL,\n+\t IGU_ADDR_TYPE_MSIX_MEM},\n+\t{0x102, 0x1ff, \"reserved\", NULL,\n+\t IGU_ADDR_TYPE_RESERVED},\n+\t{0x200, 0x200, \"Write PBA[0:63]\", NULL,\n+\t IGU_ADDR_TYPE_WRITE_PBA},\n+\t{0x201, 0x201, \"Write PBA[64:127]\", \"reserved\",\n+\t IGU_ADDR_TYPE_WRITE_PBA},\n+\t{0x202, 0x202, \"Write PBA[128]\", \"reserved\",\n+\t IGU_ADDR_TYPE_WRITE_PBA},\n+\t{0x203, 0x3ff, \"reserved\", NULL,\n+\t IGU_ADDR_TYPE_RESERVED},\n+\t{0x400, 0x5ef, \"Write interrupt acknowledgment\", NULL,\n+\t IGU_ADDR_TYPE_WRITE_INT_ACK},\n+\t{0x5f0, 0x5f0, \"Attention bits update\", NULL,\n+\t IGU_ADDR_TYPE_WRITE_ATTN_BITS},\n+\t{0x5f1, 0x5f1, \"Attention bits set\", NULL,\n+\t IGU_ADDR_TYPE_WRITE_ATTN_BITS},\n+\t{0x5f2, 0x5f2, \"Attention bits clear\", NULL,\n+\t IGU_ADDR_TYPE_WRITE_ATTN_BITS},\n+\t{0x5f3, 0x5f3, \"Read interrupt 0:63 with mask\", NULL,\n+\t IGU_ADDR_TYPE_READ_INT},\n+\t{0x5f4, 0x5f4, \"Read interrupt 0:31 with mask\", NULL,\n+\t IGU_ADDR_TYPE_READ_INT},\n+\t{0x5f5, 0x5f5, \"Read interrupt 32:63 with mask\", NULL,\n+\t IGU_ADDR_TYPE_READ_INT},\n+\t{0x5f6, 0x5f6, \"Read interrupt 0:63 without mask\", NULL,\n+\t IGU_ADDR_TYPE_READ_INT},\n+\t{0x5f7, 0x5ff, \"reserved\", NULL,\n+\t IGU_ADDR_TYPE_RESERVED},\n+\t{0x600, 0x7ff, \"Producer update\", NULL,\n+\t IGU_ADDR_TYPE_WRITE_PROD_UPDATE}\n+};\n+\n+/******************************** Variables **********************************/\n+\n+/* Temporary buffer, used for print size calculations */\n+static char s_temp_buf[MAX_MSG_LEN];\n+\n+/**************************** Private Functions ******************************/\n+\n+static u32 qed_cyclic_add(u32 a, u32 b, u32 size)\n+{\n+\treturn (a + b) % size;\n+}\n+\n+static u32 qed_cyclic_sub(u32 a, u32 b, u32 size)\n+{\n+\treturn (size + a - b) % size;\n+}\n+\n+/* Reads the specified number of bytes from the specified cyclic buffer (up to 4\n+ * bytes) and returns them as a dword value. the specified buffer offset is\n+ * updated.\n+ */\n+static u32 qed_read_from_cyclic_buf(void *buf,\n+\t\t\t\t    u32 *offset,\n+\t\t\t\t    u32 buf_size, u8 num_bytes_to_read)\n+{\n+\tu8 i, *val_ptr, *bytes_buf = (u8 *)buf;\n+\tu32 val = 0;\n+\n+\tval_ptr = (u8 *)&val;\n+\n+\t/* Assume running on a LITTLE ENDIAN and the buffer is network order\n+\t * (BIG ENDIAN), as high order bytes are placed in lower memory address.\n+\t */\n+\tfor (i = 0; i < num_bytes_to_read; i++) {\n+\t\tval_ptr[i] = bytes_buf[*offset];\n+\t\t*offset = qed_cyclic_add(*offset, 1, buf_size);\n+\t}\n+\n+\treturn val;\n+}\n+\n+/* Reads and returns the next byte from the specified buffer.\n+ * The specified buffer offset is updated.\n+ */\n+static u8 qed_read_byte_from_buf(void *buf, u32 *offset)\n+{\n+\treturn ((u8 *)buf)[(*offset)++];\n+}\n+\n+/* Reads and returns the next dword from the specified buffer.\n+ * The specified buffer offset is updated.\n+ */\n+static u32 qed_read_dword_from_buf(void *buf, u32 *offset)\n+{\n+\tu32 dword_val = *(u32 *)&((u8 *)buf)[*offset];\n+\n+\t*offset += 4;\n+\n+\treturn dword_val;\n+}\n+\n+/* Reads the next string from the specified buffer, and copies it to the\n+ * specified pointer. The specified buffer offset is updated.\n+ */\n+static void qed_read_str_from_buf(void *buf, u32 *offset, u32 size, char *dest)\n+{\n+\tconst char *source_str = &((const char *)buf)[*offset];\n+\n+\tOSAL_STRNCPY(dest, source_str, size);\n+\tdest[size - 1] = '\\0';\n+\t*offset += size;\n+}\n+\n+/* Returns a pointer to the specified offset (in bytes) of the specified buffer.\n+ * If the specified buffer in NULL, a temporary buffer pointer is returned.\n+ */\n+static char *qed_get_buf_ptr(void *buf, u32 offset)\n+{\n+\treturn buf ? (char *)buf + offset : s_temp_buf;\n+}\n+\n+/* Reads a param from the specified buffer. Returns the number of dwords read.\n+ * If the returned str_param is NULL, the param is numeric and its value is\n+ * returned in num_param.\n+ * Otheriwise, the param is a string and its pointer is returned in str_param.\n+ */\n+static u32 qed_read_param(u32 *dump_buf,\n+\t\t\t  const char **param_name,\n+\t\t\t  const char **param_str_val, u32 *param_num_val)\n+{\n+\tchar *char_buf = (char *)dump_buf;\n+\tsize_t offset = 0;\n+\n+\t/* Extract param name */\n+\t*param_name = char_buf;\n+\toffset += strlen(*param_name) + 1;\n+\n+\t/* Check param type */\n+\tif (*(char_buf + offset++)) {\n+\t\t/* String param */\n+\t\t*param_str_val = char_buf + offset;\n+\t\t*param_num_val = 0;\n+\t\toffset += strlen(*param_str_val) + 1;\n+\t\tif (offset & 0x3)\n+\t\t\toffset += (4 - (offset & 0x3));\n+\t} else {\n+\t\t/* Numeric param */\n+\t\t*param_str_val = NULL;\n+\t\tif (offset & 0x3)\n+\t\t\toffset += (4 - (offset & 0x3));\n+\t\t*param_num_val = *(u32 *)(char_buf + offset);\n+\t\toffset += 4;\n+\t}\n+\n+\treturn (u32)offset / 4;\n+}\n+\n+/* Reads a section header from the specified buffer.\n+ * Returns the number of dwords read.\n+ */\n+static u32 qed_read_section_hdr(u32 *dump_buf,\n+\t\t\t\tconst char **section_name,\n+\t\t\t\tu32 *num_section_params)\n+{\n+\tconst char *param_str_val;\n+\n+\treturn qed_read_param(dump_buf,\n+\t\t\t      section_name, &param_str_val, num_section_params);\n+}\n+\n+/* Reads section params from the specified buffer and prints them to the results\n+ * buffer. Returns the number of dwords read.\n+ */\n+static u32 qed_print_section_params(u32 *dump_buf,\n+\t\t\t\t    u32 num_section_params,\n+\t\t\t\t    char *results_buf, u32 *num_chars_printed)\n+{\n+\tu32 i, dump_offset = 0, results_offset = 0;\n+\n+\tfor (i = 0; i < num_section_params; i++) {\n+\t\tconst char *param_name, *param_str_val;\n+\t\tu32 param_num_val = 0;\n+\n+\t\tdump_offset += qed_read_param(dump_buf + dump_offset,\n+\t\t\t\t\t      &param_name,\n+\t\t\t\t\t      &param_str_val, &param_num_val);\n+\n+\t\tif (param_str_val) {\n+\t\t\tresults_offset +=\n+\t\t\t\tsprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t\t\tresults_offset),\n+\t\t\t\t\t\"%s: %s\\n\", param_name, param_str_val);\n+\t\t} else if (strcmp(param_name, \"fw-timestamp\")) {\n+\t\t\tresults_offset +=\n+\t\t\t\tsprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t\t\tresults_offset),\n+\t\t\t\t\t\"%s: %d\\n\", param_name, param_num_val);\n+\t\t}\n+\t}\n+\n+\tresults_offset += sprintf(qed_get_buf_ptr(results_buf, results_offset),\n+\t\t\t\t  \"\\n\");\n+\n+\t*num_chars_printed = results_offset;\n+\n+\treturn dump_offset;\n+}\n+\n+/* Returns the block name that matches the specified block ID,\n+ * or NULL if not found.\n+ */\n+static const char *qed_dbg_get_block_name(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t  enum block_id block_id)\n+{\n+\tconst struct dbg_block_user *block =\n+\t    (const struct dbg_block_user *)\n+\t    p_hwfn->dbg_arrays[BIN_BUF_DBG_BLOCKS_USER_DATA].ptr + block_id;\n+\n+\treturn (const char *)block->name;\n+}\n+\n+static struct dbg_tools_user_data *qed_dbg_get_user_data(struct ecore_hwfn\n+\t\t\t\t\t\t\t *p_hwfn)\n+{\n+\treturn (struct dbg_tools_user_data *)p_hwfn->dbg_user_info;\n+}\n+\n+/* Parses the idle check rules and returns the number of characters printed.\n+ * In case of parsing error, returns 0.\n+ */\n+static u32 qed_parse_idle_chk_dump_rules(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t u32 *dump_buf,\n+\t\t\t\t\t u32 *dump_buf_end,\n+\t\t\t\t\t u32 num_rules,\n+\t\t\t\t\t bool print_fw_idle_chk,\n+\t\t\t\t\t char *results_buf,\n+\t\t\t\t\t u32 *num_errors, u32 *num_warnings)\n+{\n+\t/* Offset in results_buf in bytes */\n+\tu32 results_offset = 0;\n+\n+\tu32 rule_idx;\n+\tu16 i, j;\n+\n+\t*num_errors = 0;\n+\t*num_warnings = 0;\n+\n+\t/* Go over dumped results */\n+\tfor (rule_idx = 0; rule_idx < num_rules && dump_buf < dump_buf_end;\n+\t     rule_idx++) {\n+\t\tconst struct dbg_idle_chk_rule_parsing_data *rule_parsing_data;\n+\t\tstruct dbg_idle_chk_result_hdr *hdr;\n+\t\tconst char *parsing_str, *lsi_msg;\n+\t\tu32 parsing_str_offset;\n+\t\tbool has_fw_msg;\n+\t\tu8 curr_reg_id;\n+\n+\t\thdr = (struct dbg_idle_chk_result_hdr *)dump_buf;\n+\t\trule_parsing_data =\n+\t\t    (const struct dbg_idle_chk_rule_parsing_data *)\n+\t\t    p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr +\n+\t\t    hdr->rule_id;\n+\t\tparsing_str_offset =\n+\t\t    GET_FIELD(rule_parsing_data->data,\n+\t\t\t      DBG_IDLE_CHK_RULE_PARSING_DATA_STR_OFFSET);\n+\t\thas_fw_msg =\n+\t\t    GET_FIELD(rule_parsing_data->data,\n+\t\t\t      DBG_IDLE_CHK_RULE_PARSING_DATA_HAS_FW_MSG) > 0;\n+\t\tparsing_str = (const char *)\n+\t\t    p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr +\n+\t\t    parsing_str_offset;\n+\t\tlsi_msg = parsing_str;\n+\t\tcurr_reg_id = 0;\n+\n+\t\tif (hdr->severity >= MAX_DBG_IDLE_CHK_SEVERITY_TYPES)\n+\t\t\treturn 0;\n+\n+\t\t/* Skip rule header */\n+\t\tdump_buf += BYTES_TO_DWORDS(sizeof(*hdr));\n+\n+\t\t/* Update errors/warnings count */\n+\t\tif (hdr->severity == IDLE_CHK_SEVERITY_ERROR ||\n+\t\t    hdr->severity == IDLE_CHK_SEVERITY_ERROR_NO_TRAFFIC)\n+\t\t\t(*num_errors)++;\n+\t\telse\n+\t\t\t(*num_warnings)++;\n+\n+\t\t/* Print rule severity */\n+\t\tresults_offset +=\n+\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t    results_offset), \"%s: \",\n+\t\t\t    s_idle_chk_severity_str[hdr->severity]);\n+\n+\t\t/* Print rule message */\n+\t\tif (has_fw_msg)\n+\t\t\tparsing_str += strlen(parsing_str) + 1;\n+\t\tresults_offset +=\n+\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t    results_offset), \"%s.\",\n+\t\t\t    has_fw_msg &&\n+\t\t\t    print_fw_idle_chk ? parsing_str : lsi_msg);\n+\t\tparsing_str += strlen(parsing_str) + 1;\n+\n+\t\t/* Print register values */\n+\t\tresults_offset +=\n+\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t    results_offset), \" Registers:\");\n+\t\tfor (i = 0;\n+\t\t     i < hdr->num_dumped_cond_regs + hdr->num_dumped_info_regs;\n+\t\t     i++) {\n+\t\t\tstruct dbg_idle_chk_result_reg_hdr *reg_hdr;\n+\t\t\tbool is_mem;\n+\t\t\tu8 reg_id;\n+\n+\t\t\treg_hdr =\n+\t\t\t\t(struct dbg_idle_chk_result_reg_hdr *)dump_buf;\n+\t\t\tis_mem = GET_FIELD(reg_hdr->data,\n+\t\t\t\t\t   DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM);\n+\t\t\treg_id = GET_FIELD(reg_hdr->data,\n+\t\t\t\t\t   DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID);\n+\n+\t\t\t/* Skip reg header */\n+\t\t\tdump_buf += BYTES_TO_DWORDS(sizeof(*reg_hdr));\n+\n+\t\t\t/* Skip register names until the required reg_id is\n+\t\t\t * reached.\n+\t\t\t */\n+\t\t\twhile (reg_id > curr_reg_id) {\n+\t\t\t\tcurr_reg_id++;\n+\t\t\t\tparsing_str += strlen(parsing_str) + 1;\n+\t\t\t}\n+\n+\t\t\tresults_offset +=\n+\t\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t\t    results_offset), \" %s\",\n+\t\t\t\t    parsing_str);\n+\t\t\tif (i < hdr->num_dumped_cond_regs && is_mem)\n+\t\t\t\tresults_offset +=\n+\t\t\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t\t\t    results_offset),\n+\t\t\t\t\t    \"[%d]\", hdr->mem_entry_id +\n+\t\t\t\t\t    reg_hdr->start_entry);\n+\t\t\tresults_offset +=\n+\t\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t\t    results_offset), \"=\");\n+\t\t\tfor (j = 0; j < reg_hdr->size; j++, dump_buf++) {\n+\t\t\t\tresults_offset +=\n+\t\t\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t\t\t    results_offset),\n+\t\t\t\t\t    \"0x%x\", *dump_buf);\n+\t\t\t\tif (j < reg_hdr->size - 1)\n+\t\t\t\t\tresults_offset +=\n+\t\t\t\t\t    sprintf(qed_get_buf_ptr\n+\t\t\t\t\t\t    (results_buf,\n+\t\t\t\t\t\t     results_offset), \",\");\n+\t\t\t}\n+\t\t}\n+\n+\t\tresults_offset +=\n+\t\t    sprintf(qed_get_buf_ptr(results_buf, results_offset), \"\\n\");\n+\t}\n+\n+\t/* Check if end of dump buffer was exceeded */\n+\tif (dump_buf > dump_buf_end)\n+\t\treturn 0;\n+\n+\treturn results_offset;\n+}\n+\n+/* Parses an idle check dump buffer.\n+ * If result_buf is not NULL, the idle check results are printed to it.\n+ * In any case, the required results buffer size is assigned to\n+ * parsed_results_bytes.\n+ * The parsing status is returned.\n+ */\n+static enum dbg_status qed_parse_idle_chk_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t       u32 *dump_buf,\n+\t\t\t\t\t       u32 num_dumped_dwords,\n+\t\t\t\t\t       char *results_buf,\n+\t\t\t\t\t       u32 *parsed_results_bytes,\n+\t\t\t\t\t       u32 *num_errors,\n+\t\t\t\t\t       u32 *num_warnings)\n+{\n+\tconst char *section_name, *param_name, *param_str_val;\n+\tu32 *dump_buf_end = dump_buf + num_dumped_dwords;\n+\tu32 num_section_params = 0, num_rules;\n+\n+\t/* Offset in results_buf in bytes */\n+\tu32 results_offset = 0;\n+\n+\t*parsed_results_bytes = 0;\n+\t*num_errors = 0;\n+\t*num_warnings = 0;\n+\n+\tif (!p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr ||\n+\t    !p_hwfn->dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr)\n+\t\treturn DBG_STATUS_DBG_ARRAY_NOT_SET;\n+\n+\t/* Read global_params section */\n+\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t &section_name, &num_section_params);\n+\tif (strcmp(section_name, \"global_params\"))\n+\t\treturn DBG_STATUS_IDLE_CHK_PARSE_FAILED;\n+\n+\t/* Print global params */\n+\tdump_buf += qed_print_section_params(dump_buf,\n+\t\t\t\t\t     num_section_params,\n+\t\t\t\t\t     results_buf, &results_offset);\n+\n+\t/* Read idle_chk section */\n+\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t &section_name, &num_section_params);\n+\tif (strcmp(section_name, \"idle_chk\") || num_section_params != 1)\n+\t\treturn DBG_STATUS_IDLE_CHK_PARSE_FAILED;\n+\tdump_buf += qed_read_param(dump_buf,\n+\t\t\t\t   &param_name, &param_str_val, &num_rules);\n+\tif (strcmp(param_name, \"num_rules\"))\n+\t\treturn DBG_STATUS_IDLE_CHK_PARSE_FAILED;\n+\n+\tif (num_rules) {\n+\t\tu32 rules_print_size;\n+\n+\t\t/* Print FW output */\n+\t\tresults_offset +=\n+\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t    results_offset),\n+\t\t\t    \"FW_IDLE_CHECK:\\n\");\n+\t\trules_print_size =\n+\t\t\tqed_parse_idle_chk_dump_rules(p_hwfn,\n+\t\t\t\t\t\t      dump_buf,\n+\t\t\t\t\t\t      dump_buf_end,\n+\t\t\t\t\t\t      num_rules,\n+\t\t\t\t\t\t      true,\n+\t\t\t\t\t\t      results_buf ?\n+\t\t\t\t\t\t      results_buf +\n+\t\t\t\t\t\t      results_offset :\n+\t\t\t\t\t\t      NULL,\n+\t\t\t\t\t\t      num_errors,\n+\t\t\t\t\t\t      num_warnings);\n+\t\tresults_offset += rules_print_size;\n+\t\tif (!rules_print_size)\n+\t\t\treturn DBG_STATUS_IDLE_CHK_PARSE_FAILED;\n+\n+\t\t/* Print LSI output */\n+\t\tresults_offset +=\n+\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t    results_offset),\n+\t\t\t    \"\\nLSI_IDLE_CHECK:\\n\");\n+\t\trules_print_size =\n+\t\t\tqed_parse_idle_chk_dump_rules(p_hwfn,\n+\t\t\t\t\t\t      dump_buf,\n+\t\t\t\t\t\t      dump_buf_end,\n+\t\t\t\t\t\t      num_rules,\n+\t\t\t\t\t\t      false,\n+\t\t\t\t\t\t      results_buf ?\n+\t\t\t\t\t\t      results_buf +\n+\t\t\t\t\t\t      results_offset :\n+\t\t\t\t\t\t      NULL,\n+\t\t\t\t\t\t      num_errors,\n+\t\t\t\t\t\t      num_warnings);\n+\t\tresults_offset += rules_print_size;\n+\t\tif (!rules_print_size)\n+\t\t\treturn DBG_STATUS_IDLE_CHK_PARSE_FAILED;\n+\t}\n+\n+\t/* Print errors/warnings count */\n+\tif (*num_errors)\n+\t\tresults_offset +=\n+\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t    results_offset),\n+\t\t\t    \"\\nIdle Check failed!!! (with %d errors and %d warnings)\\n\",\n+\t\t\t    *num_errors, *num_warnings);\n+\telse if (*num_warnings)\n+\t\tresults_offset +=\n+\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t    results_offset),\n+\t\t\t    \"\\nIdle Check completed successfully (with %d warnings)\\n\",\n+\t\t\t    *num_warnings);\n+\telse\n+\t\tresults_offset +=\n+\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t    results_offset),\n+\t\t\t    \"\\nIdle Check completed successfully\\n\");\n+\n+\t/* Add 1 for string NULL termination */\n+\t*parsed_results_bytes = results_offset + 1;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Allocates and fills MCP Trace meta data based on the specified meta data\n+ * dump buffer.\n+ * Returns debug status code.\n+ */\n+static enum dbg_status\n+qed_mcp_trace_alloc_meta_data(struct ecore_hwfn *p_hwfn,\n+\t\t\t      const u32 *meta_buf)\n+{\n+\tstruct dbg_tools_user_data *dev_user_data;\n+\tu32 offset = 0, signature, i;\n+\tstruct mcp_trace_meta *meta;\n+\tu8 *meta_buf_bytes = (u8 *)(osal_uintptr_t)meta_buf;\n+\n+\tdev_user_data = qed_dbg_get_user_data(p_hwfn);\n+\tmeta = &dev_user_data->mcp_trace_meta;\n+\n+\t/* Free the previous meta before loading a new one. */\n+\tif (meta->is_allocated)\n+\t\tqed_mcp_trace_free_meta_data(p_hwfn);\n+\n+\tOSAL_MEMSET(meta, 0, sizeof(*meta));\n+\n+\t/* Read first signature */\n+\tsignature = qed_read_dword_from_buf(meta_buf_bytes, &offset);\n+\tif (signature != NVM_MAGIC_VALUE)\n+\t\treturn DBG_STATUS_INVALID_TRACE_SIGNATURE;\n+\n+\t/* Read no. of modules and allocate memory for their pointers */\n+\tmeta->modules_num = qed_read_byte_from_buf(meta_buf_bytes, &offset);\n+\tmeta->modules = (char **)OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,\n+\t\t\t\t    meta->modules_num * sizeof(char *));\n+\tif (!meta->modules)\n+\t\treturn DBG_STATUS_VIRT_MEM_ALLOC_FAILED;\n+\n+\t/* Allocate and read all module strings */\n+\tfor (i = 0; i < meta->modules_num; i++) {\n+\t\tu8 module_len = qed_read_byte_from_buf(meta_buf_bytes, &offset);\n+\n+\t\t*(meta->modules + i) = (char *)OSAL_ZALLOC(p_hwfn->p_dev,\n+\t\t\t\t\t\t\t   GFP_KERNEL,\n+\t\t\t\t\t\t\t   module_len);\n+\t\tif (!(*(meta->modules + i))) {\n+\t\t\t/* Update number of modules to be released */\n+\t\t\tmeta->modules_num = i ? i - 1 : 0;\n+\t\t\treturn DBG_STATUS_VIRT_MEM_ALLOC_FAILED;\n+\t\t}\n+\n+\t\tqed_read_str_from_buf(meta_buf_bytes, &offset, module_len,\n+\t\t\t\t      *(meta->modules + i));\n+\t\tif (module_len > MCP_TRACE_MAX_MODULE_LEN)\n+\t\t\t(*(meta->modules + i))[MCP_TRACE_MAX_MODULE_LEN] = '\\0';\n+\t}\n+\n+\t/* Read second signature */\n+\tsignature = qed_read_dword_from_buf(meta_buf_bytes, &offset);\n+\tif (signature != NVM_MAGIC_VALUE)\n+\t\treturn DBG_STATUS_INVALID_TRACE_SIGNATURE;\n+\n+\t/* Read number of formats and allocate memory for all formats */\n+\tmeta->formats_num = qed_read_dword_from_buf(meta_buf_bytes, &offset);\n+\tmeta->formats =\n+\t\t(struct mcp_trace_format *)OSAL_ZALLOC(p_hwfn->p_dev,\n+\t\t\t\t\t\t       GFP_KERNEL,\n+\t\t\t\t\t\t       meta->formats_num *\n+\t\t\t\t\t       sizeof(struct mcp_trace_format));\n+\tif (!meta->formats)\n+\t\treturn DBG_STATUS_VIRT_MEM_ALLOC_FAILED;\n+\n+\t/* Allocate and read all strings */\n+\tfor (i = 0; i < meta->formats_num; i++) {\n+\t\tstruct mcp_trace_format *format_ptr = &meta->formats[i];\n+\t\tu8 format_len;\n+\n+\t\tformat_ptr->data = qed_read_dword_from_buf(meta_buf_bytes,\n+\t\t\t\t\t\t\t   &offset);\n+\t\tformat_len = GET_MFW_FIELD(format_ptr->data,\n+\t\t\t\t\t   MCP_TRACE_FORMAT_LEN);\n+\t\tformat_ptr->format_str = (char *)OSAL_ZALLOC(p_hwfn->p_dev,\n+\t\t\t\t\t\t\t     GFP_KERNEL,\n+\t\t\t\t\t\t\t     format_len);\n+\t\tif (!format_ptr->format_str) {\n+\t\t\t/* Update number of modules to be released */\n+\t\t\tmeta->formats_num = i ? i - 1 : 0;\n+\t\t\treturn DBG_STATUS_VIRT_MEM_ALLOC_FAILED;\n+\t\t}\n+\n+\t\tqed_read_str_from_buf(meta_buf_bytes,\n+\t\t\t\t      &offset,\n+\t\t\t\t      format_len, format_ptr->format_str);\n+\t}\n+\n+\tmeta->is_allocated = true;\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Parses an MCP trace buffer. If result_buf is not NULL, the MCP Trace results\n+ * are printed to it. The parsing status is returned.\n+ * Arguments:\n+ * trace_buf - MCP trace cyclic buffer\n+ * trace_buf_size - MCP trace cyclic buffer size in bytes\n+ * data_offset - offset in bytes of the data to parse in the MCP trace cyclic\n+ *\t\t buffer.\n+ * data_size - size in bytes of data to parse.\n+ * parsed_buf - destination buffer for parsed data.\n+ * parsed_results_bytes - size of parsed data in bytes.\n+ */\n+static enum dbg_status qed_parse_mcp_trace_buf(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t       u8 *trace_buf,\n+\t\t\t\t\t       u32 trace_buf_size,\n+\t\t\t\t\t       u32 data_offset,\n+\t\t\t\t\t       u32 data_size,\n+\t\t\t\t\t       char *parsed_buf,\n+\t\t\t\t\t       u32 *parsed_results_bytes)\n+{\n+\tstruct dbg_tools_user_data *dev_user_data;\n+\tstruct mcp_trace_meta *meta;\n+\tu32 param_mask, param_shift;\n+\tenum dbg_status status;\n+\n+\tdev_user_data = qed_dbg_get_user_data(p_hwfn);\n+\tmeta = &dev_user_data->mcp_trace_meta;\n+\t*parsed_results_bytes = 0;\n+\n+\tif (!meta->is_allocated)\n+\t\treturn DBG_STATUS_MCP_TRACE_BAD_DATA;\n+\n+\tstatus = DBG_STATUS_OK;\n+\n+\twhile (data_size) {\n+\t\tstruct mcp_trace_format *format_ptr;\n+\t\tu8 format_level, format_module;\n+\t\tu32 params[3] = { 0, 0, 0 };\n+\t\tu32 header, format_idx, i;\n+\n+\t\tif (data_size < MFW_TRACE_ENTRY_SIZE)\n+\t\t\treturn DBG_STATUS_MCP_TRACE_BAD_DATA;\n+\n+\t\theader = qed_read_from_cyclic_buf(trace_buf,\n+\t\t\t\t\t\t  &data_offset,\n+\t\t\t\t\t\t  trace_buf_size,\n+\t\t\t\t\t\t  MFW_TRACE_ENTRY_SIZE);\n+\t\tdata_size -= MFW_TRACE_ENTRY_SIZE;\n+\t\tformat_idx = header & MFW_TRACE_EVENTID_MASK;\n+\n+\t\t/* Skip message if its index doesn't exist in the meta data */\n+\t\tif (format_idx >= meta->formats_num) {\n+\t\t\tu8 format_size = (u8)GET_MFW_FIELD(header,\n+\t\t\t\t\t\t\t   MFW_TRACE_PRM_SIZE);\n+\n+\t\t\tif (data_size < format_size)\n+\t\t\t\treturn DBG_STATUS_MCP_TRACE_BAD_DATA;\n+\n+\t\t\tdata_offset = qed_cyclic_add(data_offset,\n+\t\t\t\t\t\t     format_size,\n+\t\t\t\t\t\t     trace_buf_size);\n+\t\t\tdata_size -= format_size;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tformat_ptr =\n+\t\t\t(struct mcp_trace_format *)&meta->formats[format_idx];\n+\n+\t\tfor (i = 0,\n+\t\t     param_mask = MCP_TRACE_FORMAT_P1_SIZE_MASK, param_shift =\n+\t\t     MCP_TRACE_FORMAT_P1_SIZE_OFFSET;\n+\t\t     i < MCP_TRACE_FORMAT_MAX_PARAMS;\n+\t\t     i++, param_mask <<= MCP_TRACE_FORMAT_PARAM_WIDTH,\n+\t\t     param_shift += MCP_TRACE_FORMAT_PARAM_WIDTH) {\n+\t\t\t/* Extract param size (0..3) */\n+\t\t\tu8 param_size = (u8)((format_ptr->data & param_mask) >>\n+\t\t\t\t\t     param_shift);\n+\n+\t\t\t/* If the param size is zero, there are no other\n+\t\t\t * parameters.\n+\t\t\t */\n+\t\t\tif (!param_size)\n+\t\t\t\tbreak;\n+\n+\t\t\t/* Size is encoded using 2 bits, where 3 is used to\n+\t\t\t * encode 4.\n+\t\t\t */\n+\t\t\tif (param_size == 3)\n+\t\t\t\tparam_size = 4;\n+\n+\t\t\tif (data_size < param_size)\n+\t\t\t\treturn DBG_STATUS_MCP_TRACE_BAD_DATA;\n+\n+\t\t\tparams[i] = qed_read_from_cyclic_buf(trace_buf,\n+\t\t\t\t\t\t\t     &data_offset,\n+\t\t\t\t\t\t\t     trace_buf_size,\n+\t\t\t\t\t\t\t     param_size);\n+\t\t\tdata_size -= param_size;\n+\t\t}\n+\n+\t\tformat_level = (u8)GET_MFW_FIELD(format_ptr->data,\n+\t\t\t\t\t\t MCP_TRACE_FORMAT_LEVEL);\n+\t\tformat_module = (u8)GET_MFW_FIELD(format_ptr->data,\n+\t\t\t\t\t\t  MCP_TRACE_FORMAT_MODULE);\n+\t\tif (format_level >= OSAL_ARRAY_SIZE(s_mcp_trace_level_str))\n+\t\t\treturn DBG_STATUS_MCP_TRACE_BAD_DATA;\n+\n+\t\t/* Print current message to results buffer */\n+\t\t*parsed_results_bytes +=\n+\t\t\tOSAL_SPRINTF(qed_get_buf_ptr(parsed_buf,\n+\t\t\t\t\t\t*parsed_results_bytes),\n+\t\t\t\t\"%s %-8s: \",\n+\t\t\t\ts_mcp_trace_level_str[format_level],\n+\t\t\t\tmeta->modules[format_module]);\n+\t\t*parsed_results_bytes +=\n+\t\t    sprintf(qed_get_buf_ptr(parsed_buf, *parsed_results_bytes),\n+\t\t\t    format_ptr->format_str,\n+\t\t\t    params[0], params[1], params[2]);\n+\t}\n+\n+\t/* Add string NULL terminator */\n+\t(*parsed_results_bytes)++;\n+\n+\treturn status;\n+}\n+\n+/* Parses an MCP Trace dump buffer.\n+ * If result_buf is not NULL, the MCP Trace results are printed to it.\n+ * In any case, the required results buffer size is assigned to\n+ * parsed_results_bytes.\n+ * The parsing status is returned.\n+ */\n+static enum dbg_status qed_parse_mcp_trace_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\tu32 *dump_buf,\n+\t\t\t\t\t\tchar *results_buf,\n+\t\t\t\t\t\tu32 *parsed_results_bytes,\n+\t\t\t\t\t\tbool free_meta_data)\n+{\n+\tconst char *section_name, *param_name, *param_str_val;\n+\tu32 data_size, trace_data_dwords, trace_meta_dwords;\n+\tu32 offset, results_offset, results_buf_bytes;\n+\tu32 param_num_val, num_section_params;\n+\tstruct mcp_trace *trace;\n+\tenum dbg_status status;\n+\tconst u32 *meta_buf;\n+\tu8 *trace_buf;\n+\n+\t*parsed_results_bytes = 0;\n+\n+\t/* Read global_params section */\n+\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t &section_name, &num_section_params);\n+\tif (strcmp(section_name, \"global_params\"))\n+\t\treturn DBG_STATUS_MCP_TRACE_BAD_DATA;\n+\n+\t/* Print global params */\n+\tdump_buf += qed_print_section_params(dump_buf,\n+\t\t\t\t\t     num_section_params,\n+\t\t\t\t\t     results_buf, &results_offset);\n+\n+\t/* Read trace_data section */\n+\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t &section_name, &num_section_params);\n+\tif (strcmp(section_name, \"mcp_trace_data\") || num_section_params != 1)\n+\t\treturn DBG_STATUS_MCP_TRACE_BAD_DATA;\n+\tdump_buf += qed_read_param(dump_buf,\n+\t\t\t\t   &param_name, &param_str_val, &param_num_val);\n+\tif (strcmp(param_name, \"size\"))\n+\t\treturn DBG_STATUS_MCP_TRACE_BAD_DATA;\n+\ttrace_data_dwords = param_num_val;\n+\n+\t/* Prepare trace info */\n+\ttrace = (struct mcp_trace *)dump_buf;\n+\tif (trace->signature != MFW_TRACE_SIGNATURE || !trace->size)\n+\t\treturn DBG_STATUS_MCP_TRACE_BAD_DATA;\n+\n+\ttrace_buf = (u8 *)dump_buf + sizeof(*trace);\n+\toffset = trace->trace_oldest;\n+\tdata_size = qed_cyclic_sub(trace->trace_prod, offset, trace->size);\n+\tdump_buf += trace_data_dwords;\n+\n+\t/* Read meta_data section */\n+\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t &section_name, &num_section_params);\n+\tif (strcmp(section_name, \"mcp_trace_meta\"))\n+\t\treturn DBG_STATUS_MCP_TRACE_BAD_DATA;\n+\tdump_buf += qed_read_param(dump_buf,\n+\t\t\t\t   &param_name, &param_str_val, &param_num_val);\n+\tif (strcmp(param_name, \"size\"))\n+\t\treturn DBG_STATUS_MCP_TRACE_BAD_DATA;\n+\ttrace_meta_dwords = param_num_val;\n+\n+\t/* Choose meta data buffer */\n+\tif (!trace_meta_dwords) {\n+\t\t/* Dump doesn't include meta data */\n+\t\tstruct dbg_tools_user_data *dev_user_data =\n+\t\t\tqed_dbg_get_user_data(p_hwfn);\n+\n+\t\tif (!dev_user_data->mcp_trace_user_meta_buf)\n+\t\t\treturn DBG_STATUS_MCP_TRACE_NO_META;\n+\n+\t\tmeta_buf = dev_user_data->mcp_trace_user_meta_buf;\n+\t} else {\n+\t\t/* Dump includes meta data */\n+\t\tmeta_buf = dump_buf;\n+\t}\n+\n+\t/* Allocate meta data memory */\n+\tstatus = qed_mcp_trace_alloc_meta_data(p_hwfn, meta_buf);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\tstatus = qed_parse_mcp_trace_buf(p_hwfn,\n+\t\t\t\t\t trace_buf,\n+\t\t\t\t\t trace->size,\n+\t\t\t\t\t offset,\n+\t\t\t\t\t data_size,\n+\t\t\t\t\t results_buf ?\n+\t\t\t\t\t results_buf + results_offset :\n+\t\t\t\t\t NULL,\n+\t\t\t\t\t &results_buf_bytes);\n+\tif (status != DBG_STATUS_OK)\n+\t\treturn status;\n+\n+\tif (free_meta_data)\n+\t\tqed_mcp_trace_free_meta_data(p_hwfn);\n+\n+\t*parsed_results_bytes = results_offset + results_buf_bytes;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Parses a Reg FIFO dump buffer.\n+ * If result_buf is not NULL, the Reg FIFO results are printed to it.\n+ * In any case, the required results buffer size is assigned to\n+ * parsed_results_bytes.\n+ * The parsing status is returned.\n+ */\n+static enum dbg_status qed_parse_reg_fifo_dump(u32 *dump_buf,\n+\t\t\t\t\t       char *results_buf,\n+\t\t\t\t\t       u32 *parsed_results_bytes)\n+{\n+\tconst char *section_name, *param_name, *param_str_val;\n+\tu32 param_num_val, num_section_params, num_elements;\n+\tstruct reg_fifo_element *elements;\n+\tu8 i, j, err_code, vf_val;\n+\tu32 results_offset = 0;\n+\tchar vf_str[4];\n+\n+\t/* Read global_params section */\n+\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t &section_name, &num_section_params);\n+\tif (strcmp(section_name, \"global_params\"))\n+\t\treturn DBG_STATUS_REG_FIFO_BAD_DATA;\n+\n+\t/* Print global params */\n+\tdump_buf += qed_print_section_params(dump_buf,\n+\t\t\t\t\t     num_section_params,\n+\t\t\t\t\t     results_buf, &results_offset);\n+\n+\t/* Read reg_fifo_data section */\n+\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t &section_name, &num_section_params);\n+\tif (strcmp(section_name, \"reg_fifo_data\"))\n+\t\treturn DBG_STATUS_REG_FIFO_BAD_DATA;\n+\tdump_buf += qed_read_param(dump_buf,\n+\t\t\t\t   &param_name, &param_str_val, &param_num_val);\n+\tif (strcmp(param_name, \"size\"))\n+\t\treturn DBG_STATUS_REG_FIFO_BAD_DATA;\n+\tif (param_num_val % REG_FIFO_ELEMENT_DWORDS)\n+\t\treturn DBG_STATUS_REG_FIFO_BAD_DATA;\n+\tnum_elements = param_num_val / REG_FIFO_ELEMENT_DWORDS;\n+\telements = (struct reg_fifo_element *)dump_buf;\n+\n+\t/* Decode elements */\n+\tfor (i = 0; i < num_elements; i++) {\n+\t\tconst char *err_msg = NULL;\n+\n+\t\t/* Discover if element belongs to a VF or a PF */\n+\t\tvf_val = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_VF);\n+\t\tif (vf_val == REG_FIFO_ELEMENT_IS_PF_VF_VAL)\n+\t\t\tsprintf(vf_str, \"%s\", \"N/A\");\n+\t\telse\n+\t\t\tsprintf(vf_str, \"%d\", vf_val);\n+\n+\t\t/* Find error message */\n+\t\terr_code = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_ERROR);\n+\t\tfor (j = 0; j < OSAL_ARRAY_SIZE(s_reg_fifo_errors) && !err_msg;\n+\t\t     j++)\n+\t\t\tif (err_code == s_reg_fifo_errors[j].err_code)\n+\t\t\t\terr_msg = s_reg_fifo_errors[j].err_msg;\n+\n+\t\t/* Add parsed element to parsed buffer */\n+\t\tresults_offset +=\n+\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t    results_offset),\n+\t\t\t    \"raw: 0x%016lx, address: 0x%07x, access: %-5s, pf: %2d, vf: %s, port: %d, privilege: %-3s, protection: %-12s, master: %-4s, error: %s\\n\",\n+\t\t\t    elements[i].data,\n+\t\t\t    (u32)GET_FIELD(elements[i].data,\n+\t\t\t\t\t   REG_FIFO_ELEMENT_ADDRESS) *\n+\t\t\t    REG_FIFO_ELEMENT_ADDR_FACTOR,\n+\t\t\t    s_access_strs[GET_FIELD(elements[i].data,\n+\t\t\t\t\t\t    REG_FIFO_ELEMENT_ACCESS)],\n+\t\t\t    (u32)GET_FIELD(elements[i].data,\n+\t\t\t\t\t   REG_FIFO_ELEMENT_PF),\n+\t\t\t    vf_str,\n+\t\t\t    (u32)GET_FIELD(elements[i].data,\n+\t\t\t\t\t   REG_FIFO_ELEMENT_PORT),\n+\t\t\t    s_privilege_strs[GET_FIELD(elements[i].data,\n+\t\t\t\t\t\tREG_FIFO_ELEMENT_PRIVILEGE)],\n+\t\t\t    s_protection_strs[GET_FIELD(elements[i].data,\n+\t\t\t\t\t\tREG_FIFO_ELEMENT_PROTECTION)],\n+\t\t\t    s_master_strs[GET_FIELD(elements[i].data,\n+\t\t\t\t\t\t    REG_FIFO_ELEMENT_MASTER)],\n+\t\t\t    err_msg ? err_msg : \"unknown error code\");\n+\t}\n+\n+\tresults_offset += sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t\t  results_offset),\n+\t\t\t\t  \"fifo contained %d elements\", num_elements);\n+\n+\t/* Add 1 for string NULL termination */\n+\t*parsed_results_bytes = results_offset + 1;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+static enum dbg_status qed_parse_igu_fifo_element(struct igu_fifo_element\n+\t\t\t\t\t\t  *element, char\n+\t\t\t\t\t\t  *results_buf,\n+\t\t\t\t\t\t  u32 *results_offset)\n+{\n+\tconst struct igu_fifo_addr_data *found_addr = NULL;\n+\tu8 source, err_type, i, is_cleanup;\n+\tchar parsed_addr_data[32];\n+\tchar parsed_wr_data[256];\n+\tu32 wr_data, prod_cons;\n+\tbool is_wr_cmd, is_pf;\n+\tu16 cmd_addr;\n+\tu64 dword12;\n+\n+\t/* Dword12 (dword index 1 and 2) contains bits 32..95 of the\n+\t * FIFO element.\n+\t */\n+\tdword12 = ((u64)element->dword2 << 32) | element->dword1;\n+\tis_wr_cmd = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD);\n+\tis_pf = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_IS_PF);\n+\tcmd_addr = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR);\n+\tsource = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_SOURCE);\n+\terr_type = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE);\n+\n+\tif (source >= OSAL_ARRAY_SIZE(s_igu_fifo_source_strs))\n+\t\treturn DBG_STATUS_IGU_FIFO_BAD_DATA;\n+\tif (err_type >= OSAL_ARRAY_SIZE(s_igu_fifo_error_strs))\n+\t\treturn DBG_STATUS_IGU_FIFO_BAD_DATA;\n+\n+\t/* Find address data */\n+\tfor (i = 0; i < OSAL_ARRAY_SIZE(s_igu_fifo_addr_data) && !found_addr;\n+\t     i++) {\n+\t\tconst struct igu_fifo_addr_data *curr_addr =\n+\t\t\t&s_igu_fifo_addr_data[i];\n+\n+\t\tif (cmd_addr >= curr_addr->start_addr && cmd_addr <=\n+\t\t    curr_addr->end_addr)\n+\t\t\tfound_addr = curr_addr;\n+\t}\n+\n+\tif (!found_addr)\n+\t\treturn DBG_STATUS_IGU_FIFO_BAD_DATA;\n+\n+\t/* Prepare parsed address data */\n+\tswitch (found_addr->type) {\n+\tcase IGU_ADDR_TYPE_MSIX_MEM:\n+\t\tsprintf(parsed_addr_data, \" vector_num = 0x%x\", cmd_addr / 2);\n+\t\tbreak;\n+\tcase IGU_ADDR_TYPE_WRITE_INT_ACK:\n+\tcase IGU_ADDR_TYPE_WRITE_PROD_UPDATE:\n+\t\tsprintf(parsed_addr_data,\n+\t\t\t\" SB = 0x%x\", cmd_addr - found_addr->start_addr);\n+\t\tbreak;\n+\tdefault:\n+\t\tparsed_addr_data[0] = '\\0';\n+\t}\n+\n+\tif (!is_wr_cmd) {\n+\t\tparsed_wr_data[0] = '\\0';\n+\t\tgoto out;\n+\t}\n+\n+\t/* Prepare parsed write data */\n+\twr_data = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_WR_DATA);\n+\tprod_cons = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_PROD_CONS);\n+\tis_cleanup = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_CMD_TYPE);\n+\n+\tif (source == IGU_SRC_ATTN) {\n+\t\tsprintf(parsed_wr_data, \"prod: 0x%x, \", prod_cons);\n+\t} else {\n+\t\tif (is_cleanup) {\n+\t\t\tu8 cleanup_val, cleanup_type;\n+\n+\t\t\tcleanup_val =\n+\t\t\t\tGET_FIELD(wr_data,\n+\t\t\t\t\t  IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL);\n+\t\t\tcleanup_type =\n+\t\t\t    GET_FIELD(wr_data,\n+\t\t\t\t      IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE);\n+\n+\t\t\tsprintf(parsed_wr_data,\n+\t\t\t\t\"cmd_type: cleanup, cleanup_val: %s, cleanup_type : %d, \",\n+\t\t\t\tcleanup_val ? \"set\" : \"clear\",\n+\t\t\t\tcleanup_type);\n+\t\t} else {\n+\t\t\tu8 update_flag, en_dis_int_for_sb, segment;\n+\t\t\tu8 timer_mask;\n+\n+\t\t\tupdate_flag = GET_FIELD(wr_data,\n+\t\t\t\t\t\tIGU_FIFO_WR_DATA_UPDATE_FLAG);\n+\t\t\ten_dis_int_for_sb =\n+\t\t\t\tGET_FIELD(wr_data,\n+\t\t\t\t\t  IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB);\n+\t\t\tsegment = GET_FIELD(wr_data,\n+\t\t\t\t\t    IGU_FIFO_WR_DATA_SEGMENT);\n+\t\t\ttimer_mask = GET_FIELD(wr_data,\n+\t\t\t\t\t       IGU_FIFO_WR_DATA_TIMER_MASK);\n+\n+\t\t\tsprintf(parsed_wr_data,\n+\t\t\t\t\"cmd_type: prod/cons update, prod/cons: 0x%x, update_flag: %s, en_dis_int_for_sb : %s, segment : %s, timer_mask = %d, \",\n+\t\t\t\tprod_cons,\n+\t\t\t\tupdate_flag ? \"update\" : \"nop\",\n+\t\t\t\ten_dis_int_for_sb ?\n+\t\t\t\t(en_dis_int_for_sb == 1 ? \"disable\" : \"nop\") :\n+\t\t\t\t\"enable\",\n+\t\t\t\tsegment ? \"attn\" : \"regular\",\n+\t\t\t\ttimer_mask);\n+\t\t}\n+\t}\n+out:\n+\t/* Add parsed element to parsed buffer */\n+\t*results_offset += sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t\t   *results_offset),\n+\t\t\t\t   \"raw: 0x%01x%08x%08x, %s: %d, source : %s, type : %s, cmd_addr : 0x%x(%s%s), %serror: %s\\n\",\n+\t\t\t\t   element->dword2, element->dword1,\n+\t\t\t\t   element->dword0,\n+\t\t\t\t   is_pf ? \"pf\" : \"vf\",\n+\t\t\t\t   GET_FIELD(element->dword0,\n+\t\t\t\t\t     IGU_FIFO_ELEMENT_DWORD0_FID),\n+\t\t\t\t   s_igu_fifo_source_strs[source],\n+\t\t\t\t   is_wr_cmd ? \"wr\" : \"rd\",\n+\t\t\t\t   cmd_addr,\n+\t\t\t\t   (!is_pf && found_addr->vf_desc)\n+\t\t\t\t   ? found_addr->vf_desc\n+\t\t\t\t   : found_addr->desc,\n+\t\t\t\t   parsed_addr_data,\n+\t\t\t\t   parsed_wr_data,\n+\t\t\t\t   s_igu_fifo_error_strs[err_type]);\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Parses an IGU FIFO dump buffer.\n+ * If result_buf is not NULL, the IGU FIFO results are printed to it.\n+ * In any case, the required results buffer size is assigned to\n+ * parsed_results_bytes.\n+ * The parsing status is returned.\n+ */\n+static enum dbg_status qed_parse_igu_fifo_dump(u32 *dump_buf,\n+\t\t\t\t\t       char *results_buf,\n+\t\t\t\t\t       u32 *parsed_results_bytes)\n+{\n+\tconst char *section_name, *param_name, *param_str_val;\n+\tu32 param_num_val, num_section_params, num_elements;\n+\tstruct igu_fifo_element *elements;\n+\tenum dbg_status status;\n+\tu32 results_offset = 0;\n+\tu8 i;\n+\n+\t/* Read global_params section */\n+\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t &section_name, &num_section_params);\n+\tif (strcmp(section_name, \"global_params\"))\n+\t\treturn DBG_STATUS_IGU_FIFO_BAD_DATA;\n+\n+\t/* Print global params */\n+\tdump_buf += qed_print_section_params(dump_buf,\n+\t\t\t\t\t     num_section_params,\n+\t\t\t\t\t     results_buf, &results_offset);\n+\n+\t/* Read igu_fifo_data section */\n+\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t &section_name, &num_section_params);\n+\tif (strcmp(section_name, \"igu_fifo_data\"))\n+\t\treturn DBG_STATUS_IGU_FIFO_BAD_DATA;\n+\tdump_buf += qed_read_param(dump_buf,\n+\t\t\t\t   &param_name, &param_str_val, &param_num_val);\n+\tif (strcmp(param_name, \"size\"))\n+\t\treturn DBG_STATUS_IGU_FIFO_BAD_DATA;\n+\tif (param_num_val % IGU_FIFO_ELEMENT_DWORDS)\n+\t\treturn DBG_STATUS_IGU_FIFO_BAD_DATA;\n+\tnum_elements = param_num_val / IGU_FIFO_ELEMENT_DWORDS;\n+\telements = (struct igu_fifo_element *)dump_buf;\n+\n+\t/* Decode elements */\n+\tfor (i = 0; i < num_elements; i++) {\n+\t\tstatus = qed_parse_igu_fifo_element(&elements[i],\n+\t\t\t\t\t\t    results_buf,\n+\t\t\t\t\t\t    &results_offset);\n+\t\tif (status != DBG_STATUS_OK)\n+\t\t\treturn status;\n+\t}\n+\n+\tresults_offset += sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t\t  results_offset),\n+\t\t\t\t  \"fifo contained %d elements\", num_elements);\n+\n+\t/* Add 1 for string NULL termination */\n+\t*parsed_results_bytes = results_offset + 1;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+static enum dbg_status\n+qed_parse_protection_override_dump(u32 *dump_buf,\n+\t\t\t\t   char *results_buf,\n+\t\t\t\t   u32 *parsed_results_bytes)\n+{\n+\tconst char *section_name, *param_name, *param_str_val;\n+\tu32 param_num_val, num_section_params, num_elements;\n+\tstruct protection_override_element *elements;\n+\tu32 results_offset = 0;\n+\tu8 i;\n+\n+\t/* Read global_params section */\n+\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t &section_name, &num_section_params);\n+\tif (strcmp(section_name, \"global_params\"))\n+\t\treturn DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;\n+\n+\t/* Print global params */\n+\tdump_buf += qed_print_section_params(dump_buf,\n+\t\t\t\t\t     num_section_params,\n+\t\t\t\t\t     results_buf, &results_offset);\n+\n+\t/* Read protection_override_data section */\n+\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t &section_name, &num_section_params);\n+\tif (strcmp(section_name, \"protection_override_data\"))\n+\t\treturn DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;\n+\tdump_buf += qed_read_param(dump_buf,\n+\t\t\t\t   &param_name, &param_str_val, &param_num_val);\n+\tif (strcmp(param_name, \"size\"))\n+\t\treturn DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;\n+\tif (param_num_val % PROTECTION_OVERRIDE_ELEMENT_DWORDS)\n+\t\treturn DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;\n+\tnum_elements = param_num_val / PROTECTION_OVERRIDE_ELEMENT_DWORDS;\n+\telements = (struct protection_override_element *)dump_buf;\n+\n+\t/* Decode elements */\n+\tfor (i = 0; i < num_elements; i++) {\n+\t\tu32 address = GET_FIELD(elements[i].data,\n+\t\t\t\t\tPROTECTION_OVERRIDE_ELEMENT_ADDRESS) *\n+\t\t\t      PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR;\n+\n+\t\tresults_offset +=\n+\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t    results_offset),\n+\t\t\t    \"window %2d, address: 0x%07x, size: %7d regs, read: %d, write: %d, read protection: %-12s, write protection: %-12s\\n\",\n+\t\t\t    i, address,\n+\t\t\t    (u32)GET_FIELD(elements[i].data,\n+\t\t\t\t      PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE),\n+\t\t\t    (u32)GET_FIELD(elements[i].data,\n+\t\t\t\t      PROTECTION_OVERRIDE_ELEMENT_READ),\n+\t\t\t    (u32)GET_FIELD(elements[i].data,\n+\t\t\t\t      PROTECTION_OVERRIDE_ELEMENT_WRITE),\n+\t\t\t    s_protection_strs[GET_FIELD(elements[i].data,\n+\t\t\t\tPROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION)],\n+\t\t\t    s_protection_strs[GET_FIELD(elements[i].data,\n+\t\t\t\tPROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION)]);\n+\t}\n+\n+\tresults_offset += sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t\t  results_offset),\n+\t\t\t\t  \"protection override contained %d elements\",\n+\t\t\t\t  num_elements);\n+\n+\t/* Add 1 for string NULL termination */\n+\t*parsed_results_bytes = results_offset + 1;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Parses a FW Asserts dump buffer.\n+ * If result_buf is not NULL, the FW Asserts results are printed to it.\n+ * In any case, the required results buffer size is assigned to\n+ * parsed_results_bytes.\n+ * The parsing status is returned.\n+ */\n+static enum dbg_status qed_parse_fw_asserts_dump(u32 *dump_buf,\n+\t\t\t\t\t\t char *results_buf,\n+\t\t\t\t\t\t u32 *parsed_results_bytes)\n+{\n+\tu32 num_section_params, param_num_val, i, results_offset = 0;\n+\tconst char *param_name, *param_str_val, *section_name;\n+\tbool last_section_found = false;\n+\n+\t*parsed_results_bytes = 0;\n+\n+\t/* Read global_params section */\n+\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t &section_name, &num_section_params);\n+\tif (strcmp(section_name, \"global_params\"))\n+\t\treturn DBG_STATUS_FW_ASSERTS_PARSE_FAILED;\n+\n+\t/* Print global params */\n+\tdump_buf += qed_print_section_params(dump_buf,\n+\t\t\t\t\t     num_section_params,\n+\t\t\t\t\t     results_buf, &results_offset);\n+\n+\twhile (!last_section_found) {\n+\t\tdump_buf += qed_read_section_hdr(dump_buf,\n+\t\t\t\t\t\t &section_name,\n+\t\t\t\t\t\t &num_section_params);\n+\t\tif (!strcmp(section_name, \"fw_asserts\")) {\n+\t\t\t/* Extract params */\n+\t\t\tconst char *storm_letter = NULL;\n+\t\t\tu32 storm_dump_size = 0;\n+\n+\t\t\tfor (i = 0; i < num_section_params; i++) {\n+\t\t\t\tdump_buf += qed_read_param(dump_buf,\n+\t\t\t\t\t\t\t   &param_name,\n+\t\t\t\t\t\t\t   &param_str_val,\n+\t\t\t\t\t\t\t   &param_num_val);\n+\t\t\t\tif (!strcmp(param_name, \"storm\"))\n+\t\t\t\t\tstorm_letter = param_str_val;\n+\t\t\t\telse if (!strcmp(param_name, \"size\"))\n+\t\t\t\t\tstorm_dump_size = param_num_val;\n+\t\t\t\telse\n+\t\t\t\t\treturn\n+\t\t\t\t\t    DBG_STATUS_FW_ASSERTS_PARSE_FAILED;\n+\t\t\t}\n+\n+\t\t\tif (!storm_letter || !storm_dump_size)\n+\t\t\t\treturn DBG_STATUS_FW_ASSERTS_PARSE_FAILED;\n+\n+\t\t\t/* Print data */\n+\t\t\tresults_offset +=\n+\t\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t\t    results_offset),\n+\t\t\t\t    \"\\n%sSTORM_ASSERT: size=%d\\n\",\n+\t\t\t\t    storm_letter, storm_dump_size);\n+\t\t\tfor (i = 0; i < storm_dump_size; i++, dump_buf++)\n+\t\t\t\tresults_offset +=\n+\t\t\t\t    sprintf(qed_get_buf_ptr(results_buf,\n+\t\t\t\t\t\t\t    results_offset),\n+\t\t\t\t\t    \"%08x\\n\", *dump_buf);\n+\t\t} else if (!strcmp(section_name, \"last\")) {\n+\t\t\tlast_section_found = true;\n+\t\t} else {\n+\t\t\treturn DBG_STATUS_FW_ASSERTS_PARSE_FAILED;\n+\t\t}\n+\t}\n+\n+\t/* Add 1 for string NULL termination */\n+\t*parsed_results_bytes = results_offset + 1;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/***************************** Public Functions *******************************/\n+\n+enum dbg_status qed_dbg_user_set_bin_ptr(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t const u8 * const bin_ptr)\n+{\n+\tstruct bin_buffer_hdr *buf_hdrs =\n+\t\t\t(struct bin_buffer_hdr *)(osal_uintptr_t)bin_ptr;\n+\tu8 buf_id;\n+\n+\t/* Convert binary data to debug arrays */\n+\tfor (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++)\n+\t\tqed_set_dbg_bin_buf(p_hwfn,\n+\t\t\t\t    (enum bin_dbg_buffer_type)buf_id,\n+\t\t\t\t    (const u32 *)(bin_ptr +\n+\t\t\t\t\t\t  buf_hdrs[buf_id].offset),\n+\t\t\t\t\t\t  buf_hdrs[buf_id].length);\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+enum dbg_status qed_dbg_alloc_user_data(__rte_unused struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\tvoid **user_data_ptr)\n+{\n+\t*user_data_ptr = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,\n+\t\t\t\t     sizeof(struct dbg_tools_user_data));\n+\tif (!(*user_data_ptr))\n+\t\treturn DBG_STATUS_VIRT_MEM_ALLOC_FAILED;\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+const char *qed_dbg_get_status_str(enum dbg_status status)\n+{\n+\treturn (status <\n+\t\tMAX_DBG_STATUS) ? s_status_str[status] : \"Invalid debug status\";\n+}\n+\n+enum dbg_status qed_get_idle_chk_results_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t  u32 *dump_buf,\n+\t\t\t\t\t\t  u32 num_dumped_dwords,\n+\t\t\t\t\t\t  u32 *results_buf_size)\n+{\n+\tu32 num_errors, num_warnings;\n+\n+\treturn qed_parse_idle_chk_dump(p_hwfn,\n+\t\t\t\t       dump_buf,\n+\t\t\t\t       num_dumped_dwords,\n+\t\t\t\t       NULL,\n+\t\t\t\t       results_buf_size,\n+\t\t\t\t       &num_errors, &num_warnings);\n+}\n+\n+enum dbg_status qed_print_idle_chk_results(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t   u32 *dump_buf,\n+\t\t\t\t\t   u32 num_dumped_dwords,\n+\t\t\t\t\t   char *results_buf,\n+\t\t\t\t\t   u32 *num_errors,\n+\t\t\t\t\t   u32 *num_warnings)\n+{\n+\tu32 parsed_buf_size;\n+\n+\treturn qed_parse_idle_chk_dump(p_hwfn,\n+\t\t\t\t       dump_buf,\n+\t\t\t\t       num_dumped_dwords,\n+\t\t\t\t       results_buf,\n+\t\t\t\t       &parsed_buf_size,\n+\t\t\t\t       num_errors, num_warnings);\n+}\n+\n+void qed_dbg_mcp_trace_set_meta_data(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t     const u32 *meta_buf)\n+{\n+\tstruct dbg_tools_user_data *dev_user_data =\n+\t\tqed_dbg_get_user_data(p_hwfn);\n+\n+\tdev_user_data->mcp_trace_user_meta_buf = meta_buf;\n+}\n+\n+enum dbg_status\n+qed_get_mcp_trace_results_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   u32 *dump_buf,\n+\t\t\t\t   __rte_unused u32 num_dumped_dwords,\n+\t\t\t\t   u32 *results_buf_size)\n+{\n+\treturn qed_parse_mcp_trace_dump(p_hwfn,\n+\t\t\t\t\tdump_buf, NULL, results_buf_size, true);\n+}\n+\n+enum dbg_status qed_print_mcp_trace_results(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t    u32 *dump_buf,\n+\t\t\t\t\t    __rte_unused u32 num_dumped_dwords,\n+\t\t\t\t\t    char *results_buf)\n+{\n+\tu32 parsed_buf_size;\n+\n+\treturn qed_parse_mcp_trace_dump(p_hwfn,\n+\t\t\t\t\tdump_buf,\n+\t\t\t\t\tresults_buf, &parsed_buf_size, true);\n+}\n+\n+enum dbg_status qed_print_mcp_trace_results_cont(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t u32 *dump_buf,\n+\t\t\t\t\t\t char *results_buf)\n+{\n+\tu32 parsed_buf_size;\n+\n+\treturn qed_parse_mcp_trace_dump(p_hwfn, dump_buf, results_buf,\n+\t\t\t\t\t&parsed_buf_size, false);\n+}\n+\n+enum dbg_status qed_print_mcp_trace_line(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t u8 *dump_buf,\n+\t\t\t\t\t u32 num_dumped_bytes,\n+\t\t\t\t\t char *results_buf)\n+{\n+\tu32 parsed_results_bytes;\n+\n+\treturn qed_parse_mcp_trace_buf(p_hwfn,\n+\t\t\t\t       dump_buf,\n+\t\t\t\t       num_dumped_bytes,\n+\t\t\t\t       0,\n+\t\t\t\t       num_dumped_bytes,\n+\t\t\t\t       results_buf, &parsed_results_bytes);\n+}\n+\n+/* Frees the specified MCP Trace meta data */\n+void qed_mcp_trace_free_meta_data(struct ecore_hwfn *p_hwfn)\n+{\n+\tstruct dbg_tools_user_data *dev_user_data;\n+\tstruct mcp_trace_meta *meta;\n+\tu32 i;\n+\n+\tdev_user_data = qed_dbg_get_user_data(p_hwfn);\n+\tmeta = &dev_user_data->mcp_trace_meta;\n+\tif (!meta->is_allocated)\n+\t\treturn;\n+\n+\t/* Release modules */\n+\tif (meta->modules) {\n+\t\tfor (i = 0; i < meta->modules_num; i++)\n+\t\t\tOSAL_FREE(p_hwfn, meta->modules[i]);\n+\t\tOSAL_FREE(p_hwfn, meta->modules);\n+\t}\n+\n+\t/* Release formats */\n+\tif (meta->formats) {\n+\t\tfor (i = 0; i < meta->formats_num; i++)\n+\t\t\tOSAL_FREE(p_hwfn, meta->formats[i].format_str);\n+\t\tOSAL_FREE(p_hwfn, meta->formats);\n+\t}\n+\n+\tmeta->is_allocated = false;\n+}\n+\n+enum dbg_status\n+qed_get_reg_fifo_results_buf_size(__rte_unused struct ecore_hwfn *p_hwfn,\n+\t\t\t\t  u32 *dump_buf,\n+\t\t\t\t  __rte_unused u32 num_dumped_dwords,\n+\t\t\t\t  u32 *results_buf_size)\n+{\n+\treturn qed_parse_reg_fifo_dump(dump_buf, NULL, results_buf_size);\n+}\n+\n+enum dbg_status\n+qed_print_reg_fifo_results(__rte_unused struct ecore_hwfn *p_hwfn,\n+\t\t\t   u32 *dump_buf,\n+\t\t\t   __rte_unused u32 num_dumped_dwords,\n+\t\t\t   char *results_buf)\n+{\n+\tu32 parsed_buf_size;\n+\n+\treturn qed_parse_reg_fifo_dump(dump_buf, results_buf, &parsed_buf_size);\n+}\n+\n+enum dbg_status\n+qed_get_igu_fifo_results_buf_size(__rte_unused struct ecore_hwfn *p_hwfn,\n+\t\t\t\t  u32 *dump_buf,\n+\t\t\t\t  __rte_unused u32 num_dumped_dwords,\n+\t\t\t\t  u32 *results_buf_size)\n+{\n+\treturn qed_parse_igu_fifo_dump(dump_buf, NULL, results_buf_size);\n+}\n+\n+enum dbg_status\n+qed_print_igu_fifo_results(__rte_unused struct ecore_hwfn *p_hwfn,\n+\t\t\t   u32 *dump_buf,\n+\t\t\t   __rte_unused u32 num_dumped_dwords,\n+\t\t\t   char *results_buf)\n+{\n+\tu32 parsed_buf_size;\n+\n+\treturn qed_parse_igu_fifo_dump(dump_buf, results_buf, &parsed_buf_size);\n+}\n+\n+enum dbg_status\n+qed_get_protection_override_results_buf_size(__rte_unused\n+\t\t\t\t\t     struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t     u32 *dump_buf,\n+\t\t\t\t\t     __rte_unused u32 num_dumped_dwords,\n+\t\t\t\t\t     u32 *results_buf_size)\n+{\n+\treturn qed_parse_protection_override_dump(dump_buf,\n+\t\t\t\t\t\t  NULL, results_buf_size);\n+}\n+\n+enum dbg_status\n+qed_print_protection_override_results(__rte_unused struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      u32 *dump_buf,\n+\t\t\t\t      __rte_unused u32 num_dumped_dwords,\n+\t\t\t\t      char *results_buf)\n+{\n+\tu32 parsed_buf_size;\n+\n+\treturn qed_parse_protection_override_dump(dump_buf,\n+\t\t\t\t\t\t  results_buf,\n+\t\t\t\t\t\t  &parsed_buf_size);\n+}\n+\n+enum dbg_status\n+qed_get_fw_asserts_results_buf_size(__rte_unused struct ecore_hwfn *p_hwfn,\n+\t\t\t\t    u32 *dump_buf,\n+\t\t\t\t    __rte_unused u32 num_dumped_dwords,\n+\t\t\t\t    u32 *results_buf_size)\n+{\n+\treturn qed_parse_fw_asserts_dump(dump_buf, NULL, results_buf_size);\n+}\n+\n+enum dbg_status\n+qed_print_fw_asserts_results(__rte_unused struct ecore_hwfn *p_hwfn,\n+\t\t\t     u32 *dump_buf,\n+\t\t\t     __rte_unused u32 num_dumped_dwords,\n+\t\t\t     char *results_buf)\n+{\n+\tu32 parsed_buf_size;\n+\n+\treturn qed_parse_fw_asserts_dump(dump_buf,\n+\t\t\t\t\t results_buf, &parsed_buf_size);\n+}\n+\n+enum dbg_status qed_dbg_parse_attn(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   struct dbg_attn_block_result *results)\n+{\n+\tconst u32 *block_attn_name_offsets;\n+\tconst char *attn_name_base;\n+\tconst char *block_name;\n+\tenum dbg_attn_type attn_type;\n+\tu8 num_regs, i, j;\n+\n+\tnum_regs = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_NUM_REGS);\n+\tattn_type = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE);\n+\tblock_name = qed_dbg_get_block_name(p_hwfn, results->block_id);\n+\tif (!block_name)\n+\t\treturn DBG_STATUS_INVALID_ARGS;\n+\n+\tif (!p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr ||\n+\t    !p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr ||\n+\t    !p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr)\n+\t\treturn DBG_STATUS_DBG_ARRAY_NOT_SET;\n+\n+\tblock_attn_name_offsets =\n+\t    (u32 *)p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr +\n+\t    results->names_offset;\n+\n+\tattn_name_base = p_hwfn->dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr;\n+\n+\t/* Go over registers with a non-zero attention status */\n+\tfor (i = 0; i < num_regs; i++) {\n+\t\tstruct dbg_attn_bit_mapping *bit_mapping;\n+\t\tstruct dbg_attn_reg_result *reg_result;\n+\t\tu8 num_reg_attn, bit_idx = 0;\n+\n+\t\treg_result = &results->reg_results[i];\n+\t\tnum_reg_attn = GET_FIELD(reg_result->data,\n+\t\t\t\t\t DBG_ATTN_REG_RESULT_NUM_REG_ATTN);\n+\t\tbit_mapping = (struct dbg_attn_bit_mapping *)\n+\t\t    p_hwfn->dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr +\n+\t\t    reg_result->block_attn_offset;\n+\n+\t\t/* Go over attention status bits */\n+\t\tfor (j = 0; j < num_reg_attn; j++, bit_idx++) {\n+\t\t\tu16 attn_idx_val = GET_FIELD(bit_mapping[j].data,\n+\t\t\t\t\t\t     DBG_ATTN_BIT_MAPPING_VAL);\n+\t\t\tconst char *attn_name, *attn_type_str, *masked_str;\n+\t\t\tu32 attn_name_offset;\n+\t\t\tu32 sts_addr;\n+\n+\t\t\t/* Check if bit mask should be advanced (due to unused\n+\t\t\t * bits).\n+\t\t\t */\n+\t\t\tif (GET_FIELD(bit_mapping[j].data,\n+\t\t\t\t      DBG_ATTN_BIT_MAPPING_IS_UNUSED_BIT_CNT)) {\n+\t\t\t\tbit_idx += (u8)attn_idx_val;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\t/* Check current bit index */\n+\t\t\tif (!(reg_result->sts_val & OSAL_BIT(bit_idx)))\n+\t\t\t\tcontinue;\n+\n+\t\t\t/* An attention bit with value=1 was found\n+\t\t\t * Find attention name\n+\t\t\t */\n+\t\t\tattn_name_offset =\n+\t\t\t\tblock_attn_name_offsets[attn_idx_val];\n+\t\t\tattn_name = attn_name_base + attn_name_offset;\n+\t\t\tattn_type_str =\n+\t\t\t\t(attn_type ==\n+\t\t\t\t ATTN_TYPE_INTERRUPT ? \"Interrupt\" :\n+\t\t\t\t \"Parity\");\n+\t\t\tmasked_str = reg_result->mask_val & OSAL_BIT(bit_idx) ?\n+\t\t\t\t     \" [masked]\" : \"\";\n+\t\t\tsts_addr = GET_FIELD(reg_result->data,\n+\t\t\t\t\t     DBG_ATTN_REG_RESULT_STS_ADDRESS);\n+\t\t\tDP_NOTICE(p_hwfn, false,\n+\t\t\t\t  \"%s (%s) : %s [address 0x%08x, bit %d]%s\\n\",\n+\t\t\t\t  block_name, attn_type_str, attn_name,\n+\t\t\t\t  sts_addr * 4, bit_idx, masked_str);\n+\t\t}\n+\t}\n+\n+\treturn DBG_STATUS_OK;\n+}\n+\n+/* Wrapper for unifying the idle_chk and mcp_trace api */\n+static enum dbg_status\n+qed_print_idle_chk_results_wrapper(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   u32 *dump_buf,\n+\t\t\t\t   u32 num_dumped_dwords,\n+\t\t\t\t   char *results_buf)\n+{\n+\tu32 num_errors, num_warnnings;\n+\n+\treturn qed_print_idle_chk_results(p_hwfn, dump_buf, num_dumped_dwords,\n+\t\t\t\t\t  results_buf, &num_errors,\n+\t\t\t\t\t  &num_warnnings);\n+}\n+\n+/* Feature meta data lookup table */\n+static struct {\n+\tconst char *name;\n+\tenum dbg_status (*get_size)(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t    struct ecore_ptt *p_ptt, u32 *size);\n+\tenum dbg_status (*perform_dump)(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\tstruct ecore_ptt *p_ptt, u32 *dump_buf,\n+\t\t\t\t\tu32 buf_size, u32 *dumped_dwords);\n+\tenum dbg_status (*print_results)(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t u32 *dump_buf, u32 num_dumped_dwords,\n+\t\t\t\t\t char *results_buf);\n+\tenum dbg_status (*results_buf_size)(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t    u32 *dump_buf,\n+\t\t\t\t\t    u32 num_dumped_dwords,\n+\t\t\t\t\t    u32 *results_buf_size);\n+} qed_features_lookup[] = {\n+\t{\n+\t\"grc\", qed_dbg_grc_get_dump_buf_size,\n+\t\t    qed_dbg_grc_dump, NULL, NULL}, {\n+\t\"idle_chk\",\n+\t\t    qed_dbg_idle_chk_get_dump_buf_size,\n+\t\t    qed_dbg_idle_chk_dump,\n+\t\t    qed_print_idle_chk_results_wrapper,\n+\t\t    qed_get_idle_chk_results_buf_size}, {\n+\t\"mcp_trace\",\n+\t\t    qed_dbg_mcp_trace_get_dump_buf_size,\n+\t\t    qed_dbg_mcp_trace_dump, qed_print_mcp_trace_results,\n+\t\t    qed_get_mcp_trace_results_buf_size}, {\n+\t\"reg_fifo\",\n+\t\t    qed_dbg_reg_fifo_get_dump_buf_size,\n+\t\t    qed_dbg_reg_fifo_dump, qed_print_reg_fifo_results,\n+\t\t    qed_get_reg_fifo_results_buf_size}, {\n+\t\"igu_fifo\",\n+\t\t    qed_dbg_igu_fifo_get_dump_buf_size,\n+\t\t    qed_dbg_igu_fifo_dump, qed_print_igu_fifo_results,\n+\t\t    qed_get_igu_fifo_results_buf_size}, {\n+\t\"protection_override\",\n+\t\t    qed_dbg_protection_override_get_dump_buf_size,\n+\t\t    qed_dbg_protection_override_dump,\n+\t\t    qed_print_protection_override_results,\n+\t\t    qed_get_protection_override_results_buf_size}, {\n+\t\"fw_asserts\",\n+\t\t    qed_dbg_fw_asserts_get_dump_buf_size,\n+\t\t    qed_dbg_fw_asserts_dump,\n+\t\t    qed_print_fw_asserts_results,\n+\t\t    qed_get_fw_asserts_results_buf_size}, {\n+\t\"ilt\",\n+\t\t    qed_dbg_ilt_get_dump_buf_size,\n+\t\t    qed_dbg_ilt_dump, NULL, NULL},};\n+\n+#define QED_RESULTS_BUF_MIN_SIZE 16\n+/* Generic function for decoding debug feature info */\n+static enum dbg_status format_feature(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      enum ecore_dbg_features feature_idx)\n+{\n+\tstruct ecore_dbg_feature *feature =\n+\t    &p_hwfn->p_dev->dbg_params.features[feature_idx];\n+\tu32 text_size_bytes, null_char_pos, i;\n+\tenum dbg_status rc;\n+\tchar *text_buf;\n+\n+\t/* Check if feature supports formatting capability */\n+\tif (!qed_features_lookup[feature_idx].results_buf_size)\n+\t\treturn DBG_STATUS_OK;\n+\n+\t/* Obtain size of formatted output */\n+\trc = qed_features_lookup[feature_idx].results_buf_size(p_hwfn,\n+\t\t\t\t\t\t(u32 *)feature->dump_buf,\n+\t\t\t\t\t\tfeature->dumped_dwords,\n+\t\t\t\t\t\t&text_size_bytes);\n+\tif (rc != DBG_STATUS_OK)\n+\t\treturn rc;\n+\n+\t/* Make sure that the allocated size is a multiple of dword (4 bytes) */\n+\tnull_char_pos = text_size_bytes - 1;\n+\ttext_size_bytes = (text_size_bytes + 3) & ~0x3;\n+\n+\tif (text_size_bytes < QED_RESULTS_BUF_MIN_SIZE) {\n+\t\tDP_NOTICE(p_hwfn->p_dev, false,\n+\t\t\t  \"formatted size of feature was too small %d. Aborting\\n\",\n+\t\t\t  text_size_bytes);\n+\t\treturn DBG_STATUS_INVALID_ARGS;\n+\t}\n+\n+\t/* Allocate temp text buf */\n+\ttext_buf = OSAL_VZALLOC(p_hwfn, text_size_bytes);\n+\tif (!text_buf) {\n+\t\tDP_NOTICE(p_hwfn->p_dev, false,\n+\t\t\t  \"failed to allocate text buffer. Aborting\\n\");\n+\t\treturn DBG_STATUS_VIRT_MEM_ALLOC_FAILED;\n+\t}\n+\n+\t/* Decode feature opcodes to string on temp buf */\n+\trc = qed_features_lookup[feature_idx].print_results(p_hwfn,\n+\t\t\t\t\t\t(u32 *)feature->dump_buf,\n+\t\t\t\t\t\tfeature->dumped_dwords,\n+\t\t\t\t\t\ttext_buf);\n+\tif (rc != DBG_STATUS_OK) {\n+\t\tOSAL_VFREE(p_hwfn, text_buf);\n+\t\treturn rc;\n+\t}\n+\n+\t/* Replace the original null character with a '\\n' character.\n+\t * The bytes that were added as a result of the dword alignment are also\n+\t * padded with '\\n' characters.\n+\t */\n+\tfor (i = null_char_pos; i < text_size_bytes; i++)\n+\t\ttext_buf[i] = '\\n';\n+\n+\n+\t/* Free the old dump_buf and point the dump_buf to the newly allocagted\n+\t * and formatted text buffer.\n+\t */\n+\tOSAL_VFREE(p_hwfn, feature->dump_buf);\n+\tfeature->dump_buf = (u8 *)text_buf;\n+\tfeature->buf_size = text_size_bytes;\n+\tfeature->dumped_dwords = text_size_bytes / 4;\n+\treturn rc;\n+}\n+\n+#define MAX_DBG_FEATURE_SIZE_DWORDS\t0x3FFFFFFF\n+\n+/* Generic function for performing the dump of a debug feature. */\n+static enum dbg_status qed_dbg_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t    struct ecore_ptt *p_ptt,\n+\t\t\t\t    enum ecore_dbg_features feature_idx)\n+{\n+\tstruct ecore_dbg_feature *feature =\n+\t    &p_hwfn->p_dev->dbg_params.features[feature_idx];\n+\tu32 buf_size_dwords;\n+\tenum dbg_status rc;\n+\n+\tDP_NOTICE(p_hwfn->p_dev, false, \"Collecting a debug feature [\\\"%s\\\"]\\n\",\n+\t\t  qed_features_lookup[feature_idx].name);\n+\n+\t/* Dump_buf was already allocated need to free (this can happen if dump\n+\t * was called but file was never read).\n+\t * We can't use the buffer as is since size may have changed.\n+\t */\n+\tif (feature->dump_buf) {\n+\t\tOSAL_VFREE(p_hwfn, feature->dump_buf);\n+\t\tfeature->dump_buf = NULL;\n+\t}\n+\n+\t/* Get buffer size from hsi, allocate accordingly, and perform the\n+\t * dump.\n+\t */\n+\trc = qed_features_lookup[feature_idx].get_size(p_hwfn, p_ptt,\n+\t\t\t\t\t\t       &buf_size_dwords);\n+\tif (rc != DBG_STATUS_OK && rc != DBG_STATUS_NVRAM_GET_IMAGE_FAILED)\n+\t\treturn rc;\n+\n+\tif (buf_size_dwords > MAX_DBG_FEATURE_SIZE_DWORDS) {\n+\t\tfeature->buf_size = 0;\n+\t\tDP_NOTICE(p_hwfn->p_dev, false,\n+\t\t\t  \"Debug feature [\\\"%s\\\"] size (0x%x dwords) exceeds maximum size (0x%x dwords)\\n\",\n+\t\t\t  qed_features_lookup[feature_idx].name,\n+\t\t\t  buf_size_dwords, MAX_DBG_FEATURE_SIZE_DWORDS);\n+\n+\t\treturn DBG_STATUS_OK;\n+\t}\n+\n+\tfeature->buf_size = buf_size_dwords * sizeof(u32);\n+\tfeature->dump_buf = OSAL_ZALLOC(p_hwfn, GFP_KERNEL, feature->buf_size);\n+\tif (!feature->dump_buf)\n+\t\treturn DBG_STATUS_VIRT_MEM_ALLOC_FAILED;\n+\n+\trc = qed_features_lookup[feature_idx].perform_dump(p_hwfn, p_ptt,\n+\t\t\t\t\t(u32 *)feature->dump_buf,\n+\t\t\t\t\tfeature->buf_size / sizeof(u32),\n+\t\t\t\t\t&feature->dumped_dwords);\n+\n+\t/* If mcp is stuck we get DBG_STATUS_NVRAM_GET_IMAGE_FAILED error.\n+\t * In this case the buffer holds valid binary data, but we wont able\n+\t * to parse it (since parsing relies on data in NVRAM which is only\n+\t * accessible when MFW is responsive). skip the formatting but return\n+\t * success so that binary data is provided.\n+\t */\n+\tif (rc == DBG_STATUS_NVRAM_GET_IMAGE_FAILED)\n+\t\treturn DBG_STATUS_OK;\n+\n+\tif (rc != DBG_STATUS_OK)\n+\t\treturn rc;\n+\n+\t/* Format output */\n+\trc = format_feature(p_hwfn, feature_idx);\n+\treturn rc;\n+}\n+\n+int qed_dbg_grc(struct ecore_dev *edev, void *buffer, u32 *num_dumped_bytes)\n+{\n+\treturn qed_dbg_feature(edev, buffer, DBG_FEATURE_GRC, num_dumped_bytes);\n+}\n+\n+int qed_dbg_grc_size(struct ecore_dev *edev)\n+{\n+\treturn qed_dbg_feature_size(edev, DBG_FEATURE_GRC);\n+}\n+\n+int\n+qed_dbg_idle_chk(struct ecore_dev *edev, void *buffer, u32 *num_dumped_bytes)\n+{\n+\treturn qed_dbg_feature(edev, buffer, DBG_FEATURE_IDLE_CHK,\n+\t\t\t       num_dumped_bytes);\n+}\n+\n+int qed_dbg_idle_chk_size(struct ecore_dev *edev)\n+{\n+\treturn qed_dbg_feature_size(edev, DBG_FEATURE_IDLE_CHK);\n+}\n+\n+int\n+qed_dbg_reg_fifo(struct ecore_dev *edev, void *buffer, u32 *num_dumped_bytes)\n+{\n+\treturn qed_dbg_feature(edev, buffer, DBG_FEATURE_REG_FIFO,\n+\t\t\t       num_dumped_bytes);\n+}\n+\n+int qed_dbg_reg_fifo_size(struct ecore_dev *edev)\n+{\n+\treturn qed_dbg_feature_size(edev, DBG_FEATURE_REG_FIFO);\n+}\n+\n+int\n+qed_dbg_igu_fifo(struct ecore_dev *edev, void *buffer, u32 *num_dumped_bytes)\n+{\n+\treturn qed_dbg_feature(edev, buffer, DBG_FEATURE_IGU_FIFO,\n+\t\t\t       num_dumped_bytes);\n+}\n+\n+int qed_dbg_igu_fifo_size(struct ecore_dev *edev)\n+{\n+\treturn qed_dbg_feature_size(edev, DBG_FEATURE_IGU_FIFO);\n+}\n+\n+static int qed_dbg_nvm_image_length(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t    enum ecore_nvm_images image_id, u32 *length)\n+{\n+\tstruct ecore_nvm_image_att image_att;\n+\tint rc;\n+\n+\t*length = 0;\n+\trc = ecore_mcp_get_nvm_image_att(p_hwfn, image_id, &image_att);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t*length = image_att.length;\n+\n+\treturn rc;\n+}\n+\n+int qed_dbg_protection_override(struct ecore_dev *edev, void *buffer,\n+\t\t\t\tu32 *num_dumped_bytes)\n+{\n+\treturn qed_dbg_feature(edev, buffer, DBG_FEATURE_PROTECTION_OVERRIDE,\n+\t\t\t       num_dumped_bytes);\n+}\n+\n+int qed_dbg_protection_override_size(struct ecore_dev *edev)\n+{\n+\treturn qed_dbg_feature_size(edev, DBG_FEATURE_PROTECTION_OVERRIDE);\n+}\n+\n+int qed_dbg_fw_asserts(struct ecore_dev *edev, void *buffer,\n+\t\t       u32 *num_dumped_bytes)\n+{\n+\treturn qed_dbg_feature(edev, buffer, DBG_FEATURE_FW_ASSERTS,\n+\t\t\t       num_dumped_bytes);\n+}\n+\n+int qed_dbg_fw_asserts_size(struct ecore_dev *edev)\n+{\n+\treturn qed_dbg_feature_size(edev, DBG_FEATURE_FW_ASSERTS);\n+}\n+\n+int qed_dbg_ilt(struct ecore_dev *edev, void *buffer, u32 *num_dumped_bytes)\n+{\n+\treturn qed_dbg_feature(edev, buffer, DBG_FEATURE_ILT, num_dumped_bytes);\n+}\n+\n+int qed_dbg_ilt_size(struct ecore_dev *edev)\n+{\n+\treturn qed_dbg_feature_size(edev, DBG_FEATURE_ILT);\n+}\n+\n+int qed_dbg_mcp_trace(struct ecore_dev *edev, void *buffer,\n+\t\t      u32 *num_dumped_bytes)\n+{\n+\treturn qed_dbg_feature(edev, buffer, DBG_FEATURE_MCP_TRACE,\n+\t\t\t       num_dumped_bytes);\n+}\n+\n+int qed_dbg_mcp_trace_size(struct ecore_dev *edev)\n+{\n+\treturn qed_dbg_feature_size(edev, DBG_FEATURE_MCP_TRACE);\n+}\n+\n+/* Defines the amount of bytes allocated for recording the length of debug\n+ * feature buffer.\n+ */\n+#define REGDUMP_HEADER_SIZE\t\t\tsizeof(u32)\n+#define REGDUMP_HEADER_SIZE_SHIFT\t\t0\n+#define REGDUMP_HEADER_SIZE_MASK\t\t0xffffff\n+#define REGDUMP_HEADER_FEATURE_SHIFT\t\t24\n+#define REGDUMP_HEADER_FEATURE_MASK\t\t0x3f\n+#define REGDUMP_HEADER_OMIT_ENGINE_SHIFT\t30\n+#define REGDUMP_HEADER_OMIT_ENGINE_MASK\t\t0x1\n+#define REGDUMP_HEADER_ENGINE_SHIFT\t\t31\n+#define REGDUMP_HEADER_ENGINE_MASK\t\t0x1\n+#define REGDUMP_MAX_SIZE\t\t\t0x1000000\n+#define ILT_DUMP_MAX_SIZE\t\t\t(1024 * 1024 * 15)\n+\n+enum debug_print_features {\n+\tOLD_MODE = 0,\n+\tIDLE_CHK = 1,\n+\tGRC_DUMP = 2,\n+\tMCP_TRACE = 3,\n+\tREG_FIFO = 4,\n+\tPROTECTION_OVERRIDE = 5,\n+\tIGU_FIFO = 6,\n+\tPHY = 7,\n+\tFW_ASSERTS = 8,\n+\tNVM_CFG1 = 9,\n+\tDEFAULT_CFG = 10,\n+\tNVM_META = 11,\n+\tMDUMP = 12,\n+\tILT_DUMP = 13,\n+};\n+\n+static u32 qed_calc_regdump_header(struct ecore_dev *edev,\n+\t\t\t\t   enum debug_print_features feature,\n+\t\t\t\t   int engine, u32 feature_size, u8 omit_engine)\n+{\n+\tu32 res = 0;\n+\n+\tSET_FIELD(res, REGDUMP_HEADER_SIZE, feature_size);\n+\tif (res != feature_size)\n+\t\tDP_NOTICE(edev, false,\n+\t\t\t  \"Feature %d is too large (size 0x%x) and will corrupt the dump\\n\",\n+\t\t\t  feature, feature_size);\n+\n+\tSET_FIELD(res, REGDUMP_HEADER_FEATURE, feature);\n+\tSET_FIELD(res, REGDUMP_HEADER_OMIT_ENGINE, omit_engine);\n+\tSET_FIELD(res, REGDUMP_HEADER_ENGINE, engine);\n+\n+\treturn res;\n+}\n+\n+int qed_dbg_all_data(struct ecore_dev *edev, void *buffer)\n+{\n+\tu8 cur_engine, omit_engine = 0, org_engine;\n+\tstruct ecore_hwfn *p_hwfn =\n+\t\t&edev->hwfns[edev->dbg_params.engine_for_debug];\n+\tstruct dbg_tools_data *dev_data = &p_hwfn->dbg_info;\n+\tint grc_params[MAX_DBG_GRC_PARAMS], i;\n+\tu32 offset = 0, feature_size;\n+\tint rc;\n+\n+\tfor (i = 0; i < MAX_DBG_GRC_PARAMS; i++)\n+\t\tgrc_params[i] = dev_data->grc.param_val[i];\n+\n+\tif (!ECORE_IS_CMT(edev))\n+\t\tomit_engine = 1;\n+\n+\tOSAL_MUTEX_ACQUIRE(&edev->dbg_lock);\n+\n+\torg_engine = qed_get_debug_engine(edev);\n+\tfor (cur_engine = 0; cur_engine < edev->num_hwfns; cur_engine++) {\n+\t\t/* Collect idle_chks and grcDump for each hw function */\n+\t\tDP_VERBOSE(edev, ECORE_MSG_DEBUG,\n+\t\t\t   \"obtaining idle_chk and grcdump for current engine\\n\");\n+\t\tqed_set_debug_engine(edev, cur_engine);\n+\n+\t\t/* First idle_chk */\n+\t\trc = qed_dbg_idle_chk(edev, (u8 *)buffer + offset +\n+\t\t\t\t      REGDUMP_HEADER_SIZE, &feature_size);\n+\t\tif (!rc) {\n+\t\t\t*(u32 *)((u8 *)buffer + offset) =\n+\t\t\t    qed_calc_regdump_header(edev, IDLE_CHK, cur_engine,\n+\t\t\t\t\t\t    feature_size, omit_engine);\n+\t\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\t} else {\n+\t\t\tDP_ERR(edev, \"qed_dbg_idle_chk failed. rc = %d\\n\", rc);\n+\t\t}\n+\n+\t\t/* Second idle_chk */\n+\t\trc = qed_dbg_idle_chk(edev, (u8 *)buffer + offset +\n+\t\t\t\t      REGDUMP_HEADER_SIZE, &feature_size);\n+\t\tif (!rc) {\n+\t\t\t*(u32 *)((u8 *)buffer + offset) =\n+\t\t\t    qed_calc_regdump_header(edev, IDLE_CHK, cur_engine,\n+\t\t\t\t\t\t    feature_size, omit_engine);\n+\t\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\t} else {\n+\t\t\tDP_ERR(edev, \"qed_dbg_idle_chk failed. rc = %d\\n\", rc);\n+\t\t}\n+\n+\t\t/* reg_fifo dump */\n+\t\trc = qed_dbg_reg_fifo(edev, (u8 *)buffer + offset +\n+\t\t\t\t      REGDUMP_HEADER_SIZE, &feature_size);\n+\t\tif (!rc) {\n+\t\t\t*(u32 *)((u8 *)buffer + offset) =\n+\t\t\t    qed_calc_regdump_header(edev, REG_FIFO, cur_engine,\n+\t\t\t\t\t\t    feature_size, omit_engine);\n+\t\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\t} else {\n+\t\t\tDP_ERR(edev, \"qed_dbg_reg_fifo failed. rc = %d\\n\", rc);\n+\t\t}\n+\n+\t\t/* igu_fifo dump */\n+\t\trc = qed_dbg_igu_fifo(edev, (u8 *)buffer + offset +\n+\t\t\t\t      REGDUMP_HEADER_SIZE, &feature_size);\n+\t\tif (!rc) {\n+\t\t\t*(u32 *)((u8 *)buffer + offset) =\n+\t\t\t    qed_calc_regdump_header(edev, IGU_FIFO, cur_engine,\n+\t\t\t\t\t\t    feature_size, omit_engine);\n+\t\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\t} else {\n+\t\t\tDP_ERR(edev, \"qed_dbg_igu_fifo failed. rc = %d\", rc);\n+\t\t}\n+\n+\t\t/* protection_override dump */\n+\t\trc = qed_dbg_protection_override(edev, (u8 *)buffer + offset +\n+\t\t\t\t\t\t REGDUMP_HEADER_SIZE,\n+\t\t\t\t\t\t &feature_size);\n+\t\tif (!rc) {\n+\t\t\t*(u32 *)((u8 *)buffer + offset) =\n+\t\t\t    qed_calc_regdump_header(edev, PROTECTION_OVERRIDE,\n+\t\t\t\t\t\t    cur_engine,\n+\t\t\t\t\t\t    feature_size, omit_engine);\n+\t\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\t} else {\n+\t\t\tDP_ERR(edev,\n+\t\t\t       \"qed_dbg_protection_override failed. rc = %d\\n\",\n+\t\t\t       rc);\n+\t\t}\n+\n+\t\t/* fw_asserts dump */\n+\t\trc = qed_dbg_fw_asserts(edev, (u8 *)buffer + offset +\n+\t\t\t\t\tREGDUMP_HEADER_SIZE, &feature_size);\n+\t\tif (!rc) {\n+\t\t\t*(u32 *)((u8 *)buffer + offset) =\n+\t\t\t    qed_calc_regdump_header(edev, FW_ASSERTS,\n+\t\t\t\t\t\t    cur_engine, feature_size,\n+\t\t\t\t\t\t    omit_engine);\n+\t\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\t} else {\n+\t\t\tDP_ERR(edev, \"qed_dbg_fw_asserts failed. rc = %d\\n\",\n+\t\t\t       rc);\n+\t\t}\n+\n+\t\t/* GRC dump - must be last because when mcp stuck it will\n+\t\t * clutter idle_chk, reg_fifo, ...\n+\t\t */\n+\t\tfor (i = 0; i < MAX_DBG_GRC_PARAMS; i++)\n+\t\t\tdev_data->grc.param_val[i] = grc_params[i];\n+\n+\t\trc = qed_dbg_grc(edev, (u8 *)buffer + offset +\n+\t\t\t\t REGDUMP_HEADER_SIZE, &feature_size);\n+\t\tif (!rc) {\n+\t\t\t*(u32 *)((u8 *)buffer + offset) =\n+\t\t\t    qed_calc_regdump_header(edev, GRC_DUMP,\n+\t\t\t\t\t\t    cur_engine,\n+\t\t\t\t\t\t    feature_size, omit_engine);\n+\t\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\t} else {\n+\t\t\tDP_ERR(edev, \"qed_dbg_grc failed. rc = %d\", rc);\n+\t\t}\n+\t}\n+\n+\tqed_set_debug_engine(edev, org_engine);\n+\n+\t/* mcp_trace */\n+\trc = qed_dbg_mcp_trace(edev, (u8 *)buffer + offset +\n+\t\t\t       REGDUMP_HEADER_SIZE, &feature_size);\n+\tif (!rc) {\n+\t\t*(u32 *)((u8 *)buffer + offset) =\n+\t\t    qed_calc_regdump_header(edev, MCP_TRACE, cur_engine,\n+\t\t\t\t\t    feature_size, omit_engine);\n+\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t} else {\n+\t\tDP_ERR(edev, \"qed_dbg_mcp_trace failed. rc = %d\\n\", rc);\n+\t}\n+\n+\tOSAL_MUTEX_RELEASE(&edev->dbg_lock);\n+\n+\treturn 0;\n+}\n+\n+int qed_dbg_all_data_size(struct ecore_dev *edev)\n+{\n+\tstruct ecore_hwfn *p_hwfn =\n+\t\t&edev->hwfns[edev->dbg_params.engine_for_debug];\n+\tu32 regs_len = 0, image_len = 0, ilt_len = 0, total_ilt_len = 0;\n+\tu8 cur_engine, org_engine;\n+\n+\tedev->disable_ilt_dump = false;\n+\torg_engine = qed_get_debug_engine(edev);\n+\tfor (cur_engine = 0; cur_engine < edev->num_hwfns; cur_engine++) {\n+\t\t/* Engine specific */\n+\t\tDP_VERBOSE(edev, ECORE_MSG_DEBUG,\n+\t\t\t   \"calculating idle_chk and grcdump register length for current engine\\n\");\n+\t\tqed_set_debug_engine(edev, cur_engine);\n+\t\tregs_len += REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(edev) +\n+\t\t\t    REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(edev) +\n+\t\t\t    REGDUMP_HEADER_SIZE + qed_dbg_grc_size(edev) +\n+\t\t\t    REGDUMP_HEADER_SIZE + qed_dbg_reg_fifo_size(edev) +\n+\t\t\t    REGDUMP_HEADER_SIZE + qed_dbg_igu_fifo_size(edev) +\n+\t\t\t    REGDUMP_HEADER_SIZE +\n+\t\t\t    qed_dbg_protection_override_size(edev) +\n+\t\t\t    REGDUMP_HEADER_SIZE + qed_dbg_fw_asserts_size(edev);\n+\n+\t\tilt_len = REGDUMP_HEADER_SIZE + qed_dbg_ilt_size(edev);\n+\t\tif (ilt_len < ILT_DUMP_MAX_SIZE) {\n+\t\t\ttotal_ilt_len += ilt_len;\n+\t\t\tregs_len += ilt_len;\n+\t\t}\n+\t}\n+\n+\tqed_set_debug_engine(edev, org_engine);\n+\n+\t/* Engine common */\n+\tregs_len += REGDUMP_HEADER_SIZE + qed_dbg_mcp_trace_size(edev);\n+\tqed_dbg_nvm_image_length(p_hwfn, ECORE_NVM_IMAGE_NVM_CFG1, &image_len);\n+\tif (image_len)\n+\t\tregs_len += REGDUMP_HEADER_SIZE + image_len;\n+\tqed_dbg_nvm_image_length(p_hwfn, ECORE_NVM_IMAGE_DEFAULT_CFG,\n+\t\t\t\t &image_len);\n+\tif (image_len)\n+\t\tregs_len += REGDUMP_HEADER_SIZE + image_len;\n+\tqed_dbg_nvm_image_length(p_hwfn, ECORE_NVM_IMAGE_NVM_META, &image_len);\n+\tif (image_len)\n+\t\tregs_len += REGDUMP_HEADER_SIZE + image_len;\n+\tqed_dbg_nvm_image_length(p_hwfn, ECORE_NVM_IMAGE_MDUMP, &image_len);\n+\tif (image_len)\n+\t\tregs_len += REGDUMP_HEADER_SIZE + image_len;\n+\n+\tif (regs_len > REGDUMP_MAX_SIZE) {\n+\t\tDP_VERBOSE(edev, ECORE_MSG_DEBUG,\n+\t\t\t   \"Dump exceeds max size 0x%x, disable ILT dump\\n\",\n+\t\t\t   REGDUMP_MAX_SIZE);\n+\t\tedev->disable_ilt_dump = true;\n+\t\tregs_len -= total_ilt_len;\n+\t}\n+\n+\treturn regs_len;\n+}\n+\n+int qed_dbg_feature(struct ecore_dev *edev, void *buffer,\n+\t\t    enum ecore_dbg_features feature, u32 *num_dumped_bytes)\n+{\n+\tstruct ecore_hwfn *p_hwfn =\n+\t\t&edev->hwfns[edev->dbg_params.engine_for_debug];\n+\tstruct ecore_dbg_feature *qed_feature =\n+\t\t&edev->dbg_params.features[feature];\n+\tenum dbg_status dbg_rc;\n+\tstruct ecore_ptt *p_ptt;\n+\tint rc = 0;\n+\n+\t/* Acquire ptt */\n+\tp_ptt = ecore_ptt_acquire(p_hwfn);\n+\tif (!p_ptt)\n+\t\treturn -EINVAL;\n+\n+\t/* Get dump */\n+\tdbg_rc = qed_dbg_dump(p_hwfn, p_ptt, feature);\n+\tif (dbg_rc != DBG_STATUS_OK) {\n+\t\tDP_VERBOSE(edev, ECORE_MSG_DEBUG, \"%s\\n\",\n+\t\t\t   qed_dbg_get_status_str(dbg_rc));\n+\t\t*num_dumped_bytes = 0;\n+\t\trc = -EINVAL;\n+\t\tgoto out;\n+\t}\n+\n+\tDP_VERBOSE(edev, ECORE_MSG_DEBUG,\n+\t\t   \"copying debug feature to external buffer\\n\");\n+\tmemcpy(buffer, qed_feature->dump_buf, qed_feature->buf_size);\n+\t*num_dumped_bytes = edev->dbg_params.features[feature].dumped_dwords *\n+\t\t\t    4;\n+\n+out:\n+\tecore_ptt_release(p_hwfn, p_ptt);\n+\treturn rc;\n+}\n+\n+int\n+qed_dbg_feature_size(struct ecore_dev *edev, enum ecore_dbg_features feature)\n+{\n+\tstruct ecore_hwfn *p_hwfn =\n+\t\t&edev->hwfns[edev->dbg_params.engine_for_debug];\n+\tstruct ecore_dbg_feature *qed_feature = &edev->dbg_features[feature];\n+\tstruct ecore_ptt *p_ptt = ecore_ptt_acquire(p_hwfn);\n+\tu32 buf_size_dwords;\n+\tenum dbg_status rc;\n+\n+\tif (!p_ptt)\n+\t\treturn -EINVAL;\n+\n+\trc = qed_features_lookup[feature].get_size(p_hwfn, p_ptt,\n+\t\t\t\t\t\t   &buf_size_dwords);\n+\tif (rc != DBG_STATUS_OK)\n+\t\tbuf_size_dwords = 0;\n+\n+\t/* Feature will not be dumped if it exceeds maximum size */\n+\tif (buf_size_dwords > MAX_DBG_FEATURE_SIZE_DWORDS)\n+\t\tbuf_size_dwords = 0;\n+\n+\tecore_ptt_release(p_hwfn, p_ptt);\n+\tqed_feature->buf_size = buf_size_dwords * sizeof(u32);\n+\treturn qed_feature->buf_size;\n+}\n+\n+u8 qed_get_debug_engine(struct ecore_dev *edev)\n+{\n+\treturn edev->dbg_params.engine_for_debug;\n+}\n+\n+void qed_set_debug_engine(struct ecore_dev *edev, int engine_number)\n+{\n+\tDP_VERBOSE(edev, ECORE_MSG_DEBUG, \"set debug engine to %d\\n\",\n+\t\t   engine_number);\n+\tedev->dbg_params.engine_for_debug = engine_number;\n+}\n+\n+void qed_dbg_pf_init(struct ecore_dev *edev)\n+{\n+\tconst u8 *dbg_values = NULL;\n+\tint i;\n+\n+\tPMD_INIT_FUNC_TRACE(edev);\n+\n+\tOSAL_MUTEX_INIT(&edev->dbg_lock);\n+\n+\t/* Sync ver with debugbus qed code */\n+\tqed_dbg_set_app_ver(TOOLS_VERSION);\n+\n+\t/* Debug values are after init values.\n+\t * The offset is the first dword of the file.\n+\t */\n+\t/* TBD: change hardcoded value to offset from FW file */\n+\tdbg_values = (const u8 *)edev->firmware + 1337296;\n+\n+\tfor_each_hwfn(edev, i) {\n+\t\tqed_dbg_set_bin_ptr(&edev->hwfns[i], dbg_values);\n+\t\tqed_dbg_user_set_bin_ptr(&edev->hwfns[i], dbg_values);\n+\t}\n+\n+\t/* Set the hwfn to be 0 as default */\n+\tedev->dbg_params.engine_for_debug = 0;\n+}\n+\n+void qed_dbg_pf_exit(struct ecore_dev *edev)\n+{\n+\tstruct ecore_dbg_feature *feature = NULL;\n+\tenum ecore_dbg_features feature_idx;\n+\n+\tPMD_INIT_FUNC_TRACE(edev);\n+\n+\t/* debug features' buffers may be allocated if debug feature was used\n+\t * but dump wasn't called\n+\t */\n+\tfor (feature_idx = 0; feature_idx < DBG_FEATURE_NUM; feature_idx++) {\n+\t\tfeature = &edev->dbg_features[feature_idx];\n+\t\tif (feature->dump_buf) {\n+\t\t\tOSAL_VFREE(edev, feature->dump_buf);\n+\t\t\tfeature->dump_buf = NULL;\n+\t\t}\n+\t}\n+\n+\tOSAL_MUTEX_DEALLOC(&edev->dbg_lock);\n+}\ndiff --git a/drivers/net/qede/qede_debug.h b/drivers/net/qede/qede_debug.h\nnew file mode 100644\nindex 000000000..93e1bd710\n--- /dev/null\n+++ b/drivers/net/qede/qede_debug.h\n@@ -0,0 +1,759 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2020 Marvell Semiconductor Inc.\n+ * All rights reserved.\n+ * www.marvell.com\n+ */\n+\n+#ifndef _QED_DEBUG_H\n+#define _QED_DEBUG_H\n+\n+/* Forward Declaration */\n+struct ecore_dev;\n+enum ecore_dbg_features;\n+\n+int qed_dbg_grc(struct ecore_dev *edev, void *buffer, u32 *num_dumped_bytes);\n+int qed_dbg_grc_size(struct ecore_dev *edev);\n+int qed_dbg_idle_chk(struct ecore_dev *edev, void *buffer,\n+\t\t     u32 *num_dumped_bytes);\n+int qed_dbg_idle_chk_size(struct ecore_dev *edev);\n+int qed_dbg_reg_fifo(struct ecore_dev *edev, void *buffer,\n+\t\t     u32 *num_dumped_bytes);\n+int qed_dbg_reg_fifo_size(struct ecore_dev *edev);\n+int qed_dbg_igu_fifo(struct ecore_dev *edev, void *buffer,\n+\t\t     u32 *num_dumped_bytes);\n+int qed_dbg_igu_fifo_size(struct ecore_dev *edev);\n+int qed_dbg_protection_override(struct ecore_dev *edev, void *buffer,\n+\t\t\t\tu32 *num_dumped_bytes);\n+int qed_dbg_protection_override_size(struct ecore_dev *edev);\n+int qed_dbg_fw_asserts(struct ecore_dev *edev, void *buffer,\n+\t\t       u32 *num_dumped_bytes);\n+int qed_dbg_fw_asserts_size(struct ecore_dev *edev);\n+int qed_dbg_ilt(struct ecore_dev *edev, void *buffer, u32 *num_dumped_bytes);\n+int qed_dbg_ilt_size(struct ecore_dev *edev);\n+int qed_dbg_mcp_trace(struct ecore_dev *edev, void *buffer,\n+\t\t      u32 *num_dumped_bytes);\n+int qed_dbg_mcp_trace_size(struct ecore_dev *edev);\n+int qed_dbg_all_data(struct ecore_dev *edev, void *buffer);\n+int qed_dbg_all_data_size(struct ecore_dev *edev);\n+u8 qed_get_debug_engine(struct ecore_dev *edev);\n+void qed_set_debug_engine(struct ecore_dev *edev, int engine_number);\n+int qed_dbg_feature(struct ecore_dev *edev, void *buffer,\n+\t\t    enum ecore_dbg_features feature, u32 *num_dumped_bytes);\n+int\n+qed_dbg_feature_size(struct ecore_dev *edev, enum ecore_dbg_features feature);\n+\n+void qed_dbg_pf_init(struct ecore_dev *edev);\n+void qed_dbg_pf_exit(struct ecore_dev *edev);\n+\n+/***************************** Public Functions *******************************/\n+\n+/**\n+ * @brief qed_dbg_set_bin_ptr - Sets a pointer to the binary data with debug\n+ *\tarrays.\n+ *\n+ * @param p_hwfn -\t    HW device data\n+ * @param bin_ptr - a pointer to the binary data with debug arrays.\n+ */\n+enum dbg_status qed_dbg_set_bin_ptr(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t    const u8 * const bin_ptr);\n+\n+/**\n+ * @brief qed_dbg_set_app_ver - Sets the version of the calling app.\n+ *\n+ * The application should call this function with the TOOLS_VERSION\n+ * it compiles with. Must be called before all other debug functions.\n+ *\n+ * @return error if one of the following holds:\n+ *      - the specified app version is not supported\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_set_app_ver(u32 ver);\n+\n+/**\n+ * @brief qed_read_regs - Reads registers into a buffer (using GRC).\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param buf - Destination buffer.\n+ * @param addr - Source GRC address in dwords.\n+ * @param len - Number of registers to read.\n+ */\n+void qed_read_regs(struct ecore_hwfn *p_hwfn,\n+\t\t   struct ecore_ptt *p_ptt, u32 *buf, u32 addr, u32 len);\n+\n+/**\n+ * @brief qed_read_fw_info - Reads FW info from the chip.\n+ *\n+ * The FW info contains FW-related information, such as the FW version,\n+ * FW image (main/L2B/kuku), FW timestamp, etc.\n+ * The FW info is read from the internal RAM of the first Storm that is not in\n+ * reset.\n+ *\n+ * @param p_hwfn -\t    HW device data\n+ * @param p_ptt -\t    Ptt window used for writing the registers.\n+ * @param fw_info -\tOut: a pointer to write the FW info into.\n+ *\n+ * @return true if the FW info was read successfully from one of the Storms,\n+ * or false if all Storms are in reset.\n+ */\n+bool qed_read_fw_info(struct ecore_hwfn *p_hwfn,\n+\t\t      struct ecore_ptt *p_ptt, struct fw_info *fw_info);\n+/**\n+ * @brief qed_dbg_grc_config - Sets the value of a GRC parameter.\n+ *\n+ * @param p_hwfn -\tHW device data\n+ * @param grc_param -\tGRC parameter\n+ * @param val -\t\tValue to set.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ *\t- grc_param is invalid\n+ *\t- val is outside the allowed boundaries\n+ */\n+enum dbg_status qed_dbg_grc_config(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   enum dbg_grc_params grc_param, u32 val);\n+\n+/**\n+ * @brief qed_dbg_grc_set_params_default - Reverts all GRC parameters to their\n+ *\tdefault value.\n+ *\n+ * @param p_hwfn\t\t- HW device data\n+ */\n+void qed_dbg_grc_set_params_default(struct ecore_hwfn *p_hwfn);\n+/**\n+ * @brief qed_dbg_grc_get_dump_buf_size - Returns the required buffer size for\n+ *\tGRC Dump.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param buf_size - OUT: required buffer size (in dwords) for the GRC Dump\n+ *\tdata.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_grc_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t\t      u32 *buf_size);\n+\n+/**\n+ * @brief qed_dbg_grc_dump - Dumps GRC data into the specified buffer.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param dump_buf - Pointer to write the collected GRC data into.\n+ * @param buf_size_in_dwords - Size of the specified buffer in dwords.\n+ * @param num_dumped_dwords - OUT: number of dumped dwords.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ *\t- the specified dump buffer is too small\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_grc_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t struct ecore_ptt *p_ptt,\n+\t\t\t\t u32 *dump_buf,\n+\t\t\t\t u32 buf_size_in_dwords,\n+\t\t\t\t u32 *num_dumped_dwords);\n+/**\n+ * @brief qed_dbg_idle_chk_get_dump_buf_size - Returns the required buffer size\n+ *\tfor idle check results.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param buf_size - OUT: required buffer size (in dwords) for the idle check\n+ *\tdata.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_idle_chk_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t   struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t   u32 *buf_size);\n+\n+/**\n+ * @brief qed_dbg_idle_chk_dump - Performs idle check and writes the results\n+ *\tinto the specified buffer.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param dump_buf - Pointer to write the idle check data into.\n+ * @param buf_size_in_dwords - Size of the specified buffer in dwords.\n+ * @param num_dumped_dwords - OUT: number of dumped dwords.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ *\t- the specified buffer is too small\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_idle_chk_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t      u32 *dump_buf,\n+\t\t\t\t      u32 buf_size_in_dwords,\n+\t\t\t\t      u32 *num_dumped_dwords);\n+\n+/**\n+ * @brief qed_dbg_mcp_trace_get_dump_buf_size - Returns the required buffer size\n+ *\tfor mcp trace results.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param buf_size - OUT: required buffer size (in dwords) for mcp trace data.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ *\t- the trace data in MCP scratchpad contain an invalid signature\n+ *\t- the bundle ID in NVRAM is invalid\n+ *\t- the trace meta data cannot be found (in NVRAM or image file)\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_mcp_trace_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t    struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t    u32 *buf_size);\n+\n+/**\n+ * @brief qed_dbg_mcp_trace_dump - Performs mcp trace and writes the results\n+ *\tinto the specified buffer.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param dump_buf - Pointer to write the mcp trace data into.\n+ * @param buf_size_in_dwords - Size of the specified buffer in dwords.\n+ * @param num_dumped_dwords - OUT: number of dumped dwords.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ *\t- the specified buffer is too small\n+ *\t- the trace data in MCP scratchpad contain an invalid signature\n+ *\t- the bundle ID in NVRAM is invalid\n+ *\t- the trace meta data cannot be found (in NVRAM or image file)\n+ *\t- the trace meta data cannot be read (from NVRAM or image file)\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_mcp_trace_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t       struct ecore_ptt *p_ptt,\n+\t\t\t\t       u32 *dump_buf,\n+\t\t\t\t       u32 buf_size_in_dwords,\n+\t\t\t\t       u32 *num_dumped_dwords);\n+\n+/**\n+ * @brief qed_dbg_reg_fifo_get_dump_buf_size - Returns the required buffer size\n+ *\tfor grc trace fifo results.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param buf_size - OUT: required buffer size (in dwords) for reg fifo data.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_reg_fifo_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t   struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t   u32 *buf_size);\n+\n+/**\n+ * @brief qed_dbg_reg_fifo_dump - Reads the reg fifo and writes the results into\n+ *\tthe specified buffer.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param dump_buf - Pointer to write the reg fifo data into.\n+ * @param buf_size_in_dwords - Size of the specified buffer in dwords.\n+ * @param num_dumped_dwords - OUT: number of dumped dwords.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ *\t- the specified buffer is too small\n+ *\t- DMAE transaction failed\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_reg_fifo_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t      u32 *dump_buf,\n+\t\t\t\t      u32 buf_size_in_dwords,\n+\t\t\t\t      u32 *num_dumped_dwords);\n+\n+/**\n+ * @brief qed_dbg_igu_fifo_get_dump_buf_size - Returns the required buffer size\n+ *\tfor the IGU fifo results.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param buf_size - OUT: required buffer size (in dwords) for the IGU fifo\n+ *\tdata.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_igu_fifo_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t   struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t   u32 *buf_size);\n+\n+/**\n+ * @brief qed_dbg_igu_fifo_dump - Reads the IGU fifo and writes the results into\n+ *\tthe specified buffer.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param dump_buf - Pointer to write the IGU fifo data into.\n+ * @param buf_size_in_dwords - Size of the specified buffer in dwords.\n+ * @param num_dumped_dwords - OUT: number of dumped dwords.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ *\t- the specified buffer is too small\n+ *\t- DMAE transaction failed\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_igu_fifo_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t      u32 *dump_buf,\n+\t\t\t\t      u32 buf_size_in_dwords,\n+\t\t\t\t      u32 *num_dumped_dwords);\n+\n+/**\n+ * @brief qed_dbg_protection_override_get_dump_buf_size - Returns the required\n+ *\tbuffer size for protection override window results.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param buf_size - OUT: required buffer size (in dwords) for protection\n+ *\toverride data.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status\n+qed_dbg_protection_override_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t      struct ecore_ptt *p_ptt,\n+\t\t\t\t\t      u32 *buf_size);\n+/**\n+ * @brief qed_dbg_protection_override_dump - Reads protection override window\n+ *\tentries and writes the results into the specified buffer.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param dump_buf - Pointer to write the protection override data into.\n+ * @param buf_size_in_dwords - Size of the specified buffer in dwords.\n+ * @param num_dumped_dwords - OUT: number of dumped dwords.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ *\t- the specified buffer is too small\n+ *\t- DMAE transaction failed\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_protection_override_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t u32 *dump_buf,\n+\t\t\t\t\t\t u32 buf_size_in_dwords,\n+\t\t\t\t\t\t u32 *num_dumped_dwords);\n+/**\n+ * @brief qed_dbg_fw_asserts_get_dump_buf_size - Returns the required buffer\n+ *\tsize for FW Asserts results.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param buf_size - OUT: required buffer size (in dwords) for FW Asserts data.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_fw_asserts_get_dump_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t     struct ecore_ptt *p_ptt,\n+\t\t\t\t\t\t     u32 *buf_size);\n+/**\n+ * @brief qed_dbg_fw_asserts_dump - Reads the FW Asserts and writes the results\n+ *\tinto the specified buffer.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param p_ptt - Ptt window used for writing the registers.\n+ * @param dump_buf - Pointer to write the FW Asserts data into.\n+ * @param buf_size_in_dwords - Size of the specified buffer in dwords.\n+ * @param num_dumped_dwords - OUT: number of dumped dwords.\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ *\t- the specified buffer is too small\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_fw_asserts_dump(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\tstruct ecore_ptt *p_ptt,\n+\t\t\t\t\tu32 *dump_buf,\n+\t\t\t\t\tu32 buf_size_in_dwords,\n+\t\t\t\t\tu32 *num_dumped_dwords);\n+\n+/**\n+ * @brief qed_dbg_read_attn - Reads the attention registers of the specified\n+ * block and type, and writes the results into the specified buffer.\n+ *\n+ * @param p_hwfn -\t HW device data\n+ * @param p_ptt -\t Ptt window used for writing the registers.\n+ * @param block -\t Block ID.\n+ * @param attn_type -\t Attention type.\n+ * @param clear_status - Indicates if the attention status should be cleared.\n+ * @param results -\t OUT: Pointer to write the read results into\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_read_attn(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t  struct ecore_ptt *p_ptt,\n+\t\t\t\t  enum block_id block,\n+\t\t\t\t  enum dbg_attn_type attn_type,\n+\t\t\t\t  bool clear_status,\n+\t\t\t\t  struct dbg_attn_block_result *results);\n+\n+/**\n+ * @brief qed_dbg_print_attn - Prints attention registers values in the\n+ *\tspecified results struct.\n+ *\n+ * @param p_hwfn\n+ * @param results - Pointer to the attention read results\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_print_attn(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   struct dbg_attn_block_result *results);\n+\n+/******************************* Data Types **********************************/\n+\n+struct mcp_trace_format {\n+\tu32 data;\n+#define MCP_TRACE_FORMAT_MODULE_MASK\t0x0000ffff\n+#define MCP_TRACE_FORMAT_MODULE_OFFSET\t0\n+#define MCP_TRACE_FORMAT_LEVEL_MASK\t0x00030000\n+#define MCP_TRACE_FORMAT_LEVEL_OFFSET\t16\n+#define MCP_TRACE_FORMAT_P1_SIZE_MASK\t0x000c0000\n+#define MCP_TRACE_FORMAT_P1_SIZE_OFFSET 18\n+#define MCP_TRACE_FORMAT_P2_SIZE_MASK\t0x00300000\n+#define MCP_TRACE_FORMAT_P2_SIZE_OFFSET 20\n+#define MCP_TRACE_FORMAT_P3_SIZE_MASK\t0x00c00000\n+#define MCP_TRACE_FORMAT_P3_SIZE_OFFSET 22\n+#define MCP_TRACE_FORMAT_LEN_MASK\t0xff000000\n+#define MCP_TRACE_FORMAT_LEN_OFFSET\t24\n+\n+\tchar *format_str;\n+};\n+\n+/* MCP Trace Meta data structure */\n+struct mcp_trace_meta {\n+\tu32 modules_num;\n+\tchar **modules;\n+\tu32 formats_num;\n+\tstruct mcp_trace_format *formats;\n+\tbool is_allocated;\n+};\n+\n+/* Debug Tools user data */\n+struct dbg_tools_user_data {\n+\tstruct mcp_trace_meta mcp_trace_meta;\n+\tconst u32 *mcp_trace_user_meta_buf;\n+};\n+\n+/******************************** Constants **********************************/\n+\n+#define MAX_NAME_LEN\t16\n+\n+/***************************** Public Functions *******************************/\n+\n+/**\n+ * @brief qed_dbg_user_set_bin_ptr - Sets a pointer to the binary data with\n+ *\tdebug arrays.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param bin_ptr - a pointer to the binary data with debug arrays.\n+ */\n+enum dbg_status qed_dbg_user_set_bin_ptr(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t const u8 * const bin_ptr);\n+\n+/**\n+ * @brief qed_dbg_alloc_user_data - Allocates user debug data.\n+ *\n+ * @param p_hwfn -\t\t HW device data\n+ * @param user_data_ptr - OUT: a pointer to the allocated memory.\n+ */\n+enum dbg_status qed_dbg_alloc_user_data(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\tvoid **user_data_ptr);\n+\n+/**\n+ * @brief qed_dbg_get_status_str - Returns a string for the specified status.\n+ *\n+ * @param status - a debug status code.\n+ *\n+ * @return a string for the specified status\n+ */\n+const char *qed_dbg_get_status_str(enum dbg_status status);\n+\n+/**\n+ * @brief qed_get_idle_chk_results_buf_size - Returns the required buffer size\n+ *\tfor idle check results (in bytes).\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param dump_buf - idle check dump buffer.\n+ * @param num_dumped_dwords - number of dwords that were dumped.\n+ * @param results_buf_size - OUT: required buffer size (in bytes) for the parsed\n+ *\tresults.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_get_idle_chk_results_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t  u32 *dump_buf,\n+\t\t\t\t\t\t  u32  num_dumped_dwords,\n+\t\t\t\t\t\t  u32 *results_buf_size);\n+/**\n+ * @brief qed_print_idle_chk_results - Prints idle check results\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param dump_buf - idle check dump buffer.\n+ * @param num_dumped_dwords - number of dwords that were dumped.\n+ * @param results_buf - buffer for printing the idle check results.\n+ * @param num_errors - OUT: number of errors found in idle check.\n+ * @param num_warnings - OUT: number of warnings found in idle check.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_print_idle_chk_results(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t   u32 *dump_buf,\n+\t\t\t\t\t   u32 num_dumped_dwords,\n+\t\t\t\t\t   char *results_buf,\n+\t\t\t\t\t   u32 *num_errors,\n+\t\t\t\t\t   u32 *num_warnings);\n+\n+/**\n+ * @brief qed_dbg_mcp_trace_set_meta_data - Sets the MCP Trace meta data.\n+ *\n+ * Needed in case the MCP Trace dump doesn't contain the meta data (e.g. due to\n+ * no NVRAM access).\n+ *\n+ * @param data - pointer to MCP Trace meta data\n+ * @param size - size of MCP Trace meta data in dwords\n+ */\n+void qed_dbg_mcp_trace_set_meta_data(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t     const u32 *meta_buf);\n+\n+/**\n+ * @brief qed_get_mcp_trace_results_buf_size - Returns the required buffer size\n+ *\tfor MCP Trace results (in bytes).\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param dump_buf - MCP Trace dump buffer.\n+ * @param num_dumped_dwords - number of dwords that were dumped.\n+ * @param results_buf_size - OUT: required buffer size (in bytes) for the parsed\n+ *\tresults.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_get_mcp_trace_results_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t   u32 *dump_buf,\n+\t\t\t\t\t\t   u32 num_dumped_dwords,\n+\t\t\t\t\t\t   u32 *results_buf_size);\n+\n+/**\n+ * @brief qed_print_mcp_trace_results - Prints MCP Trace results\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param dump_buf - mcp trace dump buffer, starting from the header.\n+ * @param num_dumped_dwords - number of dwords that were dumped.\n+ * @param results_buf - buffer for printing the mcp trace results.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_print_mcp_trace_results(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t    u32 *dump_buf,\n+\t\t\t\t\t    u32 num_dumped_dwords,\n+\t\t\t\t\t    char *results_buf);\n+\n+/**\n+ * @brief qed_print_mcp_trace_results_cont - Prints MCP Trace results, and\n+ * keeps the MCP trace meta data allocated, to support continuous MCP Trace\n+ * parsing. After the continuous parsing ends, mcp_trace_free_meta_data should\n+ * be called to free the meta data.\n+ *\n+ * @param p_hwfn -\t      HW device data\n+ * @param dump_buf -\t      mcp trace dump buffer, starting from the header.\n+ * @param results_buf -\t      buffer for printing the mcp trace results.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_print_mcp_trace_results_cont(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t u32 *dump_buf,\n+\t\t\t\t\t\t char *results_buf);\n+\n+/**\n+ * @brief print_mcp_trace_line - Prints MCP Trace results for a single line\n+ *\n+ * @param p_hwfn -\t      HW device data\n+ * @param dump_buf -\t      mcp trace dump buffer, starting from the header.\n+ * @param num_dumped_bytes -  number of bytes that were dumped.\n+ * @param results_buf -\t      buffer for printing the mcp trace results.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_print_mcp_trace_line(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t u8 *dump_buf,\n+\t\t\t\t\t u32 num_dumped_bytes,\n+\t\t\t\t\t char *results_buf);\n+\n+/**\n+ * @brief mcp_trace_free_meta_data - Frees the MCP Trace meta data.\n+ * Should be called after continuous MCP Trace parsing.\n+ *\n+ * @param p_hwfn - HW device data\n+ */\n+void qed_mcp_trace_free_meta_data(struct ecore_hwfn *p_hwfn);\n+\n+/**\n+ * @brief qed_get_reg_fifo_results_buf_size - Returns the required buffer size\n+ *\tfor reg_fifo results (in bytes).\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param dump_buf - reg fifo dump buffer.\n+ * @param num_dumped_dwords - number of dwords that were dumped.\n+ * @param results_buf_size - OUT: required buffer size (in bytes) for the parsed\n+ *\tresults.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_get_reg_fifo_results_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t  u32 *dump_buf,\n+\t\t\t\t\t\t  u32 num_dumped_dwords,\n+\t\t\t\t\t\t  u32 *results_buf_size);\n+\n+/**\n+ * @brief qed_print_reg_fifo_results - Prints reg fifo results\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param dump_buf - reg fifo dump buffer, starting from the header.\n+ * @param num_dumped_dwords - number of dwords that were dumped.\n+ * @param results_buf - buffer for printing the reg fifo results.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_print_reg_fifo_results(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t   u32 *dump_buf,\n+\t\t\t\t\t   u32 num_dumped_dwords,\n+\t\t\t\t\t   char *results_buf);\n+\n+/**\n+ * @brief qed_get_igu_fifo_results_buf_size - Returns the required buffer size\n+ *\tfor igu_fifo results (in bytes).\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param dump_buf - IGU fifo dump buffer.\n+ * @param num_dumped_dwords - number of dwords that were dumped.\n+ * @param results_buf_size - OUT: required buffer size (in bytes) for the parsed\n+ *\tresults.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_get_igu_fifo_results_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t  u32 *dump_buf,\n+\t\t\t\t\t\t  u32 num_dumped_dwords,\n+\t\t\t\t\t\t  u32 *results_buf_size);\n+\n+/**\n+ * @brief qed_print_igu_fifo_results - Prints IGU fifo results\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param dump_buf - IGU fifo dump buffer, starting from the header.\n+ * @param num_dumped_dwords - number of dwords that were dumped.\n+ * @param results_buf - buffer for printing the IGU fifo results.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_print_igu_fifo_results(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t   u32 *dump_buf,\n+\t\t\t\t\t   u32 num_dumped_dwords,\n+\t\t\t\t\t   char *results_buf);\n+\n+/**\n+ * @brief qed_get_protection_override_results_buf_size - Returns the required\n+ *\tbuffer size for protection override results (in bytes).\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param dump_buf - protection override dump buffer.\n+ * @param num_dumped_dwords - number of dwords that were dumped.\n+ * @param results_buf_size - OUT: required buffer size (in bytes) for the parsed\n+ *\tresults.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status\n+qed_get_protection_override_results_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t     u32 *dump_buf,\n+\t\t\t\t\t     u32 num_dumped_dwords,\n+\t\t\t\t\t     u32 *results_buf_size);\n+\n+/**\n+ * @brief qed_print_protection_override_results - Prints protection override\n+ *\tresults.\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param dump_buf - protection override dump buffer, starting from the header.\n+ * @param num_dumped_dwords - number of dwords that were dumped.\n+ * @param results_buf - buffer for printing the reg fifo results.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_print_protection_override_results(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t      u32 *dump_buf,\n+\t\t\t\t\t\t      u32 num_dumped_dwords,\n+\t\t\t\t\t\t      char *results_buf);\n+\n+/**\n+ * @brief qed_get_fw_asserts_results_buf_size - Returns the required buffer size\n+ *\tfor FW Asserts results (in bytes).\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param dump_buf - FW Asserts dump buffer.\n+ * @param num_dumped_dwords - number of dwords that were dumped.\n+ * @param results_buf_size - OUT: required buffer size (in bytes) for the parsed\n+ *\tresults.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_get_fw_asserts_results_buf_size(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t\t    u32 *dump_buf,\n+\t\t\t\t\t\t    u32 num_dumped_dwords,\n+\t\t\t\t\t\t    u32 *results_buf_size);\n+\n+/**\n+ * @brief qed_print_fw_asserts_results - Prints FW Asserts results\n+ *\n+ * @param p_hwfn - HW device data\n+ * @param dump_buf - FW Asserts dump buffer, starting from the header.\n+ * @param num_dumped_dwords - number of dwords that were dumped.\n+ * @param results_buf - buffer for printing the FW Asserts results.\n+ *\n+ * @return error if the parsing fails, ok otherwise.\n+ */\n+enum dbg_status qed_print_fw_asserts_results(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t\t     u32 *dump_buf,\n+\t\t\t\t\t     u32 num_dumped_dwords,\n+\t\t\t\t\t     char *results_buf);\n+\n+/**\n+ * @brief qed_dbg_parse_attn - Parses and prints attention registers values in\n+ * the specified results struct.\n+ *\n+ * @param p_hwfn -  HW device data\n+ * @param results - Pointer to the attention read results\n+ *\n+ * @return error if one of the following holds:\n+ *\t- the version wasn't set\n+ * Otherwise, returns ok.\n+ */\n+enum dbg_status qed_dbg_parse_attn(struct ecore_hwfn *p_hwfn,\n+\t\t\t\t   struct dbg_attn_block_result *results);\n+\n+#endif\ndiff --git a/drivers/net/qede/qede_if.h b/drivers/net/qede/qede_if.h\nindex 858cd51d5..c5ae3fb2e 100644\n--- a/drivers/net/qede/qede_if.h\n+++ b/drivers/net/qede/qede_if.h\n@@ -189,6 +189,51 @@ struct qed_common_ops {\n \t\t\t      uint32_t dp_module, uint8_t dp_level);\n \n \tint (*send_drv_state)(struct ecore_dev *edev, bool active);\n+\n+\t/* ###############  DEBUG *************************/\n+\n+\tint     (*dbg_grc)(struct ecore_dev       *edev,\n+\t\t\t   void\t\t *buffer,\n+\t\t\t   u32\t\t  *num_dumped_bytes);\n+\tint     (*dbg_grc_size)(struct ecore_dev *edev);\n+\n+\tint     (*dbg_idle_chk)(struct ecore_dev  *edev,\n+\t\t\t\tvoid\t    *buffer,\n+\t\t\t\tu32\t     *num_dumped_bytes);\n+\tint     (*dbg_idle_chk_size)(struct ecore_dev *edev);\n+\n+\tint     (*dbg_reg_fifo)(struct ecore_dev  *edev,\n+\t\t\t\tvoid\t    *buffer,\n+\t\t\t\tu32\t     *num_dumped_bytes);\n+\tint     (*dbg_reg_fifo_size)(struct ecore_dev *edev);\n+\n+\tint     (*dbg_mcp_trace)(struct ecore_dev *edev,\n+\t\t\t\t void\t   *buffer,\n+\t\t\t\t u32\t    *num_dumped_bytes);\n+\tint     (*dbg_mcp_trace_size)(struct ecore_dev *edev);\n+\n+\tint\t(*dbg_protection_override)(struct ecore_dev *edev, void *buffer,\n+\t\t\t\t\t   u32 *num_dumped_bytes);\n+\tint     (*dbg_protection_override_size)(struct ecore_dev *edev);\n+\n+\tint\t(*dbg_igu_fifo_size)(struct ecore_dev *edev);\n+\tint\t(*dbg_igu_fifo)(struct ecore_dev *edev, void *buffer,\n+\t\t\t\tu32 *num_dumped_bytes);\n+\n+\tint\t(*dbg_fw_asserts)(struct ecore_dev *edev, void *buffer,\n+\t\t\t\t  u32 *num_dumped_bytes);\n+\n+\tint\t(*dbg_fw_asserts_size)(struct ecore_dev *edev);\n+\n+\tint\t(*dbg_ilt)(struct ecore_dev *edev, void *buffer,\n+\t\t\t   u32 *num_dumped_bytes);\n+\n+\tint\t(*dbg_ilt_size)(struct ecore_dev *edev);\n+\n+\tu8      (*dbg_get_debug_engine)(struct ecore_dev *edev);\n+\tvoid    (*dbg_set_debug_engine)(struct ecore_dev  *edev,\n+\t\t\t\t\tint\t     engine_number);\n+\n };\n \n /* Externs */\ndiff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c\nindex 51aa639c6..987a6f1e1 100644\n--- a/drivers/net/qede/qede_main.c\n+++ b/drivers/net/qede/qede_main.c\n@@ -9,6 +9,8 @@\n #include <rte_string_fns.h>\n \n #include \"qede_ethdev.h\"\n+/* ######### DEBUG ###########*/\n+#include \"qede_debug.h\"\n \n /* Alarm timeout. */\n #define QEDE_ALARM_TIMEOUT_US 100000\n@@ -276,10 +278,15 @@ static int qed_slowpath_start(struct ecore_dev *edev,\n \tqed_start_iov_task(edev);\n \n #ifdef CONFIG_ECORE_BINARY_FW\n-\tif (IS_PF(edev))\n+\tif (IS_PF(edev)) {\n \t\tdata = (const uint8_t *)edev->firmware + sizeof(u32);\n+\n+\t\t/* ############### DEBUG ################## */\n+\t\tqed_dbg_pf_init(edev);\n+\t}\n #endif\n \n+\n \t/* Start the slowpath */\n \tmemset(&hw_init_params, 0, sizeof(hw_init_params));\n \thw_init_params.b_hw_start = true;\n@@ -779,6 +786,36 @@ const struct qed_common_ops qed_common_ops_pass = {\n \tINIT_STRUCT_FIELD(slowpath_stop, &qed_slowpath_stop),\n \tINIT_STRUCT_FIELD(remove, &qed_remove),\n \tINIT_STRUCT_FIELD(send_drv_state, &qed_send_drv_state),\n+\t/* ############### DEBUG ####################*/\n+\n+\tINIT_STRUCT_FIELD(dbg_get_debug_engine, &qed_get_debug_engine),\n+\tINIT_STRUCT_FIELD(dbg_set_debug_engine, &qed_set_debug_engine),\n+\n+\tINIT_STRUCT_FIELD(dbg_protection_override,\n+\t\t\t  &qed_dbg_protection_override),\n+\tINIT_STRUCT_FIELD(dbg_protection_override_size,\n+\t\t\t  &qed_dbg_protection_override_size),\n+\n+\tINIT_STRUCT_FIELD(dbg_grc, &qed_dbg_grc),\n+\tINIT_STRUCT_FIELD(dbg_grc_size, &qed_dbg_grc_size),\n+\n+\tINIT_STRUCT_FIELD(dbg_idle_chk, &qed_dbg_idle_chk),\n+\tINIT_STRUCT_FIELD(dbg_idle_chk_size, &qed_dbg_idle_chk_size),\n+\n+\tINIT_STRUCT_FIELD(dbg_mcp_trace, &qed_dbg_mcp_trace),\n+\tINIT_STRUCT_FIELD(dbg_mcp_trace_size, &qed_dbg_mcp_trace_size),\n+\n+\tINIT_STRUCT_FIELD(dbg_fw_asserts, &qed_dbg_fw_asserts),\n+\tINIT_STRUCT_FIELD(dbg_fw_asserts_size, &qed_dbg_fw_asserts_size),\n+\n+\tINIT_STRUCT_FIELD(dbg_ilt, &qed_dbg_ilt),\n+\tINIT_STRUCT_FIELD(dbg_ilt_size, &qed_dbg_ilt_size),\n+\n+\tINIT_STRUCT_FIELD(dbg_reg_fifo_size, &qed_dbg_reg_fifo_size),\n+\tINIT_STRUCT_FIELD(dbg_reg_fifo, &qed_dbg_reg_fifo),\n+\n+\tINIT_STRUCT_FIELD(dbg_igu_fifo_size, &qed_dbg_igu_fifo_size),\n+\tINIT_STRUCT_FIELD(dbg_igu_fifo, &qed_dbg_igu_fifo),\n };\n \n const struct qed_eth_ops qed_eth_ops_pass = {\n",
    "prefixes": [
        "v3",
        "3/4"
    ]
}