// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
 /* QLogic qed NIC Driver
  * Copyright (c) 2015 QLogic Corporation
- * Copyright (c) 2019-2020 Marvell International Ltd.
+ * Copyright (c) 2019-2021 Marvell International Ltd.
  */
 
 #include <linux/module.h>
        return (r[0] & ~r[1]) != imm[0];
 }
 
+static u32 cond14(const u32 *r, const u32 *imm)
+{
+       return (r[0] | imm[0]) != imm[1];
+}
+
 static u32 cond1(const u32 *r, const u32 *imm)
 {
        return r[0] != imm[0];
        cond11,
        cond12,
        cond13,
+       cond14,
 };
 
 #define NUM_PHYS_BLOCKS 84
        DBG_BUS_NUM_FRAME_MODES
 };
 
+/* Debug bus SEMI frame modes */
+enum dbg_bus_semi_frame_modes {
+       DBG_BUS_SEMI_FRAME_MODE_4FAST = 0,      /* 4 fast dw */
+       DBG_BUS_SEMI_FRAME_MODE_2FAST_2SLOW = 1, /* 2 fast dw, 2 slow dw */
+       DBG_BUS_SEMI_FRAME_MODE_1FAST_3SLOW = 2, /* 1 fast dw,3 slow dw */
+       DBG_BUS_SEMI_FRAME_MODE_4SLOW = 3,      /* 4 slow dw */
+       DBG_BUS_SEMI_NUM_FRAME_MODES
+};
+
+/* Debug bus filter types */
+enum dbg_bus_filter_types {
+       DBG_BUS_FILTER_TYPE_OFF,        /* Filter always off */
+       DBG_BUS_FILTER_TYPE_PRE,        /* Filter before trigger only */
+       DBG_BUS_FILTER_TYPE_POST,       /* Filter after trigger only */
+       DBG_BUS_FILTER_TYPE_ON  /* Filter always on */
+};
+
+/* Debug bus pre-trigger recording types */
+enum dbg_bus_pre_trigger_types {
+       DBG_BUS_PRE_TRIGGER_FROM_ZERO,  /* Record from time 0 */
+       DBG_BUS_PRE_TRIGGER_NUM_CHUNKS, /* Record some chunks before trigger */
+       DBG_BUS_PRE_TRIGGER_DROP        /* Drop data before trigger */
+};
+
+/* Debug bus post-trigger recording types */
+enum dbg_bus_post_trigger_types {
+       DBG_BUS_POST_TRIGGER_RECORD,    /* Start recording after trigger */
+       DBG_BUS_POST_TRIGGER_DROP       /* Drop data after trigger */
+};
+
+/* Debug bus other engine mode */
+enum dbg_bus_other_engine_modes {
+       DBG_BUS_OTHER_ENGINE_MODE_NONE,
+       DBG_BUS_OTHER_ENGINE_MODE_DOUBLE_BW_TX,
+       DBG_BUS_OTHER_ENGINE_MODE_DOUBLE_BW_RX,
+       DBG_BUS_OTHER_ENGINE_MODE_CROSS_ENGINE_TX,
+       DBG_BUS_OTHER_ENGINE_MODE_CROSS_ENGINE_RX
+};
+
+/* DBG block Framing mode definitions */
+struct framing_mode_defs {
+       u8 id;
+       u8 blocks_dword_mask;
+       u8 storms_dword_mask;
+       u8 semi_framing_mode_id;
+       u8 full_buf_thr;
+};
+
 /* Chip constant definitions */
 struct chip_defs {
        const char *name;
+       u8 dwords_per_cycle;
+       u8 num_framing_modes;
        u32 num_ilt_pages;
+       struct framing_mode_defs *framing_modes;
 };
 
 /* HW type constant definitions */
 #define FIELD_BIT_OFFSET(type, field)  type ## _ ## field ## _ ## OFFSET
 #define FIELD_BIT_SIZE(type, field)    type ## _ ## field ## _ ## SIZE
 #define FIELD_DWORD_OFFSET(type, field) \
