From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id E53D9A00BE; Wed, 8 Jul 2020 11:29:18 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id CDD151D918; Wed, 8 Jul 2020 11:29:18 +0200 (CEST) Received: from mail-il1-f196.google.com (mail-il1-f196.google.com [209.85.166.196]) by dpdk.org (Postfix) with ESMTP id 021E11D8F4 for ; Wed, 8 Jul 2020 11:29:16 +0200 (CEST) Received: by mail-il1-f196.google.com with SMTP id a6so21745191ilq.13 for ; Wed, 08 Jul 2020 02:29:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=4izdm2ew9UPQ8C7L/fWjvFuZKWrf8TPF9OVW8xNtfa0=; b=QOXtynF3CVOaFXMSuuAA5MQq+mJuHEU6YsrRWY0ACKbfKZUEjrB3cJ4WmBzJMrpO6V 5WFk9fi0em0nmC5glVBdctDSQqzs58NVLwwhXteJhqpg/zDEPAia+vl6T3NyID6f18JT mYDlAqbc7p1A67jFLC2mXxVp0Q2aOR8SqT8edVWKjGE5ViG5bhlSOqsyIs+Z6i4YSdQb X/C5BgrBTcsoydS+dmy4WqWdKqdG6jYTybnOCi0kozfjDRRZ2W8uia2ddzvl/7Fc1zwg c8jQDmw/o8adyIph9t6xmL8BE5gBsL5yrWPaiW3s/PSADsuYyRneclWrORRyH4bWkd26 xaHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=4izdm2ew9UPQ8C7L/fWjvFuZKWrf8TPF9OVW8xNtfa0=; b=cXl7E47OWe2mYHaRi8ja/ffaPU5waE/ebynVvIvbJmK1kjwbRkGu1m3RJH7I5cU83u qTx3DU/BJ+nuuEn1BPU/ixu3ntUC6vunS3NCr7ePRsOJ3dN1FwYTfZhrMUF/vBS3aGxd 2UoWEh+KXQpUmPgu4+FGGeT2G22fursPO9w8/ZI8lBOzDZdgoZwcdkR9eP4NdMPKJwPJ Eymr9mZKntLn4q7kg396Y17+eOvWkSqO0Wth+Z7J2R5zRtQFV4p8Xshfqxkd0rc5UXQJ zDGvxPPVhr2UGf/S+Y8bynT3KGlVfDesTXTftsvmY1ohFutIkipOyEEPmywfPPvCRJOy wQ4g== X-Gm-Message-State: AOAM5333yLOWos1wKB1oJpIWi7LVuDk/lROtZkc+sieJEAc4fjReykaY e2qrH9oBXvBhKh52Us6GluP7m9gZR2sa4Ej+i44ifWAmuZA= X-Google-Smtp-Source: ABdhPJxJmHuDZhQay4KRwyhP9getCGX9Obzhjl/nWZDuujrRPhEcZciVAj5nousWJO5ZVvEt7b4N9m8WBRUblkgBue0= X-Received: by 2002:a92:d206:: with SMTP id y6mr19665747ily.162.1594200556116; Wed, 08 Jul 2020 02:29:16 -0700 (PDT) MIME-Version: 1.0 References: <20200707201844.16111-1-rmody@marvell.com> <20200707211617.4408-5-rmody@marvell.com> In-Reply-To: <20200707211617.4408-5-rmody@marvell.com> From: Jerin Jacob Date: Wed, 8 Jul 2020 14:59:00 +0530 Message-ID: To: Rasesh Mody Cc: Jerin Jacob , Ferruh Yigit , dpdk-dev , GR-Everest-DPDK-Dev , Igor Russkikh Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [dpdk-dev] [PATCH v4 4/4] net/qede: add support for get register operation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" On Wed, Jul 8, 2020 at 2:47 AM Rasesh Mody wrote: > > Add support for .get_reg eth_dev ops which will be used to collect the > firmware debug data. > > PMD on detecting on some HW errors will collect the FW/HW Dump to a > buffer and then it will save it to a file implemented in > qede_save_fw_dump(). > > Dump file location and name: > Location: or DPDK root > Name: qede_pmd_dump_mm-dd-yy_hh-mm-ss.bin > > DPDK applications can initiate a debug data collection by invoking DPDK > library=E2=80=99s rte_eth_dev_get_reg_info() API. This API invokes .get_r= eg() > interface in the PMD. > > PMD implementation of .get_reg() collects the FW/HW Dump, saves it to > data field of rte_dev_reg_info and passes it to the application. It=E2=80= =99s > the responsibility of the application to save the FW/HW Dump to a file. > We recommendation using the file name format used by qede_save_fw_dump(). > > Signed-off-by: Rasesh Mody > Signed-off-by: Igor Russkikh Found meson build failure with gcc 10. Please check. meson -Dexamples=3Dl3fwd --buildtype=3Ddebugoptimized --werror --default-library=3Dstatic /export/dpdk-next-net-mrvl/devtools/.. ./build-gcc-static gcc -o drivers/librte_pmd_qede.so.20.0.3 'drivers/a715181@@rte_pmd_qede@sha/meson-generated_.._rte_pmd_qede.pmd.c.o' 'drivers/net/qede/base/f6110d5@@qede_base@sta/bcm_osal.c.o' 'drivers/net/qede/base/f6110d5@@qede_base@sta/ecore_cxt.c.o' ' drivers/net/qede/base/f6110d5@@qede_base@sta/ecore_dcbx.c.o' 'drivers/net/qede/base/f6110d5@@qede_base@sta/ecore_dev.c.o' 'drivers/net/qede/base/f6110d5@@qede_base@sta/ecore_hw.c.o' 'drivers/net/qede/base/f6110d5@@qede_base@sta/ecore_init_f w_funcs.c.o' 'drivers/net/qede/base/f6110d5@@qede_base@sta/ecore_init_ops.c= .o' 'drivers/net/qede/base/f6110d5@@qede_base@sta/ecore_int.c.o' 'drivers/net/qede/base/f6110d5@@qede_base@sta/ecore_l2.c.o' 'drivers/net/qede/base/f6110d5@@qede_bas e@sta/ecore_mcp.c.o' 'drivers/net/qede/base/f6110d5@@qede_base@sta/ecore_sp_commands.c.o' 'drivers/net/qede/base/f6110d5@@qede_base@sta/ecore_spq.c.o' 'drivers/net/qede/base/f6110d5@@qede_base@sta/ecore_sriov.c.o' 'drivers/net/qede/base/f61 10d5@@qede_base@sta/ecore_vf.c.o' 'drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_ethdev.c.o' 'drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_filter.c.o' 'drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o' 'drivers/a715 181@@tmp_rte_pmd_qede@sta/net_qede_qede_rxtx.c.o' -Wl,--as-needed -Wl,--no-undefined -shared -fPIC -Wl,--start-group -Wl,-soname,librte_pmd_qede.so.20.0 -Wl,--no-as-needed -pthread -lm -ldl -lnuma lib/librte_ethdev.so.20.0.3 lib/librte_eal. so.20.0.3 lib/librte_kvargs.so.20.0.3 lib/librte_telemetry.so.20.0.3 lib/librte_net.so.20.0.3 lib/librte_mbuf.so.20.0.3 lib/librte_mempool.so.20.0.3 lib/librte_ring.so.20.0.3 lib/librte_meter.so.20.0.3 drivers/librte_bus_pci.so.20.0.3 lib/l ibrte_pci.so.20.0.3 drivers/librte_bus_vdev.so.20.0.3 -Wl,--version-script=3D/export/dpdk-next-net-mrvl/drivers/net/qede/rte_pmd_= qede_version.map /usr/lib/libbsd.so -Wl,--end-group '-Wl,-rpath,$ORIGIN/../lib:$ORIGIN/' -Wl,-rpath-link,/export/ dpdk-next-net-mrvl/build-gcc-static/lib -Wl,-rpath-link,/export/dpdk-next-net-mrvl/build-gcc-static/drivers /usr/bin/ld: drivers/net/qede/base/f6110d5@@qede_base@sta/ecore_dev.c.o: in function `ecore_resc_alloc': /export/dpdk-next-net-mrvl/build-gcc-static/../drivers/net/qede/base/ecore_= dev.c:2516: undefined reference to `qed_dbg_alloc_user_data' /usr/bin/ld: /export/dpdk-next-net-mrvl/build-gcc-static/../drivers/net/qed= e/base/ecore_dev.c:2525: undefined reference to `qed_dbg_alloc_user_data' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o: in function `qed_slowpath_start': /export/dpdk-next-net-mrvl/build-gcc-static/../drivers/net/qede/qede_main.c= :285: undefined reference to `qed_dbg_pf_init' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0xa8): undefined reference to `qed_dbg_grc' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0xb0): undefined reference to `qed_dbg_grc_size' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0xb8): undefined reference to `qed_dbg_idle_chk' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0xc0): undefined reference to `qed_dbg_idle_chk_size' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0xc8): undefined reference to `qed_dbg_reg_fifo' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0xd0): undefined reference to `qed_dbg_reg_fifo_size' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0xd8): undefined reference to `qed_dbg_mcp_trace' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0xe0): undefined reference to `qed_dbg_mcp_trace_size' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0xe8): undefined reference to `qed_dbg_protection_override' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0xf0): undefined reference to `qed_dbg_protection_override_size' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0xf8): undefined reference to `qed_dbg_igu_fifo_size' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0x100): undefined reference to `qed_dbg_igu_fifo' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0x108): undefined reference to `qed_dbg_fw_asserts' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0x110): undefined reference to `qed_dbg_fw_asserts_size' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0x118): undefined reference to `qed_dbg_ilt' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0x120): undefined reference to `qed_dbg_ilt_size' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0x128): undefined reference to `qed_get_debug_engine' /usr/bin/ld: drivers/a715181@@tmp_rte_pmd_qede@sta/net_qede_qede_main.c.o:(= .data.rel.ro+0x130): undefined reference to `qed_set_debug_engine' > --- > doc/guides/nics/features/qede.ini | 1 + > drivers/net/qede/Makefile | 1 + > drivers/net/qede/base/bcm_osal.c | 25 +++ > drivers/net/qede/base/bcm_osal.h | 5 + > drivers/net/qede/qede_ethdev.c | 1 + > drivers/net/qede/qede_ethdev.h | 25 +++ > drivers/net/qede/qede_regs.c | 271 ++++++++++++++++++++++++++++++ > 7 files changed, 329 insertions(+) > create mode 100644 drivers/net/qede/qede_regs.c > > diff --git a/doc/guides/nics/features/qede.ini b/doc/guides/nics/features= /qede.ini > index 20c90e626..f8716523e 100644 > --- a/doc/guides/nics/features/qede.ini > +++ b/doc/guides/nics/features/qede.ini > @@ -31,6 +31,7 @@ Packet type parsing =3D Y > Basic stats =3D Y > Extended stats =3D Y > Stats per queue =3D Y > +Registers dump =3D Y > Multiprocess aware =3D Y > Linux UIO =3D Y > Linux VFIO =3D Y > diff --git a/drivers/net/qede/Makefile b/drivers/net/qede/Makefile > index 3b00338ff..0e8a67b0d 100644 > --- a/drivers/net/qede/Makefile > +++ b/drivers/net/qede/Makefile > @@ -104,5 +104,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) +=3D qede_main.c > SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) +=3D qede_rxtx.c > SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) +=3D qede_filter.c > SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) +=3D qede_debug.c > +SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) +=3D qede_regs.c > > include $(RTE_SDK)/mk/rte.lib.mk > diff --git a/drivers/net/qede/base/bcm_osal.c b/drivers/net/qede/base/bcm= _osal.c > index 45557fe3c..65837b53d 100644 > --- a/drivers/net/qede/base/bcm_osal.c > +++ b/drivers/net/qede/base/bcm_osal.c > @@ -246,6 +246,28 @@ qede_get_mcp_proto_stats(struct ecore_dev *edev, > } > } > > +static void qede_hw_err_handler(void *dev, enum ecore_hw_err_type err_ty= pe) > +{ > + struct ecore_dev *edev =3D dev; > + > + switch (err_type) { > + case ECORE_HW_ERR_FAN_FAIL: > + break; > + > + case ECORE_HW_ERR_MFW_RESP_FAIL: > + case ECORE_HW_ERR_HW_ATTN: > + case ECORE_HW_ERR_DMAE_FAIL: > + case ECORE_HW_ERR_RAMROD_FAIL: > + case ECORE_HW_ERR_FW_ASSERT: > + OSAL_SAVE_FW_DUMP(0); /* Using port 0 as default port_id = */ > + break; > + > + default: > + DP_NOTICE(edev, false, "Unknown HW error [%d]\n", err_typ= e); > + return; > + } > +} > + > void > qede_hw_err_notify(struct ecore_hwfn *p_hwfn, enum ecore_hw_err_type err= _type) > { > @@ -275,6 +297,9 @@ qede_hw_err_notify(struct ecore_hwfn *p_hwfn, enum ec= ore_hw_err_type err_type) > } > > DP_ERR(p_hwfn, "HW error occurred [%s]\n", err_str); > + > + qede_hw_err_handler(p_hwfn->p_dev, err_type); > + > ecore_int_attn_clr_enable(p_hwfn->p_dev, true); > } > > diff --git a/drivers/net/qede/base/bcm_osal.h b/drivers/net/qede/base/bcm= _osal.h > index b4b94231b..5d4df5907 100644 > --- a/drivers/net/qede/base/bcm_osal.h > +++ b/drivers/net/qede/base/bcm_osal.h > @@ -371,6 +371,11 @@ void qede_hw_err_notify(struct ecore_hwfn *p_hwfn, > > /* TODO: */ > #define OSAL_SCHEDULE_RECOVERY_HANDLER(hwfn) nothing > + > +int qede_save_fw_dump(uint8_t port_id); > + > +#define OSAL_SAVE_FW_DUMP(port_id) qede_save_fw_dump(port_id) > + > #define OSAL_HW_ERROR_OCCURRED(hwfn, err_type) \ > qede_hw_err_notify(hwfn, err_type) > > diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethde= v.c > index b5d6c7c43..e5a2581dd 100644 > --- a/drivers/net/qede/qede_ethdev.c > +++ b/drivers/net/qede/qede_ethdev.c > @@ -2426,6 +2426,7 @@ static const struct eth_dev_ops qede_eth_dev_ops = =3D { > .udp_tunnel_port_add =3D qede_udp_dst_port_add, > .udp_tunnel_port_del =3D qede_udp_dst_port_del, > .fw_version_get =3D qede_fw_version_get, > + .get_reg =3D qede_get_regs, > }; > > static const struct eth_dev_ops qede_eth_vf_dev_ops =3D { > diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethde= v.h > index b988a73f2..76c5dae3b 100644 > --- a/drivers/net/qede/qede_ethdev.h > +++ b/drivers/net/qede/qede_ethdev.h > @@ -214,6 +214,8 @@ struct qede_tunn_params { > uint16_t udp_port; > }; > > +#define QEDE_FW_DUMP_FILE_SIZE 128 > + > /* > * Structure to store private data for each port. > */ > @@ -252,6 +254,7 @@ struct qede_dev { > char drv_ver[QEDE_PMD_DRV_VER_STR_SIZE]; > bool vport_started; > int vlan_offload_mask; > + char dump_file[QEDE_FW_DUMP_FILE_SIZE]; > void *ethdev; > }; > > @@ -313,4 +316,26 @@ void qede_config_accept_any_vlan(struct qede_dev *qd= ev, bool flg); > int qede_ucast_filter(struct rte_eth_dev *eth_dev, > struct ecore_filter_ucast *ucast, > bool add); > + > +#define REGDUMP_HEADER_SIZE sizeof(u32) > +#define REGDUMP_HEADER_FEATURE_SHIFT 24 > +#define REGDUMP_HEADER_ENGINE_SHIFT 31 > +#define REGDUMP_HEADER_OMIT_ENGINE_SHIFT 30 > + > +enum debug_print_features { > + OLD_MODE =3D 0, > + IDLE_CHK =3D 1, > + GRC_DUMP =3D 2, > + MCP_TRACE =3D 3, > + REG_FIFO =3D 4, > + PROTECTION_OVERRIDE =3D 5, > + IGU_FIFO =3D 6, > + PHY =3D 7, > + FW_ASSERTS =3D 8, > +}; > + > +int qede_get_regs_len(struct qede_dev *qdev); > +int qede_get_regs(struct rte_eth_dev *dev, struct rte_dev_reg_info *regs= ); > +void qede_config_rx_mode(struct rte_eth_dev *eth_dev); > +void qed_dbg_dump(struct rte_eth_dev *eth_dev); > #endif /* _QEDE_ETHDEV_H_ */ > diff --git a/drivers/net/qede/qede_regs.c b/drivers/net/qede/qede_regs.c > new file mode 100644 > index 000000000..4409d2180 > --- /dev/null > +++ b/drivers/net/qede/qede_regs.c > @@ -0,0 +1,271 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright (c) 2020 Marvell Semiconductor Inc. > + * All rights reserved. > + * www.marvell.com > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include "base/bcm_osal.h" > +#include "qede_ethdev.h" > + > +int > +qede_get_regs_len(struct qede_dev *qdev) > +{ > + struct ecore_dev *edev =3D &qdev->edev; > + int cur_engine, num_of_hwfns, regs_len =3D 0; > + uint8_t org_engine; > + > + if (IS_VF(edev)) > + return 0; > + > + if (qdev->ops && qdev->ops->common) { > + num_of_hwfns =3D qdev->dev_info.common.num_hwfns; > + org_engine =3D qdev->ops->common->dbg_get_debug_engine(ed= ev); > + for (cur_engine =3D 0; cur_engine < num_of_hwfns; cur_eng= ine++) { > + /* compute required buffer size for idle_chks and > + * grcDump for each hw function > + */ > + DP_NOTICE(edev, false, > + "Calculating idle_chk and grcdump registe= r length for current engine\n"); > + qdev->ops->common->dbg_set_debug_engine(edev, > + cur_engin= e); > + regs_len +=3D REGDUMP_HEADER_SIZE + > + qdev->ops->common->dbg_idle_chk_size(edev= ) + > + REGDUMP_HEADER_SIZE + > + qdev->ops->common->dbg_idle_chk_size(edev= ) + > + REGDUMP_HEADER_SIZE + > + qdev->ops->common->dbg_grc_size(edev) + > + REGDUMP_HEADER_SIZE + > + qdev->ops->common->dbg_reg_fifo_size(edev= ) + > + REGDUMP_HEADER_SIZE + > + qdev->ops->common->dbg_protection_overrid= e_size(edev) + > + REGDUMP_HEADER_SIZE + > + qdev->ops->common->dbg_igu_fifo_size(edev= ) + > + REGDUMP_HEADER_SIZE + > + qdev->ops->common->dbg_fw_asserts_size(ed= ev); > + } > + /* compute required buffer size for mcp trace and add it = to the > + * total required buffer size > + */ > + regs_len +=3D REGDUMP_HEADER_SIZE + > + qdev->ops->common->dbg_mcp_trace_size(edev); > + > + qdev->ops->common->dbg_set_debug_engine(edev, org_engine)= ; > + } > + DP_NOTICE(edev, false, "Total length =3D %u\n", regs_len); > + > + return regs_len; > +} > + > +static uint32_t > +qede_calc_regdump_header(enum debug_print_features feature, int engine, > + uint32_t feature_size, uint8_t omit_engine) > +{ > + /* insert the engine, feature and mode inside the header and > + * combine it with feature size > + */ > + return (feature_size | (feature << REGDUMP_HEADER_FEATURE_SHIFT) = | > + (omit_engine << REGDUMP_HEADER_OMIT_ENGINE_SHIFT) | > + (engine << REGDUMP_HEADER_ENGINE_SHIFT)); > +} > + > +int qede_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *= regs) > +{ > + struct qede_dev *qdev =3D eth_dev->data->dev_private; > + struct ecore_dev *edev =3D &qdev->edev; > + uint32_t *buffer =3D regs->data; > + int cur_engine, num_of_hwfns; > + /* '1' tells the parser to omit the engine number in the output f= iles */ > + uint8_t omit_engine =3D 0; > + uint8_t org_engine; > + uint32_t feature_size; > + uint32_t offset =3D 0; > + > + if (IS_VF(edev)) > + return -ENOTSUP; > + > + if (buffer =3D=3D NULL) { > + regs->length =3D qede_get_regs_len(qdev); > + regs->width =3D sizeof(uint32_t); > + DP_INFO(edev, "Length %u\n", regs->length); > + return 0; > + } > + > + memset(buffer, 0, regs->length); > + num_of_hwfns =3D qdev->dev_info.common.num_hwfns; > + if (num_of_hwfns =3D=3D 1) > + omit_engine =3D 1; > + > + OSAL_MUTEX_ACQUIRE(&edev->dbg_lock); > + > + org_engine =3D qdev->ops->common->dbg_get_debug_engine(edev); > + for (cur_engine =3D 0; cur_engine < num_of_hwfns; cur_engine++) { > + /* collect idle_chks and grcDump for each hw function */ > + DP_NOTICE(edev, false, "obtaining idle_chk and grcdump fo= r current engine\n"); > + qdev->ops->common->dbg_set_debug_engine(edev, cur_engine)= ; > + > + /* first idle_chk */ > + qdev->ops->common->dbg_idle_chk(edev, (uint8_t *)buffer + > + offset + REGDUMP_HEADER_SIZE, &feature_size); > + *(uint32_t *)((uint8_t *)buffer + offset) =3D > + qede_calc_regdump_header(IDLE_CHK, cur_engine, > + feature_size, omit_engin= e); > + offset +=3D (feature_size + REGDUMP_HEADER_SIZE); > + DP_NOTICE(edev, false, "Idle Check1 feature_size %u\n", > + feature_size); > + > + /* second idle_chk */ > + qdev->ops->common->dbg_idle_chk(edev, (uint8_t *)buffer + > + offset + REGDUMP_HEADER_SIZE, &feature_size); > + *(uint32_t *)((uint8_t *)buffer + offset) =3D > + qede_calc_regdump_header(IDLE_CHK, cur_engine, > + feature_size, omit_engin= e); > + offset +=3D (feature_size + REGDUMP_HEADER_SIZE); > + DP_NOTICE(edev, false, "Idle Check2 feature_size %u\n", > + feature_size); > + > + /* reg_fifo dump */ > + qdev->ops->common->dbg_reg_fifo(edev, (uint8_t *)buffer + > + offset + REGDUMP_HEADER_SIZE, &feature_size); > + *(uint32_t *)((uint8_t *)buffer + offset) =3D > + qede_calc_regdump_header(REG_FIFO, cur_engine, > + feature_size, omit_engin= e); > + offset +=3D (feature_size + REGDUMP_HEADER_SIZE); > + DP_NOTICE(edev, false, "Reg fifo feature_size %u\n", > + feature_size); > + > + /* igu_fifo dump */ > + qdev->ops->common->dbg_igu_fifo(edev, (uint8_t *)buffer + > + offset + REGDUMP_HEADER_SIZE, &feature_size); > + *(uint32_t *)((uint8_t *)buffer + offset) =3D > + qede_calc_regdump_header(IGU_FIFO, cur_engine, > + feature_size, omit_engin= e); > + offset +=3D (feature_size + REGDUMP_HEADER_SIZE); > + DP_NOTICE(edev, false, "IGU fifo feature_size %u\n", > + feature_size); > + > + /* protection_override dump */ > + qdev->ops->common->dbg_protection_override(edev, > + (uint8_t *)buf= fer + > + offset + REGDUMP_HEADER_SIZE, &feature_size); > + *(uint32_t *)((uint8_t *)buffer + offset) =3D > + qede_calc_regdump_header(PROTECTION_OVERRIDE, cur_= engine, > + feature_size, omit_engine= ); > + offset +=3D (feature_size + REGDUMP_HEADER_SIZE); > + DP_NOTICE(edev, false, "Protection override feature_size = %u\n", > + feature_size); > + > + /* fw_asserts dump */ > + qdev->ops->common->dbg_fw_asserts(edev, (uint8_t *)buffer= + > + offset + REGDUMP_HEADER_SIZE, &feature_size); > + *(uint32_t *)((uint8_t *)buffer + offset) =3D > + qede_calc_regdump_header(FW_ASSERTS, cur_engine, > + feature_size, omit_engin= e); > + offset +=3D (feature_size + REGDUMP_HEADER_SIZE); > + DP_NOTICE(edev, false, "FW assert feature_size %u\n", > + feature_size); > + > + /* grc dump */ > + qdev->ops->common->dbg_grc(edev, (uint8_t *)buffer + > + offset + REGDUMP_HEADER_SIZE, &feature_size); > + *(uint32_t *)((uint8_t *)buffer + offset) =3D > + qede_calc_regdump_header(GRC_DUMP, cur_engine, > + feature_size, omit_engin= e); > + offset +=3D (feature_size + REGDUMP_HEADER_SIZE); > + DP_NOTICE(edev, false, "GRC dump feature_size %u\n", > + feature_size); > + } > + > + /* mcp_trace */ > + qdev->ops->common->dbg_mcp_trace(edev, (uint8_t *)buffer + > + offset + REGDUMP_HEADER_SIZE, &feature_size); > + *(uint32_t *)((uint8_t *)buffer + offset) =3D > + qede_calc_regdump_header(MCP_TRACE, cur_engine, feature_s= ize, > + omit_engine); > + offset +=3D (feature_size + REGDUMP_HEADER_SIZE); > + DP_NOTICE(edev, false, "MCP trace feature_size %u\n", feature_siz= e); > + > + qdev->ops->common->dbg_set_debug_engine(edev, org_engine); > + > + OSAL_MUTEX_RELEASE(&edev->dbg_lock); > + > + return 0; > +} > + > +static void > +qede_set_fw_dump_file_name(struct qede_dev *qdev) > +{ > + time_t ltime; > + struct tm *tm; > + > + ltime =3D time(NULL); > + tm =3D localtime(<ime); > + snprintf(qdev->dump_file, QEDE_FW_DUMP_FILE_SIZE, > + "qede_pmd_dump_%02d-%02d-%02d_%02d-%02d-%02d.bin", > + tm->tm_mon + 1, (int)tm->tm_mday, 1900 + tm->tm_year, > + tm->tm_hour, tm->tm_min, tm->tm_sec); > +} > + > +static int > +qede_write_fwdump(const char *dump_file, void *dump, size_t len) > +{ > + int err =3D 0; > + FILE *f; > + size_t bytes; > + > + f =3D fopen(dump_file, "wb+"); > + > + if (!f) { > + fprintf(stderr, "Can't open file %s: %s\n", > + dump_file, strerror(errno)); > + return 1; > + } > + bytes =3D fwrite(dump, 1, len, f); > + if (bytes !=3D len) { > + fprintf(stderr, "Can not write all of dump data bytes=3D%= ld len=3D%ld\n", > + bytes, len); > + err =3D 1; > + } > + > + if (fclose(f)) { > + fprintf(stderr, "Can't close file %s: %s\n", > + dump_file, strerror(errno)); > + err =3D 1; > + } > + > + return err; > +} > + > +int > +qede_save_fw_dump(uint8_t port_id) > +{ > + struct rte_eth_dev *eth_dev =3D &rte_eth_devices[port_id]; > + struct rte_dev_reg_info regs; > + struct qede_dev *qdev =3D eth_dev->data->dev_private; > + struct ecore_dev *edev =3D &qdev->edev; > + int rc =3D 0; > + > + if (!rte_eth_dev_is_valid_port(port_id)) { > + DP_ERR(edev, "port %u invalid port ID", port_id); > + return -ENODEV; > + } > + > + memset(®s, 0, sizeof(regs)); > + regs.length =3D qede_get_regs_len(qdev); > + regs.data =3D OSAL_ZALLOC(eth_dev, GFP_KERNEL, regs.length); > + if (regs.data) { > + qede_get_regs(eth_dev, ®s); > + qede_set_fw_dump_file_name(qdev); > + rc =3D qede_write_fwdump(qdev->dump_file, regs.data, regs= .length); > + if (!rc) > + DP_NOTICE(edev, false, "FW dump written to %s fil= e\n", > + qdev->dump_file); > + OSAL_FREE(edev, regs.data); > + } > + > + return rc; > +} > -- > 2.18.0 >