get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 73468,
    "url": "https://patches.dpdk.org/api/patches/73468/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20200707201844.16111-5-rmody@marvell.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20200707201844.16111-5-rmody@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200707201844.16111-5-rmody@marvell.com",
    "date": "2020-07-07T20:18:44",
    "name": "[v3,4/4] net/qede: add support for get register operation",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "1e8f931b0bdf4a611a8392d85bc053e86d5076ba",
    "submitter": {
        "id": 1211,
        "url": "https://patches.dpdk.org/api/people/1211/?format=api",
        "name": "Rasesh Mody",
        "email": "rmody@marvell.com"
    },
    "delegate": {
        "id": 310,
        "url": "https://patches.dpdk.org/api/users/310/?format=api",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerinj@marvell.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20200707201844.16111-5-rmody@marvell.com/mbox/",
    "series": [
        {
            "id": 10681,
            "url": "https://patches.dpdk.org/api/series/10681/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=10681",
            "date": "2020-06-30T08:32:11",
            "name": "net/qede: add FW debug data collection support",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/10681/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/73468/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/73468/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 57B52A00BE;\n\tTue,  7 Jul 2020 22:19:56 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id DAD7A1DCF5;\n\tTue,  7 Jul 2020 22:19:35 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com\n [67.231.156.173]) by dpdk.org (Postfix) with ESMTP id C0CF91DB99\n for <dev@dpdk.org>; Tue,  7 Jul 2020 22:19:33 +0200 (CEST)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id\n 067K14bh016834; Tue, 7 Jul 2020 13:19:33 -0700",
            "from sc-exch02.marvell.com ([199.233.58.182])\n by mx0b-0016f401.pphosted.com with ESMTP id 322s9ncsk5-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT);\n Tue, 07 Jul 2020 13:19:32 -0700",
            "from DC5-EXCH01.marvell.com (10.69.176.38) by SC-EXCH02.marvell.com\n (10.93.176.82) with Microsoft SMTP Server (TLS) id 15.0.1497.2;\n Tue, 7 Jul 2020 13:19:30 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.2 via Frontend\n Transport; Tue, 7 Jul 2020 13:19:30 -0700",
            "from irv1user08.caveonetworks.com (unknown [10.104.116.105])\n by maili.marvell.com (Postfix) with ESMTP id 80F4C3F703F;\n Tue,  7 Jul 2020 13:19:30 -0700 (PDT)",
            "(from rmody@localhost)\n by irv1user08.caveonetworks.com (8.14.4/8.14.4/Submit) id 067KJU6b016412;\n Tue, 7 Jul 2020 13:19:30 -0700"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-type : content-transfer-encoding; s=pfpt0818;\n bh=FBvwDI8qiuMKQSeadedjs4bmEgSS//MKounNL6Deon4=;\n b=GfoXoIa06iO83mAzBenjPmzs+W8sQYSliOAKQ00Y8eYN9oYkWcNCD+osVgMg9CApnfpf\n TY251uPJ7M/NEuv4ASvv9sjhblfkizt0tNfpXWWUZomRdXdxfGUTHy3ktjakyvVQ3hXF\n o3CHC+wp2Az6dzGHRbre+Kx6/WflEp7Gtu4rR++C95qiiGYZRVD5AluFo8PFJW93U9Cj\n RAwaj770YX2Ko0N5UypwaVch0N8dCfPqLDEtZezccFNpJAwJSQgDq0Qa2/nZLFW1jf1Q\n JpVqfeJ6bK57tlGz1iOFSj2CwouJle5XZe2E3zNS4ZSpCY78qrMlY9K1pXX2TLG+57A3 kg==",
        "X-Authentication-Warning": "irv1user08.caveonetworks.com: rmody set sender to\n rmody@marvell.com using -f",
        "From": "Rasesh Mody <rmody@marvell.com>",
        "To": "<jerinj@marvell.com>, <ferruh.yigit@intel.com>",
        "CC": "Rasesh Mody <rmody@marvell.com>, <dev@dpdk.org>,\n <GR-Everest-DPDK-Dev@marvell.com>, Igor Russkikh <irusskikh@marvell.com>",
        "Date": "Tue, 7 Jul 2020 13:18:44 -0700",
        "Message-ID": "<20200707201844.16111-5-rmody@marvell.com>",
        "X-Mailer": "git-send-email 2.18.0",
        "In-Reply-To": "<20200630083215.13108-1-rmody@marvell.com>",
        "References": "<20200630083215.13108-1-rmody@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"UTF-8\"",
        "Content-Transfer-Encoding": "8bit",
        "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10434:6.0.235, 18.0.687\n definitions=2020-07-07_13:2020-07-07,\n 2020-07-07 signatures=0",
        "Subject": "[dpdk-dev] [PATCH v3 4/4] net/qede: add support for get register\n\toperation",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add support for .get_reg eth_dev ops which will be used to collect the\nfirmware debug data.\n\nPMD on detecting on some HW errors will collect the FW/HW Dump to a\nbuffer and then it will save it to a file implemented in\nqede_save_fw_dump().\n\nDump file location and name:\nLocation: <RTE_SDK> or DPDK root\nName: qede_pmd_dump_mm-dd-yy_hh-mm-ss.bin\n\nDPDK applications can initiate a debug data collection by invoking DPDK\nlibrary’s rte_eth_dev_get_reg_info() API. This API invokes .get_reg()\ninterface in the PMD.\n\nPMD implementation of .get_reg() collects the FW/HW Dump, saves it to\ndata field of rte_dev_reg_info and passes it to the application. It’s\nthe responsibility of the application to save the FW/HW Dump to a file.\nWe recommendation using the file name format used by qede_save_fw_dump().\n\nSigned-off-by: Rasesh Mody <rmody@marvell.com>\nSigned-off-by: Igor Russkikh <irusskikh@marvell.com>\n---\n doc/guides/nics/features/qede.ini |   1 +\n drivers/net/qede/Makefile         |   1 +\n drivers/net/qede/base/bcm_osal.c  |  25 +++\n drivers/net/qede/base/bcm_osal.h  |   5 +\n drivers/net/qede/qede_ethdev.c    |   1 +\n drivers/net/qede/qede_ethdev.h    |  25 +++\n drivers/net/qede/qede_regs.c      | 271 ++++++++++++++++++++++++++++++\n 7 files changed, 329 insertions(+)\n create mode 100644 drivers/net/qede/qede_regs.c",
    "diff": "diff --git a/doc/guides/nics/features/qede.ini b/doc/guides/nics/features/qede.ini\nindex 20c90e626..f8716523e 100644\n--- a/doc/guides/nics/features/qede.ini\n+++ b/doc/guides/nics/features/qede.ini\n@@ -31,6 +31,7 @@ Packet type parsing  = Y\n Basic stats          = Y\n Extended stats       = Y\n Stats per queue      = Y\n+Registers dump       = Y\n Multiprocess aware   = Y\n Linux UIO            = Y\n Linux VFIO           = Y\ndiff --git a/drivers/net/qede/Makefile b/drivers/net/qede/Makefile\nindex 3b00338ff..0e8a67b0d 100644\n--- a/drivers/net/qede/Makefile\n+++ b/drivers/net/qede/Makefile\n@@ -104,5 +104,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_main.c\n SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_rxtx.c\n SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_filter.c\n SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_debug.c\n+SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_regs.c\n \n include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/drivers/net/qede/base/bcm_osal.c b/drivers/net/qede/base/bcm_osal.c\nindex 45557fe3c..65837b53d 100644\n--- a/drivers/net/qede/base/bcm_osal.c\n+++ b/drivers/net/qede/base/bcm_osal.c\n@@ -246,6 +246,28 @@ qede_get_mcp_proto_stats(struct ecore_dev *edev,\n \t}\n }\n \n+static void qede_hw_err_handler(void *dev, enum ecore_hw_err_type err_type)\n+{\n+\tstruct ecore_dev *edev = dev;\n+\n+\tswitch (err_type) {\n+\tcase ECORE_HW_ERR_FAN_FAIL:\n+\t\tbreak;\n+\n+\tcase ECORE_HW_ERR_MFW_RESP_FAIL:\n+\tcase ECORE_HW_ERR_HW_ATTN:\n+\tcase ECORE_HW_ERR_DMAE_FAIL:\n+\tcase ECORE_HW_ERR_RAMROD_FAIL:\n+\tcase ECORE_HW_ERR_FW_ASSERT:\n+\t\tOSAL_SAVE_FW_DUMP(0); /* Using port 0 as default port_id */\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tDP_NOTICE(edev, false, \"Unknown HW error [%d]\\n\", err_type);\n+\t\treturn;\n+\t}\n+}\n+\n void\n qede_hw_err_notify(struct ecore_hwfn *p_hwfn, enum ecore_hw_err_type err_type)\n {\n@@ -275,6 +297,9 @@ qede_hw_err_notify(struct ecore_hwfn *p_hwfn, enum ecore_hw_err_type err_type)\n \t}\n \n \tDP_ERR(p_hwfn, \"HW error occurred [%s]\\n\", err_str);\n+\n+\tqede_hw_err_handler(p_hwfn->p_dev, err_type);\n+\n \tecore_int_attn_clr_enable(p_hwfn->p_dev, true);\n }\n \ndiff --git a/drivers/net/qede/base/bcm_osal.h b/drivers/net/qede/base/bcm_osal.h\nindex b4b94231b..5d4df5907 100644\n--- a/drivers/net/qede/base/bcm_osal.h\n+++ b/drivers/net/qede/base/bcm_osal.h\n@@ -371,6 +371,11 @@ void qede_hw_err_notify(struct ecore_hwfn *p_hwfn,\n \n /* TODO: */\n #define OSAL_SCHEDULE_RECOVERY_HANDLER(hwfn) nothing\n+\n+int qede_save_fw_dump(uint8_t port_id);\n+\n+#define OSAL_SAVE_FW_DUMP(port_id) qede_save_fw_dump(port_id)\n+\n #define OSAL_HW_ERROR_OCCURRED(hwfn, err_type) \\\n \tqede_hw_err_notify(hwfn, err_type)\n \ndiff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c\nindex b5d6c7c43..e5a2581dd 100644\n--- a/drivers/net/qede/qede_ethdev.c\n+++ b/drivers/net/qede/qede_ethdev.c\n@@ -2426,6 +2426,7 @@ static const struct eth_dev_ops qede_eth_dev_ops = {\n \t.udp_tunnel_port_add = qede_udp_dst_port_add,\n \t.udp_tunnel_port_del = qede_udp_dst_port_del,\n \t.fw_version_get = qede_fw_version_get,\n+\t.get_reg = qede_get_regs,\n };\n \n static const struct eth_dev_ops qede_eth_vf_dev_ops = {\ndiff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h\nindex b988a73f2..76c5dae3b 100644\n--- a/drivers/net/qede/qede_ethdev.h\n+++ b/drivers/net/qede/qede_ethdev.h\n@@ -214,6 +214,8 @@ struct qede_tunn_params {\n \tuint16_t udp_port;\n };\n \n+#define QEDE_FW_DUMP_FILE_SIZE 128\n+\n /*\n  *  Structure to store private data for each port.\n  */\n@@ -252,6 +254,7 @@ struct qede_dev {\n \tchar drv_ver[QEDE_PMD_DRV_VER_STR_SIZE];\n \tbool vport_started;\n \tint vlan_offload_mask;\n+\tchar dump_file[QEDE_FW_DUMP_FILE_SIZE];\n \tvoid *ethdev;\n };\n \n@@ -313,4 +316,26 @@ void qede_config_accept_any_vlan(struct qede_dev *qdev, bool flg);\n int qede_ucast_filter(struct rte_eth_dev *eth_dev,\n \t\t      struct ecore_filter_ucast *ucast,\n \t\t      bool add);\n+\n+#define REGDUMP_HEADER_SIZE sizeof(u32)\n+#define REGDUMP_HEADER_FEATURE_SHIFT 24\n+#define REGDUMP_HEADER_ENGINE_SHIFT 31\n+#define REGDUMP_HEADER_OMIT_ENGINE_SHIFT 30\n+\n+enum debug_print_features {\n+\tOLD_MODE = 0,\n+\tIDLE_CHK = 1,\n+\tGRC_DUMP = 2,\n+\tMCP_TRACE = 3,\n+\tREG_FIFO = 4,\n+\tPROTECTION_OVERRIDE = 5,\n+\tIGU_FIFO = 6,\n+\tPHY = 7,\n+\tFW_ASSERTS = 8,\n+};\n+\n+int qede_get_regs_len(struct qede_dev *qdev);\n+int qede_get_regs(struct rte_eth_dev *dev, struct rte_dev_reg_info *regs);\n+void qede_config_rx_mode(struct rte_eth_dev *eth_dev);\n+void qed_dbg_dump(struct rte_eth_dev *eth_dev);\n #endif /* _QEDE_ETHDEV_H_ */\ndiff --git a/drivers/net/qede/qede_regs.c b/drivers/net/qede/qede_regs.c\nnew file mode 100644\nindex 000000000..4409d2180\n--- /dev/null\n+++ b/drivers/net/qede/qede_regs.c\n@@ -0,0 +1,271 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2020 Marvell Semiconductor Inc.\n+ * All rights reserved.\n+ * www.marvell.com\n+ */\n+\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <fcntl.h>\n+#include <time.h>\n+#include <rte_ethdev.h>\n+#include \"base/bcm_osal.h\"\n+#include \"qede_ethdev.h\"\n+\n+int\n+qede_get_regs_len(struct qede_dev *qdev)\n+{\n+\tstruct ecore_dev *edev = &qdev->edev;\n+\tint cur_engine, num_of_hwfns, regs_len = 0;\n+\tuint8_t org_engine;\n+\n+\tif (IS_VF(edev))\n+\t\treturn 0;\n+\n+\tif (qdev->ops && qdev->ops->common) {\n+\t\tnum_of_hwfns = qdev->dev_info.common.num_hwfns;\n+\t\torg_engine = qdev->ops->common->dbg_get_debug_engine(edev);\n+\t\tfor (cur_engine = 0; cur_engine < num_of_hwfns; cur_engine++) {\n+\t\t\t/* compute requierd buffer size for idle_chks and\n+\t\t\t * grcDump for each hw function\n+\t\t\t */\n+\t\t\tDP_NOTICE(edev, false,\n+\t\t\t\t\"Calculating idle_chk and grcdump register length for current engine\\n\");\n+\t\t\tqdev->ops->common->dbg_set_debug_engine(edev,\n+\t\t\t\t\t\t\t\tcur_engine);\n+\t\t\tregs_len += REGDUMP_HEADER_SIZE +\n+\t\t\t\tqdev->ops->common->dbg_idle_chk_size(edev) +\n+\t\t\t\tREGDUMP_HEADER_SIZE +\n+\t\t\t\tqdev->ops->common->dbg_idle_chk_size(edev) +\n+\t\t\t\tREGDUMP_HEADER_SIZE +\n+\t\t\t\tqdev->ops->common->dbg_grc_size(edev) +\n+\t\t\t\tREGDUMP_HEADER_SIZE +\n+\t\t\t\tqdev->ops->common->dbg_reg_fifo_size(edev) +\n+\t\t\t\tREGDUMP_HEADER_SIZE +\n+\t\t\t\tqdev->ops->common->dbg_protection_override_size(edev) +\n+\t\t\t\tREGDUMP_HEADER_SIZE +\n+\t\t\t\tqdev->ops->common->dbg_igu_fifo_size(edev) +\n+\t\t\t\tREGDUMP_HEADER_SIZE +\n+\t\t\t\tqdev->ops->common->dbg_fw_asserts_size(edev);\n+\t\t}\n+\t\t/* compute requierd buffer size for mcp trace and add it to the\n+\t\t * total requierd buffer size\n+\t\t */\n+\t\tregs_len += REGDUMP_HEADER_SIZE +\n+\t\t\t    qdev->ops->common->dbg_mcp_trace_size(edev);\n+\n+\t\tqdev->ops->common->dbg_set_debug_engine(edev, org_engine);\n+\t}\n+\tDP_NOTICE(edev, false, \"Total length = %u\\n\", regs_len);\n+\n+\treturn regs_len;\n+}\n+\n+static uint32_t\n+qede_calc_regdump_header(enum debug_print_features feature, int engine,\n+\t\t\t uint32_t feature_size, uint8_t omit_engine)\n+{\n+\t/* insert the engine, feature and mode inside the header and\n+\t * combine it with feature size\n+\t */\n+\treturn (feature_size | (feature << REGDUMP_HEADER_FEATURE_SHIFT) |\n+\t\t(omit_engine << REGDUMP_HEADER_OMIT_ENGINE_SHIFT) |\n+\t\t(engine << REGDUMP_HEADER_ENGINE_SHIFT));\n+}\n+\n+int qede_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)\n+{\n+\tstruct qede_dev *qdev = eth_dev->data->dev_private;\n+\tstruct ecore_dev *edev = &qdev->edev;\n+\tuint32_t *buffer = regs->data;\n+\tint cur_engine, num_of_hwfns;\n+\t/* '1' tells the parser to omit the engine number in the output files */\n+\tuint8_t omit_engine = 0;\n+\tuint8_t org_engine;\n+\tuint32_t feature_size;\n+\tuint32_t offset = 0;\n+\n+\tif (IS_VF(edev))\n+\t\treturn -ENOTSUP;\n+\n+\tif (buffer == NULL) {\n+\t\tregs->length = qede_get_regs_len(qdev);\n+\t\tregs->width =  sizeof(uint32_t);\n+\t\tDP_INFO(edev, \"Length %u\\n\", regs->length);\n+\t\treturn 0;\n+\t}\n+\n+\tmemset(buffer, 0, regs->length);\n+\tnum_of_hwfns = qdev->dev_info.common.num_hwfns;\n+\tif (num_of_hwfns == 1)\n+\t\tomit_engine = 1;\n+\n+\tOSAL_MUTEX_ACQUIRE(&edev->dbg_lock);\n+\n+\torg_engine = qdev->ops->common->dbg_get_debug_engine(edev);\n+\tfor (cur_engine = 0; cur_engine < num_of_hwfns; cur_engine++) {\n+\t\t/* collect idle_chks and grcDump for each hw function */\n+\t\tDP_NOTICE(edev, false, \"obtaining idle_chk and grcdump for current engine\\n\");\n+\t\tqdev->ops->common->dbg_set_debug_engine(edev, cur_engine);\n+\n+\t\t/* first idle_chk */\n+\t\tqdev->ops->common->dbg_idle_chk(edev, (uint8_t *)buffer +\n+\t\t\toffset + REGDUMP_HEADER_SIZE, &feature_size);\n+\t\t*(uint32_t *)((uint8_t *)buffer + offset) =\n+\t\t\tqede_calc_regdump_header(IDLE_CHK, cur_engine,\n+\t\t\t\t\t\t feature_size, omit_engine);\n+\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\tDP_NOTICE(edev, false, \"Idle Check1 feature_size %u\\n\",\n+\t\t\t  feature_size);\n+\n+\t\t/* second idle_chk */\n+\t\tqdev->ops->common->dbg_idle_chk(edev, (uint8_t *)buffer +\n+\t\t\toffset + REGDUMP_HEADER_SIZE, &feature_size);\n+\t\t*(uint32_t *)((uint8_t *)buffer + offset) =\n+\t\t\tqede_calc_regdump_header(IDLE_CHK, cur_engine,\n+\t\t\t\t\t\t feature_size, omit_engine);\n+\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\tDP_NOTICE(edev, false, \"Idle Check2 feature_size %u\\n\",\n+\t\t\t  feature_size);\n+\n+\t\t/* reg_fifo dump */\n+\t\tqdev->ops->common->dbg_reg_fifo(edev, (uint8_t *)buffer +\n+\t\t\toffset + REGDUMP_HEADER_SIZE, &feature_size);\n+\t\t*(uint32_t *)((uint8_t *)buffer + offset) =\n+\t\t\tqede_calc_regdump_header(REG_FIFO, cur_engine,\n+\t\t\t\t\t\t feature_size, omit_engine);\n+\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\tDP_NOTICE(edev, false, \"Reg fifo feature_size %u\\n\",\n+\t\t\t  feature_size);\n+\n+\t\t/* igu_fifo dump */\n+\t\tqdev->ops->common->dbg_igu_fifo(edev, (uint8_t *)buffer +\n+\t\t\toffset + REGDUMP_HEADER_SIZE, &feature_size);\n+\t\t*(uint32_t *)((uint8_t *)buffer + offset) =\n+\t\t\tqede_calc_regdump_header(IGU_FIFO, cur_engine,\n+\t\t\t\t\t\t feature_size, omit_engine);\n+\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\tDP_NOTICE(edev, false, \"IGU fifo feature_size %u\\n\",\n+\t\t\t  feature_size);\n+\n+\t\t/* protection_override dump */\n+\t\tqdev->ops->common->dbg_protection_override(edev,\n+\t\t\t\t\t\t\t   (uint8_t *)buffer +\n+\t\t\toffset + REGDUMP_HEADER_SIZE, &feature_size);\n+\t\t*(uint32_t *)((uint8_t *)buffer + offset) =\n+\t\t       qede_calc_regdump_header(PROTECTION_OVERRIDE, cur_engine,\n+\t\t\t\t\t\tfeature_size, omit_engine);\n+\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\tDP_NOTICE(edev, false, \"Protection override feature_size %u\\n\",\n+\t\t\t  feature_size);\n+\n+\t\t/* fw_asserts dump */\n+\t\tqdev->ops->common->dbg_fw_asserts(edev, (uint8_t *)buffer +\n+\t\t\toffset + REGDUMP_HEADER_SIZE, &feature_size);\n+\t\t*(uint32_t *)((uint8_t *)buffer + offset) =\n+\t\t\tqede_calc_regdump_header(FW_ASSERTS, cur_engine,\n+\t\t\t\t\t\t feature_size, omit_engine);\n+\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\tDP_NOTICE(edev, false, \"FW assert feature_size %u\\n\",\n+\t\t\t  feature_size);\n+\n+\t\t/* grc dump */\n+\t\tqdev->ops->common->dbg_grc(edev, (uint8_t *)buffer +\n+\t\t\toffset + REGDUMP_HEADER_SIZE, &feature_size);\n+\t\t*(uint32_t *)((uint8_t *)buffer + offset) =\n+\t\t\tqede_calc_regdump_header(GRC_DUMP, cur_engine,\n+\t\t\t\t\t\t feature_size, omit_engine);\n+\t\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\t\tDP_NOTICE(edev, false, \"GRC dump feature_size %u\\n\",\n+\t\t\t  feature_size);\n+\t}\n+\n+\t/* mcp_trace */\n+\tqdev->ops->common->dbg_mcp_trace(edev, (uint8_t *)buffer +\n+\t\toffset + REGDUMP_HEADER_SIZE, &feature_size);\n+\t*(uint32_t *)((uint8_t *)buffer + offset) =\n+\t\tqede_calc_regdump_header(MCP_TRACE, cur_engine, feature_size,\n+\t\t\t\t\t omit_engine);\n+\toffset += (feature_size + REGDUMP_HEADER_SIZE);\n+\tDP_NOTICE(edev, false, \"MCP trace feature_size %u\\n\", feature_size);\n+\n+\tqdev->ops->common->dbg_set_debug_engine(edev, org_engine);\n+\n+\tOSAL_MUTEX_RELEASE(&edev->dbg_lock);\n+\n+\treturn 0;\n+}\n+\n+static void\n+qede_set_fw_dump_file_name(struct qede_dev *qdev)\n+{\n+\ttime_t ltime;\n+\tstruct tm *tm;\n+\n+\tltime = time(NULL);\n+\ttm = localtime(&ltime);\n+\tsnprintf(qdev->dump_file, QEDE_FW_DUMP_FILE_SIZE,\n+\t\t \"qede_pmd_dump_%02d-%02d-%02d_%02d-%02d-%02d.bin\",\n+\t\t tm->tm_mon + 1, (int)tm->tm_mday, 1900 + tm->tm_year,\n+\t\t tm->tm_hour, tm->tm_min, tm->tm_sec);\n+}\n+\n+static int\n+qede_write_fwdump(const char *dump_file, void *dump, size_t len)\n+{\n+\tint err = 0;\n+\tFILE *f;\n+\tsize_t bytes;\n+\n+\tf = fopen(dump_file, \"wb+\");\n+\n+\tif (!f) {\n+\t\tfprintf(stderr, \"Can't open file %s: %s\\n\",\n+\t\t\tdump_file, strerror(errno));\n+\t\treturn 1;\n+\t}\n+\tbytes = fwrite(dump, 1, len, f);\n+\tif (bytes != len) {\n+\t\tfprintf(stderr, \"Can not write all of dump data bytes=%ld len=%ld\\n\",\n+\t\t\tbytes, len);\n+\t\terr = 1;\n+\t}\n+\n+\tif (fclose(f)) {\n+\t\tfprintf(stderr, \"Can't close file %s: %s\\n\",\n+\t\t\tdump_file, strerror(errno));\n+\t\terr = 1;\n+\t}\n+\n+\treturn err;\n+}\n+\n+int\n+qede_save_fw_dump(uint8_t port_id)\n+{\n+\tstruct rte_eth_dev *eth_dev = &rte_eth_devices[port_id];\n+\tstruct rte_dev_reg_info regs;\n+\tstruct qede_dev *qdev = eth_dev->data->dev_private;\n+\tstruct ecore_dev *edev = &qdev->edev;\n+\tint rc = 0;\n+\n+\tif (!rte_eth_dev_is_valid_port(port_id)) {\n+\t\tDP_ERR(edev, \"port %u invalid port ID\", port_id);\n+\t\treturn -ENODEV;\n+\t}\n+\n+\tmemset(&regs, 0, sizeof(regs));\n+\tregs.length = qede_get_regs_len(qdev);\n+\tregs.data = OSAL_ZALLOC(eth_dev, GFP_KERNEL, regs.length);\n+\tif (regs.data) {\n+\t\tqede_get_regs(eth_dev, &regs);\n+\t\tqede_set_fw_dump_file_name(qdev);\n+\t\trc = qede_write_fwdump(qdev->dump_file, regs.data, regs.length);\n+\t\tif (!rc)\n+\t\t\tDP_NOTICE(edev, false, \"FW dump written to %s file\\n\",\n+\t\t\t\t  qdev->dump_file);\n+\t\tOSAL_FREE(edev, regs.data);\n+\t}\n+\n+\treturn rc;\n+}\n",
    "prefixes": [
        "v3",
        "4/4"
    ]
}