-        (int)(FIELD_BIT_OFFSET(type, field) / 32)
+        ((int)(FIELD_BIT_OFFSET(type, field) / 32))
 #define FIELD_DWORD_SHIFT(type, field) (FIELD_BIT_OFFSET(type, field) % 32)
 #define FIELD_BIT_MASK(type, field) \
        (((1 << FIELD_BIT_SIZE(type, field)) - 1) << \
 
 #define STATIC_DEBUG_LINE_DWORDS       9
 
-#define NUM_COMMON_GLOBAL_PARAMS       9
+#define NUM_COMMON_GLOBAL_PARAMS       11
 
 #define MAX_RECURSION_DEPTH            10
 
+#define FW_IMG_KUKU                     0
 #define FW_IMG_MAIN                    1
+#define FW_IMG_L2B                      2
 
 #define REG_FIFO_ELEMENT_DWORDS                2
 #define REG_FIFO_DEPTH_ELEMENTS                32
 
 /***************************** Constant Arrays *******************************/
 
+/* DBG block framing mode definitions, in descending preference order */
+static struct framing_mode_defs s_framing_mode_defs[4] = {
+       {DBG_BUS_FRAME_MODE_4ST, 0x0, 0xf,
+        DBG_BUS_SEMI_FRAME_MODE_4FAST,
+        10},
+       {DBG_BUS_FRAME_MODE_4HW, 0xf, 0x0, DBG_BUS_SEMI_FRAME_MODE_4SLOW,
+        10},
+       {DBG_BUS_FRAME_MODE_2ST_2HW, 0x3, 0xc,
+        DBG_BUS_SEMI_FRAME_MODE_2FAST_2SLOW, 10},
+       {DBG_BUS_FRAME_MODE_1ST_3HW, 0x7, 0x8,
+        DBG_BUS_SEMI_FRAME_MODE_1FAST_3SLOW, 10}
+};
+
 /* Chip constant definitions array */
 static struct chip_defs s_chip_defs[MAX_CHIP_IDS] = {
-       {"bb", PSWRQ2_REG_ILT_MEMORY_SIZE_BB / 2},
-       {"ah", PSWRQ2_REG_ILT_MEMORY_SIZE_K2 / 2}
+       {"bb", 4, DBG_BUS_NUM_FRAME_MODES, PSWRQ2_REG_ILT_MEMORY_SIZE_BB / 2,
+        s_framing_mode_defs},
+       {"ah", 4, DBG_BUS_NUM_FRAME_MODES, PSWRQ2_REG_ILT_MEMORY_SIZE_K2 / 2,
+        s_framing_mode_defs}
 };
 
 /* Storm constant definitions array */
                {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
                true,
                TSEM_REG_FAST_MEMORY,
-               TSEM_REG_DBG_FRAME_MODE_BB_K2, TSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
-               TSEM_REG_SLOW_DBG_MODE_BB_K2, TSEM_REG_DBG_MODE1_CFG_BB_K2,
+               TSEM_REG_DBG_FRAME_MODE, TSEM_REG_SLOW_DBG_ACTIVE,
+               TSEM_REG_SLOW_DBG_MODE, TSEM_REG_DBG_MODE1_CFG,
                TSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_DBG_GPRE_VECT,
                TCM_REG_CTX_RBC_ACCS,
                {TCM_REG_AGG_CON_CTX, TCM_REG_SM_CON_CTX, TCM_REG_AGG_TASK_CTX,
                {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM},
                false,
                MSEM_REG_FAST_MEMORY,
-               MSEM_REG_DBG_FRAME_MODE_BB_K2,
-               MSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
-               MSEM_REG_SLOW_DBG_MODE_BB_K2,
-               MSEM_REG_DBG_MODE1_CFG_BB_K2,
+               MSEM_REG_DBG_FRAME_MODE,
+               MSEM_REG_SLOW_DBG_ACTIVE,
+               MSEM_REG_SLOW_DBG_MODE,
+               MSEM_REG_DBG_MODE1_CFG,
                MSEM_REG_SYNC_DBG_EMPTY,
                MSEM_REG_DBG_GPRE_VECT,
                MCM_REG_CTX_RBC_ACCS,
                {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
                false,
                USEM_REG_FAST_MEMORY,
-               USEM_REG_DBG_FRAME_MODE_BB_K2,
-               USEM_REG_SLOW_DBG_ACTIVE_BB_K2,
-               USEM_REG_SLOW_DBG_MODE_BB_K2,
-               USEM_REG_DBG_MODE1_CFG_BB_K2,
+               USEM_REG_DBG_FRAME_MODE,
+               USEM_REG_SLOW_DBG_ACTIVE,
+               USEM_REG_SLOW_DBG_MODE,
+               USEM_REG_DBG_MODE1_CFG,
                USEM_REG_SYNC_DBG_EMPTY,
                USEM_REG_DBG_GPRE_VECT,
                UCM_REG_CTX_RBC_ACCS,
                {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
                false,
                XSEM_REG_FAST_MEMORY,
-               XSEM_REG_DBG_FRAME_MODE_BB_K2,
-               XSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
-               XSEM_REG_SLOW_DBG_MODE_BB_K2,
-               XSEM_REG_DBG_MODE1_CFG_BB_K2,
+               XSEM_REG_DBG_FRAME_MODE,
+               XSEM_REG_SLOW_DBG_ACTIVE,
+               XSEM_REG_SLOW_DBG_MODE,
+               XSEM_REG_DBG_MODE1_CFG,
                XSEM_REG_SYNC_DBG_EMPTY,
                XSEM_REG_DBG_GPRE_VECT,
                XCM_REG_CTX_RBC_ACCS,
                {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY},
                false,
                YSEM_REG_FAST_MEMORY,
-               YSEM_REG_DBG_FRAME_MODE_BB_K2,
-               YSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
-               YSEM_REG_SLOW_DBG_MODE_BB_K2,
-               YSEM_REG_DBG_MODE1_CFG_BB_K2,
+               YSEM_REG_DBG_FRAME_MODE,
+               YSEM_REG_SLOW_DBG_ACTIVE,
+               YSEM_REG_SLOW_DBG_MODE,
+               YSEM_REG_DBG_MODE1_CFG,
                YSEM_REG_SYNC_DBG_EMPTY,
                YSEM_REG_DBG_GPRE_VECT,
                YCM_REG_CTX_RBC_ACCS,
                {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
                true,
                PSEM_REG_FAST_MEMORY,
-               PSEM_REG_DBG_FRAME_MODE_BB_K2,
-               PSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
-               PSEM_REG_SLOW_DBG_MODE_BB_K2,
-               PSEM_REG_DBG_MODE1_CFG_BB_K2,
+               PSEM_REG_DBG_FRAME_MODE,
+               PSEM_REG_SLOW_DBG_ACTIVE,
+               PSEM_REG_SLOW_DBG_MODE,
+               PSEM_REG_DBG_MODE1_CFG,
                PSEM_REG_SYNC_DBG_EMPTY,
                PSEM_REG_DBG_GPRE_VECT,
                PCM_REG_CTX_RBC_ACCS,
        {"asic", 1, 256, 32768},
        {"reserved", 0, 0, 0},
        {"reserved2", 0, 0, 0},
-       {"reserved3", 0, 0, 0}
+       {"reserved3", 0, 0, 0},
+       {"reserved4", 0, 0, 0}
 };
 
 static struct grc_param_defs s_grc_param_defs[] = {
 
 static struct phy_defs s_phy_defs[] = {
        {"nw_phy", NWS_REG_NWS_CMU_K2,
-        PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_7_0_K2_E5,
-        PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_15_8_K2_E5,
-        PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_7_0_K2_E5,
-        PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_11_8_K2_E5},
-       {"sgmii_phy", MS_REG_MS_CMU_K2_E5,
-        PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X132_K2_E5,
-        PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X133_K2_E5,
-        PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X130_K2_E5,
-        PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X131_K2_E5},
-       {"pcie_phy0", PHY_PCIE_REG_PHY0_K2_E5,
-        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2_E5,
-        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2_E5,
-        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2_E5,
-        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2_E5},
-       {"pcie_phy1", PHY_PCIE_REG_PHY1_K2_E5,
-        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2_E5,
-        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2_E5,
-        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2_E5,
-        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2_E5},
+        PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_7_0_K2,
+        PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_15_8_K2,
+        PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_7_0_K2,
+        PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_11_8_K2},
+       {"sgmii_phy", MS_REG_MS_CMU_K2,
+        PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X132_K2,
+        PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X133_K2,
+        PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X130_K2,
+        PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X131_K2},
+       {"pcie_phy0", PHY_PCIE_REG_PHY0_K2,
+        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2,
+        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2,
+        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2,
+        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2},
+       {"pcie_phy1", PHY_PCIE_REG_PHY1_K2,
+        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2,
+        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2,
+        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2,
+        PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2},
 };
 
 static struct split_type_defs s_split_type_defs[] = {
        {"vf"}
 };
 
+/******************************** Variables **********************************/
+
+/* The version of the calling app */
+static u32 s_app_ver;
+
 /**************************** Private Functions ******************************/
 
+static void qed_static_asserts(void)
+{
+}
+
 /* Reads and returns a single dword from the specified unaligned buffer */
 static u32 qed_read_unaligned_dword(u8 *buf)
 {
        if (dev_data->initialized)
                return DBG_STATUS_OK;
 
+       if (!s_app_ver)
+               return DBG_STATUS_APP_VERSION_NOT_SET;
+
        /* Set chip */
        if (QED_IS_K2(p_hwfn->cdev)) {
                dev_data->chip_id = CHIP_K2;
        for (i = 0; i < size; i++, addr += BYTES_IN_DWORD)
                dest[i] = qed_rd(p_hwfn, p_ptt, addr);
 
-       /* qed_rq() fetches data in CPU byteorder. Swap it back to
-        * the device's to get right structure layout.
-        */
-       cpu_to_le32_array(dest, size);
-
        /* Read FW version info from Storm RAM */
        size = le32_to_cpu(fw_info_location.size);
        if (!size || size > sizeof(*fw_info))
 
        for (i = 0; i < size; i++, addr += BYTES_IN_DWORD)
                dest[i] = qed_rd(p_hwfn, p_ptt, addr);
-
-       cpu_to_le32_array(dest, size);
 }
 
 /* Dumps the specified string to the specified buffer.
                        DP_NOTICE(p_hwfn,
                                  "Unexpected debug error: invalid FW version string\n");
                switch (fw_info.ver.image_id) {
+               case FW_IMG_KUKU:
+                       strcpy(fw_img_str, "kuku");
+                       break;
                case FW_IMG_MAIN:
                        strcpy(fw_img_str, "main");
                        break;
+               case FW_IMG_L2B:
+                       strcpy(fw_img_str, "l2b");
+                       break;
                default:
                        strcpy(fw_img_str, "unknown");
                        break;
                                         u8 num_specific_global_params)
 {
        struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
+       char sw_platform_str[MAX_SW_PLTAFORM_STR_SIZE];
        u32 offset = 0;
        u8 num_params;
 
                                     dump,
                                     "platform",
                                     s_hw_type_defs[dev_data->hw_type].name);
+       offset += qed_dump_str_param(dump_buf + offset,
+                                    dump, "sw-platform", sw_platform_str);
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump, "pci-func", p_hwfn->abs_pf_id);
+       offset += qed_dump_num_param(dump_buf + offset,
+                                    dump, "epoch", qed_get_epoch_time());
        if (dev_data->chip_id == CHIP_BB)
                offset += qed_dump_num_param(dump_buf + offset,
                                             dump, "path", QED_PATH_ID(p_hwfn));
                        continue;
 
                reg_addr = s_storm_defs[storm_id].sem_fast_mem_addr +
-                   SEM_FAST_REG_STALL_0_BB_K2;
+                   SEM_FAST_REG_STALL_0;
                qed_wr(p_hwfn, p_ptt, reg_addr, stall ? 1 : 0);
        }
 
 {
        struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
        const struct dbg_attn_reg *attn_reg_arr;
+       u32 block_id, sts_clr_address;
        u8 reg_idx, num_attn_regs;
-       u32 block_id;
 
        for (block_id = 0; block_id < NUM_PHYS_BLOCKS; block_id++) {
                if (dev_data->block_in_reset[block_id])
                                GET_FIELD(reg_data->mode.data,
                                          DBG_MODE_HDR_MODES_BUF_OFFSET);
 
+                       sts_clr_address = reg_data->sts_clr_address;
                        /* If Mode match: clear parity status */
                        if (!eval_mode ||
                            qed_is_mode_match(p_hwfn, &modes_buf_offset))
                                qed_rd(p_hwfn, p_ptt,
-                                      DWORDS_TO_BYTES(reg_data->
-                                                      sts_clr_address));
+                                      DWORDS_TO_BYTES(sts_clr_address));
                }
        }
 }
 
+/* Finds the meta data image in NVRAM */
+static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
+                                           struct qed_ptt *p_ptt,
+                                           u32 image_type,
+                                           u32 *nvram_offset_bytes,
+                                           u32 *nvram_size_bytes)
+{
+       u32 ret_mcp_resp, ret_mcp_param, ret_txn_size;
+       struct mcp_file_att file_att;
+       int nvm_result;
+
+       /* Call NVRAM get file command */
+       nvm_result = qed_mcp_nvm_rd_cmd(p_hwfn,
+                                       p_ptt,
+                                       DRV_MSG_CODE_NVM_GET_FILE_ATT,
+                                       image_type,
+                                       &ret_mcp_resp,
+                                       &ret_mcp_param,
+                                       &ret_txn_size,
+                                       (u32 *)&file_att, false);
+
+       /* Check response */
+       if (nvm_result || (ret_mcp_resp & FW_MSG_CODE_MASK) !=
+           FW_MSG_CODE_NVM_OK)
+               return DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
+
+       /* Update return values */
+       *nvram_offset_bytes = file_att.nvm_start_addr;
+       *nvram_size_bytes = file_att.len;
+
+       DP_VERBOSE(p_hwfn,
+                  QED_MSG_DEBUG,
+                  "find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\n",
+                  image_type, *nvram_offset_bytes, *nvram_size_bytes);
+
+       /* Check alignment */
+       if (*nvram_size_bytes & 0x3)
+               return DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE;
+
+       return DBG_STATUS_OK;
+}
+
+/* Reads data from NVRAM */
+static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
+                                     struct qed_ptt *p_ptt,
+                                     u32 nvram_offset_bytes,
+                                     u32 nvram_size_bytes, u32 *ret_buf)
+{
+       u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy;
+       s32 bytes_left = nvram_size_bytes;
+       u32 read_offset = 0, param = 0;
+
+       DP_VERBOSE(p_hwfn,
+                  QED_MSG_DEBUG,
+                  "nvram_read: reading image of size %d bytes from NVRAM\n",
+                  nvram_size_bytes);
+
+       do {
+               bytes_to_copy =
+                   (bytes_left >
+                    MCP_DRV_NVM_BUF_LEN) ? MCP_DRV_NVM_BUF_LEN : bytes_left;
+
+               /* Call NVRAM read command */
+               SET_MFW_FIELD(param,
+                             DRV_MB_PARAM_NVM_OFFSET,
+                             nvram_offset_bytes + read_offset);
+               SET_MFW_FIELD(param, DRV_MB_PARAM_NVM_LEN, bytes_to_copy);
+               if (qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt,
+                                      DRV_MSG_CODE_NVM_READ_NVRAM, param,
+                                      &ret_mcp_resp,
+                                      &ret_mcp_param, &ret_read_size,
+                                      (u32 *)((u8 *)ret_buf + read_offset),
+                                      false))
+                       return DBG_STATUS_NVRAM_READ_FAILED;
+
+               /* Check response */
+               if ((ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
+                       return DBG_STATUS_NVRAM_READ_FAILED;
+
+               /* Update read offset */
+               read_offset += ret_read_size;
+               bytes_left -= ret_read_size;
+       } while (bytes_left > 0);
+
+       return DBG_STATUS_OK;
+}
+
 /* Dumps GRC registers section header. Returns the dumped size in dwords.
  * the following parameters are dumped:
  * - count: no. of dumped entries
        return offset;
 }
 
-static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
-                                           struct qed_ptt *p_ptt,
-                                           u32 image_type,
-                                           u32 *nvram_offset_bytes,
-                                           u32 *nvram_size_bytes);
-
-static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
-                                     struct qed_ptt *p_ptt,
-                                     u32 nvram_offset_bytes,
-                                     u32 nvram_size_bytes, u32 *ret_buf);
-
 /* Dumps the MCP HW dump from NVRAM. Returns the dumped size in dwords. */
 static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn,
                                    struct qed_ptt *p_ptt,
                has_dbg_bus = GET_FIELD(block_per_chip->flags,
                                        DBG_BLOCK_CHIP_HAS_DBG_BUS);
 
-               /* read+clear for NWS parity is not working, skip NWS block */
-               if (block_id == BLOCK_NWS)
-                       continue;
-
                if (!is_removed && has_dbg_bus &&
                    GET_FIELD(block_per_chip->dbg_bus_mode.data,
                              DBG_MODE_HDR_EVAL_MODE) > 0) {
                                    bool dump, u32 *num_dumped_dwords)
 {
        struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
-       u32 dwords_read, offset = 0;
        bool parities_masked = false;
+       u32 dwords_read, offset = 0;
        u8 i;
 
        *num_dumped_dwords = 0;
  */
 static u32 qed_idle_chk_dump_failure(struct qed_hwfn *p_hwfn,
                                     struct qed_ptt *p_ptt,
-                                    u32 *
-                                    dump_buf,
+                                    u32 *dump_buf,
                                     bool dump,
                                     u16 rule_id,
                                     const struct dbg_idle_chk_rule *rule,
        return offset;
 }
 
-/* Finds the meta data image in NVRAM */
-static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
-                                           struct qed_ptt *p_ptt,
-                                           u32 image_type,
-                                           u32 *nvram_offset_bytes,
-                                           u32 *nvram_size_bytes)
-{
-       u32 ret_mcp_resp, ret_mcp_param, ret_txn_size;
-       struct mcp_file_att file_att;
-       int nvm_result;
-
-       /* Call NVRAM get file command */
-       nvm_result = qed_mcp_nvm_rd_cmd(p_hwfn,
-                                       p_ptt,
-                                       DRV_MSG_CODE_NVM_GET_FILE_ATT,
-                                       image_type,
-                                       &ret_mcp_resp,
-                                       &ret_mcp_param,
-                                       &ret_txn_size, (u32 *)&file_att);
-
-       /* Check response */
-       if (nvm_result ||
-           (ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
-               return DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
-
-       /* Update return values */
-       *nvram_offset_bytes = file_att.nvm_start_addr;
-       *nvram_size_bytes = file_att.len;
-
-       DP_VERBOSE(p_hwfn,
-                  QED_MSG_DEBUG,
-                  "find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\n",
-                  image_type, *nvram_offset_bytes, *nvram_size_bytes);
-
-       /* Check alignment */
-       if (*nvram_size_bytes & 0x3)
-               return DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE;
-
-       return DBG_STATUS_OK;
-}
-
-/* Reads data from NVRAM */
-static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
-                                     struct qed_ptt *p_ptt,
-                                     u32 nvram_offset_bytes,
-                                     u32 nvram_size_bytes, u32 *ret_buf)
-{
-       u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy;
-       s32 bytes_left = nvram_size_bytes;
-       u32 read_offset = 0, param = 0;
-
-       DP_VERBOSE(p_hwfn,
-                  QED_MSG_DEBUG,
-                  "nvram_read: reading image of size %d bytes from NVRAM\n",
-                  nvram_size_bytes);
-
-       do {
-               bytes_to_copy =
-                   (bytes_left >
-                    MCP_DRV_NVM_BUF_LEN) ? MCP_DRV_NVM_BUF_LEN : bytes_left;
-
-               /* Call NVRAM read command */
-               SET_MFW_FIELD(param,
-                             DRV_MB_PARAM_NVM_OFFSET,
-                             nvram_offset_bytes + read_offset);
-               SET_MFW_FIELD(param, DRV_MB_PARAM_NVM_LEN, bytes_to_copy);
-               if (qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt,
-                                      DRV_MSG_CODE_NVM_READ_NVRAM, param,
-                                      &ret_mcp_resp,
-                                      &ret_mcp_param, &ret_read_size,
-                                      (u32 *)((u8 *)ret_buf + read_offset)))
-                       return DBG_STATUS_NVRAM_READ_FAILED;
-
-               /* Check response */
-               if ((ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
-                       return DBG_STATUS_NVRAM_READ_FAILED;
-
-               /* Update read offset */
-               read_offset += ret_read_size;
-               bytes_left -= ret_read_size;
-       } while (bytes_left > 0);
-
-       return DBG_STATUS_OK;
-}
-
 /* Get info on the MCP Trace data in the scratchpad:
  * - trace_data_grc_addr (OUT): trace data GRC address in bytes
  * - trace_data_size (OUT): trace data size in bytes (without the header)
 /* Dumps the specified ILT pages to the specified buffer.
  * Returns the dumped size in dwords.
  */
-static u32 qed_ilt_dump_pages_range(u32 *dump_buf,
-                                   bool dump,
-                                   u32 start_page_id,
+static u32 qed_ilt_dump_pages_range(u32 *dump_buf, u32 *given_offset,
+                                   bool *dump, u32 start_page_id,
                                    u32 num_pages,
                                    struct phys_mem_desc *ilt_pages,
-                                   bool dump_page_ids)
+                                   bool dump_page_ids, u32 buf_size_in_dwords,
+                                   u32 *given_actual_dump_size_in_dwords)
 {
-       u32 page_id, end_page_id, offset = 0;
+       u32 actual_dump_size_in_dwords = *given_actual_dump_size_in_dwords;
+       u32 page_id, end_page_id, offset = *given_offset;
+       struct phys_mem_desc *mem_desc = NULL;
+       bool continue_dump = *dump;
+       u32 partial_page_size = 0;
 
        if (num_pages == 0)
                return offset;
        end_page_id = start_page_id + num_pages - 1;
 
        for (page_id = start_page_id; page_id <= end_page_id; page_id++) {
-               struct phys_mem_desc *mem_desc = &ilt_pages[page_id];
-
-               /**
-                *
-                * if (page_id >= ->p_cxt_mngr->ilt_shadow_size)
-                *     break;
-                */
-
+               mem_desc = &ilt_pages[page_id];
                if (!ilt_pages[page_id].virt_addr)
                        continue;
 
                if (dump_page_ids) {
-                       /* Copy page ID to dump buffer */
-                       if (dump)
+                       /* Copy page ID to dump buffer
+                        * (if dump is needed and buffer is not full)
+                        */
+                       if ((continue_dump) &&
+                           (offset + 1 > buf_size_in_dwords)) {
+                               continue_dump = false;
+                               actual_dump_size_in_dwords = offset;
+                       }
+                       if (continue_dump)
                                *(dump_buf + offset) = page_id;
                        offset++;
                } else {
                        /* Copy page memory to dump buffer */
-                       if (dump)
+                       if ((continue_dump) &&
+                           (offset + BYTES_TO_DWORDS(mem_desc->size) >
+                            buf_size_in_dwords)) {
+                               if (offset + BYTES_TO_DWORDS(mem_desc->size) >
+                                   buf_size_in_dwords) {
+                                       partial_page_size =
+                                           buf_size_in_dwords - offset;
+                                       memcpy(dump_buf + offset,
+                                              mem_desc->virt_addr,
+                                              partial_page_size);
+                                       continue_dump = false;
+                                       actual_dump_size_in_dwords =
+                                           offset + partial_page_size;
+                               }
+                       }
+
+                       if (continue_dump)
                                memcpy(dump_buf + offset,
                                       mem_desc->virt_addr, mem_desc->size);
                        offset += BYTES_TO_DWORDS(mem_desc->size);
                }
        }
 
+       *dump = continue_dump;
+       *given_offset = offset;
+       *given_actual_dump_size_in_dwords = actual_dump_size_in_dwords;
+
        return offset;
 }
 
  */
 static u32 qed_ilt_dump_pages_section(struct qed_hwfn *p_hwfn,
                                      u32 *dump_buf,
-                                     bool dump,
+                                     u32 *given_offset,
+                                     bool *dump,
                                      u32 valid_conn_pf_pages,
                                      u32 valid_conn_vf_pages,
                                      struct phys_mem_desc *ilt_pages,
-                                     bool dump_page_ids)
+                                     bool dump_page_ids,
+                                     u32 buf_size_in_dwords,
+                                     u32 *given_actual_dump_size_in_dwords)
 {
        struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
-       u32 pf_start_line, start_page_id, offset = 0;
+       u32 pf_start_line, start_page_id, offset = *given_offset;
        u32 cdut_pf_init_pages, cdut_vf_init_pages;
        u32 cdut_pf_work_pages, cdut_vf_work_pages;
        u32 base_data_offset, size_param_offset;
+       u32 src_pages;
+       u32 section_header_and_param_size;
        u32 cdut_pf_pages, cdut_vf_pages;
+       u32 actual_dump_size_in_dwords;
+       bool continue_dump = *dump;
+       bool update_size = *dump;
        const char *section_name;
-       u8 i;
+       u32 i;
 
+       actual_dump_size_in_dwords = *given_actual_dump_size_in_dwords;
        section_name = dump_page_ids ? "ilt_page_ids" : "ilt_page_mem";
        cdut_pf_init_pages = qed_get_cdut_num_pf_init_pages(p_hwfn);
        cdut_vf_init_pages = qed_get_cdut_num_vf_init_pages(p_hwfn);
        cdut_pf_pages = cdut_pf_init_pages + cdut_pf_work_pages;
        cdut_vf_pages = cdut_vf_init_pages + cdut_vf_work_pages;
        pf_start_line = p_hwfn->p_cxt_mngr->pf_start_line;
+       section_header_and_param_size = qed_dump_section_hdr(NULL,
+                                                            false,
+                                                            section_name,
+                                                            1) +
+       qed_dump_num_param(NULL, false, "size", 0);
+
+       if ((continue_dump) &&
+           (offset + section_header_and_param_size > buf_size_in_dwords)) {
+               continue_dump = false;
+               update_size = false;
+               actual_dump_size_in_dwords = offset;
+       }
 
-       offset +=
-           qed_dump_section_hdr(dump_buf + offset, dump, section_name, 1);
+       offset += qed_dump_section_hdr(dump_buf + offset,
+                                      continue_dump, section_name, 1);
 
        /* Dump size parameter (0 for now, overwritten with real size later) */
        size_param_offset = offset;
-       offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
+       offset += qed_dump_num_param(dump_buf + offset,
+                                    continue_dump, "size", 0);
        base_data_offset = offset;
 
        /* CDUC pages are ordered as follows:
        if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_DUMP_ILT_CDUC)) {
                /* Dump connection PF pages */
                start_page_id = clients[ILT_CLI_CDUC].first.val - pf_start_line;
-               offset += qed_ilt_dump_pages_range(dump_buf + offset,
-                                                  dump,
-                                                  start_page_id,
-                                                  valid_conn_pf_pages,
-                                                  ilt_pages, dump_page_ids);
+               qed_ilt_dump_pages_range(dump_buf, &offset, &continue_dump,
+                                        start_page_id, valid_conn_pf_pages,
+                                        ilt_pages, dump_page_ids,
+                                        buf_size_in_dwords,
+                                        &actual_dump_size_in_dwords);
 
                /* Dump connection VF pages */
                start_page_id += clients[ILT_CLI_CDUC].pf_total_lines;
                for (i = 0; i < p_hwfn->p_cxt_mngr->vf_count;
                     i++, start_page_id += clients[ILT_CLI_CDUC].vf_total_lines)
-                       offset += qed_ilt_dump_pages_range(dump_buf + offset,
-                                                          dump,
-                                                          start_page_id,
-                                                          valid_conn_vf_pages,
-                                                          ilt_pages,
-                                                          dump_page_ids);
+                       qed_ilt_dump_pages_range(dump_buf, &offset,
+                                                &continue_dump, start_page_id,
+                                                valid_conn_vf_pages,
+                                                ilt_pages, dump_page_ids,
+                                                buf_size_in_dwords,
+                                                &actual_dump_size_in_dwords);
        }
 
        /* CDUT pages are ordered as follows:
                /* Dump task PF pages */
                start_page_id = clients[ILT_CLI_CDUT].first.val +
                    cdut_pf_init_pages - pf_start_line;
-               offset += qed_ilt_dump_pages_range(dump_buf + offset,
-                                                  dump,
-                                                  start_page_id,
-                                                  cdut_pf_work_pages,
-                                                  ilt_pages, dump_page_ids);
+               qed_ilt_dump_pages_range(dump_buf, &offset, &continue_dump,
+                                        start_page_id, cdut_pf_work_pages,
+                                        ilt_pages, dump_page_ids,
+                                        buf_size_in_dwords,
+                                        &actual_dump_size_in_dwords);
 
                /* Dump task VF pages */
                start_page_id = clients[ILT_CLI_CDUT].first.val +
                    cdut_pf_pages + cdut_vf_init_pages - pf_start_line;
                for (i = 0; i < p_hwfn->p_cxt_mngr->vf_count;
                     i++, start_page_id += cdut_vf_pages)
-                       offset += qed_ilt_dump_pages_range(dump_buf + offset,
-                                                          dump,
-                                                          start_page_id,
-                                                          cdut_vf_work_pages,
-                                                          ilt_pages,
-                                                          dump_page_ids);
+                       qed_ilt_dump_pages_range(dump_buf, &offset,
+                                                &continue_dump, start_page_id,
+                                                cdut_vf_work_pages, ilt_pages,
+                                                dump_page_ids,
+                                                buf_size_in_dwords,
+                                                &actual_dump_size_in_dwords);
+       }
+
+       /*Dump Searcher pages */
+       if (clients[ILT_CLI_SRC].active) {
+               start_page_id = clients[ILT_CLI_SRC].first.val - pf_start_line;
+               src_pages = clients[ILT_CLI_SRC].last.val -
+                   clients[ILT_CLI_SRC].first.val + 1;
+               qed_ilt_dump_pages_range(dump_buf, &offset, &continue_dump,
+                                        start_page_id, src_pages, ilt_pages,
+                                        dump_page_ids, buf_size_in_dwords,
+                                        &actual_dump_size_in_dwords);
        }
 
        /* Overwrite size param */
-       if (dump)
-               qed_dump_num_param(dump_buf + size_param_offset,
-                                  dump, "size", offset - base_data_offset);
+       if (update_size) {
+               u32 section_size = (*dump == continue_dump) ?
+                   offset - base_data_offset :
+                   actual_dump_size_in_dwords - base_data_offset;
+               if (section_size > 0)
+                       qed_dump_num_param(dump_buf + size_param_offset,
+                                          *dump, "size", section_size);
+               else if ((section_size == 0) && (*dump != continue_dump))
+                       actual_dump_size_in_dwords -=
+                           section_header_and_param_size;
+       }
+
+       *dump = continue_dump;
+       *given_offset = offset;
+       *given_actual_dump_size_in_dwords = actual_dump_size_in_dwords;
 
        return offset;
 }
 
-/* Performs ILT Dump to the specified buffer.
+/* Dumps a section containing the global parameters.
+ * Part of ilt dump process
  * Returns the dumped size in dwords.
  */
-static u32 qed_ilt_dump(struct qed_hwfn *p_hwfn,
-                       struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
+static u32
+qed_ilt_dump_dump_common_global_params(struct qed_hwfn *p_hwfn,
+                                      struct qed_ptt *p_ptt,
+                                      u32 *dump_buf,
+                                      bool dump,
+                                      u32 cduc_page_size,
+                                      u32 conn_ctx_size,
+                                      u32 cdut_page_size,
+                                      u32 *full_dump_size_param_offset,
+                                      u32 *actual_dump_size_param_offset)
 {
        struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
-       u32 valid_conn_vf_cids, valid_conn_vf_pages, offset = 0;
-       u32 valid_conn_pf_cids, valid_conn_pf_pages, num_pages;
-       u32 num_cids_per_page, conn_ctx_size;
-       u32 cduc_page_size, cdut_page_size;
-       struct phys_mem_desc *ilt_pages;
-       u8 conn_type;
-
-       cduc_page_size = 1 <<
-           (clients[ILT_CLI_CDUC].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN);
-       cdut_page_size = 1 <<
-           (clients[ILT_CLI_CDUT].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN);
-       conn_ctx_size = p_hwfn->p_cxt_mngr->conn_ctx_size;
-       num_cids_per_page = (int)(cduc_page_size / conn_ctx_size);
-       ilt_pages = p_hwfn->p_cxt_mngr->ilt_shadow;
+       u32 offset = 0;
 
-       /* Dump global params - 22 must match number of params below */
        offset += qed_dump_common_global_params(p_hwfn, p_ptt,
-                                               dump_buf + offset, dump, 22);
+                                               dump_buf + offset,
+                                               dump, 30);
        offset += qed_dump_str_param(dump_buf + offset,
-                                    dump, "dump-type", "ilt-dump");
+                                    dump,
+                                    "dump-type", "ilt-dump");
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump,
-                                    "cduc-page-size", cduc_page_size);
+                                    "cduc-page-size",
+                                    cduc_page_size);
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump,
                                     "cduc-first-page-id",
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump,
                                     "cduc-num-pf-pages",
-                                    clients
-                                    [ILT_CLI_CDUC].pf_total_lines);
+                                    clients[ILT_CLI_CDUC].pf_total_lines);
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump,
                                     "cduc-num-vf-pages",
-                                    clients
-                                    [ILT_CLI_CDUC].vf_total_lines);
+                                    clients[ILT_CLI_CDUC].vf_total_lines);
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump,
                                     "max-conn-ctx-size",
                                     conn_ctx_size);
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump,
-                                    "cdut-page-size", cdut_page_size);
+                                    "cdut-page-size",
+                                    cdut_page_size);
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump,
                                     "cdut-first-page-id",
                                     dump,
                                     "max-task-ctx-size",
                                     p_hwfn->p_cxt_mngr->task_ctx_size);
-       offset += qed_dump_num_param(dump_buf + offset,
-                                    dump,
-                                    "task-type-id",
-                                    p_hwfn->p_cxt_mngr->task_type_id);
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump,
                                     "first-vf-id-in-pf",
                                     p_hwfn->p_cxt_mngr->first_vf_in_pf);
-       offset += /* 18 */ qed_dump_num_param(dump_buf + offset,
-                                             dump,
-                                             "num-vfs-in-pf",
-                                             p_hwfn->p_cxt_mngr->vf_count);
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump,
-                                    "ptr-size-bytes", sizeof(void *));
+                                    "num-vfs-in-pf",
+                                    p_hwfn->p_cxt_mngr->vf_count);
+       offset += qed_dump_num_param(dump_buf + offset,
+                                    dump,
+                                    "ptr-size-bytes",
+                                    sizeof(void *));
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump,
                                     "pf-start-line",
                                     dump,
                                     "ilt-shadow-size",
                                     p_hwfn->p_cxt_mngr->ilt_shadow_size);
+
+       *full_dump_size_param_offset = offset;
+
+       offset += qed_dump_num_param(dump_buf + offset,
+                                    dump, "dump-size-full", 0);
+
+       *actual_dump_size_param_offset = offset;
+
+       offset += qed_dump_num_param(dump_buf + offset,
+                                    dump,
+                                    "dump-size-actual", 0);
+       offset += qed_dump_num_param(dump_buf + offset,
+                                    dump,
+                                    "iscsi_task_pages",
+                                    p_hwfn->p_cxt_mngr->iscsi_task_pages);
+       offset += qed_dump_num_param(dump_buf + offset,
+                                    dump,
+                                    "fcoe_task_pages",
+                                    p_hwfn->p_cxt_mngr->fcoe_task_pages);
+       offset += qed_dump_num_param(dump_buf + offset,
+                                    dump,
+                                    "roce_task_pages",
+                                    p_hwfn->p_cxt_mngr->roce_task_pages);
+       offset += qed_dump_num_param(dump_buf + offset,
+                                    dump,
+                                    "eth_task_pages",
+                                    p_hwfn->p_cxt_mngr->eth_task_pages);
+       offset += qed_dump_num_param(dump_buf + offset,
+                                     dump,
+                                     "src-first-page-id",
+                                     clients[ILT_CLI_SRC].first.val);
+       offset += qed_dump_num_param(dump_buf + offset,
+                                    dump,
+                                    "src-last-page-id",
+                                    clients[ILT_CLI_SRC].last.val);
+       offset += qed_dump_num_param(dump_buf + offset,
+                                    dump,
+                                    "src-is-active",
+                                    clients[ILT_CLI_SRC].active);
+
        /* Additional/Less parameters require matching of number in call to
         * dump_common_global_params()
         */
 
-       /* Dump section containing number of PF CIDs per connection type */
+       return offset;
+}
+
+/* Dump section containing number of PF CIDs per connection type.
+ * Part of ilt dump process.
+ * Returns the dumped size in dwords.
+ */
+static u32 qed_ilt_dump_dump_num_pf_cids(struct qed_hwfn *p_hwfn,
+                                        u32 *dump_buf,
+                                        bool dump, u32 *valid_conn_pf_cids)
+{
+       u32 num_pf_cids = 0;
+       u32 offset = 0;
+       u8 conn_type;
+
        offset += qed_dump_section_hdr(dump_buf + offset,
                                       dump, "num_pf_cids_per_conn_type", 1);
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump, "size", NUM_OF_CONNECTION_TYPES);
-       for (conn_type = 0, valid_conn_pf_cids = 0;
+       for (conn_type = 0, *valid_conn_pf_cids = 0;
             conn_type < NUM_OF_CONNECTION_TYPES; conn_type++, offset++) {
-               u32 num_pf_cids =
-                   p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cid_count;
-
+               num_pf_cids = p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cid_count;
                if (dump)
                        *(dump_buf + offset) = num_pf_cids;
-               valid_conn_pf_cids += num_pf_cids;
+               *valid_conn_pf_cids += num_pf_cids;
        }
 
-       /* Dump section containing number of VF CIDs per connection type */
-       offset += qed_dump_section_hdr(dump_buf + offset,
-                                      dump, "num_vf_cids_per_conn_type", 1);
+       return offset;
+}
+
+/* Dump section containing number of VF CIDs per connection type
+ * Part of ilt dump process.
+ * Returns the dumped size in dwords.
+ */
+static u32 qed_ilt_dump_dump_num_vf_cids(struct qed_hwfn *p_hwfn,
+                                        u32 *dump_buf,
+                                        bool dump, u32 *valid_conn_vf_cids)
+{
+       u32 num_vf_cids = 0;
+       u32 offset = 0;
+       u8 conn_type;
+
+       offset += qed_dump_section_hdr(dump_buf + offset, dump,
+                                      "num_vf_cids_per_conn_type", 1);
        offset += qed_dump_num_param(dump_buf + offset,
                                     dump, "size", NUM_OF_CONNECTION_TYPES);
-       for (conn_type = 0, valid_conn_vf_cids = 0;
+       for (conn_type = 0, *valid_conn_vf_cids = 0;
             conn_type < NUM_OF_CONNECTION_TYPES; conn_type++, offset++) {
-               u32 num_vf_cids =
+               num_vf_cids =
                    p_hwfn->p_cxt_mngr->conn_cfg[conn_type].cids_per_vf;
-
                if (dump)
                        *(dump_buf + offset) = num_vf_cids;
-               valid_conn_vf_cids += num_vf_cids;
+               *valid_conn_vf_cids += num_vf_cids;
+       }
+
+       return offset;
+}
+
+/* Performs ILT Dump to the specified buffer.
+ * buf_size_in_dwords - The dumped buffer size.
+ * Returns the dumped size in dwords.
+ */
+static u32 qed_ilt_dump(struct qed_hwfn *p_hwfn,
+                       struct qed_ptt *p_ptt,
+                       u32 *dump_buf, u32 buf_size_in_dwords, bool dump)
+{
+#if ((!defined VMWARE) && (!defined UEFI))
+       struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
+#endif
+       u32 valid_conn_vf_cids = 0,
+           valid_conn_vf_pages, offset = 0, real_dumped_size = 0;
+       u32 valid_conn_pf_cids = 0, valid_conn_pf_pages, num_pages;
+       u32 num_cids_per_page, conn_ctx_size;
+       u32 cduc_page_size, cdut_page_size;
+       u32 actual_dump_size_in_dwords = 0;
+       struct phys_mem_desc *ilt_pages;
+       u32 actul_dump_off = 0;
+       u32 last_section_size;
+       u32 full_dump_off = 0;
+       u32 section_size = 0;
+       bool continue_dump;
+       u32 page_id;
+
+       last_section_size = qed_dump_last_section(NULL, 0, false);
+       cduc_page_size = 1 <<
+           (clients[ILT_CLI_CDUC].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN);
+       cdut_page_size = 1 <<
+           (clients[ILT_CLI_CDUT].p_size.val + PXP_ILT_PAGE_SIZE_NUM_BITS_MIN);
+       conn_ctx_size = p_hwfn->p_cxt_mngr->conn_ctx_size;
+       num_cids_per_page = (int)(cduc_page_size / conn_ctx_size);
+       ilt_pages = p_hwfn->p_cxt_mngr->ilt_shadow;
+       continue_dump = dump;
+
+       /* if need to dump then save memory for the last section
+        * (last section calculates CRC of dumped data)
+        */
+       if (dump) {
+               if (buf_size_in_dwords >= last_section_size) {
+                       buf_size_in_dwords -= last_section_size;
+               } else {
+                       continue_dump = false;
+                       actual_dump_size_in_dwords = offset;
+               }
        }
 
-       /* Dump section containing physical memory descs for each ILT page */
+       /* Dump global params */
+
+       /* if need to dump then first check that there is enough memory
+        * in dumped buffer for this section calculate the size of this
+        * section without dumping. if there is not enough memory - then
+        * stop the dumping.
+        */
+       if (continue_dump) {
+               section_size =
+                       qed_ilt_dump_dump_common_global_params(p_hwfn,
+                                                              p_ptt,
+                                                              NULL,
+                                                              false,
+                                                              cduc_page_size,
+                                                              conn_ctx_size,
+                                                              cdut_page_size,
+                                                              &full_dump_off,
+                                                              &actul_dump_off);
+               if (offset + section_size > buf_size_in_dwords) {
+                       continue_dump = false;
+                       actual_dump_size_in_dwords = offset;
+               }
+       }
+
+       offset += qed_ilt_dump_dump_common_global_params(p_hwfn,
+                                                        p_ptt,
+                                                        dump_buf + offset,
+                                                        continue_dump,
+                                                        cduc_page_size,
+                                                        conn_ctx_size,
+                                                        cdut_page_size,
+                                                        &full_dump_off,
+                                                        &actul_dump_off);
+
+       /* Dump section containing number of PF CIDs per connection type
+        * If need to dump then first check that there is enough memory in
+        * dumped buffer for this section.
+        */
+       if (continue_dump) {
+               section_size =
+                       qed_ilt_dump_dump_num_pf_cids(p_hwfn,
+                                                     NULL,
+                                                     false,
+                                                     &valid_conn_pf_cids);
+               if (offset + section_size > buf_size_in_dwords) {
+                       continue_dump = false;
+                       actual_dump_size_in_dwords = offset;
+               }
+       }
+
+       offset += qed_ilt_dump_dump_num_pf_cids(p_hwfn,
+                                               dump_buf + offset,
+                                               continue_dump,
+                                               &valid_conn_pf_cids);
+
+       /* Dump section containing number of VF CIDs per connection type
+        * If need to dump then first check that there is enough memory in
+        * dumped buffer for this section.
+        */
+       if (continue_dump) {
+               section_size =
+                       qed_ilt_dump_dump_num_vf_cids(p_hwfn,
+                                                     NULL,
+                                                     false,
+                                                     &valid_conn_vf_cids);
+               if (offset + section_size > buf_size_in_dwords) {
+                       continue_dump = false;
+                       actual_dump_size_in_dwords = offset;
+               }
+       }
+
+       offset += qed_ilt_dump_dump_num_vf_cids(p_hwfn,
+                                               dump_buf + offset,
+                                               continue_dump,
+                                               &valid_conn_vf_cids);
+
+       /* Dump section containing physical memory descriptors for each
+        * ILT page.
+        */
        num_pages = p_hwfn->p_cxt_mngr->ilt_shadow_size;
+
+       /* If need to dump then first check that there is enough memory
+        * in dumped buffer for the section header.
+        */
+       if (continue_dump) {
+               section_size = qed_dump_section_hdr(NULL,
+                                                   false,
+                                                   "ilt_page_desc",
+                                                   1) +
+                   qed_dump_num_param(NULL,
+                                      false,
+                                      "size",
+                                      num_pages * PAGE_MEM_DESC_SIZE_DWORDS);
+               if (offset + section_size > buf_size_in_dwords) {
+                       continue_dump = false;
+                       actual_dump_size_in_dwords = offset;
+               }
+       }
+
        offset += qed_dump_section_hdr(dump_buf + offset,
-                                      dump, "ilt_page_desc", 1);
+                                      continue_dump, "ilt_page_desc", 1);
        offset += qed_dump_num_param(dump_buf + offset,
-                                    dump,
+                                    continue_dump,
                                     "size",
                                     num_pages * PAGE_MEM_DESC_SIZE_DWORDS);
 
-       /* Copy memory descriptors to dump buffer */
-       if (dump) {
-               u32 page_id;
-
+       /* Copy memory descriptors to dump buffer
+        * If need to dump then dump till the dump buffer size
+        */
+       if (continue_dump) {
                for (page_id = 0; page_id < num_pages;
-                    page_id++, offset += PAGE_MEM_DESC_SIZE_DWORDS)
-                       memcpy(dump_buf + offset,
-                              &ilt_pages[page_id],
-                              DWORDS_TO_BYTES(PAGE_MEM_DESC_SIZE_DWORDS));
+                    page_id++, offset += PAGE_MEM_DESC_SIZE_DWORDS) {
+                       if (continue_dump &&
+                           (offset + PAGE_MEM_DESC_SIZE_DWORDS <=
+                            buf_size_in_dwords)) {
+                               memcpy(dump_buf + offset,
+                                      &ilt_pages[page_id],
+                                      DWORDS_TO_BYTES
+                                      (PAGE_MEM_DESC_SIZE_DWORDS));
+                       } else {
+                               if (continue_dump) {
+                                       continue_dump = false;
+                                       actual_dump_size_in_dwords = offset;
+                               }
+                       }
+               }
        } else {
                offset += num_pages * PAGE_MEM_DESC_SIZE_DWORDS;
        }
                                           num_cids_per_page);
 
        /* Dump ILT pages IDs */
-       offset += qed_ilt_dump_pages_section(p_hwfn,
-                                            dump_buf + offset,
-                                            dump,
-                                            valid_conn_pf_pages,
-                                            valid_conn_vf_pages,
-                                            ilt_pages, true);
+       qed_ilt_dump_pages_section(p_hwfn, dump_buf, &offset, &continue_dump,
+                                  valid_conn_pf_pages, valid_conn_vf_pages,
+                                  ilt_pages, true, buf_size_in_dwords,
+                                  &actual_dump_size_in_dwords);
 
        /* Dump ILT pages memory */
-       offset += qed_ilt_dump_pages_section(p_hwfn,
-                                            dump_buf + offset,
-                                            dump,
-                                            valid_conn_pf_pages,
-                                            valid_conn_vf_pages,
-                                            ilt_pages, false);
+       qed_ilt_dump_pages_section(p_hwfn, dump_buf, &offset, &continue_dump,
+                                  valid_conn_pf_pages, valid_conn_vf_pages,
+                                  ilt_pages, false, buf_size_in_dwords,
+                                  &actual_dump_size_in_dwords);
+
+       real_dumped_size =
+           (continue_dump == dump) ? offset : actual_dump_size_in_dwords;
+       qed_dump_num_param(dump_buf + full_dump_off, dump,
+                          "full-dump-size", offset + last_section_size);
+       qed_dump_num_param(dump_buf + actul_dump_off,
+                          dump,
+                          "actual-dump-size",
+                          real_dumped_size + last_section_size);
 
        /* Dump last section */
-       offset += qed_dump_last_section(dump_buf, offset, dump);
+       real_dumped_size += qed_dump_last_section(dump_buf,
+                                                 real_dumped_size, dump);
 
-       return offset;
+       return real_dumped_size;
 }
 
 /***************************** Public Functions *******************************/
        return DBG_STATUS_OK;
 }
 
+static enum dbg_status qed_dbg_set_app_ver(u32 ver)
+{
+       if (ver < TOOLS_VERSION)
+               return DBG_STATUS_UNSUPPORTED_APP_VERSION;
+
+       s_app_ver = ver;
+
+       return DBG_STATUS_OK;
+}
+
 bool qed_read_fw_info(struct qed_hwfn *p_hwfn,
                      struct qed_ptt *p_ptt, struct fw_info *fw_info)
 {
         */
        qed_dbg_grc_init_params(p_hwfn);
 
-       if (grc_param >= MAX_DBG_GRC_PARAMS)
+       if (grc_param >= MAX_DBG_GRC_PARAMS || grc_param < 0)
                return DBG_STATUS_INVALID_ARGS;
        if (val < s_grc_param_defs[grc_param].min ||
            val > s_grc_param_defs[grc_param].max)
        if (buf_size_in_dwords < needed_buf_size_in_dwords)
                return DBG_STATUS_DUMP_BUF_TOO_SMALL;
 
+       /* Doesn't do anything, needed for compile time asserts */
+       qed_static_asserts();
+
        /* GRC Dump */
        status = qed_grc_dump(p_hwfn, p_ptt, dump_buf, true, num_dumped_dwords);
 
        if (status != DBG_STATUS_OK)
                return status;
 
-       *buf_size = qed_ilt_dump(p_hwfn, p_ptt, NULL, false);
+       *buf_size = qed_ilt_dump(p_hwfn, p_ptt, NULL, 0, false);
 
        return DBG_STATUS_OK;
 }
                                        u32 buf_size_in_dwords,
                                        u32 *num_dumped_dwords)
 {
-       u32 needed_buf_size_in_dwords;
-       enum dbg_status status;
-
-       *num_dumped_dwords = 0;
-
-       status = qed_dbg_ilt_get_dump_buf_size(p_hwfn,
-                                              p_ptt,
-                                              &needed_buf_size_in_dwords);
-       if (status != DBG_STATUS_OK)
-               return status;
-
-       if (buf_size_in_dwords < needed_buf_size_in_dwords)
-               return DBG_STATUS_DUMP_BUF_TOO_SMALL;
-
-       *num_dumped_dwords = qed_ilt_dump(p_hwfn, p_ptt, dump_buf, true);
+       *num_dumped_dwords = qed_ilt_dump(p_hwfn,
+                                         p_ptt,
+                                         dump_buf, buf_size_in_dwords, true);
 
        /* Reveret GRC params to their default */
        qed_dbg_grc_set_params_default(p_hwfn);
        "The configured filter mode requires that all the constraints of a single trigger state will be defined on a single Storm/block input",
 
        /* DBG_STATUS_MISSING_TRIGGER_STATE_STORM */
-       "When triggering on Storm data, the Storm to trigger on must be specified"
+       "When triggering on Storm data, the Storm to trigger on must be specified",
+
+       /* DBG_STATUS_MDUMP2_FAILED_TO_REQUEST_OFFSIZE */
+       "Failed to request MDUMP2 Offsize",
+
+       /* DBG_STATUS_MDUMP2_FAILED_VALIDATION_OF_DATA_CRC */
+       "Expected CRC (part of the MDUMP2 data) is different than the calculated CRC over that data",
+
+       /* DBG_STATUS_MDUMP2_INVALID_SIGNATURE */
+       "Invalid Signature found at start of MDUMP2",
+
+       /* DBG_STATUS_MDUMP2_INVALID_LOG_SIZE */
+       "Invalid Log Size of MDUMP2",
+
+       /* DBG_STATUS_MDUMP2_INVALID_LOG_HDR */
+       "Invalid Log Header of MDUMP2",
+
+       /* DBG_STATUS_MDUMP2_INVALID_LOG_DATA */
+       "Invalid Log Data of MDUMP2",
+
+       /* DBG_STATUS_MDUMP2_ERROR_EXTRACTING_NUM_PORTS */
+       "Could not extract number of ports from regval buf of MDUMP2",
+
+       /* DBG_STATUS_MDUMP2_ERROR_EXTRACTING_MFW_STATUS */
+       "Could not extract MFW (link) status from regval buf of MDUMP2",
+
+       /* DBG_STATUS_MDUMP2_ERROR_DISPLAYING_LINKDUMP */
+       "Could not display linkdump of MDUMP2",
+
+       /* DBG_STATUS_MDUMP2_ERROR_READING_PHY_CFG */
+       "Could not read PHY CFG of MDUMP2",
+
+       /* DBG_STATUS_MDUMP2_ERROR_READING_PLL_MODE */
+       "Could not read PLL Mode of MDUMP2",
+
+       /* DBG_STATUS_MDUMP2_ERROR_READING_LANE_REGS */
+       "Could not read TSCF/TSCE Lane Regs of MDUMP2",
+
+       /* DBG_STATUS_MDUMP2_ERROR_ALLOCATING_BUF */
+       "Could not allocate MDUMP2 reg-val internal buffer"
 };
 
 /* Idle check severity names array */
 
 /**************************** Private Functions ******************************/
 
+static void qed_user_static_asserts(void)
+{
+}
+
 static u32 qed_cyclic_add(u32 a, u32 b, u32 size)
 {
        return (a + b) % size;
                        /* Skip register names until the required reg_id is
                         * reached.
                         */
-                       for (; reg_id > curr_reg_id;
-                            curr_reg_id++,
-                            parsing_str += strlen(parsing_str) + 1);
+                       for (; reg_id > curr_reg_id; curr_reg_id++)
+                               parsing_str += strlen(parsing_str) + 1;
 
                        results_offset +=
                            sprintf(qed_get_buf_ptr(results_buf,
                                               u32 *num_errors,
                                               u32 *num_warnings)
 {
+       u32 num_section_params = 0, num_rules, num_rules_not_dumped;
        const char *section_name, *param_name, *param_str_val;
        u32 *dump_buf_end = dump_buf + num_dumped_dwords;
-       u32 num_section_params = 0, num_rules;
 
        /* Offset in results_buf in bytes */
        u32 results_offset = 0;
                                             num_section_params,
                                             results_buf, &results_offset);
 
-       /* Read idle_chk section */
+       /* Read idle_chk section
+        * There may be 1 or 2 idle_chk section parameters:
+        * - 1st is "num_rules"
+        * - 2nd is "num_rules_not_dumped" (optional)
+        */
+
        dump_buf += qed_read_section_hdr(dump_buf,
                                         §ion_name, &num_section_params);
-       if (strcmp(section_name, "idle_chk") || num_section_params != 1)
+       if (strcmp(section_name, "idle_chk") ||
+           (num_section_params != 2 && num_section_params != 1))
                return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
        dump_buf += qed_read_param(dump_buf,
                                   ¶m_name, ¶m_str_val, &num_rules);
        if (strcmp(param_name, "num_rules"))
                return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
+       if (num_section_params > 1) {
+               dump_buf += qed_read_param(dump_buf,
+                                          ¶m_name,
+                                          ¶m_str_val,
+                                          &num_rules_not_dumped);
+               if (strcmp(param_name, "num_rules_not_dumped"))
+                       return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
+       } else {
+               num_rules_not_dumped = 0;
+       }
 
        if (num_rules) {
                u32 rules_print_size;
                                            results_offset),
                            "\nIdle Check completed successfully\n");
 
+       if (num_rules_not_dumped)
+               results_offset +=
+                   sprintf(qed_get_buf_ptr(results_buf,
+                                           results_offset),
+                           "\nIdle Check Partially dumped : num_rules_not_dumped = %d\n",
+                           num_rules_not_dumped);
+
        /* Add 1 for string NULL termination */
        *parsed_results_bytes = results_offset + 1;
 
 {
        u32 parsed_buf_size;
 
+       /* Doesn't do anything, needed for compile time asserts */
+       qed_user_static_asserts();
+
        return qed_parse_mcp_trace_dump(p_hwfn,
                                        dump_buf,
                                        results_buf, &parsed_buf_size, true);
                    reg_result->block_attn_offset;
 
                /* Go over attention status bits */
-               for (j = 0; j < num_reg_attn; j++, bit_idx++) {
+               for (j = 0; j < num_reg_attn; j++) {
                        u16 attn_idx_val = GET_FIELD(bit_mapping[j].data,
                                                     DBG_ATTN_BIT_MAPPING_VAL);
                        const char *attn_name, *attn_type_str, *masked_str;
                        }
 
                        /* Check current bit index */
-                       if (!(reg_result->sts_val & BIT(bit_idx)))
-                               continue;
+                       if (reg_result->sts_val & BIT(bit_idx)) {
+                               /* An attention bit with value=1 was found
+                                * Find attention name
+                                */
+                               attn_name_offset =
+                                       block_attn_name_offsets[attn_idx_val];
+                               attn_name = attn_name_base + attn_name_offset;
+                               attn_type_str =
+                                       (attn_type ==
+                                        ATTN_TYPE_INTERRUPT ? "Interrupt" :
+                                        "Parity");
+                               masked_str = reg_result->mask_val &
+                                            BIT(bit_idx) ?
+                                            " [masked]" : "";
+                               sts_addr =
+                               GET_FIELD(reg_result->data,
+                                         DBG_ATTN_REG_RESULT_STS_ADDRESS);
+                               DP_NOTICE(p_hwfn,
+                                         "%s (%s) : %s [address 0x%08x, bit %d]%s\n",
+                                         block_name, attn_type_str, attn_name,
+                                         sts_addr * 4, bit_idx, masked_str);
+                       }
 
-                       /* An attention bit with value=1 was found
-                        * Find attention name
-                        */
-                       attn_name_offset =
-                               block_attn_name_offsets[attn_idx_val];
-                       attn_name = attn_name_base + attn_name_offset;
-                       attn_type_str =
-                               (attn_type ==
-                                ATTN_TYPE_INTERRUPT ? "Interrupt" :
-                                "Parity");
-                       masked_str = reg_result->mask_val & BIT(bit_idx) ?
-                                    " [masked]" : "";
-                       sts_addr = GET_FIELD(reg_result->data,
-                                            DBG_ATTN_REG_RESULT_STS_ADDRESS);
-                       DP_NOTICE(p_hwfn,
-                                 "%s (%s) : %s [address 0x%08x, bit %d]%s\n",
-                                 block_name, attn_type_str, attn_name,
-                                 sts_addr * 4, bit_idx, masked_str);
+                       bit_idx++;
                }
        }
 
        return DBG_STATUS_OK;
 }
 
-static DEFINE_MUTEX(qed_dbg_lock);
-
 /* Wrapper for unifying the idle_chk and mcp_trace api */
 static enum dbg_status
 qed_print_idle_chk_results_wrapper(struct qed_hwfn *p_hwfn,
                                          &num_warnnings);
 }
 
+static DEFINE_MUTEX(qed_dbg_lock);
+
+#define MAX_PHY_RESULT_BUFFER 9000
+
+/******************************** Feature Meta data section ******************/
+
+#define GRC_NUM_STR_FUNCS 2
+#define IDLE_CHK_NUM_STR_FUNCS 1
+#define MCP_TRACE_NUM_STR_FUNCS 1
+#define REG_FIFO_NUM_STR_FUNCS 1
+#define IGU_FIFO_NUM_STR_FUNCS 1
+#define PROTECTION_OVERRIDE_NUM_STR_FUNCS 1
+#define FW_ASSERTS_NUM_STR_FUNCS 1
+#define ILT_NUM_STR_FUNCS 1
+#define PHY_NUM_STR_FUNCS 20
+
 /* Feature meta data lookup table */
 static struct {
        char *name;
+       u32 num_funcs;
        enum dbg_status (*get_size)(struct qed_hwfn *p_hwfn,
                                    struct qed_ptt *p_ptt, u32 *size);
        enum dbg_status (*perform_dump)(struct qed_hwfn *p_hwfn,
                                            u32 *dump_buf,
                                            u32 num_dumped_dwords,
                                            u32 *results_buf_size);
+       const struct qed_func_lookup *hsi_func_lookup;
 } qed_features_lookup[] = {
        {
-       "grc", qed_dbg_grc_get_dump_buf_size,
-                   qed_dbg_grc_dump, NULL, NULL}, {
-       "idle_chk",
+       "grc", GRC_NUM_STR_FUNCS, qed_dbg_grc_get_dump_buf_size,
+                   qed_dbg_grc_dump, NULL, NULL, NULL}, {
+       "idle_chk", IDLE_CHK_NUM_STR_FUNCS,
                    qed_dbg_idle_chk_get_dump_buf_size,
                    qed_dbg_idle_chk_dump,
                    qed_print_idle_chk_results_wrapper,
-                   qed_get_idle_chk_results_buf_size}, {
-       "mcp_trace",
+                   qed_get_idle_chk_results_buf_size,
+                   NULL}, {
+       "mcp_trace", MCP_TRACE_NUM_STR_FUNCS,
                    qed_dbg_mcp_trace_get_dump_buf_size,
                    qed_dbg_mcp_trace_dump, qed_print_mcp_trace_results,
-                   qed_get_mcp_trace_results_buf_size}, {
-       "reg_fifo",
+                   qed_get_mcp_trace_results_buf_size,
+                   NULL}, {
+       "reg_fifo", REG_FIFO_NUM_STR_FUNCS,
                    qed_dbg_reg_fifo_get_dump_buf_size,
                    qed_dbg_reg_fifo_dump, qed_print_reg_fifo_results,
-                   qed_get_reg_fifo_results_buf_size}, {
-       "igu_fifo",
+                   qed_get_reg_fifo_results_buf_size,
+                   NULL}, {
+       "igu_fifo", IGU_FIFO_NUM_STR_FUNCS,
                    qed_dbg_igu_fifo_get_dump_buf_size,
                    qed_dbg_igu_fifo_dump, qed_print_igu_fifo_results,
-                   qed_get_igu_fifo_results_buf_size}, {
-       "protection_override",
+                   qed_get_igu_fifo_results_buf_size,
+                   NULL}, {
+       "protection_override", PROTECTION_OVERRIDE_NUM_STR_FUNCS,
                    qed_dbg_protection_override_get_dump_buf_size,
                    qed_dbg_protection_override_dump,
                    qed_print_protection_override_results,
-                   qed_get_protection_override_results_buf_size}, {
-       "fw_asserts",
+                   qed_get_protection_override_results_buf_size,
+                   NULL}, {
+       "fw_asserts", FW_ASSERTS_NUM_STR_FUNCS,
                    qed_dbg_fw_asserts_get_dump_buf_size,
                    qed_dbg_fw_asserts_dump,
                    qed_print_fw_asserts_results,
-                   qed_get_fw_asserts_results_buf_size}, {
-       "ilt",
-                   qed_dbg_ilt_get_dump_buf_size,
-                   qed_dbg_ilt_dump, NULL, NULL},};
+                   qed_get_fw_asserts_results_buf_size,
+                   NULL}, {
+       "ilt", ILT_NUM_STR_FUNCS, qed_dbg_ilt_get_dump_buf_size,
+                   qed_dbg_ilt_dump, NULL, NULL, NULL},};
 
 static void qed_dbg_print_feature(u8 *p_text_buf, u32 text_size)
 {
 {
        struct qed_dbg_feature *feature =
            &p_hwfn->cdev->dbg_features[feature_idx];
-       u32 text_size_bytes, null_char_pos, i;
+       u32 txt_size_bytes, null_char_pos, i;
+       u32 *dbuf, dwords;
        enum dbg_status rc;
        char *text_buf;
 
        if (!qed_features_lookup[feature_idx].results_buf_size)
                return DBG_STATUS_OK;
 
+       dbuf = (u32 *)feature->dump_buf;
+       dwords = feature->dumped_dwords;
+
        /* Obtain size of formatted output */
-       rc = qed_features_lookup[feature_idx].
-               results_buf_size(p_hwfn, (u32 *)feature->dump_buf,
-                                feature->dumped_dwords, &text_size_bytes);
+       rc = qed_features_lookup[feature_idx].results_buf_size(p_hwfn,
+                                                              dbuf,
+                                                              dwords,
+                                                              &txt_size_bytes);
        if (rc != DBG_STATUS_OK)
                return rc;
 
-       /* Make sure that the allocated size is a multiple of dword (4 bytes) */
-       null_char_pos = text_size_bytes - 1;
-       text_size_bytes = (text_size_bytes + 3) & ~0x3;
+       /* Make sure that the allocated size is a multiple of dword
+        * (4 bytes).
+        */
+       null_char_pos = txt_size_bytes - 1;
+       txt_size_bytes = (txt_size_bytes + 3) & ~0x3;
 
-       if (text_size_bytes < QED_RESULTS_BUF_MIN_SIZE) {
+       if (txt_size_bytes < QED_RESULTS_BUF_MIN_SIZE) {
                DP_NOTICE(p_hwfn->cdev,
                          "formatted size of feature was too small %d. Aborting\n",
-                         text_size_bytes);
+                         txt_size_bytes);
                return DBG_STATUS_INVALID_ARGS;
        }
 
-       /* Allocate temp text buf */
-       text_buf = vzalloc(text_size_bytes);
-       if (!text_buf)
+       /* allocate temp text buf */
+       text_buf = vzalloc(txt_size_bytes);
+       if (!text_buf) {
+               DP_NOTICE(p_hwfn->cdev,
+                         "failed to allocate text buffer. Aborting\n");
                return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
+       }
 
        /* Decode feature opcodes to string on temp buf */
-       rc = qed_features_lookup[feature_idx].
-               print_results(p_hwfn, (u32 *)feature->dump_buf,
-                             feature->dumped_dwords, text_buf);
+       rc = qed_features_lookup[feature_idx].print_results(p_hwfn,
+                                                           dbuf,
+                                                           dwords,
+                                                           text_buf);
        if (rc != DBG_STATUS_OK) {
                vfree(text_buf);
                return rc;
         * The bytes that were added as a result of the dword alignment are also
         * padded with '\n' characters.
         */
-       for (i = null_char_pos; i < text_size_bytes; i++)
+       for (i = null_char_pos; i < txt_size_bytes; i++)
                text_buf[i] = '\n';
 
        /* Dump printable feature to log */
        if (p_hwfn->cdev->print_dbg_data)
-               qed_dbg_print_feature(text_buf, text_size_bytes);
+               qed_dbg_print_feature(text_buf, txt_size_bytes);
 
-       /* Just return the original binary buffer if requested */
+       /* Dump binary data as is to the output file */
        if (p_hwfn->cdev->dbg_bin_dump) {
                vfree(text_buf);
-               return DBG_STATUS_OK;
+               return rc;
        }
 
-       /* Free the old dump_buf and point the dump_buf to the newly allocagted
+       /* Free the old dump_buf and point the dump_buf to the newly allocated
         * and formatted text buffer.
         */
        vfree(feature->dump_buf);
        feature->dump_buf = text_buf;
-       feature->buf_size = text_size_bytes;
-       feature->dumped_dwords = text_size_bytes / 4;
+       feature->buf_size = txt_size_bytes;
+       feature->dumped_dwords = txt_size_bytes / 4;
+
        return rc;
 }
 
 {
        struct qed_dbg_feature *feature =
            &p_hwfn->cdev->dbg_features[feature_idx];
-       u32 buf_size_dwords;
+       u32 buf_size_dwords, *dbuf, *dwords;
        enum dbg_status rc;
 
        DP_NOTICE(p_hwfn->cdev, "Collecting a debug feature [\"%s\"]\n",
        if (!feature->dump_buf)
                return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
 
-       rc = qed_features_lookup[feature_idx].
-               perform_dump(p_hwfn, p_ptt, (u32 *)feature->dump_buf,
-                            feature->buf_size / sizeof(u32),
-                            &feature->dumped_dwords);
+       dbuf = (u32 *)feature->dump_buf;
+       dwords = &feature->dumped_dwords;
+       rc = qed_features_lookup[feature_idx].perform_dump(p_hwfn, p_ptt,
+                                                          dbuf,
+                                                          feature->buf_size /
+                                                          sizeof(u32),
+                                                          dwords);
 
        /* If mcp is stuck we get DBG_STATUS_NVRAM_GET_IMAGE_FAILED error.
-        * In this case the buffer holds valid binary data, but we wont able
+        * In this case the buffer holds valid binary data, but we won't able
         * to parse it (since parsing relies on data in NVRAM which is only
         * accessible when MFW is responsive). skip the formatting but return
         * success so that binary data is provided.
 
 static u32 qed_calc_regdump_header(struct qed_dev *cdev,
                                   enum debug_print_features feature,
-                                  int engine, u32 feature_size, u8 omit_engine)
+                                  int engine, u32 feature_size,
+                                  u8 omit_engine, u8 dbg_bin_dump)
 {
        u32 res = 0;
 
                          feature, feature_size);
 
        SET_FIELD(res, REGDUMP_HEADER_FEATURE, feature);
-       SET_FIELD(res, REGDUMP_HEADER_BIN_DUMP, 1);
+       SET_FIELD(res, REGDUMP_HEADER_BIN_DUMP, dbg_bin_dump);
        SET_FIELD(res, REGDUMP_HEADER_OMIT_ENGINE, omit_engine);
        SET_FIELD(res, REGDUMP_HEADER_ENGINE, engine);
 
 int qed_dbg_all_data(struct qed_dev *cdev, void *buffer)
 {
        u8 cur_engine, omit_engine = 0, org_engine;
-       struct qed_hwfn *p_hwfn =
-               &cdev->hwfns[cdev->engine_for_debug];
+       struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug];
        struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
-       int grc_params[MAX_DBG_GRC_PARAMS], i;
+       int grc_params[MAX_DBG_GRC_PARAMS], rc, i;
        u32 offset = 0, feature_size;
-       int rc;
 
        for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
                grc_params[i] = dev_data->grc.param_val[i];
        if (!QED_IS_CMT(cdev))
                omit_engine = 1;
 
+       cdev->dbg_bin_dump = 1;
        mutex_lock(&qed_dbg_lock);
-       cdev->dbg_bin_dump = true;
 
        org_engine = qed_get_debug_engine(cdev);
        for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
                                      REGDUMP_HEADER_SIZE, &feature_size);
                if (!rc) {
                        *(u32 *)((u8 *)buffer + offset) =
-                           qed_calc_regdump_header(cdev, IDLE_CHK, cur_engine,
-                                                   feature_size, omit_engine);
+                           qed_calc_regdump_header(cdev, IDLE_CHK,
+                                                   cur_engine,
+                                                   feature_size,
+                                                   omit_engine,
+                                                   cdev->dbg_bin_dump);
                        offset += (feature_size + REGDUMP_HEADER_SIZE);
                } else {
                        DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
                                      REGDUMP_HEADER_SIZE, &feature_size);
                if (!rc) {
                        *(u32 *)((u8 *)buffer + offset) =
-                           qed_calc_regdump_header(cdev, IDLE_CHK, cur_engine,
-                                                   feature_size, omit_engine);
+                           qed_calc_regdump_header(cdev, IDLE_CHK,
+                                                   cur_engine,
+                                                   feature_size,
+                                                   omit_engine,
+                                                   cdev->dbg_bin_dump);
                        offset += (feature_size + REGDUMP_HEADER_SIZE);
                } else {
                        DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
                                      REGDUMP_HEADER_SIZE, &feature_size);
                if (!rc) {
                        *(u32 *)((u8 *)buffer + offset) =
-                           qed_calc_regdump_header(cdev, REG_FIFO, cur_engine,
-                                                   feature_size, omit_engine);
+                           qed_calc_regdump_header(cdev, REG_FIFO,
+                                                   cur_engine,
+                                                   feature_size,
+                                                   omit_engine,
+                                                   cdev->dbg_bin_dump);
                        offset += (feature_size + REGDUMP_HEADER_SIZE);
                } else {
                        DP_ERR(cdev, "qed_dbg_reg_fifo failed. rc = %d\n", rc);
                                      REGDUMP_HEADER_SIZE, &feature_size);
                if (!rc) {
                        *(u32 *)((u8 *)buffer + offset) =
-                           qed_calc_regdump_header(cdev, IGU_FIFO, cur_engine,
-                                                   feature_size, omit_engine);
+                           qed_calc_regdump_header(cdev, IGU_FIFO,
+                                                   cur_engine,
+                                                   feature_size,
+                                                   omit_engine,
+                                                   cdev->dbg_bin_dump);
                        offset += (feature_size + REGDUMP_HEADER_SIZE);
                } else {
                        DP_ERR(cdev, "qed_dbg_igu_fifo failed. rc = %d", rc);
                                                 &feature_size);
                if (!rc) {
                        *(u32 *)((u8 *)buffer + offset) =
-                           qed_calc_regdump_header(cdev, PROTECTION_OVERRIDE,
+                           qed_calc_regdump_header(cdev,
+                                                   PROTECTION_OVERRIDE,
                                                    cur_engine,
-                                                   feature_size, omit_engine);
+                                                   feature_size,
+                                                   omit_engine,
+                                                   cdev->dbg_bin_dump);
                        offset += (feature_size + REGDUMP_HEADER_SIZE);
                } else {
                        DP_ERR(cdev,
                if (!rc) {
                        *(u32 *)((u8 *)buffer + offset) =
                            qed_calc_regdump_header(cdev, FW_ASSERTS,
-                                                   cur_engine, feature_size,
-                                                   omit_engine);
+                                                   cur_engine,
+                                                   feature_size,
+                                                   omit_engine,
+                                                   cdev->dbg_bin_dump);
                        offset += (feature_size + REGDUMP_HEADER_SIZE);
                } else {
                        DP_ERR(cdev, "qed_dbg_fw_asserts failed. rc = %d\n",
                }
 
                feature_size = qed_dbg_ilt_size(cdev);
-               if (!cdev->disable_ilt_dump &&
-                   feature_size < ILT_DUMP_MAX_SIZE) {
+               if (!cdev->disable_ilt_dump && feature_size <
+                   ILT_DUMP_MAX_SIZE) {
                        rc = qed_dbg_ilt(cdev, (u8 *)buffer + offset +
                                         REGDUMP_HEADER_SIZE, &feature_size);
                        if (!rc) {
                                    qed_calc_regdump_header(cdev, ILT_DUMP,
                                                            cur_engine,
                                                            feature_size,
-                                                           omit_engine);
-                               offset += feature_size + REGDUMP_HEADER_SIZE;
+                                                           omit_engine,
+                                                           cdev->dbg_bin_dump);
+                               offset += (feature_size + REGDUMP_HEADER_SIZE);
                        } else {
                                DP_ERR(cdev, "qed_dbg_ilt failed. rc = %d\n",
                                       rc);
                        }
                }
 
-               /* GRC dump - must be last because when mcp stuck it will
+               /* Grc dump - must be last because when mcp stuck it will
                 * clutter idle_chk, reg_fifo, ...
                 */
                for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
                        *(u32 *)((u8 *)buffer + offset) =
                            qed_calc_regdump_header(cdev, GRC_DUMP,
                                                    cur_engine,
-                                                   feature_size, omit_engine);
+                                                   feature_size,
+                                                   omit_engine,
+                                                   cdev->dbg_bin_dump);
                        offset += (feature_size + REGDUMP_HEADER_SIZE);
                } else {
                        DP_ERR(cdev, "qed_dbg_grc failed. rc = %d", rc);
        if (!rc) {
                *(u32 *)((u8 *)buffer + offset) =
                    qed_calc_regdump_header(cdev, MCP_TRACE, cur_engine,
-                                           feature_size, omit_engine);
+                                           feature_size, omit_engine,
+                                           cdev->dbg_bin_dump);
                offset += (feature_size + REGDUMP_HEADER_SIZE);
        } else {
                DP_ERR(cdev, "qed_dbg_mcp_trace failed. rc = %d\n", rc);
        }
 
-       /* Re-populate nvm attribute info */
-       qed_mcp_nvm_info_free(p_hwfn);
-       qed_mcp_nvm_info_populate(p_hwfn);
-
        /* nvm cfg1 */
        rc = qed_dbg_nvm_image(cdev,
                               (u8 *)buffer + offset +
        if (!rc) {
                *(u32 *)((u8 *)buffer + offset) =
                    qed_calc_regdump_header(cdev, NVM_CFG1, cur_engine,
-                                           feature_size, omit_engine);
+                                           feature_size, omit_engine,
+                                           cdev->dbg_bin_dump);
                offset += (feature_size + REGDUMP_HEADER_SIZE);
        } else if (rc != -ENOENT) {
                DP_ERR(cdev,
                       "qed_dbg_nvm_image failed for image  %d (%s), rc = %d\n",
-                      QED_NVM_IMAGE_NVM_CFG1, "QED_NVM_IMAGE_NVM_CFG1", rc);
+                      QED_NVM_IMAGE_NVM_CFG1, "QED_NVM_IMAGE_NVM_CFG1",
+                      rc);
        }
 
-       /* nvm default */
+               /* nvm default */
        rc = qed_dbg_nvm_image(cdev,
-                              (u8 *)buffer + offset + REGDUMP_HEADER_SIZE,
-                              &feature_size, QED_NVM_IMAGE_DEFAULT_CFG);
+                              (u8 *)buffer + offset +
+                              REGDUMP_HEADER_SIZE, &feature_size,
+                              QED_NVM_IMAGE_DEFAULT_CFG);
        if (!rc) {
                *(u32 *)((u8 *)buffer + offset) =
-                   qed_calc_regdump_header(cdev, DEFAULT_CFG, cur_engine,
-                                           feature_size, omit_engine);
+                   qed_calc_regdump_header(cdev, DEFAULT_CFG,
+                                           cur_engine, feature_size,
+                                           omit_engine,
+                                           cdev->dbg_bin_dump);
                offset += (feature_size + REGDUMP_HEADER_SIZE);
        } else if (rc != -ENOENT) {
                DP_ERR(cdev,
                       "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
-                      QED_NVM_IMAGE_DEFAULT_CFG, "QED_NVM_IMAGE_DEFAULT_CFG",
-                      rc);
+                      QED_NVM_IMAGE_DEFAULT_CFG,
+                      "QED_NVM_IMAGE_DEFAULT_CFG", rc);
        }
 
        /* nvm meta */
        rc = qed_dbg_nvm_image(cdev,
-                              (u8 *)buffer + offset + REGDUMP_HEADER_SIZE,
-                              &feature_size, QED_NVM_IMAGE_NVM_META);
+                              (u8 *)buffer + offset +
+                              REGDUMP_HEADER_SIZE, &feature_size,
+                              QED_NVM_IMAGE_NVM_META);
        if (!rc) {
                *(u32 *)((u8 *)buffer + offset) =
-                       qed_calc_regdump_header(cdev, NVM_META, cur_engine,
-                                               feature_size, omit_engine);
+                   qed_calc_regdump_header(cdev, NVM_META, cur_engine,
+                                           feature_size, omit_engine,
+                                           cdev->dbg_bin_dump);
                offset += (feature_size + REGDUMP_HEADER_SIZE);
        } else if (rc != -ENOENT) {
                DP_ERR(cdev,
                       "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
-                      QED_NVM_IMAGE_NVM_META, "QED_NVM_IMAGE_NVM_META", rc);
+                      QED_NVM_IMAGE_NVM_META, "QED_NVM_IMAGE_NVM_META",
+                      rc);
        }
 
        /* nvm mdump */
                               QED_NVM_IMAGE_MDUMP);
        if (!rc) {
                *(u32 *)((u8 *)buffer + offset) =
-                       qed_calc_regdump_header(cdev, MDUMP, cur_engine,
-                                               feature_size, omit_engine);
+                   qed_calc_regdump_header(cdev, MDUMP, cur_engine,
+                                           feature_size, omit_engine,
+                                           cdev->dbg_bin_dump);
                offset += (feature_size + REGDUMP_HEADER_SIZE);
        } else if (rc != -ENOENT) {
                DP_ERR(cdev,
                       QED_NVM_IMAGE_MDUMP, "QED_NVM_IMAGE_MDUMP", rc);
        }
 
-       cdev->dbg_bin_dump = false;
        mutex_unlock(&qed_dbg_lock);
+       cdev->dbg_bin_dump = 0;
 
        return 0;
 }
 
 int qed_dbg_all_data_size(struct qed_dev *cdev)
 {
-       struct qed_hwfn *p_hwfn =
-               &cdev->hwfns[cdev->engine_for_debug];
        u32 regs_len = 0, image_len = 0, ilt_len = 0, total_ilt_len = 0;
+       struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug];
        u8 cur_engine, org_engine;
 
        cdev->disable_ilt_dump = false;
                           "calculating idle_chk and grcdump register length for current engine\n");
                qed_set_debug_engine(cdev, cur_engine);
                regs_len += REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
-                           REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
-                           REGDUMP_HEADER_SIZE + qed_dbg_grc_size(cdev) +
-                           REGDUMP_HEADER_SIZE + qed_dbg_reg_fifo_size(cdev) +
-                           REGDUMP_HEADER_SIZE + qed_dbg_igu_fifo_size(cdev) +
-                           REGDUMP_HEADER_SIZE +
-                           qed_dbg_protection_override_size(cdev) +
-                           REGDUMP_HEADER_SIZE + qed_dbg_fw_asserts_size(cdev);
-
+                   REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
+                   REGDUMP_HEADER_SIZE + qed_dbg_grc_size(cdev) +
+                   REGDUMP_HEADER_SIZE + qed_dbg_reg_fifo_size(cdev) +
+                   REGDUMP_HEADER_SIZE + qed_dbg_igu_fifo_size(cdev) +
+                   REGDUMP_HEADER_SIZE +
+                   qed_dbg_protection_override_size(cdev) +
+                   REGDUMP_HEADER_SIZE + qed_dbg_fw_asserts_size(cdev);
                ilt_len = REGDUMP_HEADER_SIZE + qed_dbg_ilt_size(cdev);
                if (ilt_len < ILT_DUMP_MAX_SIZE) {
                        total_ilt_len += ilt_len;
        qed_set_debug_engine(cdev, org_engine);
 
        /* Engine common */
-       regs_len += REGDUMP_HEADER_SIZE + qed_dbg_mcp_trace_size(cdev);
+       regs_len += REGDUMP_HEADER_SIZE + qed_dbg_mcp_trace_size(cdev) +
+           REGDUMP_HEADER_SIZE + qed_dbg_phy_size(cdev);
        qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_CFG1, &image_len);
        if (image_len)
                regs_len += REGDUMP_HEADER_SIZE + image_len;
 int qed_dbg_feature(struct qed_dev *cdev, void *buffer,
                    enum qed_dbg_features feature, u32 *num_dumped_bytes)
 {
-       struct qed_hwfn *p_hwfn =
-               &cdev->hwfns[cdev->engine_for_debug];
-       struct qed_dbg_feature *qed_feature =
-               &cdev->dbg_features[feature];
+       struct qed_dbg_feature *qed_feature = &cdev->dbg_features[feature];
+       struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug];
        enum dbg_status dbg_rc;
        struct qed_ptt *p_ptt;
        int rc = 0;
 
 int qed_dbg_feature_size(struct qed_dev *cdev, enum qed_dbg_features feature)
 {
-       struct qed_hwfn *p_hwfn =
-               &cdev->hwfns[cdev->engine_for_debug];
        struct qed_dbg_feature *qed_feature = &cdev->dbg_features[feature];
+       struct qed_hwfn *p_hwfn = &cdev->hwfns[cdev->engine_for_debug];
        struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
        u32 buf_size_dwords;
        enum dbg_status rc;
        return qed_feature->buf_size;
 }
 
+int qed_dbg_phy_size(struct qed_dev *cdev)
+{
+       /* return max size of phy info and
+        * phy mac_stat multiplied by the number of ports
+        */
+       return MAX_PHY_RESULT_BUFFER * (1 + qed_device_num_ports(cdev));
+}
+
 u8 qed_get_debug_engine(struct qed_dev *cdev)
 {
        return cdev->engine_for_debug;
        const u8 *dbg_values = NULL;
        int i;
 
+       /* Sync ver with debugbus qed code */
+       qed_dbg_set_app_ver(TOOLS_VERSION);
+
        /* Debug values are after init values.
         * The offset is the first dword of the file.
         */