From patchwork Thu Jun 17 10:59:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94326 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id EBFA1A0C4D; Thu, 17 Jun 2021 12:58:17 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 61387410DF; Thu, 17 Jun 2021 12:58:15 +0200 (CEST) Received: from smtpbgau1.qq.com (smtpbgau1.qq.com [54.206.16.166]) by mails.dpdk.org (Postfix) with ESMTP id D5417410E3 for ; Thu, 17 Jun 2021 12:58:12 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927484t5zfy0zr Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:04 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: uZ1irgsSB1kKE1F06M50UtuK7R77I+CxhnqYYrOrsUhJEfOV2HtFWD7yBIwDL G7qFkktXu/XE4Ojh/RhyZ4DvpONQw24247G4ozBokmVXrK7O/K9RswKBgeHB5DYN6coemlf QuV1K5bSEmMLo8/WmQVgyC3orNmyrkQG+z/tvRIav6doQr72MwHbFEnBjawqus0h2UOnel5 eKuAiPPZ5jANrBOoryvQ+eegl6e5FcdZA1FjKDOpez8+o3f8U4BFtjJH0WOxGSlap7ozJSA gehA5Q7j9NBfgFLg+hQqrx5Ua2Jpj2M/CeeYS0Mcbz7oG2cNXckvlTQIv2BAljJ2c+o54By E042Zuh0Zsiv9CrlqY8udW4siREdw6imyCUST23 X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:47 +0800 Message-Id: <20210617110005.4132926-2-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign1 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 01/19] net/ngbe: add build and doc infrastructure X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Adding bare minimum PMD library and doc build infrastructure and claim the maintainership for ngbe PMD. Signed-off-by: Jiawen Wu --- MAINTAINERS | 6 +++++ doc/guides/nics/features/ngbe.ini | 10 +++++++++ doc/guides/nics/index.rst | 1 + doc/guides/nics/ngbe.rst | 31 ++++++++++++++++++++++++++ doc/guides/rel_notes/release_21_08.rst | 6 +++++ drivers/net/meson.build | 1 + drivers/net/ngbe/meson.build | 12 ++++++++++ drivers/net/ngbe/ngbe_ethdev.c | 29 ++++++++++++++++++++++++ drivers/net/ngbe/version.map | 3 +++ 9 files changed, 99 insertions(+) create mode 100644 doc/guides/nics/features/ngbe.ini create mode 100644 doc/guides/nics/ngbe.rst create mode 100644 drivers/net/ngbe/meson.build create mode 100644 drivers/net/ngbe/ngbe_ethdev.c create mode 100644 drivers/net/ngbe/version.map diff --git a/MAINTAINERS b/MAINTAINERS index 5877a16971..b3574c9b49 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -896,6 +896,12 @@ F: drivers/net/sfc/ F: doc/guides/nics/sfc_efx.rst F: doc/guides/nics/features/sfc.ini +Wangxun ngbe +M: Jiawen Wu +F: drivers/net/ngbe/ +F: doc/guides/nics/ngbe.rst +F: doc/guides/nics/features/ngbe.ini + Wangxun txgbe M: Jiawen Wu M: Jian Wang diff --git a/doc/guides/nics/features/ngbe.ini b/doc/guides/nics/features/ngbe.ini new file mode 100644 index 0000000000..a7a524defc --- /dev/null +++ b/doc/guides/nics/features/ngbe.ini @@ -0,0 +1,10 @@ +; +; Supported features of the 'ngbe' network poll mode driver. +; +; Refer to default.ini for the full list of available PMD features. +; +[Features] +Linux = Y +ARMv8 = Y +x86-32 = Y +x86-64 = Y diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst index 799697caf0..31a3e6bcdc 100644 --- a/doc/guides/nics/index.rst +++ b/doc/guides/nics/index.rst @@ -47,6 +47,7 @@ Network Interface Controller Drivers netvsc nfb nfp + ngbe null octeontx octeontx2 diff --git a/doc/guides/nics/ngbe.rst b/doc/guides/nics/ngbe.rst new file mode 100644 index 0000000000..37502627a3 --- /dev/null +++ b/doc/guides/nics/ngbe.rst @@ -0,0 +1,31 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + +NGBE Poll Mode Driver +====================== + +The NGBE PMD (librte_pmd_ngbe) provides poll mode driver support +for Wangxun 1 Gigabit Ethernet NICs. + + +Prerequisites +------------- + +- Learning about Wangxun 1 Gigabit Ethernet NICs using + ``_. + +- Follow the DPDK :ref:`Getting Started Guide for Linux ` to setup the basic DPDK environment. + + +Driver compilation and testing +------------------------------ + +Refer to the document :ref:`compiling and testing a PMD for a NIC ` +for details. + + +Limitations or Known issues +--------------------------- + +Build with ICC is not supported yet. +Power8, ARMv7 and BSD are not supported yet. diff --git a/doc/guides/rel_notes/release_21_08.rst b/doc/guides/rel_notes/release_21_08.rst index a6ecfdf3ce..2deac4f398 100644 --- a/doc/guides/rel_notes/release_21_08.rst +++ b/doc/guides/rel_notes/release_21_08.rst @@ -55,6 +55,12 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Added Wangxun ngbe PMD.** + + Added a new PMD driver for Wangxun 1 Gigabit Ethernet NICs. + + See the :doc:`../nics/ngbe` for more details. + Removed Items ------------- diff --git a/drivers/net/meson.build b/drivers/net/meson.build index c8b5ce2980..d6c1751540 100644 --- a/drivers/net/meson.build +++ b/drivers/net/meson.build @@ -40,6 +40,7 @@ drivers = [ 'netvsc', 'nfb', 'nfp', + 'ngbe', 'null', 'octeontx', 'octeontx2', diff --git a/drivers/net/ngbe/meson.build b/drivers/net/ngbe/meson.build new file mode 100644 index 0000000000..de2d7be716 --- /dev/null +++ b/drivers/net/ngbe/meson.build @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + +if is_windows + build = false + reason = 'not supported on Windows' + subdir_done() +endif + +sources = files( + 'ngbe_ethdev.c', +) diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c new file mode 100644 index 0000000000..f8e19066de --- /dev/null +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#include +#include +#include + +static int +eth_ngbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, + struct rte_pci_device *pci_dev) +{ + RTE_SET_USED(pci_dev); + return -EINVAL; +} + +static int eth_ngbe_pci_remove(struct rte_pci_device *pci_dev) +{ + RTE_SET_USED(pci_dev); + return -EINVAL; +} + +static struct rte_pci_driver rte_ngbe_pmd = { + .probe = eth_ngbe_pci_probe, + .remove = eth_ngbe_pci_remove, +}; + +RTE_PMD_REGISTER_PCI(net_ngbe, rte_ngbe_pmd); diff --git a/drivers/net/ngbe/version.map b/drivers/net/ngbe/version.map new file mode 100644 index 0000000000..4a76d1d52d --- /dev/null +++ b/drivers/net/ngbe/version.map @@ -0,0 +1,3 @@ +DPDK_21 { + local: *; +}; From patchwork Thu Jun 17 10:59:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94327 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 53B92A0C4D; Thu, 17 Jun 2021 12:58:24 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6EE43410EF; Thu, 17 Jun 2021 12:58:16 +0200 (CEST) Received: from smtpbgau1.qq.com (smtpbgau1.qq.com [54.206.16.166]) by mails.dpdk.org (Postfix) with ESMTP id D095740150 for ; Thu, 17 Jun 2021 12:58:12 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927486tmnck5nk Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:06 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: YKCDl5A3/arQbc4jGmmEoxO/ILVazIaivF3YH6Ar+7gcJvyo65JBoBrkZM5xA +4rFIFHqRsxniWrNZfE0yIAYAN4GaGE0IJsgPZ/AvKW0wZ41h3y7mUYH+5LVTGeTMOSF/cC 0IxS+KJNWou++wKGySABtEKHBkOTJOo/q0iaZtDpCbMMsk/DusT2goFeRkrZBzSwsrpA2QH fR4eCoX0oVE0KfVnNIrOvX8z0/3vw40xNaS948rDHILOYDHWg4BS/fqqQM/JbvqfudeWhEw 1bg61/MTne6zSeQibXkoFrEXWAAYY9WXUbmscsAMYUywME5iT42pFJs0zXOmJ+K7CpawHS0 TTmbSE663mcPdCfsabp03+t/Vjg4A== X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:48 +0800 Message-Id: <20210617110005.4132926-3-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign1 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 02/19] net/ngbe: support probe and remove X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Add device IDs for Wangxun 1Gb NICs, map device IDs to register ngbe PMD. Add basic PCIe ethdev probe and remove. Signed-off-by: Jiawen Wu --- doc/guides/nics/features/ngbe.ini | 1 + drivers/net/ngbe/base/meson.build | 18 +++++++ drivers/net/ngbe/base/ngbe_devids.h | 83 +++++++++++++++++++++++++++++ drivers/net/ngbe/meson.build | 6 +++ drivers/net/ngbe/ngbe_ethdev.c | 66 +++++++++++++++++++++-- drivers/net/ngbe/ngbe_ethdev.h | 16 ++++++ 6 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 drivers/net/ngbe/base/meson.build create mode 100644 drivers/net/ngbe/base/ngbe_devids.h create mode 100644 drivers/net/ngbe/ngbe_ethdev.h diff --git a/doc/guides/nics/features/ngbe.ini b/doc/guides/nics/features/ngbe.ini index a7a524defc..977286ac04 100644 --- a/doc/guides/nics/features/ngbe.ini +++ b/doc/guides/nics/features/ngbe.ini @@ -4,6 +4,7 @@ ; Refer to default.ini for the full list of available PMD features. ; [Features] +Multiprocess aware = Y Linux = Y ARMv8 = Y x86-32 = Y diff --git a/drivers/net/ngbe/base/meson.build b/drivers/net/ngbe/base/meson.build new file mode 100644 index 0000000000..c5f6467743 --- /dev/null +++ b/drivers/net/ngbe/base/meson.build @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + +sources = [] + +error_cflags = [] + +c_args = cflags +foreach flag: error_cflags + if cc.has_argument(flag) + c_args += flag + endif +endforeach + +base_lib = static_library('ngbe_base', sources, + dependencies: [static_rte_eal, static_rte_ethdev, static_rte_bus_pci], + c_args: c_args) +base_objs = base_lib.extract_all_objects() diff --git a/drivers/net/ngbe/base/ngbe_devids.h b/drivers/net/ngbe/base/ngbe_devids.h new file mode 100644 index 0000000000..eb9a0b231e --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_devids.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + */ + +#ifndef _NGBE_DEVIDS_H_ +#define _NGBE_DEVIDS_H_ + +/* + * Vendor ID + */ +#ifndef PCI_VENDOR_ID_WANGXUN +#define PCI_VENDOR_ID_WANGXUN 0x8088 +#endif + +/* + * Device IDs + */ +#define NGBE_DEV_ID_EM_VF 0x0110 +#define NGBE_SUB_DEV_ID_EM_VF 0x0110 +#define NGBE_DEV_ID_EM 0x0100 +#define NGBE_SUB_DEV_ID_EM_MVL_RGMII 0x0200 +#define NGBE_SUB_DEV_ID_EM_MVL_SFP 0x0403 +#define NGBE_SUB_DEV_ID_EM_RTL_SGMII 0x0410 +#define NGBE_SUB_DEV_ID_EM_YT8521S_SFP 0x0460 + +#define NGBE_DEV_ID_EM_WX1860AL_W 0x0100 +#define NGBE_DEV_ID_EM_WX1860AL_W_VF 0x0110 +#define NGBE_DEV_ID_EM_WX1860A2 0x0101 +#define NGBE_DEV_ID_EM_WX1860A2_VF 0x0111 +#define NGBE_DEV_ID_EM_WX1860A2S 0x0102 +#define NGBE_DEV_ID_EM_WX1860A2S_VF 0x0112 +#define NGBE_DEV_ID_EM_WX1860A4 0x0103 +#define NGBE_DEV_ID_EM_WX1860A4_VF 0x0113 +#define NGBE_DEV_ID_EM_WX1860A4S 0x0104 +#define NGBE_DEV_ID_EM_WX1860A4S_VF 0x0114 +#define NGBE_DEV_ID_EM_WX1860AL2 0x0105 +#define NGBE_DEV_ID_EM_WX1860AL2_VF 0x0115 +#define NGBE_DEV_ID_EM_WX1860AL2S 0x0106 +#define NGBE_DEV_ID_EM_WX1860AL2S_VF 0x0116 +#define NGBE_DEV_ID_EM_WX1860AL4 0x0107 +#define NGBE_DEV_ID_EM_WX1860AL4_VF 0x0117 +#define NGBE_DEV_ID_EM_WX1860AL4S 0x0108 +#define NGBE_DEV_ID_EM_WX1860AL4S_VF 0x0118 +#define NGBE_DEV_ID_EM_WX1860NCSI 0x0109 +#define NGBE_DEV_ID_EM_WX1860NCSI_VF 0x0119 +#define NGBE_DEV_ID_EM_WX1860A1 0x010A +#define NGBE_DEV_ID_EM_WX1860A1_VF 0x011A +#define NGBE_DEV_ID_EM_WX1860A1L 0x010B +#define NGBE_DEV_ID_EM_WX1860A1L_VF 0x011B +#define NGBE_SUB_DEV_ID_EM_ZTE5201_RJ45 0x0100 +#define NGBE_SUB_DEV_ID_EM_SF100F_LP 0x0103 +#define NGBE_SUB_DEV_ID_EM_M88E1512_RJ45 0x0200 +#define NGBE_SUB_DEV_ID_EM_SF100HT 0x0102 +#define NGBE_SUB_DEV_ID_EM_SF200T 0x0201 +#define NGBE_SUB_DEV_ID_EM_SF200HT 0x0202 +#define NGBE_SUB_DEV_ID_EM_SF200T_S 0x0210 +#define NGBE_SUB_DEV_ID_EM_SF200HT_S 0x0220 +#define NGBE_SUB_DEV_ID_EM_SF200HXT 0x0230 +#define NGBE_SUB_DEV_ID_EM_SF400T 0x0401 +#define NGBE_SUB_DEV_ID_EM_SF400HT 0x0402 +#define NGBE_SUB_DEV_ID_EM_M88E1512_SFP 0x0403 +#define NGBE_SUB_DEV_ID_EM_SF400T_S 0x0410 +#define NGBE_SUB_DEV_ID_EM_SF400HT_S 0x0420 +#define NGBE_SUB_DEV_ID_EM_SF400HXT 0x0430 +#define NGBE_SUB_DEV_ID_EM_SF400_OCP 0x0440 +#define NGBE_SUB_DEV_ID_EM_SF400_LY 0x0450 +#define NGBE_SUB_DEV_ID_EM_SF400_LY_YT 0x0470 + +/* Assign excessive id with masks */ +#define NGBE_INTERNAL_MASK 0x000F +#define NGBE_OEM_MASK 0x00F0 +#define NGBE_WOL_SUP_MASK 0x4000 +#define NGBE_NCSI_SUP_MASK 0x8000 + +#define NGBE_INTERNAL_SFP 0x0003 +#define NGBE_OCP_CARD 0x0040 +#define NGBE_LY_M88E1512_SFP 0x0050 +#define NGBE_YT8521S_SFP 0x0060 +#define NGBE_LY_YT8521S_SFP 0x0070 +#define NGBE_WOL_SUP 0x4000 +#define NGBE_NCSI_SUP 0x8000 + +#endif /* _NGBE_DEVIDS_H_ */ diff --git a/drivers/net/ngbe/meson.build b/drivers/net/ngbe/meson.build index de2d7be716..81173fa7f0 100644 --- a/drivers/net/ngbe/meson.build +++ b/drivers/net/ngbe/meson.build @@ -7,6 +7,12 @@ if is_windows subdir_done() endif +subdir('base') +objs = [base_objs] + sources = files( 'ngbe_ethdev.c', ) + +includes += include_directories('base') + diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index f8e19066de..d8df7ef896 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -7,23 +7,81 @@ #include #include +#include +#include "ngbe_ethdev.h" + +/* + * The set of PCI devices this driver supports + */ +static const struct rte_pci_id pci_id_ngbe_map[] = { + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A2) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A2S) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A4) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A4S) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL2) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL2S) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL4) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL4S) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860NCSI) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A1) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A1L) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL_W) }, + { .vendor_id = 0, /* sentinel */ }, +}; + +static int +eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) +{ + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + rte_eth_copy_pci_info(eth_dev, pci_dev); + + return -EINVAL; +} + +static int +eth_ngbe_dev_uninit(struct rte_eth_dev *eth_dev) +{ + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + RTE_SET_USED(eth_dev); + + return -EINVAL; +} + static int eth_ngbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct rte_pci_device *pci_dev) { - RTE_SET_USED(pci_dev); - return -EINVAL; + return rte_eth_dev_create(&pci_dev->device, pci_dev->device.name, + sizeof(struct ngbe_adapter), + eth_dev_pci_specific_init, pci_dev, + eth_ngbe_dev_init, NULL); } static int eth_ngbe_pci_remove(struct rte_pci_device *pci_dev) { - RTE_SET_USED(pci_dev); - return -EINVAL; + struct rte_eth_dev *ethdev; + + ethdev = rte_eth_dev_allocated(pci_dev->device.name); + if (ethdev == NULL) + return 0; + + return rte_eth_dev_destroy(ethdev, eth_ngbe_dev_uninit); } static struct rte_pci_driver rte_ngbe_pmd = { + .id_table = pci_id_ngbe_map, + .drv_flags = RTE_PCI_DRV_NEED_MAPPING, .probe = eth_ngbe_pci_probe, .remove = eth_ngbe_pci_remove, }; RTE_PMD_REGISTER_PCI(net_ngbe, rte_ngbe_pmd); +RTE_PMD_REGISTER_PCI_TABLE(net_ngbe, pci_id_ngbe_map); +RTE_PMD_REGISTER_KMOD_DEP(net_ngbe, "* igb_uio | uio_pci_generic | vfio-pci"); + diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h new file mode 100644 index 0000000000..38f55f7fb1 --- /dev/null +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _NGBE_ETHDEV_H_ +#define _NGBE_ETHDEV_H_ + +/* + * Structure to store private data for each driver instance (for each port). + */ +struct ngbe_adapter { + void *back; +}; + +#endif /* _NGBE_ETHDEV_H_ */ From patchwork Thu Jun 17 10:59:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94328 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 06865A0C4D; Thu, 17 Jun 2021 12:58:31 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 86A5D410F6; Thu, 17 Jun 2021 12:58:17 +0200 (CEST) Received: from smtpproxy21.qq.com (smtpbg704.qq.com [203.205.195.105]) by mails.dpdk.org (Postfix) with ESMTP id 10922410EC for ; Thu, 17 Jun 2021 12:58:15 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927488toqh6x52 Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:08 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: PXOtw599/AZY25nWjLXFqs6pT2KubEwx+5LbNpz/6LBE4WLAx8eH7v1sGDONH qTmoPfRZp9CFR3JIYHYKkb0TsP0Y72sAsDxxY6LkzPR9G5WLP3PyeLwkc8SxG6VkBCjq8IZ GGdhooHhRBZwvuPFXDwBRXmPxYCAUYldacT0+m5VC9bQbr8wg0/gfIVv6rQn35pCAJfqbUM 2WxMz0bFDqbIDoUG7/wpSA3Y4PeWFhakWitm66d0k3CX2TJ82LFlL4adh3N16BJuGBVuYvx rnhhW+w4f2o7dHwU8jPyquN4Kvy7qoxlFVN+jPskZGOcBo+z5MDVZBM9xXa+DpSyS+l+T8J oQC298/InbeTUO0+tHA4ohuUq/CdA== X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:49 +0800 Message-Id: <20210617110005.4132926-4-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign2 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 03/19] net/ngbe: add log type and error type X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Add log type and error type to trace functions. Signed-off-by: Jiawen Wu --- doc/guides/nics/ngbe.rst | 21 +++++++++ drivers/net/ngbe/base/ngbe_status.h | 73 +++++++++++++++++++++++++++++ drivers/net/ngbe/ngbe_ethdev.c | 14 ++++++ drivers/net/ngbe/ngbe_logs.h | 46 ++++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 drivers/net/ngbe/base/ngbe_status.h create mode 100644 drivers/net/ngbe/ngbe_logs.h diff --git a/doc/guides/nics/ngbe.rst b/doc/guides/nics/ngbe.rst index 37502627a3..54d0665db9 100644 --- a/doc/guides/nics/ngbe.rst +++ b/doc/guides/nics/ngbe.rst @@ -17,6 +17,27 @@ Prerequisites - Follow the DPDK :ref:`Getting Started Guide for Linux ` to setup the basic DPDK environment. +Pre-Installation Configuration +------------------------------ + +Dynamic Logging Parameters +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +One may leverage EAL option "--log-level" to change default levels +for the log types supported by the driver. The option is used with +an argument typically consisting of two parts separated by a colon. + +NGBE PMD provides the following log types available for control: + +- ``pmd.net.ngbe.driver`` (default level is **notice**) + + Affects driver-wide messages unrelated to any particular devices. + +- ``pmd.net.ngbe.init`` (default level is **notice**) + + Extra logging of the messages during PMD initialization. + + Driver compilation and testing ------------------------------ diff --git a/drivers/net/ngbe/base/ngbe_status.h b/drivers/net/ngbe/base/ngbe_status.h new file mode 100644 index 0000000000..917b7da8aa --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_status.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _NGBE_STATUS_H_ +#define _NGBE_STATUS_H_ + +/* Error Codes: + * common error + * module error(simple) + * module error(detailed) + * + * (-256, 256): reserved for non-ngbe defined error code + */ +#define TERR_BASE (0x100) + +/* WARNING: just for legacy compatibility */ +#define NGBE_NOT_IMPLEMENTED 0x7FFFFFFF +#define NGBE_ERR_OPS_DUMMY 0x3FFFFFFF + +/* Error Codes */ +#define NGBE_ERR_EEPROM -(TERR_BASE + 1) +#define NGBE_ERR_EEPROM_CHECKSUM -(TERR_BASE + 2) +#define NGBE_ERR_PHY -(TERR_BASE + 3) +#define NGBE_ERR_CONFIG -(TERR_BASE + 4) +#define NGBE_ERR_PARAM -(TERR_BASE + 5) +#define NGBE_ERR_MAC_TYPE -(TERR_BASE + 6) +#define NGBE_ERR_UNKNOWN_PHY -(TERR_BASE + 7) +#define NGBE_ERR_LINK_SETUP -(TERR_BASE + 8) +#define NGBE_ERR_ADAPTER_STOPPED -(TERR_BASE + 9) +#define NGBE_ERR_INVALID_MAC_ADDR -(TERR_BASE + 10) +#define NGBE_ERR_DEVICE_NOT_SUPPORTED -(TERR_BASE + 11) +#define NGBE_ERR_MASTER_REQUESTS_PENDING -(TERR_BASE + 12) +#define NGBE_ERR_INVALID_LINK_SETTINGS -(TERR_BASE + 13) +#define NGBE_ERR_AUTONEG_NOT_COMPLETE -(TERR_BASE + 14) +#define NGBE_ERR_RESET_FAILED -(TERR_BASE + 15) +#define NGBE_ERR_SWFW_SYNC -(TERR_BASE + 16) +#define NGBE_ERR_PHY_ADDR_INVALID -(TERR_BASE + 17) +#define NGBE_ERR_I2C -(TERR_BASE + 18) +#define NGBE_ERR_SFP_NOT_SUPPORTED -(TERR_BASE + 19) +#define NGBE_ERR_SFP_NOT_PRESENT -(TERR_BASE + 20) +#define NGBE_ERR_SFP_NO_INIT_SEQ_PRESENT -(TERR_BASE + 21) +#define NGBE_ERR_NO_SAN_ADDR_PTR -(TERR_BASE + 22) +#define NGBE_ERR_FDIR_REINIT_FAILED -(TERR_BASE + 23) +#define NGBE_ERR_EEPROM_VERSION -(TERR_BASE + 24) +#define NGBE_ERR_NO_SPACE -(TERR_BASE + 25) +#define NGBE_ERR_OVERTEMP -(TERR_BASE + 26) +#define NGBE_ERR_FC_NOT_NEGOTIATED -(TERR_BASE + 27) +#define NGBE_ERR_FC_NOT_SUPPORTED -(TERR_BASE + 28) +#define NGBE_ERR_SFP_SETUP_NOT_COMPLETE -(TERR_BASE + 30) +#define NGBE_ERR_PBA_SECTION -(TERR_BASE + 31) +#define NGBE_ERR_INVALID_ARGUMENT -(TERR_BASE + 32) +#define NGBE_ERR_HOST_INTERFACE_COMMAND -(TERR_BASE + 33) +#define NGBE_ERR_OUT_OF_MEM -(TERR_BASE + 34) +#define NGBE_ERR_FEATURE_NOT_SUPPORTED -(TERR_BASE + 36) +#define NGBE_ERR_EEPROM_PROTECTED_REGION -(TERR_BASE + 37) +#define NGBE_ERR_FDIR_CMD_INCOMPLETE -(TERR_BASE + 38) +#define NGBE_ERR_FW_RESP_INVALID -(TERR_BASE + 39) +#define NGBE_ERR_TOKEN_RETRY -(TERR_BASE + 40) +#define NGBE_ERR_FLASH_LOADING_FAILED -(TERR_BASE + 41) + +#define NGBE_ERR_NOSUPP -(TERR_BASE + 42) +#define NGBE_ERR_UNDERTEMP -(TERR_BASE + 43) +#define NGBE_ERR_XPCS_POWER_UP_FAILED -(TERR_BASE + 44) +#define NGBE_ERR_PHY_INIT_NOT_DONE -(TERR_BASE + 45) +#define NGBE_ERR_TIMEOUT -(TERR_BASE + 46) +#define NGBE_ERR_REGISTER -(TERR_BASE + 47) +#define NGBE_ERR_MNG_ACCESS_FAILED -(TERR_BASE + 49) +#define NGBE_ERR_PHY_TYPE -(TERR_BASE + 50) +#define NGBE_ERR_PHY_TIMEOUT -(TERR_BASE + 51) + +#endif /* _NGBE_STATUS_H_ */ diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index d8df7ef896..e05766752a 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -7,6 +7,7 @@ #include #include +#include "ngbe_logs.h" #include #include "ngbe_ethdev.h" @@ -34,6 +35,8 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) { struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); + PMD_INIT_FUNC_TRACE(); + if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; @@ -45,6 +48,8 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) static int eth_ngbe_dev_uninit(struct rte_eth_dev *eth_dev) { + PMD_INIT_FUNC_TRACE(); + if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; @@ -85,3 +90,12 @@ RTE_PMD_REGISTER_PCI(net_ngbe, rte_ngbe_pmd); RTE_PMD_REGISTER_PCI_TABLE(net_ngbe, pci_id_ngbe_map); RTE_PMD_REGISTER_KMOD_DEP(net_ngbe, "* igb_uio | uio_pci_generic | vfio-pci"); +RTE_LOG_REGISTER(ngbe_logtype_init, pmd.net.ngbe.init, NOTICE); +RTE_LOG_REGISTER(ngbe_logtype_driver, pmd.net.ngbe.driver, NOTICE); + +#ifdef RTE_ETHDEV_DEBUG_RX + RTE_LOG_REGISTER(ngbe_logtype_rx, pmd.net.ngbe.rx, DEBUG); +#endif +#ifdef RTE_ETHDEV_DEBUG_TX + RTE_LOG_REGISTER(ngbe_logtype_tx, pmd.net.ngbe.tx, DEBUG); +#endif diff --git a/drivers/net/ngbe/ngbe_logs.h b/drivers/net/ngbe/ngbe_logs.h new file mode 100644 index 0000000000..c5d1ab0930 --- /dev/null +++ b/drivers/net/ngbe/ngbe_logs.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _NGBE_LOGS_H_ +#define _NGBE_LOGS_H_ + +/* + * PMD_USER_LOG: for user + */ +extern int ngbe_logtype_init; +#define PMD_INIT_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, ngbe_logtype_init, \ + "%s(): " fmt "\n", __func__, ##args) + +extern int ngbe_logtype_driver; +#define PMD_DRV_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, ngbe_logtype_driver, \ + "%s(): " fmt "\n", __func__, ##args) + +#ifdef RTE_ETHDEV_DEBUG_RX +extern int ngbe_logtype_rx; +#define PMD_RX_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, ngbe_logtype_rx, \ + "%s(): " fmt "\n", __func__, ##args) +#else +#define PMD_RX_LOG(level, fmt, args...) do { } while (0) +#endif + +#ifdef RTE_ETHDEV_DEBUG_TX +extern int ngbe_logtype_tx; +#define PMD_TX_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, ngbe_logtype_tx, \ + "%s(): " fmt "\n", __func__, ##args) +#else +#define PMD_TX_LOG(level, fmt, args...) do { } while (0) +#endif + +#define TLOG_DEBUG(fmt, args...) PMD_DRV_LOG(DEBUG, fmt, ##args) + +#define DEBUGOUT(fmt, args...) TLOG_DEBUG(fmt, ##args) +#define PMD_INIT_FUNC_TRACE() TLOG_DEBUG(" >>") +#define DEBUGFUNC(fmt) TLOG_DEBUG(fmt) + +#endif /* _NGBE_LOGS_H_ */ From patchwork Thu Jun 17 10:59:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94329 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B010BA0C4D; Thu, 17 Jun 2021 12:58:37 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A30D9410FA; Thu, 17 Jun 2021 12:58:19 +0200 (CEST) Received: from smtpbg511.qq.com (smtpbg511.qq.com [203.205.250.109]) by mails.dpdk.org (Postfix) with ESMTP id A8DFD410EB for ; Thu, 17 Jun 2021 12:58:15 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927490tzqx37fc Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:10 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: xmzaef4TE3f/ThGiewy/0lbpHbnA80l+qPGArs6R0xXrO89mqm8FCfa4DjUh+ 88TpC6s6hwXLBPvEtyeDP5LusgHWv1XbEHgczWqKWRCU4kqydENW1+HmTiM9QBfze1U77lZ FiiIznDD086BuYk0bc+yWOpR1Cu1m9tRvxZ4Y5aWJSC4HIXZiqXuW5U7i8n0vLjl/P2Ve/u EMCrIU2Kvvof04XnYrRn5X8OD5tqJ4DYB7OmRzyCTr4MxRUHu1Dg6Hiq3W6eEt2ceNf3LEw xHPzHH47SpAyueEjTHyGC3OcA2FhGun1WGFqltPrmgDUPYetBv/G+DIR8d5FaGSMymJfe7M MIPZEOUvoqQ3uCjlOw= X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:50 +0800 Message-Id: <20210617110005.4132926-5-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign7 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 04/19] net/ngbe: define registers X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Define all registers that will be used. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/base/ngbe_regs.h | 1490 +++++++++++++++++++++++++++++ 1 file changed, 1490 insertions(+) create mode 100644 drivers/net/ngbe/base/ngbe_regs.h diff --git a/drivers/net/ngbe/base/ngbe_regs.h b/drivers/net/ngbe/base/ngbe_regs.h new file mode 100644 index 0000000000..737bd796a1 --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_regs.h @@ -0,0 +1,1490 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _NGBE_REGS_H_ +#define _NGBE_REGS_H_ + +#define NGBE_PVMBX_QSIZE (16) /* 16*4B */ +#define NGBE_PVMBX_BSIZE (NGBE_PVMBX_QSIZE * 4) + +#define NGBE_REMOVED(a) (0) + +#define NGBE_REG_DUMMY 0xFFFFFF + +#define MS8(shift, mask) (((u8)(mask)) << (shift)) +#define LS8(val, shift, mask) (((u8)(val) & (u8)(mask)) << (shift)) +#define RS8(reg, shift, mask) (((u8)(reg) >> (shift)) & (u8)(mask)) + +#define MS16(shift, mask) (((u16)(mask)) << (shift)) +#define LS16(val, shift, mask) (((u16)(val) & (u16)(mask)) << (shift)) +#define RS16(reg, shift, mask) (((u16)(reg) >> (shift)) & (u16)(mask)) + +#define MS32(shift, mask) (((u32)(mask)) << (shift)) +#define LS32(val, shift, mask) (((u32)(val) & (u32)(mask)) << (shift)) +#define RS32(reg, shift, mask) (((u32)(reg) >> (shift)) & (u32)(mask)) + +#define MS64(shift, mask) (((u64)(mask)) << (shift)) +#define LS64(val, shift, mask) (((u64)(val) & (u64)(mask)) << (shift)) +#define RS64(reg, shift, mask) (((u64)(reg) >> (shift)) & (u64)(mask)) + +#define MS(shift, mask) MS32(shift, mask) +#define LS(val, shift, mask) LS32(val, shift, mask) +#define RS(reg, shift, mask) RS32(reg, shift, mask) + +#define ROUND_UP(x, y) (((x) + (y) - 1) / (y) * (y)) +#define ROUND_DOWN(x, y) ((x) / (y) * (y)) +#define ROUND_OVER(x, maxbits, unitbits) \ + ((x) >= 1 << (maxbits) ? 0 : (x) >> (unitbits)) + +/* autoc bits definition */ +#define NGBE_AUTOC NGBE_REG_DUMMY +#define NGBE_AUTOC_FLU MS64(0, 0x1) +#define NGBE_AUTOC_10G_PMA_PMD_MASK MS64(7, 0x3) /* parallel */ +#define NGBE_AUTOC_10G_XAUI LS64(0, 7, 0x3) +#define NGBE_AUTOC_10G_KX4 LS64(1, 7, 0x3) +#define NGBE_AUTOC_10G_CX4 LS64(2, 7, 0x3) +#define NGBE_AUTOC_10G_KR LS64(3, 7, 0x3) /* fixme */ +#define NGBE_AUTOC_1G_PMA_PMD_MASK MS64(9, 0x7) +#define NGBE_AUTOC_1G_BX LS64(0, 9, 0x7) +#define NGBE_AUTOC_1G_KX LS64(1, 9, 0x7) +#define NGBE_AUTOC_1G_SFI LS64(0, 9, 0x7) +#define NGBE_AUTOC_1G_KX_BX LS64(1, 9, 0x7) +#define NGBE_AUTOC_AN_RESTART MS64(12, 0x1) +#define NGBE_AUTOC_LMS_MASK MS64(13, 0x7) +#define NGBE_AUTOC_LMS_10G LS64(3, 13, 0x7) +#define NGBE_AUTOC_LMS_KX4_KX_KR LS64(4, 13, 0x7) +#define NGBE_AUTOC_LMS_SGMII_1G_100M LS64(5, 13, 0x7) +#define NGBE_AUTOC_LMS_KX4_KX_KR_1G_AN LS64(6, 13, 0x7) +#define NGBE_AUTOC_LMS_KX4_KX_KR_SGMII LS64(7, 13, 0x7) +#define NGBE_AUTOC_LMS_1G_LINK_NO_AN LS64(0, 13, 0x7) +#define NGBE_AUTOC_LMS_10G_LINK_NO_AN LS64(1, 13, 0x7) +#define NGBE_AUTOC_LMS_1G_AN LS64(2, 13, 0x7) +#define NGBE_AUTOC_LMS_KX4_AN LS64(4, 13, 0x7) +#define NGBE_AUTOC_LMS_KX4_AN_1G_AN LS64(6, 13, 0x7) +#define NGBE_AUTOC_LMS_ATTACH_TYPE LS64(7, 13, 0x7) +#define NGBE_AUTOC_LMS_AN MS64(15, 0x7) + +#define NGBE_AUTOC_KR_SUPP MS64(16, 0x1) +#define NGBE_AUTOC_FECR MS64(17, 0x1) +#define NGBE_AUTOC_FECA MS64(18, 0x1) +#define NGBE_AUTOC_AN_RX_ALIGN MS64(18, 0x1F) /* fixme */ +#define NGBE_AUTOC_AN_RX_DRIFT MS64(23, 0x3) +#define NGBE_AUTOC_AN_RX_LOOSE MS64(24, 0x3) +#define NGBE_AUTOC_PD_TMR MS64(25, 0x3) +#define NGBE_AUTOC_RF MS64(27, 0x1) +#define NGBE_AUTOC_ASM_PAUSE MS64(29, 0x1) +#define NGBE_AUTOC_SYM_PAUSE MS64(28, 0x1) +#define NGBE_AUTOC_PAUSE MS64(28, 0x3) +#define NGBE_AUTOC_KX_SUPP MS64(30, 0x1) +#define NGBE_AUTOC_KX4_SUPP MS64(31, 0x1) + +#define NGBE_AUTOC_10GS_PMA_PMD_MASK MS64(48, 0x3) /* serial */ +#define NGBE_AUTOC_10GS_KR LS64(0, 48, 0x3) +#define NGBE_AUTOC_10GS_XFI LS64(1, 48, 0x3) +#define NGBE_AUTOC_10GS_SFI LS64(2, 48, 0x3) +#define NGBE_AUTOC_LINK_DIA_MASK MS64(60, 0x7) +#define NGBE_AUTOC_LINK_DIA_D3_MASK LS64(5, 60, 0x7) + +#define NGBE_AUTOC_SPEED_MASK MS64(32, 0xFFFF) +#define NGBD_AUTOC_SPEED(r) RS64(r, 32, 0xFFFF) +#define NGBE_AUTOC_SPEED(v) LS64(v, 32, 0xFFFF) +#define NGBE_LINK_SPEED_UNKNOWN 0 +#define NGBE_LINK_SPEED_10M_FULL 0x0002 +#define NGBE_LINK_SPEED_100M_FULL 0x0008 +#define NGBE_LINK_SPEED_1GB_FULL 0x0020 +#define NGBE_LINK_SPEED_2_5GB_FULL 0x0400 +#define NGBE_LINK_SPEED_5GB_FULL 0x0800 +#define NGBE_LINK_SPEED_10GB_FULL 0x0080 +#define NGBE_LINK_SPEED_40GB_FULL 0x0100 +#define NGBE_AUTOC_AUTONEG MS64(63, 0x1) + + + +/* Hardware Datapath: + * RX: / Queue <- Filter \ + * Host | TC <=> SEC <=> MAC <=> PHY + * TX: \ Queue -> Filter / + * + * Packet Filter: + * RX: RSS < FDIR < Filter < Encrypt + * + * Macro Argument Naming: + * rp = ring pair [0,127] + * tc = traffic class [0,7] + * up = user priority [0,7] + * pi = pool index [0,63] + * r = register + * v = value + * s = shift + * m = mask + * i,j,k = array index + * H,L = high/low bits + * HI,LO = high/low state + */ + +#define NGBE_ETHPHYIF NGBE_REG_DUMMY +#define NGBE_ETHPHYIF_MDIO_ACT MS(1, 0x1) +#define NGBE_ETHPHYIF_MDIO_MODE MS(2, 0x1) +#define NGBE_ETHPHYIF_MDIO_BASE(r) RS(r, 3, 0x1F) +#define NGBE_ETHPHYIF_MDIO_SHARED MS(13, 0x1) +#define NGBE_ETHPHYIF_SPEED_10M MS(17, 0x1) +#define NGBE_ETHPHYIF_SPEED_100M MS(18, 0x1) +#define NGBE_ETHPHYIF_SPEED_1G MS(19, 0x1) +#define NGBE_ETHPHYIF_SPEED_2_5G MS(20, 0x1) +#define NGBE_ETHPHYIF_SPEED_10G MS(21, 0x1) +#define NGBE_ETHPHYIF_SGMII_ENABLE MS(25, 0x1) +#define NGBE_ETHPHYIF_INT_PHY_MODE MS(24, 0x1) +#define NGBE_ETHPHYIF_IO_XPCS MS(30, 0x1) +#define NGBE_ETHPHYIF_IO_EPHY MS(31, 0x1) + +/****************************************************************************** + * Chip Registers + ******************************************************************************/ +/** + * Chip Status + **/ +#define NGBE_PWR 0x010000 +#define NGBE_PWR_LAN(r) RS(r, 28, 0xC) +#define NGBE_PWR_LAN_0 (1) +#define NGBE_PWR_LAN_1 (2) +#define NGBE_PWR_LAN_2 (3) +#define NGBE_PWR_LAN_3 (4) +#define NGBE_CTL 0x010004 +#define NGBE_LOCKPF 0x010008 +#define NGBE_RST 0x01000C +#define NGBE_RST_SW MS(0, 0x1) +#define NGBE_RST_LAN(i) MS(((i) + 1), 0x1) +#define NGBE_RST_FW MS(5, 0x1) +#define NGBE_RST_ETH(i) MS(((i) + 29), 0x1) +#define NGBE_RST_GLB MS(31, 0x1) +#define NGBE_RST_DEFAULT (NGBE_RST_SW | \ + NGBE_RST_LAN(0) | \ + NGBE_RST_LAN(1) | \ + NGBE_RST_LAN(2) | \ + NGBE_RST_LAN(3)) +#define NGBE_PROB 0x010010 +#define NGBE_IODRV 0x010024 +#define NGBE_STAT 0x010028 +#define NGBE_STAT_MNGINIT MS(0, 0x1) +#define NGBE_STAT_MNGVETO MS(8, 0x1) +#define NGBE_STAT_ECCLAN0 MS(16, 0x1) +#define NGBE_STAT_ECCLAN1 MS(17, 0x1) +#define NGBE_STAT_ECCLAN2 MS(18, 0x1) +#define NGBE_STAT_ECCLAN3 MS(19, 0x1) +#define NGBE_STAT_ECCMNG MS(20, 0x1) +#define NGBE_STAT_ECCPCORE MS(21, 0X1) +#define NGBE_STAT_ECCPCIW MS(22, 0x1) +#define NGBE_STAT_ECCPCIEPHY MS(23, 0x1) +#define NGBE_STAT_ECCFMGR MS(24, 0x1) +#define NGBE_STAT_GPHY_IN_RST(i) MS(((i) + 9), 0x1) +#define NGBE_RSTSTAT 0x010030 +#define NGBE_RSTSTAT_PROG MS(20, 0x1) +#define NGBE_RSTSTAT_PREP MS(19, 0x1) +#define NGBE_RSTSTAT_TYPE_MASK MS(16, 0x7) +#define NGBE_RSTSTAT_TYPE(r) RS(r, 16, 0x7) +#define NGBE_RSTSTAT_TYPE_PE LS(0, 16, 0x7) +#define NGBE_RSTSTAT_TYPE_PWR LS(1, 16, 0x7) +#define NGBE_RSTSTAT_TYPE_HOT LS(2, 16, 0x7) +#define NGBE_RSTSTAT_TYPE_SW LS(3, 16, 0x7) +#define NGBE_RSTSTAT_TYPE_FW LS(4, 16, 0x7) +#define NGBE_RSTSTAT_TMRINIT_MASK MS(8, 0xFF) +#define NGBE_RSTSTAT_TMRINIT(v) LS(v, 8, 0xFF) +#define NGBE_RSTSTAT_TMRCNT_MASK MS(0, 0xFF) +#define NGBE_RSTSTAT_TMRCNT(v) LS(v, 0, 0xFF) +#define NGBE_PWRTMR 0x010034 + +/** + * SPI(Flash) + **/ +#define NGBE_SPICMD 0x010104 +#define NGBE_SPICMD_ADDR(v) LS(v, 0, 0xFFFFFF) +#define NGBE_SPICMD_CLK(v) LS(v, 25, 0x7) +#define NGBE_SPICMD_CMD(v) LS(v, 28, 0x7) +#define NGBE_SPIDAT 0x010108 +#define NGBE_SPIDAT_BYPASS MS(31, 0x1) +#define NGBE_SPIDAT_STATUS(v) LS(v, 16, 0xFF) +#define NGBE_SPIDAT_OPDONE MS(0, 0x1) +#define NGBE_SPISTAT 0x01010C +#define NGBE_SPISTAT_OPDONE MS(0, 0x1) +#define NGBE_SPISTAT_BPFLASH MS(31, 0x1) +#define NGBE_SPIUSRCMD 0x010110 +#define NGBE_SPICFG0 0x010114 +#define NGBE_SPICFG1 0x010118 + +/* FMGR Registers */ +#define NGBE_ILDRSTAT 0x010120 +#define NGBE_ILDRSTAT_PCIRST MS(0, 0x1) +#define NGBE_ILDRSTAT_PWRRST MS(1, 0x1) +#define NGBE_ILDRSTAT_SWRST MS(11, 0x1) +#define NGBE_ILDRSTAT_SWRST_LAN0 MS(13, 0x1) +#define NGBE_ILDRSTAT_SWRST_LAN1 MS(14, 0x1) +#define NGBE_ILDRSTAT_SWRST_LAN2 MS(15, 0x1) +#define NGBE_ILDRSTAT_SWRST_LAN3 MS(16, 0x1) + +#define NGBE_SRAM 0x010124 +#define NGBE_SRAM_SZ(v) LS(v, 28, 0x7) +#define NGBE_SRAMCTLECC 0x010130 +#define NGBE_SRAMINJECC 0x010134 +#define NGBE_SRAMECC 0x010138 + +/* Sensors for PVT(Process Voltage Temperature) */ +#define NGBE_TSCTRL 0x010300 +#define NGBE_TSCTRL_EVALMD MS(31, 0x1) +#define NGBE_TSEN 0x010304 +#define NGBE_TSEN_ENA MS(0, 0x1) +#define NGBE_TSSTAT 0x010308 +#define NGBE_TSSTAT_VLD MS(16, 0x1) +#define NGBE_TSSTAT_DATA(r) RS(r, 0, 0x3FF) +#define NGBE_TSATHRE 0x01030C +#define NGBE_TSDTHRE 0x010310 +#define NGBE_TSINTR 0x010314 +#define NGBE_TSINTR_AEN MS(0, 0x1) +#define NGBE_TSINTR_DEN MS(1, 0x1) +#define NGBE_TSALM 0x010318 +#define NGBE_TSALM_LO MS(0, 0x1) +#define NGBE_TSALM_HI MS(1, 0x1) + +#define NGBE_EFUSE_WDATA0 0x010320 +#define NGBE_EFUSE_WDATA1 0x010324 +#define NGBE_EFUSE_RDATA0 0x010328 +#define NGBE_EFUSE_RDATA1 0x01032C +#define NGBE_EFUSE_STATUS 0x010330 + +/****************************************************************************** + * Port Registers + ******************************************************************************/ +/* Internal PHY reg_offset [0,31] */ +#define NGBE_PHY_CONFIG(reg_offset) (0x014000 + (reg_offset) * 4) + +/* Port Control */ +#define NGBE_PORTCTL 0x014400 +#define NGBE_PORTCTL_VLANEXT MS(0, 0x1) +#define NGBE_PORTCTL_ETAG MS(1, 0x1) +#define NGBE_PORTCTL_QINQ MS(2, 0x1) +#define NGBE_PORTCTL_DRVLOAD MS(3, 0x1) +#define NGBE_PORTCTL_NUMVT_MASK MS(12, 0x1) +#define NGBE_PORTCTL_NUMVT_8 LS(1, 12, 0x1) +#define NGBE_PORTCTL_RSTDONE MS(14, 0x1) +#define NGBE_PORTCTL_TEREDODIA MS(27, 0x1) +#define NGBE_PORTCTL_GENEVEDIA MS(28, 0x1) +#define NGBE_PORTCTL_VXLANGPEDIA MS(30, 0x1) +#define NGBE_PORTCTL_VXLANDIA MS(31, 0x1) + +/* Port Status */ +#define NGBE_PORTSTAT 0x014404 +#define NGBE_PORTSTAT_BW_MASK MS(1, 0x7) +#define NGBE_PORTSTAT_BW_1G MS(1, 0x1) +#define NGBE_PORTSTAT_BW_100M MS(2, 0x1) +#define NGBE_PORTSTAT_BW_10M MS(3, 0x1) +#define NGBE_PORTSTAT_ID(r) RS(r, 8, 0x3) + +#define NGBE_EXTAG 0x014408 +#define NGBE_EXTAG_ETAG_MASK MS(0, 0xFFFF) +#define NGBE_EXTAG_ETAG(v) LS(v, 0, 0xFFFF) +#define NGBE_EXTAG_VLAN_MASK MS(16, 0xFFFF) +#define NGBE_EXTAG_VLAN(v) LS(v, 16, 0xFFFF) + +#define NGBE_TCPTIME 0x014420 + +#define NGBE_LEDCTL 0x014424 +#define NGBE_LEDCTL_SEL(s) MS((s), 0x1) +#define NGBE_LEDCTL_OD(s) MS(((s) + 16), 0x1) + /* s=1G(1),100M(2),10M(3) */ +#define NGBE_LEDCTL_100M (NGBE_LEDCTL_SEL(2) | NGBE_LEDCTL_OD(2)) + +#define NGBE_TAGTPID(i) (0x014430 + (i) * 4) /*0-3*/ +#define NGBE_TAGTPID_LSB_MASK MS(0, 0xFFFF) +#define NGBE_TAGTPID_LSB(v) LS(v, 0, 0xFFFF) +#define NGBE_TAGTPID_MSB_MASK MS(16, 0xFFFF) +#define NGBE_TAGTPID_MSB(v) LS(v, 16, 0xFFFF) + +#define NGBE_LAN_SPEED 0x014440 +#define NGBE_LAN_SPEED_MASK MS(0, 0x3) + +/* GPIO Registers */ +#define NGBE_GPIODATA 0x014800 +#define NGBE_GPIOBIT_0 MS(0, 0x1) /* O:tx fault */ +#define NGBE_GPIOBIT_1 MS(1, 0x1) /* O:tx disabled */ +#define NGBE_GPIOBIT_2 MS(2, 0x1) /* I:sfp module absent */ +#define NGBE_GPIOBIT_3 MS(3, 0x1) /* I:rx signal lost */ +#define NGBE_GPIOBIT_4 MS(4, 0x1) /* O:rate select, 1G(0) 10G(1) */ +#define NGBE_GPIOBIT_5 MS(5, 0x1) /* O:rate select, 1G(0) 10G(1) */ +#define NGBE_GPIOBIT_6 MS(6, 0x1) /* I:ext phy interrupt */ +#define NGBE_GPIOBIT_7 MS(7, 0x1) /* I:fan speed alarm */ +#define NGBE_GPIODIR 0x014804 +#define NGBE_GPIODIR_DDR(v) LS(v, 0, 0x3) +#define NGBE_GPIOCTL 0x014808 +#define NGBE_GPIOINTEN 0x014830 +#define NGBE_GPIOINTEN_INT(v) LS(v, 0, 0x3) +#define NGBE_GPIOINTMASK 0x014834 +#define NGBE_GPIOINTTYPE 0x014838 +#define NGBE_GPIOINTTYPE_LEVEL(v) LS(v, 0, 0x3) +#define NGBE_GPIOINTPOL 0x01483C +#define NGBE_GPIOINTPOL_ACT(v) LS(v, 0, 0x3) +#define NGBE_GPIOINTSTAT 0x014840 +#define NGBE_GPIOINTDB 0x014848 +#define NGBE_GPIOEOI 0x01484C +#define NGBE_GPIODAT 0x014850 + +/* TPH */ +#define NGBE_TPHCFG 0x014F00 + +/****************************************************************************** + * Transmit DMA Registers + ******************************************************************************/ +/* TDMA Control */ +#define NGBE_DMATXCTRL 0x018000 +#define NGBE_DMATXCTRL_ENA MS(0, 0x1) +#define NGBE_DMATXCTRL_TPID_MASK MS(16, 0xFFFF) +#define NGBE_DMATXCTRL_TPID(v) LS(v, 16, 0xFFFF) +#define NGBE_POOLTXENA(i) (0x018004 + (i) * 4) /*0*/ +#define NGBE_PRBTXDMACTL 0x018010 +#define NGBE_ECCTXDMACTL 0x018014 +#define NGBE_ECCTXDMAINJ 0x018018 +#define NGBE_ECCTXDMA 0x01801C +#define NGBE_PBTXDMATH 0x018020 +#define NGBE_QPTXLLI 0x018040 +#define NGBE_POOLTXLBET 0x018050 +#define NGBE_POOLTXASET 0x018058 +#define NGBE_POOLTXASMAC 0x018060 +#define NGBE_POOLTXASVLAN 0x018070 +#define NGBE_POOLTXDSA 0x0180A0 +#define NGBE_POOLTAG(pl) (0x018100 + (pl) * 4) /*0-7*/ +#define NGBE_POOLTAG_VTAG(v) LS(v, 0, 0xFFFF) +#define NGBE_POOLTAG_VTAG_MASK MS(0, 0xFFFF) +#define TXGBD_POOLTAG_VTAG_UP(r) RS(r, 13, 0x7) +#define NGBE_POOLTAG_TPIDSEL(v) LS(v, 24, 0x7) +#define NGBE_POOLTAG_ETAG_MASK MS(27, 0x3) +#define NGBE_POOLTAG_ETAG LS(2, 27, 0x3) +#define NGBE_POOLTAG_ACT_MASK MS(30, 0x3) +#define NGBE_POOLTAG_ACT_ALWAYS LS(1, 30, 0x3) +#define NGBE_POOLTAG_ACT_NEVER LS(2, 30, 0x3) + +/* Queue Arbiter(QoS) */ +#define NGBE_QARBTXCTL 0x018200 +#define NGBE_QARBTXCTL_DA MS(6, 0x1) +#define NGBE_QARBTXRATE 0x018404 +#define NGBE_QARBTXRATE_MIN(v) LS(v, 0, 0x3FFF) +#define NGBE_QARBTXRATE_MAX(v) LS(v, 16, 0x3FFF) + +/* ETAG */ +#define NGBE_POOLETAG(pl) (0x018700 + (pl) * 4) + +/****************************************************************************** + * Receive DMA Registers + ******************************************************************************/ +/* Receive Control */ +#define NGBE_ARBRXCTL 0x012000 +#define NGBE_ARBRXCTL_DIA MS(6, 0x1) +#define NGBE_POOLRXENA(i) (0x012004 + (i) * 4) /*0*/ +#define NGBE_PRBRDMA 0x012010 +#define NGBE_ECCRXDMACTL 0x012014 +#define NGBE_ECCRXDMAINJ 0x012018 +#define NGBE_ECCRXDMA 0x01201C +#define NGBE_POOLRXDNA 0x0120A0 +#define NGBE_QPRXDROP 0x012080 +#define NGBE_QPRXSTRPVLAN 0x012090 + +/****************************************************************************** + * Packet Buffer + ******************************************************************************/ +/* Flow Control */ +#define NGBE_FCXOFFTM 0x019200 +#define NGBE_FCWTRLO 0x019220 +#define NGBE_FCWTRLO_TH(v) LS(v, 10, 0x1FF) /*KB*/ +#define NGBE_FCWTRLO_XON MS(31, 0x1) +#define NGBE_FCWTRHI 0x019260 +#define NGBE_FCWTRHI_TH(v) LS(v, 10, 0x1FF) /*KB*/ +#define NGBE_FCWTRHI_XOFF MS(31, 0x1) +#define NGBE_RXFCRFSH 0x0192A0 +#define NGBE_RXFCFSH_TIME(v) LS(v, 0, 0xFFFF) +#define NGBE_FCSTAT 0x01CE00 +#define NGBE_FCSTAT_DLNK MS(0, 0x1) +#define NGBE_FCSTAT_ULNK MS(8, 0x1) + +#define NGBE_RXFCCFG 0x011090 +#define NGBE_RXFCCFG_FC MS(0, 0x1) +#define NGBE_TXFCCFG 0x0192A4 +#define NGBE_TXFCCFG_FC MS(3, 0x1) + +/* Data Buffer */ +#define NGBE_PBRXCTL 0x019000 +#define NGBE_PBRXCTL_ST MS(0, 0x1) +#define NGBE_PBRXCTL_ENA MS(31, 0x1) +#define NGBE_PBRXSTAT 0x019004 +#define NGBE_PBRXSIZE 0x019020 +#define NGBE_PBRXSIZE_KB(v) LS(v, 10, 0x3F) + +#define NGBE_PBRXOFTMR 0x019094 +#define NGBE_PBRXDBGCMD 0x019090 +#define NGBE_PBRXDBGDAT 0x0190A0 + +#define NGBE_PBTXSIZE 0x01CC00 + +/* LLI */ +#define NGBE_PBRXLLI 0x19080 +#define NGBE_PBRXLLI_SZLT(v) LS(v, 0, 0xFFF) +#define NGBE_PBRXLLI_UPLT(v) LS(v, 16, 0x7) +#define NGBE_PBRXLLI_UPEA MS(19, 0x1) + +/* Port Arbiter(QoS) */ +#define NGBE_PARBTXCTL 0x01CD00 +#define NGBE_PARBTXCTL_DA MS(6, 0x1) + +/****************************************************************************** + * Packet Filter (L2-7) + ******************************************************************************/ +/** + * Receive Scaling + **/ +#define NGBE_POOLRSS(pl) (0x019300 + (pl) * 4) /*0-7*/ +#define NGBE_POOLRSS_L4HDR MS(1, 0x1) +#define NGBE_POOLRSS_L3HDR MS(2, 0x1) +#define NGBE_POOLRSS_L2HDR MS(3, 0x1) +#define NGBE_POOLRSS_L2TUN MS(4, 0x1) +#define NGBE_POOLRSS_TUNHDR MS(5, 0x1) +#define NGBE_RSSTBL(i) (0x019400 + (i) * 4) /*32*/ +#define NGBE_RSSKEY(i) (0x019480 + (i) * 4) /*10*/ +#define NGBE_RACTL 0x0194F4 +#define NGBE_RACTL_RSSENA MS(2, 0x1) +#define NGBE_RACTL_RSSMASK MS(16, 0xFFFF) +#define NGBE_RACTL_RSSIPV4TCP MS(16, 0x1) +#define NGBE_RACTL_RSSIPV4 MS(17, 0x1) +#define NGBE_RACTL_RSSIPV6 MS(20, 0x1) +#define NGBE_RACTL_RSSIPV6TCP MS(21, 0x1) +#define NGBE_RACTL_RSSIPV4UDP MS(22, 0x1) +#define NGBE_RACTL_RSSIPV6UDP MS(23, 0x1) + +/** + * Flow Director + **/ +#define PERFECT_BUCKET_64KB_HASH_MASK 0x07FF /* 11 bits */ +#define PERFECT_BUCKET_128KB_HASH_MASK 0x0FFF /* 12 bits */ +#define PERFECT_BUCKET_256KB_HASH_MASK 0x1FFF /* 13 bits */ +#define SIG_BUCKET_64KB_HASH_MASK 0x1FFF /* 13 bits */ +#define SIG_BUCKET_128KB_HASH_MASK 0x3FFF /* 14 bits */ +#define SIG_BUCKET_256KB_HASH_MASK 0x7FFF /* 15 bits */ + +/** + * 5-tuple Filter + **/ +#define NGBE_5TFPORT(i) (0x019A00 + (i) * 4) /*0-7*/ +#define NGBE_5TFPORT_SRC(v) LS(v, 0, 0xFFFF) +#define NGBE_5TFPORT_DST(v) LS(v, 16, 0xFFFF) +#define NGBE_5TFCTL0(i) (0x019C00 + (i) * 4) /*0-7*/ +#define NGBE_5TFCTL0_PROTO(v) LS(v, 0, 0x3) +enum ngbe_5tuple_protocol { + NGBE_5TF_PROT_TCP = 0, + NGBE_5TF_PROT_UDP, + NGBE_5TF_PROT_SCTP, + NGBE_5TF_PROT_NONE, +}; +#define NGBE_5TFCTL0_PRI(v) LS(v, 2, 0x7) +#define NGBE_5TFCTL0_POOL(v) LS(v, 8, 0x7) +#define NGBE_5TFCTL0_MASK MS(27, 0xF) +#define NGBE_5TFCTL0_MSPORT MS(27, 0x1) +#define NGBE_5TFCTL0_MDPORT MS(28, 0x1) +#define NGBE_5TFCTL0_MPROTO MS(29, 0x1) +#define NGBE_5TFCTL0_MPOOL MS(30, 0x1) +#define NGBE_5TFCTL0_ENA MS(31, 0x1) +#define NGBE_5TFCTL1(i) (0x019E00 + (i) * 4) /*0-7*/ +#define NGBE_5TFCTL1_CHKSZ MS(12, 0x1) +#define NGBE_5TFCTL1_LLI MS(20, 0x1) +#define NGBE_5TFCTL1_QP(v) LS(v, 21, 0x7) + +/** + * Storm Control + **/ +#define NGBE_STRMCTL 0x015004 +#define NGBE_STRMCTL_MCPNSH MS(0, 0x1) +#define NGBE_STRMCTL_MCDROP MS(1, 0x1) +#define NGBE_STRMCTL_BCPNSH MS(2, 0x1) +#define NGBE_STRMCTL_BCDROP MS(3, 0x1) +#define NGBE_STRMCTL_DFTPOOL MS(4, 0x1) +#define NGBE_STRMCTL_ITVL(v) LS(v, 8, 0x3FF) +#define NGBE_STRMTH 0x015008 +#define NGBE_STRMTH_MC(v) LS(v, 0, 0xFFFF) +#define NGBE_STRMTH_BC(v) LS(v, 16, 0xFFFF) + +/****************************************************************************** + * Ether Flow + ******************************************************************************/ +#define NGBE_PSRCTL 0x015000 +#define NGBE_PSRCTL_TPE MS(4, 0x1) +#define NGBE_PSRCTL_ADHF12_MASK MS(5, 0x3) +#define NGBE_PSRCTL_ADHF12(v) LS(v, 5, 0x3) +#define NGBE_PSRCTL_UCHFENA MS(7, 0x1) +#define NGBE_PSRCTL_MCHFENA MS(7, 0x1) +#define NGBE_PSRCTL_MCP MS(8, 0x1) +#define NGBE_PSRCTL_UCP MS(9, 0x1) +#define NGBE_PSRCTL_BCA MS(10, 0x1) +#define NGBE_PSRCTL_L4CSUM MS(12, 0x1) +#define NGBE_PSRCTL_PCSD MS(13, 0x1) +#define NGBE_PSRCTL_LBENA MS(18, 0x1) +#define NGBE_FRMSZ 0x015020 +#define NGBE_FRMSZ_MAX_MASK MS(0, 0xFFFF) +#define NGBE_FRMSZ_MAX(v) LS(v, 0, 0xFFFF) +#define NGBE_VLANCTL 0x015088 +#define NGBE_VLANCTL_TPID_MASK MS(0, 0xFFFF) +#define NGBE_VLANCTL_TPID(v) LS(v, 0, 0xFFFF) +#define NGBE_VLANCTL_CFI MS(28, 0x1) +#define NGBE_VLANCTL_CFIENA MS(29, 0x1) +#define NGBE_VLANCTL_VFE MS(30, 0x1) +#define NGBE_POOLCTL 0x0151B0 +#define NGBE_POOLCTL_DEFDSA MS(29, 0x1) +#define NGBE_POOLCTL_RPLEN MS(30, 0x1) +#define NGBE_POOLCTL_MODE_MASK MS(16, 0x3) +#define NGBE_PSRPOOL_MODE_MAC LS(0, 16, 0x3) +#define NGBE_PSRPOOL_MODE_ETAG LS(1, 16, 0x3) +#define NGBE_POOLCTL_DEFPL(v) LS(v, 7, 0x7) +#define NGBE_POOLCTL_DEFPL_MASK MS(7, 0x7) + +#define NGBE_ETFLT(i) (0x015128 + (i) * 4) /*0-7*/ +#define NGBE_ETFLT_ETID(v) LS(v, 0, 0xFFFF) +#define NGBE_ETFLT_ETID_MASK MS(0, 0xFFFF) +#define NGBE_ETFLT_POOL(v) LS(v, 20, 0x7) +#define NGBE_ETFLT_POOLENA MS(26, 0x1) +#define NGBE_ETFLT_TXAS MS(29, 0x1) +#define NGBE_ETFLT_1588 MS(30, 0x1) +#define NGBE_ETFLT_ENA MS(31, 0x1) +#define NGBE_ETCLS(i) (0x019100 + (i) * 4) /*0-7*/ +#define NGBE_ETCLS_QPID(v) LS(v, 16, 0x7) +#define NGBD_ETCLS_QPID(r) RS(r, 16, 0x7) +#define NGBE_ETCLS_LLI MS(29, 0x1) +#define NGBE_ETCLS_QENA MS(31, 0x1) +#define NGBE_SYNCLS 0x019130 +#define NGBE_SYNCLS_ENA MS(0, 0x1) +#define NGBE_SYNCLS_QPID(v) LS(v, 1, 0x7) +#define NGBD_SYNCLS_QPID(r) RS(r, 1, 0x7) +#define NGBE_SYNCLS_QPID_MASK MS(1, 0x7) +#define NGBE_SYNCLS_HIPRIO MS(31, 0x1) + +/* MAC & VLAN & NVE */ +#define NGBE_PSRVLANIDX 0x016230 /*0-31*/ +#define NGBE_PSRVLAN 0x016220 +#define NGBE_PSRVLAN_VID(v) LS(v, 0, 0xFFF) +#define NGBE_PSRVLAN_EA MS(31, 0x1) +#define NGBE_PSRVLANPLM(i) (0x016224 + (i) * 4) /*0-1*/ + +/** + * Mirror Rules + **/ +#define NGBE_MIRRCTL(i) (0x015B00 + (i) * 4) +#define NGBE_MIRRCTL_POOL MS(0, 0x1) +#define NGBE_MIRRCTL_UPLINK MS(1, 0x1) +#define NGBE_MIRRCTL_DNLINK MS(2, 0x1) +#define NGBE_MIRRCTL_VLAN MS(3, 0x1) +#define NGBE_MIRRCTL_DESTP(v) LS(v, 8, 0x7) +#define NGBE_MIRRVLANL(i) (0x015B10 + (i) * 8) +#define NGBE_MIRRPOOLL(i) (0x015B30 + (i) * 8) + +/** + * Time Stamp + **/ +#define NGBE_TSRXCTL 0x015188 +#define NGBE_TSRXCTL_VLD MS(0, 0x1) +#define NGBE_TSRXCTL_TYPE(v) LS(v, 1, 0x7) +#define NGBE_TSRXCTL_TYPE_V2L2 (0) +#define NGBE_TSRXCTL_TYPE_V1L4 (1) +#define NGBE_TSRXCTL_TYPE_V2L24 (2) +#define NGBE_TSRXCTL_TYPE_V2EVENT (5) +#define NGBE_TSRXCTL_ENA MS(4, 0x1) +#define NGBE_TSRXSTMPL 0x0151E8 +#define NGBE_TSRXSTMPH 0x0151A4 +#define NGBE_TSTXCTL 0x011F00 +#define NGBE_TSTXCTL_VLD MS(0, 0x1) +#define NGBE_TSTXCTL_ENA MS(4, 0x1) +#define NGBE_TSTXSTMPL 0x011F04 +#define NGBE_TSTXSTMPH 0x011F08 +#define NGBE_TSTIMEL 0x011F0C +#define NGBE_TSTIMEH 0x011F10 +#define NGBE_TSTIMEINC 0x011F14 +#define NGBE_TSTIMEINC_IV(v) LS(v, 0, 0x7FFFFFF) + +/** + * Wake on Lan + **/ +#define NGBE_WOLCTL 0x015B80 +#define NGBE_WOLIPCTL 0x015B84 +#define NGBE_WOLIP4(i) (0x015BC0 + (i) * 4) /* 0-3 */ +#define NGBE_WOLIP6(i) (0x015BE0 + (i) * 4) /* 0-3 */ + +#define NGBE_WOLFLEXCTL 0x015CFC +#define NGBE_WOLFLEXI 0x015B8C +#define NGBE_WOLFLEXDAT(i) (0x015C00 + (i) * 16) /* 0-15 */ +#define NGBE_WOLFLEXMSK(i) (0x015C08 + (i) * 16) /* 0-15 */ + +/****************************************************************************** + * Security Registers + ******************************************************************************/ +#define NGBE_SECRXCTL 0x017000 +#define NGBE_SECRXCTL_ODSA MS(0, 0x1) +#define NGBE_SECRXCTL_XDSA MS(1, 0x1) +#define NGBE_SECRXCTL_CRCSTRIP MS(2, 0x1) +#define NGBE_SECRXCTL_SAVEBAD MS(6, 0x1) +#define NGBE_SECRXSTAT 0x017004 +#define NGBE_SECRXSTAT_RDY MS(0, 0x1) +#define NGBE_SECRXSTAT_ECC MS(1, 0x1) + +#define NGBE_SECTXCTL 0x01D000 +#define NGBE_SECTXCTL_ODSA MS(0, 0x1) +#define NGBE_SECTXCTL_XDSA MS(1, 0x1) +#define NGBE_SECTXCTL_STFWD MS(2, 0x1) +#define NGBE_SECTXCTL_MSKIV MS(3, 0x1) +#define NGBE_SECTXSTAT 0x01D004 +#define NGBE_SECTXSTAT_RDY MS(0, 0x1) +#define NGBE_SECTXSTAT_ECC MS(1, 0x1) +#define NGBE_SECTXBUFAF 0x01D008 +#define NGBE_SECTXBUFAE 0x01D00C +#define NGBE_SECTXIFG 0x01D020 +#define NGBE_SECTXIFG_MIN(v) LS(v, 0, 0xF) +#define NGBE_SECTXIFG_MIN_MASK MS(0, 0xF) + +/** + * LinkSec + **/ +#define NGBE_LSECRXCAP 0x017200 +#define NGBE_LSECRXCTL 0x017204 + /* disabled(0),check(1),strict(2),drop(3) */ +#define NGBE_LSECRXCTL_MODE_MASK MS(2, 0x3) +#define NGBE_LSECRXCTL_MODE_STRICT LS(2, 2, 0x3) +#define NGBE_LSECRXCTL_POSTHDR MS(6, 0x1) +#define NGBE_LSECRXCTL_REPLAY MS(7, 0x1) +#define NGBE_LSECRXSCIL 0x017208 +#define NGBE_LSECRXSCIH 0x01720C +#define NGBE_LSECRXSA(i) (0x017210 + (i) * 4) /* 0-1 */ +#define NGBE_LSECRXPN(i) (0x017218 + (i) * 4) /* 0-1 */ +#define NGBE_LSECRXKEY(n, i) (0x017220 + 0x10 * (n) + 4 * (i)) /*0-3*/ +#define NGBE_LSECTXCAP 0x01D200 +#define NGBE_LSECTXCTL 0x01D204 + /* disabled(0), auth(1), auth+encrypt(2) */ +#define NGBE_LSECTXCTL_MODE_MASK MS(0, 0x3) +#define NGBE_LSECTXCTL_MODE_AUTH LS(1, 0, 0x3) +#define NGBE_LSECTXCTL_MODE_AENC LS(2, 0, 0x3) +#define NGBE_LSECTXCTL_PNTRH_MASK MS(8, 0xFFFFFF) +#define NGBE_LSECTXCTL_PNTRH(v) LS(v, 8, 0xFFFFFF) +#define NGBE_LSECTXSCIL 0x01D208 +#define NGBE_LSECTXSCIH 0x01D20C +#define NGBE_LSECTXSA 0x01D210 +#define NGBE_LSECTXPN0 0x01D214 +#define NGBE_LSECTXPN1 0x01D218 +#define NGBE_LSECTXKEY0(i) (0x01D21C + (i) * 4) /* 0-3 */ +#define NGBE_LSECTXKEY1(i) (0x01D22C + (i) * 4) /* 0-3 */ + +#define NGBE_LSECRX_UTPKT 0x017240 +#define NGBE_LSECRX_DECOCT 0x017244 +#define NGBE_LSECRX_VLDOCT 0x017248 +#define NGBE_LSECRX_BTPKT 0x01724C +#define NGBE_LSECRX_NOSCIPKT 0x017250 +#define NGBE_LSECRX_UNSCIPKT 0x017254 +#define NGBE_LSECRX_UNCHKPKT 0x017258 +#define NGBE_LSECRX_DLYPKT 0x01725C +#define NGBE_LSECRX_LATEPKT 0x017260 +#define NGBE_LSECRX_OKPKT(i) (0x017264 + (i) * 4) /* 0-1 */ +#define NGBE_LSECRX_BADPKT(i) (0x01726C + (i) * 4) /* 0-1 */ +#define NGBE_LSECRX_INVPKT(i) (0x017274 + (i) * 4) /* 0-1 */ +#define NGBE_LSECRX_BADSAPKT(i) (0x01727C + (i) * 8) /* 0-3 */ +#define NGBE_LSECRX_INVSAPKT(i) (0x017280 + (i) * 8) /* 0-3 */ +#define NGBE_LSECTX_UTPKT 0x01D23C +#define NGBE_LSECTX_ENCPKT 0x01D240 +#define NGBE_LSECTX_PROTPKT 0x01D244 +#define NGBE_LSECTX_ENCOCT 0x01D248 +#define NGBE_LSECTX_PROTOCT 0x01D24C + +/****************************************************************************** + * MAC Registers + ******************************************************************************/ +#define NGBE_MACRXCFG 0x011004 +#define NGBE_MACRXCFG_ENA MS(0, 0x1) +#define NGBE_MACRXCFG_JUMBO MS(8, 0x1) +#define NGBE_MACRXCFG_LB MS(10, 0x1) +#define NGBE_MACCNTCTL 0x011800 +#define NGBE_MACCNTCTL_RC MS(2, 0x1) + +#define NGBE_MACRXFLT 0x011008 +#define NGBE_MACRXFLT_PROMISC MS(0, 0x1) +#define NGBE_MACRXFLT_CTL_MASK MS(6, 0x3) +#define NGBE_MACRXFLT_CTL_DROP LS(0, 6, 0x3) +#define NGBE_MACRXFLT_CTL_NOPS LS(1, 6, 0x3) +#define NGBE_MACRXFLT_CTL_NOFT LS(2, 6, 0x3) +#define NGBE_MACRXFLT_CTL_PASS LS(3, 6, 0x3) +#define NGBE_MACRXFLT_RXALL MS(31, 0x1) + +/****************************************************************************** + * Statistic Registers + ******************************************************************************/ +/* Ring Counter */ +#define NGBE_QPRXPKT(rp) (0x001014 + 0x40 * (rp)) +#define NGBE_QPRXOCTL(rp) (0x001018 + 0x40 * (rp)) +#define NGBE_QPRXOCTH(rp) (0x00101C + 0x40 * (rp)) +#define NGBE_QPRXMPKT(rp) (0x001020 + 0x40 * (rp)) +#define NGBE_QPRXBPKT(rp) (0x001024 + 0x40 * (rp)) +#define NGBE_QPTXPKT(rp) (0x003014 + 0x40 * (rp)) +#define NGBE_QPTXOCTL(rp) (0x003018 + 0x40 * (rp)) +#define NGBE_QPTXOCTH(rp) (0x00301C + 0x40 * (rp)) +#define NGBE_QPTXMPKT(rp) (0x003020 + 0x40 * (rp)) +#define NGBE_QPTXBPKT(rp) (0x003024 + 0x40 * (rp)) + +/* TDMA Counter */ +#define NGBE_DMATXDROP 0x018300 +#define NGBE_DMATXSECDROP 0x018304 +#define NGBE_DMATXPKT 0x018308 +#define NGBE_DMATXOCTL 0x01830C +#define NGBE_DMATXOCTH 0x018310 +#define NGBE_DMATXMNG 0x018314 + +/* RDMA Counter */ +#define NGBE_DMARXDROP 0x012500 +#define NGBE_DMARXPKT 0x012504 +#define NGBE_DMARXOCTL 0x012508 +#define NGBE_DMARXOCTH 0x01250C +#define NGBE_DMARXMNG 0x012510 + +/* Packet Buffer Counter */ +#define NGBE_PBRXMISS 0x019040 +#define NGBE_PBRXPKT 0x019060 +#define NGBE_PBRXREP 0x019064 +#define NGBE_PBRXDROP 0x019068 +#define NGBE_PBLBSTAT 0x01906C +#define NGBE_PBLBSTAT_FREE(r) RS(r, 0, 0x3FF) +#define NGBE_PBLBSTAT_FULL MS(11, 0x1) +#define NGBE_PBRXWRPTR 0x019180 +#define NGBE_PBRXWRPTR_HEAD(r) RS(r, 0, 0xFFFF) +#define NGBE_PBRXWRPTR_TAIL(r) RS(r, 16, 0xFFFF) +#define NGBE_PBRXRDPTR 0x0191A0 +#define NGBE_PBRXRDPTR_HEAD(r) RS(r, 0, 0xFFFF) +#define NGBE_PBRXRDPTR_TAIL(r) RS(r, 16, 0xFFFF) +#define NGBE_PBRXDATA 0x0191C0 +#define NGBE_PBRXDATA_RDPTR(r) RS(r, 0, 0xFFFF) +#define NGBE_PBRXDATA_WRPTR(r) RS(r, 16, 0xFFFF) +#define NGBE_PBRX_USDSP 0x0191E0 +#define NGBE_RXPBPFCDMACL 0x019210 +#define NGBE_RXPBPFCDMACH 0x019214 +#define NGBE_PBTXLNKXOFF 0x019218 +#define NGBE_PBTXLNKXON 0x01921C + +#define NGBE_PBTXSTAT 0x01C004 +#define NGBE_PBTXSTAT_EMPT(tc, r) ((1 << (tc) & (r)) >> (tc)) + +#define NGBE_PBRXLNKXOFF 0x011988 +#define NGBE_PBRXLNKXON 0x011E0C + +#define NGBE_PBLPBK 0x01CF08 + +/* Ether Flow Counter */ +#define NGBE_LANPKTDROP 0x0151C0 +#define NGBE_MNGPKTDROP 0x0151C4 + +#define NGBE_PSRLANPKTCNT 0x0151B8 +#define NGBE_PSRMNGPKTCNT 0x0151BC + +/* MAC Counter */ +#define NGBE_MACRXERRCRCL 0x011928 +#define NGBE_MACRXERRCRCH 0x01192C +#define NGBE_MACRXERRLENL 0x011978 +#define NGBE_MACRXERRLENH 0x01197C +#define NGBE_MACRX1TO64L 0x001940 +#define NGBE_MACRX1TO64H 0x001944 +#define NGBE_MACRX65TO127L 0x001948 +#define NGBE_MACRX65TO127H 0x00194C +#define NGBE_MACRX128TO255L 0x001950 +#define NGBE_MACRX128TO255H 0x001954 +#define NGBE_MACRX256TO511L 0x001958 +#define NGBE_MACRX256TO511H 0x00195C +#define NGBE_MACRX512TO1023L 0x001960 +#define NGBE_MACRX512TO1023H 0x001964 +#define NGBE_MACRX1024TOMAXL 0x001968 +#define NGBE_MACRX1024TOMAXH 0x00196C +#define NGBE_MACTX1TO64L 0x001834 +#define NGBE_MACTX1TO64H 0x001838 +#define NGBE_MACTX65TO127L 0x00183C +#define NGBE_MACTX65TO127H 0x001840 +#define NGBE_MACTX128TO255L 0x001844 +#define NGBE_MACTX128TO255H 0x001848 +#define NGBE_MACTX256TO511L 0x00184C +#define NGBE_MACTX256TO511H 0x001850 +#define NGBE_MACTX512TO1023L 0x001854 +#define NGBE_MACTX512TO1023H 0x001858 +#define NGBE_MACTX1024TOMAXL 0x00185C +#define NGBE_MACTX1024TOMAXH 0x001860 + +#define NGBE_MACRXUNDERSIZE 0x011938 +#define NGBE_MACRXOVERSIZE 0x01193C +#define NGBE_MACRXJABBER 0x011934 + +#define NGBE_MACRXPKTL 0x011900 +#define NGBE_MACRXPKTH 0x011904 +#define NGBE_MACTXPKTL 0x01181C +#define NGBE_MACTXPKTH 0x011820 +#define NGBE_MACRXGBOCTL 0x011908 +#define NGBE_MACRXGBOCTH 0x01190C +#define NGBE_MACTXGBOCTL 0x011814 +#define NGBE_MACTXGBOCTH 0x011818 + +#define NGBE_MACRXOCTL 0x011918 +#define NGBE_MACRXOCTH 0x01191C +#define NGBE_MACRXMPKTL 0x011920 +#define NGBE_MACRXMPKTH 0x011924 +#define NGBE_MACTXOCTL 0x011824 +#define NGBE_MACTXOCTH 0x011828 +#define NGBE_MACTXMPKTL 0x01182C +#define NGBE_MACTXMPKTH 0x011830 + +/* Management Counter */ +#define NGBE_MNGOUT 0x01CF00 +#define NGBE_MNGIN 0x01CF04 +#define NGBE_MNGDROP 0x01CF0C + +/* MAC SEC Counter */ +#define NGBE_LSECRXUNTAG 0x017240 +#define NGBE_LSECRXDECOCT 0x017244 +#define NGBE_LSECRXVLDOCT 0x017248 +#define NGBE_LSECRXBADTAG 0x01724C +#define NGBE_LSECRXNOSCI 0x017250 +#define NGBE_LSECRXUKSCI 0x017254 +#define NGBE_LSECRXUNCHK 0x017258 +#define NGBE_LSECRXDLY 0x01725C +#define NGBE_LSECRXLATE 0x017260 +#define NGBE_LSECRXGOOD 0x017264 +#define NGBE_LSECRXBAD 0x01726C +#define NGBE_LSECRXUK 0x017274 +#define NGBE_LSECRXBADSA 0x01727C +#define NGBE_LSECRXUKSA 0x017280 +#define NGBE_LSECTXUNTAG 0x01D23C +#define NGBE_LSECTXENC 0x01D240 +#define NGBE_LSECTXPTT 0x01D244 +#define NGBE_LSECTXENCOCT 0x01D248 +#define NGBE_LSECTXPTTOCT 0x01D24C + +/* Management Counter */ +#define NGBE_MNGOS2BMC 0x01E094 +#define NGBE_MNGBMC2OS 0x01E090 + +/****************************************************************************** + * PF(Physical Function) Registers + ******************************************************************************/ +/* Interrupt */ +#define NGBE_ICRMISC 0x000100 +#define NGBE_ICRMISC_MASK MS(8, 0xFFFFFF) +#define NGBE_ICRMISC_RST MS(10, 0x1) /* device reset event */ +#define NGBE_ICRMISC_TS MS(11, 0x1) /* time sync */ +#define NGBE_ICRMISC_STALL MS(12, 0x1) /* trans or recv path is stalled */ +#define NGBE_ICRMISC_LNKSEC MS(13, 0x1) /* Tx LinkSec require key exchange*/ +#define NGBE_ICRMISC_ERRBUF MS(14, 0x1) /* Packet Buffer Overrun */ +#define NGBE_ICRMISC_ERRMAC MS(17, 0x1) /* err reported by MAC */ +#define NGBE_ICRMISC_PHY MS(18, 0x1) /* interrupt reported by eth phy */ +#define NGBE_ICRMISC_ERRIG MS(20, 0x1) /* integrity error */ +#define NGBE_ICRMISC_SPI MS(21, 0x1) /* SPI interface */ +#define NGBE_ICRMISC_VFMBX MS(23, 0x1) /* VF-PF message box */ +#define NGBE_ICRMISC_GPIO MS(26, 0x1) /* GPIO interrupt */ +#define NGBE_ICRMISC_ERRPCI MS(27, 0x1) /* pcie request error */ +#define NGBE_ICRMISC_HEAT MS(28, 0x1) /* overheat detection */ +#define NGBE_ICRMISC_PROBE MS(29, 0x1) /* probe match */ +#define NGBE_ICRMISC_MNGMBX MS(30, 0x1) /* mng mailbox */ +#define NGBE_ICRMISC_TIMER MS(31, 0x1) /* tcp timer */ +#define NGBE_ICRMISC_DEFAULT ( \ + NGBE_ICRMISC_RST | \ + NGBE_ICRMISC_ERRMAC | \ + NGBE_ICRMISC_PHY | \ + NGBE_ICRMISC_ERRIG | \ + NGBE_ICRMISC_GPIO | \ + NGBE_ICRMISC_VFMBX | \ + NGBE_ICRMISC_MNGMBX | \ + NGBE_ICRMISC_STALL | \ + NGBE_ICRMISC_TIMER) +#define NGBE_ICSMISC 0x000104 +#define NGBE_IENMISC 0x000108 +#define NGBE_IVARMISC 0x0004FC +#define NGBE_IVARMISC_VEC(v) LS(v, 0, 0x7) +#define NGBE_IVARMISC_VLD MS(7, 0x1) +#define NGBE_ICR(i) (0x000120 + (i) * 4) /*0*/ +#define NGBE_ICR_MASK MS(0, 0x1FF) +#define NGBE_ICS(i) (0x000130 + (i) * 4) /*0*/ +#define NGBE_ICS_MASK NGBE_ICR_MASK +#define NGBE_IMS(i) (0x000140 + (i) * 4) /*0*/ +#define NGBE_IMS_MASK NGBE_ICR_MASK +#define NGBE_IMC(i) (0x000150 + (i) * 4) /*0*/ +#define NGBE_IMC_MASK NGBE_ICR_MASK +#define NGBE_IVAR(i) (0x000500 + (i) * 4) /*0-3*/ +#define NGBE_IVAR_VEC(v) LS(v, 0, 0x7) +#define NGBE_IVAR_VLD MS(7, 0x1) +#define NGBE_TCPTMR 0x000170 +#define NGBE_ITRSEL 0x000180 + +/* P2V Mailbox */ +#define NGBE_MBMEM(i) (0x005000 + 0x40 * (i)) /*0-7*/ +#define NGBE_MBCTL(i) (0x000600 + 4 * (i)) /*0-7*/ +#define NGBE_MBCTL_STS MS(0, 0x1) /* Initiate message send to VF */ +#define NGBE_MBCTL_ACK MS(1, 0x1) /* Ack message recv'd from VF */ +#define NGBE_MBCTL_VFU MS(2, 0x1) /* VF owns the mailbox buffer */ +#define NGBE_MBCTL_PFU MS(3, 0x1) /* PF owns the mailbox buffer */ +#define NGBE_MBCTL_RVFU MS(4, 0x1) /* Reset VFU - used when VF stuck */ +#define NGBE_MBVFICR 0x000480 +#define NGBE_MBVFICR_INDEX(vf) ((vf) >> 4) +#define NGBE_MBVFICR_VFREQ_MASK (0x0000FFFF) /* bits for VF messages */ +#define NGBE_MBVFICR_VFREQ_VF1 (0x00000001) /* bit for VF 1 message */ +#define NGBE_MBVFICR_VFACK_MASK (0xFFFF0000) /* bits for VF acks */ +#define NGBE_MBVFICR_VFACK_VF1 (0x00010000) /* bit for VF 1 ack */ +#define NGBE_FLRVFP 0x000490 +#define NGBE_FLRVFE 0x0004A0 +#define NGBE_FLRVFEC 0x0004A8 + +/****************************************************************************** + * VF(Virtual Function) Registers + ******************************************************************************/ +#define NGBE_VFPBWRAP 0x000000 +#define NGBE_VFPBWRAP_WRAP MS(0, 0x7) +#define NGBE_VFPBWRAP_EMPT MS(3, 0x1) +#define NGBE_VFSTATUS 0x000004 +#define NGBE_VFSTATUS_UP MS(0, 0x1) +#define NGBE_VFSTATUS_BW_MASK MS(1, 0x7) +#define NGBE_VFSTATUS_BW_1G LS(0x1, 1, 0x7) +#define NGBE_VFSTATUS_BW_100M LS(0x2, 1, 0x7) +#define NGBE_VFSTATUS_BW_10M LS(0x4, 1, 0x7) +#define NGBE_VFSTATUS_BUSY MS(4, 0x1) +#define NGBE_VFSTATUS_LANID MS(8, 0x3) +#define NGBE_VFRST 0x000008 +#define NGBE_VFRST_SET MS(0, 0x1) +#define NGBE_VFMSIXECC 0x00000C +#define NGBE_VFPLCFG 0x000078 +#define NGBE_VFPLCFG_RSV MS(0, 0x1) +#define NGBE_VFPLCFG_PSR(v) LS(v, 1, 0x1F) +#define NGBE_VFPLCFG_PSRL4HDR (0x1) +#define NGBE_VFPLCFG_PSRL3HDR (0x2) +#define NGBE_VFPLCFG_PSRL2HDR (0x4) +#define NGBE_VFPLCFG_PSRTUNHDR (0x8) +#define NGBE_VFPLCFG_PSRTUNMAC (0x10) +#define NGBE_VFICR 0x000100 +#define NGBE_VFICR_MASK LS(3, 0, 0x3) +#define NGBE_VFICR_MBX MS(1, 0x1) +#define NGBE_VFICR_DONE1 MS(0, 0x1) +#define NGBE_VFICS 0x000104 +#define NGBE_VFICS_MASK NGBE_VFICR_MASK +#define NGBE_VFIMS 0x000108 +#define NGBE_VFIMS_MASK NGBE_VFICR_MASK +#define NGBE_VFIMC 0x00010C +#define NGBE_VFIMC_MASK NGBE_VFICR_MASK +#define NGBE_VFGPIE 0x000118 +#define NGBE_VFIVAR(i) (0x000240 + 4 * (i)) /*0-1*/ +#define NGBE_VFIVARMISC 0x000260 +#define NGBE_VFIVAR_ALLOC(v) LS(v, 0, 0x1) +#define NGBE_VFIVAR_VLD MS(7, 0x1) + +#define NGBE_VFMBCTL 0x000600 +#define NGBE_VFMBCTL_REQ MS(0, 0x1) /* Request for PF Ready bit */ +#define NGBE_VFMBCTL_ACK MS(1, 0x1) /* Ack PF message received */ +#define NGBE_VFMBCTL_VFU MS(2, 0x1) /* VF owns the mailbox buffer */ +#define NGBE_VFMBCTL_PFU MS(3, 0x1) /* PF owns the mailbox buffer */ +#define NGBE_VFMBCTL_PFSTS MS(4, 0x1) /* PF wrote a message in the MB */ +#define NGBE_VFMBCTL_PFACK MS(5, 0x1) /* PF ack the previous VF msg */ +#define NGBE_VFMBCTL_RSTI MS(6, 0x1) /* PF has reset indication */ +#define NGBE_VFMBCTL_RSTD MS(7, 0x1) /* PF has indicated reset done */ +#define NGBE_VFMBCTL_R2C_BITS (NGBE_VFMBCTL_RSTD | \ + NGBE_VFMBCTL_PFSTS | \ + NGBE_VFMBCTL_PFACK) +#define NGBE_VFMBX 0x000C00 /*0-15*/ +#define NGBE_VFTPHCTL(i) 0x000D00 + +/****************************************************************************** + * PF&VF TxRx Interface + ******************************************************************************/ +#define RNGLEN(v) ROUND_OVER(v, 13, 7) +#define HDRLEN(v) ROUND_OVER(v, 10, 6) +#define PKTLEN(v) ROUND_OVER(v, 14, 10) +#define INTTHR(v) ROUND_OVER(v, 4, 0) + +#define NGBE_RING_DESC_ALIGN 128 +#define NGBE_RING_DESC_MIN 128 +#define NGBE_RING_DESC_MAX 8192 +#define NGBE_RXD_ALIGN NGBE_RING_DESC_ALIGN +#define NGBE_TXD_ALIGN NGBE_RING_DESC_ALIGN + +/* receive ring */ +#define NGBE_RXBAL(rp) (0x001000 + 0x40 * (rp)) +#define NGBE_RXBAH(rp) (0x001004 + 0x40 * (rp)) +#define NGBE_RXRP(rp) (0x00100C + 0x40 * (rp)) +#define NGBE_RXWP(rp) (0x001008 + 0x40 * (rp)) +#define NGBE_RXCFG(rp) (0x001010 + 0x40 * (rp)) +#define NGBE_RXCFG_ENA MS(0, 0x1) +#define NGBE_RXCFG_RNGLEN(v) LS(RNGLEN(v), 1, 0x3F) +#define NGBE_RXCFG_PKTLEN(v) LS(PKTLEN(v), 8, 0xF) +#define NGBE_RXCFG_PKTLEN_MASK MS(8, 0xF) +#define NGBE_RXCFG_HDRLEN(v) LS(HDRLEN(v), 12, 0xF) +#define NGBE_RXCFG_HDRLEN_MASK MS(12, 0xF) +#define NGBE_RXCFG_WTHRESH(v) LS(v, 16, 0x7) +#define NGBE_RXCFG_ETAG MS(22, 0x1) +#define NGBE_RXCFG_SPLIT MS(26, 0x1) +#define NGBE_RXCFG_CNTAG MS(28, 0x1) +#define NGBE_RXCFG_DROP MS(30, 0x1) +#define NGBE_RXCFG_VLAN MS(31, 0x1) + +/* transmit ring */ +#define NGBE_TXBAL(rp) (0x003000 + 0x40 * (rp)) /*0-7*/ +#define NGBE_TXBAH(rp) (0x003004 + 0x40 * (rp)) +#define NGBE_TXWP(rp) (0x003008 + 0x40 * (rp)) +#define NGBE_TXRP(rp) (0x00300C + 0x40 * (rp)) +#define NGBE_TXCFG(rp) (0x003010 + 0x40 * (rp)) +#define NGBE_TXCFG_ENA MS(0, 0x1) +#define NGBE_TXCFG_BUFLEN_MASK MS(1, 0x3F) +#define NGBE_TXCFG_BUFLEN(v) LS(RNGLEN(v), 1, 0x3F) +#define NGBE_TXCFG_HTHRESH_MASK MS(8, 0xF) +#define NGBE_TXCFG_HTHRESH(v) LS(v, 8, 0xF) +#define NGBE_TXCFG_WTHRESH_MASK MS(16, 0x7F) +#define NGBE_TXCFG_WTHRESH(v) LS(v, 16, 0x7F) +#define NGBE_TXCFG_FLUSH MS(26, 0x1) + +/* interrupt registers */ +#define NGBE_BMEPEND 0x000168 +#define NGBE_BMEPEND_ST MS(0, 0x1) +#define NGBE_ITRI 0x000180 +#define NGBE_ITR(i) (0x000200 + 4 * (i)) +#define NGBE_ITR_IVAL_MASK MS(2, 0x1FFF) /* 1ns/10G, 10ns/REST */ +#define NGBE_ITR_IVAL(v) LS(v, 2, 0x1FFF) /*1ns/10G, 10ns/REST*/ +#define NGBE_ITR_IVAL_1G(us) NGBE_ITR_IVAL((us) / 2) +#define NGBE_ITR_IVAL_10G(us) NGBE_ITR_IVAL((us) / 20) +#define NGBE_ITR_LLIEA MS(15, 0x1) +#define NGBE_ITR_LLICREDIT(v) LS(v, 16, 0x1F) +#define NGBE_ITR_CNT(v) LS(v, 21, 0x3FF) +#define NGBE_ITR_WRDSA MS(31, 0x1) +#define NGBE_GPIE 0x000118 +#define NGBE_GPIE_MSIX MS(0, 0x1) +#define NGBE_GPIE_LLIEA MS(1, 0x1) +#define NGBE_GPIE_LLIVAL(v) LS(v, 3, 0x1F) +#define NGBE_GPIE_LLIVAL_H(v) LS(v, 16, 0x7FF) + +/****************************************************************************** + * Debug Registers + ******************************************************************************/ +/** + * Probe + **/ +#define NGBE_PRBCTL 0x010200 +#define NGBE_PRBSTA 0x010204 +#define NGBE_PRBDAT 0x010220 +#define NGBE_PRBCNT 0x010228 + +#define NGBE_PRBPCI 0x01F010 +#define NGBE_PRBPSR 0x015010 +#define NGBE_PRBRDB 0x019010 +#define NGBE_PRBTDB 0x01C010 +#define NGBE_PRBRSEC 0x017010 +#define NGBE_PRBTSEC 0x01D010 +#define NGBE_PRBMNG 0x01E010 +#define NGBE_PRBRMAC 0x011014 +#define NGBE_PRBTMAC 0x011010 +#define NGBE_PRBREMAC 0x011E04 +#define NGBE_PRBTEMAC 0x011E00 + +/** + * ECC + **/ +#define NGBE_ECCRXPBCTL 0x019014 +#define NGBE_ECCRXPBINJ 0x019018 +#define NGBE_ECCRXPB 0x01901C +#define NGBE_ECCTXPBCTL 0x01C014 +#define NGBE_ECCTXPBINJ 0x01C018 +#define NGBE_ECCTXPB 0x01C01C + +#define NGBE_ECCRXETHCTL 0x015014 +#define NGBE_ECCRXETHINJ 0x015018 +#define NGBE_ECCRXETH 0x01401C + +#define NGBE_ECCRXSECCTL 0x017014 +#define NGBE_ECCRXSECINJ 0x017018 +#define NGBE_ECCRXSEC 0x01701C +#define NGBE_ECCTXSECCTL 0x01D014 +#define NGBE_ECCTXSECINJ 0x01D018 +#define NGBE_ECCTXSEC 0x01D01C + +#define NGBE_P2VMBX_SIZE (16) /* 16*4B */ +#define NGBE_P2MMBX_SIZE (64) /* 64*4B */ + +/**************** Global Registers ****************************/ +#define NGBE_POOLETHCTL(pl) (0x015600 + (pl) * 4) +#define NGBE_POOLETHCTL_LBDIA MS(0, 0x1) +#define NGBE_POOLETHCTL_LLBDIA MS(1, 0x1) +#define NGBE_POOLETHCTL_LLB MS(2, 0x1) +#define NGBE_POOLETHCTL_UCP MS(4, 0x1) +#define NGBE_POOLETHCTL_ETP MS(5, 0x1) +#define NGBE_POOLETHCTL_VLA MS(6, 0x1) +#define NGBE_POOLETHCTL_VLP MS(7, 0x1) +#define NGBE_POOLETHCTL_UTA MS(8, 0x1) +#define NGBE_POOLETHCTL_MCHA MS(9, 0x1) +#define NGBE_POOLETHCTL_UCHA MS(10, 0x1) +#define NGBE_POOLETHCTL_BCA MS(11, 0x1) +#define NGBE_POOLETHCTL_MCP MS(12, 0x1) +#define NGBE_POOLDROPSWBK(i) (0x0151C8 + (i) * 4) /*0-1*/ + +/**************************** Receive DMA registers **************************/ + +#define NGBE_RPUP2TC 0x019008 +#define NGBE_RPUP2TC_UP_SHIFT 3 +#define NGBE_RPUP2TC_UP_MASK 0x7 + +/* mac switcher */ +#define NGBE_ETHADDRL 0x016200 +#define NGBE_ETHADDRL_AD0(v) LS(v, 0, 0xFF) +#define NGBE_ETHADDRL_AD1(v) LS(v, 8, 0xFF) +#define NGBE_ETHADDRL_AD2(v) LS(v, 16, 0xFF) +#define NGBE_ETHADDRL_AD3(v) LS(v, 24, 0xFF) +#define NGBE_ETHADDRL_ETAG(r) RS(r, 0, 0x3FFF) +#define NGBE_ETHADDRH 0x016204 +#define NGBE_ETHADDRH_AD4(v) LS(v, 0, 0xFF) +#define NGBE_ETHADDRH_AD5(v) LS(v, 8, 0xFF) +#define NGBE_ETHADDRH_AD_MASK MS(0, 0xFFFF) +#define NGBE_ETHADDRH_ETAG MS(30, 0x1) +#define NGBE_ETHADDRH_VLD MS(31, 0x1) +#define NGBE_ETHADDRASS 0x016208 +#define NGBE_ETHADDRIDX 0x016210 + +/* Outmost Barrier Filters */ +#define NGBE_MCADDRTBL(i) (0x015200 + (i) * 4) /*0-127*/ +#define NGBE_UCADDRTBL(i) (0x015400 + (i) * 4) /*0-127*/ +#define NGBE_VLANTBL(i) (0x016000 + (i) * 4) /*0-127*/ + +#define NGBE_MNGFLEXSEL 0x1582C +#define NGBE_MNGFLEXDWL(i) (0x15A00 + ((i) * 16)) +#define NGBE_MNGFLEXDWH(i) (0x15A04 + ((i) * 16)) +#define NGBE_MNGFLEXMSK(i) (0x15A08 + ((i) * 16)) + +#define NGBE_LANFLEXSEL 0x15B8C +#define NGBE_LANFLEXDWL(i) (0x15C00 + ((i) * 16)) +#define NGBE_LANFLEXDWH(i) (0x15C04 + ((i) * 16)) +#define NGBE_LANFLEXMSK(i) (0x15C08 + ((i) * 16)) +#define NGBE_LANFLEXCTL 0x15CFC + +/* ipsec */ +#define NGBE_IPSRXIDX 0x017100 +#define NGBE_IPSRXIDX_ENA MS(0, 0x1) +#define NGBE_IPSRXIDX_TB_MASK MS(1, 0x3) +#define NGBE_IPSRXIDX_TB_IP LS(1, 1, 0x3) +#define NGBE_IPSRXIDX_TB_SPI LS(2, 1, 0x3) +#define NGBE_IPSRXIDX_TB_KEY LS(3, 1, 0x3) +#define NGBE_IPSRXIDX_TBIDX(v) LS(v, 3, 0xF) +#define NGBE_IPSRXIDX_READ MS(30, 0x1) +#define NGBE_IPSRXIDX_WRITE MS(31, 0x1) +#define NGBE_IPSRXADDR(i) (0x017104 + (i) * 4) + +#define NGBE_IPSRXSPI 0x017114 +#define NGBE_IPSRXADDRIDX 0x017118 +#define NGBE_IPSRXKEY(i) (0x01711C + (i) * 4) +#define NGBE_IPSRXSALT 0x01712C +#define NGBE_IPSRXMODE 0x017130 +#define NGBE_IPSRXMODE_IPV6 0x00000010 +#define NGBE_IPSRXMODE_DEC 0x00000008 +#define NGBE_IPSRXMODE_ESP 0x00000004 +#define NGBE_IPSRXMODE_AH 0x00000002 +#define NGBE_IPSRXMODE_VLD 0x00000001 +#define NGBE_IPSTXIDX 0x01D100 +#define NGBE_IPSTXIDX_ENA MS(0, 0x1) +#define NGBE_IPSTXIDX_SAIDX(v) LS(v, 3, 0x3FF) +#define NGBE_IPSTXIDX_READ MS(30, 0x1) +#define NGBE_IPSTXIDX_WRITE MS(31, 0x1) +#define NGBE_IPSTXSALT 0x01D104 +#define NGBE_IPSTXKEY(i) (0x01D108 + (i) * 4) + +#define NGBE_MACTXCFG 0x011000 +#define NGBE_MACTXCFG_TE MS(0, 0x1) +#define NGBE_MACTXCFG_SPEED_MASK MS(29, 0x3) +#define NGBE_MACTXCFG_SPEED(v) LS(v, 29, 0x3) +#define NGBE_MACTXCFG_SPEED_10G LS(0, 29, 0x3) +#define NGBE_MACTXCFG_SPEED_1G LS(3, 29, 0x3) + +#define NGBE_ISBADDRL 0x000160 +#define NGBE_ISBADDRH 0x000164 + +#define NGBE_ARBPOOLIDX 0x01820C +#define NGBE_ARBTXRATE 0x018404 +#define NGBE_ARBTXRATE_MIN(v) LS(v, 0, 0x3FFF) +#define NGBE_ARBTXRATE_MAX(v) LS(v, 16, 0x3FFF) + +/* qos */ +#define NGBE_ARBTXCTL 0x018200 +#define NGBE_ARBTXCTL_RRM MS(1, 0x1) +#define NGBE_ARBTXCTL_WSP MS(2, 0x1) +#define NGBE_ARBTXCTL_DIA MS(6, 0x1) +#define NGBE_ARBTXMMW 0x018208 + +/* Management */ +#define NGBE_MNGFWSYNC 0x01E000 +#define NGBE_MNGFWSYNC_REQ MS(0, 0x1) +#define NGBE_MNGSWSYNC 0x01E004 +#define NGBE_MNGSWSYNC_REQ MS(0, 0x1) +#define NGBE_SWSEM 0x01002C +#define NGBE_SWSEM_PF MS(0, 0x1) +#define NGBE_MNGSEM 0x01E008 +#define NGBE_MNGSEM_SW(v) LS(v, 0, 0xFFFF) +#define NGBE_MNGSEM_SWPHY MS(0, 0x1) +#define NGBE_MNGSEM_SWMBX MS(2, 0x1) +#define NGBE_MNGSEM_SWFLASH MS(3, 0x1) +#define NGBE_MNGSEM_FW(v) LS(v, 16, 0xFFFF) +#define NGBE_MNGSEM_FWPHY MS(16, 0x1) +#define NGBE_MNGSEM_FWMBX MS(18, 0x1) +#define NGBE_MNGSEM_FWFLASH MS(19, 0x1) +#define NGBE_MNGMBXCTL 0x01E044 +#define NGBE_MNGMBXCTL_SWRDY MS(0, 0x1) +#define NGBE_MNGMBXCTL_SWACK MS(1, 0x1) +#define NGBE_MNGMBXCTL_FWRDY MS(2, 0x1) +#define NGBE_MNGMBXCTL_FWACK MS(3, 0x1) +#define NGBE_MNGMBX 0x01E100 + +/** + * MDIO(PHY) + **/ +#define NGBE_MDIOSCA 0x011200 +#define NGBE_MDIOSCA_REG(v) LS(v, 0, 0xFFFF) +#define NGBE_MDIOSCA_PORT(v) LS(v, 16, 0x1F) +#define NGBE_MDIOSCA_DEV(v) LS(v, 21, 0x1F) +#define NGBE_MDIOSCD 0x011204 +#define NGBE_MDIOSCD_DAT_R(r) RS(r, 0, 0xFFFF) +#define NGBE_MDIOSCD_DAT(v) LS(v, 0, 0xFFFF) +#define NGBE_MDIOSCD_CMD_PREAD LS(2, 16, 0x3) +#define NGBE_MDIOSCD_CMD_WRITE LS(1, 16, 0x3) +#define NGBE_MDIOSCD_CMD_READ LS(3, 16, 0x3) +#define NGBE_MDIOSCD_SADDR MS(18, 0x1) +#define NGBE_MDIOSCD_CLOCK(v) LS(v, 19, 0x7) +#define NGBE_MDIOSCD_BUSY MS(22, 0x1) + +#define NGBE_MDIOMODE 0x011220 +#define NGBE_MDIOMODE_MASK MS(0, 0xF) +#define NGBE_MDIOMODE_PRT3CL22 MS(3, 0x1) +#define NGBE_MDIOMODE_PRT2CL22 MS(2, 0x1) +#define NGBE_MDIOMODE_PRT1CL22 MS(1, 0x1) +#define NGBE_MDIOMODE_PRT0CL22 MS(0, 0x1) + +#define NVM_OROM_OFFSET 0x17 +#define NVM_OROM_BLK_LOW 0x83 +#define NVM_OROM_BLK_HI 0x84 +#define NVM_OROM_PATCH_MASK 0xFF +#define NVM_OROM_SHIFT 8 +#define NVM_VER_MASK 0x00FF /* version mask */ +#define NVM_VER_SHIFT 8 /* version bit shift */ +#define NVM_OEM_PROD_VER_PTR 0x1B /* OEM Product version block pointer */ +#define NVM_OEM_PROD_VER_CAP_OFF 0x1 /* OEM Product version format offset */ +#define NVM_OEM_PROD_VER_OFF_L 0x2 /* OEM Product version offset low */ +#define NVM_OEM_PROD_VER_OFF_H 0x3 /* OEM Product version offset high */ +#define NVM_OEM_PROD_VER_CAP_MASK 0xF /* OEM Product version cap mask */ +#define NVM_OEM_PROD_VER_MOD_LEN 0x3 /* OEM Product version module length */ +#define NVM_ETK_OFF_LOW 0x2D /* version low order word */ +#define NVM_ETK_OFF_HI 0x2E /* version high order word */ +#define NVM_ETK_SHIFT 16 /* high version word shift */ +#define NVM_VER_INVALID 0xFFFF +#define NVM_ETK_VALID 0x8000 +#define NVM_INVALID_PTR 0xFFFF +#define NVM_VER_SIZE 32 /* version string size */ + +#define NGBE_REG_RSSTBL NGBE_RSSTBL(0) +#define NGBE_REG_RSSKEY NGBE_RSSKEY(0) + +/* + * read non-rc counters + */ +#define NGBE_UPDCNT32(reg, last, cur) \ +do { \ + uint32_t latest = rd32(hw, reg); \ + if (hw->offset_loaded || hw->rx_loaded) \ + last = 0; \ + cur += (latest - last) & UINT_MAX; \ + last = latest; \ +} while (0) + +#define NGBE_UPDCNT36(regl, last, cur) \ +do { \ + uint64_t new_lsb = rd32(hw, regl); \ + uint64_t new_msb = rd32(hw, regl + 4); \ + uint64_t latest = ((new_msb << 32) | new_lsb); \ + if (hw->offset_loaded || hw->rx_loaded) \ + last = 0; \ + cur += (0x1000000000LL + latest - last) & 0xFFFFFFFFFLL; \ + last = latest; \ +} while (0) + +/** + * register operations + **/ +#define NGBE_REG_READ32(addr) rte_read32(addr) +#define NGBE_REG_READ32_RELAXED(addr) rte_read32_relaxed(addr) +#define NGBE_REG_WRITE32(addr, val) rte_write32(val, addr) +#define NGBE_REG_WRITE32_RELAXED(addr, val) rte_write32_relaxed(val, addr) + +#define NGBE_DEAD_READ_REG 0xdeadbeefU +#define NGBE_FAILED_READ_REG 0xffffffffU +#define NGBE_REG_ADDR(hw, reg) \ + ((volatile u32 *)((char *)(hw)->hw_addr + (reg))) + +static inline u32 +ngbe_get32(volatile u32 *addr) +{ + u32 val = NGBE_REG_READ32(addr); + return rte_le_to_cpu_32(val); +} + +static inline void +ngbe_set32(volatile u32 *addr, u32 val) +{ + val = rte_cpu_to_le_32(val); + NGBE_REG_WRITE32(addr, val); +} + +static inline u32 +ngbe_get32_masked(volatile u32 *addr, u32 mask) +{ + u32 val = ngbe_get32(addr); + val &= mask; + return val; +} + +static inline void +ngbe_set32_masked(volatile u32 *addr, u32 mask, u32 field) +{ + u32 val = ngbe_get32(addr); + val = ((val & ~mask) | (field & mask)); + ngbe_set32(addr, val); +} + +static inline u32 +ngbe_get32_relaxed(volatile u32 *addr) +{ + u32 val = NGBE_REG_READ32_RELAXED(addr); + return rte_le_to_cpu_32(val); +} + +static inline void +ngbe_set32_relaxed(volatile u32 *addr, u32 val) +{ + val = rte_cpu_to_le_32(val); + NGBE_REG_WRITE32_RELAXED(addr, val); +} + +static inline u32 +rd32(struct ngbe_hw *hw, u32 reg) +{ + if (reg == NGBE_REG_DUMMY) + return 0; + return ngbe_get32(NGBE_REG_ADDR(hw, reg)); +} + +static inline void +wr32(struct ngbe_hw *hw, u32 reg, u32 val) +{ + if (reg == NGBE_REG_DUMMY) + return; + ngbe_set32(NGBE_REG_ADDR(hw, reg), val); +} + +static inline u32 +rd32m(struct ngbe_hw *hw, u32 reg, u32 mask) +{ + u32 val = rd32(hw, reg); + val &= mask; + return val; +} + +static inline void +wr32m(struct ngbe_hw *hw, u32 reg, u32 mask, u32 field) +{ + u32 val = rd32(hw, reg); + val = ((val & ~mask) | (field & mask)); + wr32(hw, reg, val); +} + +static inline u64 +rd64(struct ngbe_hw *hw, u32 reg) +{ + u64 lsb = rd32(hw, reg); + u64 msb = rd32(hw, reg + 4); + return (lsb | msb << 32); +} + +static inline void +wr64(struct ngbe_hw *hw, u32 reg, u64 val) +{ + wr32(hw, reg, (u32)val); + wr32(hw, reg + 4, (u32)(val >> 32)); +} + +/* poll register */ +static inline u32 +po32m(struct ngbe_hw *hw, u32 reg, u32 mask, u32 expect, u32 *actual, + u32 loop, u32 slice) +{ + bool usec = true; + u32 value = 0, all = 0; + + if (slice > 1000 * MAX_UDELAY_MS) { + usec = false; + slice = (slice + 500) / 1000; + } + + do { + all |= rd32(hw, reg); + value |= mask & all; + if (value == expect) + break; + + usec ? usec_delay(slice) : msec_delay(slice); + } while (--loop > 0); + + if (actual) + *actual = all; + + return loop; +} + +/* flush all write operations */ +#define ngbe_flush(hw) rd32(hw, 0x00100C) + +#define rd32a(hw, reg, idx) ( \ + rd32((hw), (reg) + ((idx) << 2))) +#define wr32a(hw, reg, idx, val) \ + wr32((hw), (reg) + ((idx) << 2), (val)) + +#define rd32w(hw, reg, mask, slice) do { \ + rd32((hw), reg); \ + po32m((hw), reg, mask, mask, NULL, 5, slice); \ +} while (0) + +#define wr32w(hw, reg, val, mask, slice) do { \ + wr32((hw), reg, val); \ + po32m((hw), reg, mask, mask, NULL, 5, slice); \ +} while (0) + +#define NGBE_XPCS_IDAADDR 0x13000 +#define NGBE_XPCS_IDADATA 0x13004 +#define NGBE_EPHY_IDAADDR 0x13008 +#define NGBE_EPHY_IDADATA 0x1300C +static inline u32 +rd32_epcs(struct ngbe_hw *hw, u32 addr) +{ + u32 data; + wr32(hw, NGBE_XPCS_IDAADDR, addr); + data = rd32(hw, NGBE_XPCS_IDADATA); + return data; +} + +static inline void +wr32_epcs(struct ngbe_hw *hw, u32 addr, u32 data) +{ + wr32(hw, NGBE_XPCS_IDAADDR, addr); + wr32(hw, NGBE_XPCS_IDADATA, data); +} + +static inline u32 +rd32_ephy(struct ngbe_hw *hw, u32 addr) +{ + u32 data; + wr32(hw, NGBE_EPHY_IDAADDR, addr); + data = rd32(hw, NGBE_EPHY_IDADATA); + return data; +} + +static inline void +wr32_ephy(struct ngbe_hw *hw, u32 addr, u32 data) +{ + wr32(hw, NGBE_EPHY_IDAADDR, addr); + wr32(hw, NGBE_EPHY_IDADATA, data); +} + +#endif /* _NGBE_REGS_H_ */ From patchwork Thu Jun 17 10:59:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94330 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B15B2A0C4D; Thu, 17 Jun 2021 12:58:45 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CBB4F41103; Thu, 17 Jun 2021 12:58:20 +0200 (CEST) Received: from smtpproxy21.qq.com (smtpbg704.qq.com [203.205.195.105]) by mails.dpdk.org (Postfix) with ESMTP id AE71B410F3 for ; Thu, 17 Jun 2021 12:58:16 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927493t2wbza5a Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:12 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: YKCDl5A3/aqOjOgADts3hqcaPtkbMnW9mRMXu26aln7KSUMmKjDm+rTzo3Ctz mIFhWbfny5SW591OikCODWxp4Heb+Qe9+HgDbSt43S+U4vlzNxbZF9KmL+PPm0LRhC1Jya9 dyJxeZ01LFI+52hjMDO88jxccJeEMmGQQOaX1CdgzMwTQcf9jdG53ZRtpHXoSQm/QpFHomi snYONgYstQycmIOw0NoJtYQDqhskajQnmQA2bqH8gVQyBSXGH8veQcFd8Cj8u35FBoFdrIc it9i+BdR4HfYRpi2zAmQNnIpMxtNNyVMOXR9jXvJl4Now+Ou0TEZ8Mj/qlPnUo6tznn94hP fppU2NRXtEjptRVBT8bT7pvfXfDsL02xg3Po4Nl X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:51 +0800 Message-Id: <20210617110005.4132926-6-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign1 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 05/19] net/ngbe: set MAC type and LAN ID with device initialization X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Add basic init and uninit function. Map device IDs and subsystem IDs to single ID for easy operation. Then initialize the shared code. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/base/meson.build | 4 +- drivers/net/ngbe/base/ngbe.h | 11 ++ drivers/net/ngbe/base/ngbe_dummy.h | 37 ++++++ drivers/net/ngbe/base/ngbe_hw.c | 182 ++++++++++++++++++++++++++++ drivers/net/ngbe/base/ngbe_hw.h | 18 +++ drivers/net/ngbe/base/ngbe_osdep.h | 183 +++++++++++++++++++++++++++++ drivers/net/ngbe/base/ngbe_type.h | 78 ++++++++++++ drivers/net/ngbe/ngbe_ethdev.c | 39 +++++- drivers/net/ngbe/ngbe_ethdev.h | 19 ++- 9 files changed, 565 insertions(+), 6 deletions(-) create mode 100644 drivers/net/ngbe/base/ngbe.h create mode 100644 drivers/net/ngbe/base/ngbe_dummy.h create mode 100644 drivers/net/ngbe/base/ngbe_hw.c create mode 100644 drivers/net/ngbe/base/ngbe_hw.h create mode 100644 drivers/net/ngbe/base/ngbe_osdep.h create mode 100644 drivers/net/ngbe/base/ngbe_type.h diff --git a/drivers/net/ngbe/base/meson.build b/drivers/net/ngbe/base/meson.build index c5f6467743..fdbfa99916 100644 --- a/drivers/net/ngbe/base/meson.build +++ b/drivers/net/ngbe/base/meson.build @@ -1,7 +1,9 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. -sources = [] +sources = [ + 'ngbe_hw.c', +] error_cflags = [] diff --git a/drivers/net/ngbe/base/ngbe.h b/drivers/net/ngbe/base/ngbe.h new file mode 100644 index 0000000000..63fad12ad3 --- /dev/null +++ b/drivers/net/ngbe/base/ngbe.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + */ + +#ifndef _NGBE_H_ +#define _NGBE_H_ + +#include "ngbe_type.h" +#include "ngbe_hw.h" + +#endif /* _NGBE_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h new file mode 100644 index 0000000000..75b4e50bca --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + */ + +#ifndef _NGBE_TYPE_DUMMY_H_ +#define _NGBE_TYPE_DUMMY_H_ + +#ifdef TUP +#elif defined(__GNUC__) +#define TUP(x) x##_unused ngbe_unused +#elif defined(__LCLINT__) +#define TUP(x) x /*@unused@*/ +#else +#define TUP(x) x +#endif /*TUP*/ +#define TUP0 TUP(p0) +#define TUP1 TUP(p1) +#define TUP2 TUP(p2) +#define TUP3 TUP(p3) +#define TUP4 TUP(p4) +#define TUP5 TUP(p5) +#define TUP6 TUP(p6) +#define TUP7 TUP(p7) +#define TUP8 TUP(p8) +#define TUP9 TUP(p9) + +/* struct ngbe_bus_operations */ +static inline void ngbe_bus_set_lan_id_dummy(struct ngbe_hw *TUP0) +{ +} +static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) +{ + hw->bus.set_lan_id = ngbe_bus_set_lan_id_dummy; +} + +#endif /* _NGBE_TYPE_DUMMY_H_ */ + diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c new file mode 100644 index 0000000000..014bb0faee --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#include "ngbe_type.h" +#include "ngbe_hw.h" + +/** + * ngbe_set_lan_id_multi_port - Set LAN id for PCIe multiple port devices + * @hw: pointer to the HW structure + * + * Determines the LAN function id by reading memory-mapped registers and swaps + * the port value if requested, and set MAC instance for devices. + **/ +void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw) +{ + struct ngbe_bus_info *bus = &hw->bus; + u32 reg = 0; + + DEBUGFUNC("ngbe_set_lan_id_multi_port"); + + reg = rd32(hw, NGBE_PORTSTAT); + bus->lan_id = NGBE_PORTSTAT_ID(reg); + bus->func = bus->lan_id; +} + +/** + * ngbe_set_mac_type - Sets MAC type + * @hw: pointer to the HW structure + * + * This function sets the mac type of the adapter based on the + * vendor ID and device ID stored in the hw structure. + **/ +s32 ngbe_set_mac_type(struct ngbe_hw *hw) +{ + s32 err = 0; + + DEBUGFUNC("ngbe_set_mac_type"); + + if (hw->vendor_id != PCI_VENDOR_ID_WANGXUN) { + DEBUGOUT("Unsupported vendor id: %x", hw->vendor_id); + return NGBE_ERR_DEVICE_NOT_SUPPORTED; + } + + switch (hw->sub_device_id) { + case NGBE_SUB_DEV_ID_EM_RTL_SGMII: + case NGBE_SUB_DEV_ID_EM_MVL_RGMII: + hw->phy.media_type = ngbe_media_type_copper; + hw->mac.type = ngbe_mac_em; + break; + case NGBE_SUB_DEV_ID_EM_MVL_SFP: + case NGBE_SUB_DEV_ID_EM_YT8521S_SFP: + hw->phy.media_type = ngbe_media_type_fiber; + hw->mac.type = ngbe_mac_em; + break; + case NGBE_SUB_DEV_ID_EM_VF: + hw->phy.media_type = ngbe_media_type_virtual; + hw->mac.type = ngbe_mac_em_vf; + break; + default: + err = NGBE_ERR_DEVICE_NOT_SUPPORTED; + hw->phy.media_type = ngbe_media_type_unknown; + hw->mac.type = ngbe_mac_unknown; + DEBUGOUT("Unsupported device id: %x", hw->device_id); + break; + } + + DEBUGOUT("found mac: %d media: %d, returns: %d\n", + hw->mac.type, hw->phy.media_type, err); + return err; +} + +void ngbe_map_device_id(struct ngbe_hw *hw) +{ + u16 oem = hw->sub_system_id & NGBE_OEM_MASK; + u16 internal = hw->sub_system_id & NGBE_INTERNAL_MASK; + hw->is_pf = true; + + /* move subsystem_device_id to device_id */ + switch (hw->device_id) { + case NGBE_DEV_ID_EM_WX1860AL_W_VF: + case NGBE_DEV_ID_EM_WX1860A2_VF: + case NGBE_DEV_ID_EM_WX1860A2S_VF: + case NGBE_DEV_ID_EM_WX1860A4_VF: + case NGBE_DEV_ID_EM_WX1860A4S_VF: + case NGBE_DEV_ID_EM_WX1860AL2_VF: + case NGBE_DEV_ID_EM_WX1860AL2S_VF: + case NGBE_DEV_ID_EM_WX1860AL4_VF: + case NGBE_DEV_ID_EM_WX1860AL4S_VF: + case NGBE_DEV_ID_EM_WX1860NCSI_VF: + case NGBE_DEV_ID_EM_WX1860A1_VF: + case NGBE_DEV_ID_EM_WX1860A1L_VF: + hw->device_id = NGBE_DEV_ID_EM_VF; + hw->sub_device_id = NGBE_SUB_DEV_ID_EM_VF; + hw->is_pf = false; + break; + case NGBE_DEV_ID_EM_WX1860AL_W: + case NGBE_DEV_ID_EM_WX1860A2: + case NGBE_DEV_ID_EM_WX1860A2S: + case NGBE_DEV_ID_EM_WX1860A4: + case NGBE_DEV_ID_EM_WX1860A4S: + case NGBE_DEV_ID_EM_WX1860AL2: + case NGBE_DEV_ID_EM_WX1860AL2S: + case NGBE_DEV_ID_EM_WX1860AL4: + case NGBE_DEV_ID_EM_WX1860AL4S: + case NGBE_DEV_ID_EM_WX1860NCSI: + case NGBE_DEV_ID_EM_WX1860A1: + case NGBE_DEV_ID_EM_WX1860A1L: + hw->device_id = NGBE_DEV_ID_EM; + if (oem == NGBE_LY_M88E1512_SFP || + internal == NGBE_INTERNAL_SFP) + hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_SFP; + else if (hw->sub_system_id == NGBE_SUB_DEV_ID_EM_M88E1512_RJ45) + hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_RGMII; + else if (oem == NGBE_YT8521S_SFP || + oem == NGBE_LY_YT8521S_SFP) + hw->sub_device_id = NGBE_SUB_DEV_ID_EM_YT8521S_SFP; + else + hw->sub_device_id = NGBE_SUB_DEV_ID_EM_RTL_SGMII; + break; + default: + break; + } +} + +/** + * ngbe_init_ops_pf - Inits func ptrs and MAC type + * @hw: pointer to hardware structure + * + * Initialize the function pointers and assign the MAC type. + * Does not touch the hardware. + **/ +s32 ngbe_init_ops_pf(struct ngbe_hw *hw) +{ + struct ngbe_bus_info *bus = &hw->bus; + + DEBUGFUNC("ngbe_init_ops_pf"); + + /* BUS */ + bus->set_lan_id = ngbe_set_lan_id_multi_port; + + return 0; +} + +/** + * ngbe_init_shared_code - Initialize the shared code + * @hw: pointer to hardware structure + * + * This will assign function pointers and assign the MAC type and PHY code. + * Does not touch the hardware. This function must be called prior to any + * other function in the shared code. The ngbe_hw structure should be + * memset to 0 prior to calling this function. The following fields in + * hw structure should be filled in prior to calling this function: + * hw_addr, back, device_id, vendor_id, subsystem_device_id + **/ +s32 ngbe_init_shared_code(struct ngbe_hw *hw) +{ + s32 status = 0; + + DEBUGFUNC("ngbe_init_shared_code"); + + /* + * Set the mac type + */ + ngbe_set_mac_type(hw); + + ngbe_init_ops_dummy(hw); + switch (hw->mac.type) { + case ngbe_mac_em: + ngbe_init_ops_pf(hw); + break; + default: + status = NGBE_ERR_DEVICE_NOT_SUPPORTED; + break; + } + + hw->bus.set_lan_id(hw); + + return status; +} + diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h new file mode 100644 index 0000000000..7d5de49248 --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_hw.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _NGBE_HW_H_ +#define _NGBE_HW_H_ + +#include "ngbe_type.h" + +void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw); + +s32 ngbe_init_shared_code(struct ngbe_hw *hw); +s32 ngbe_set_mac_type(struct ngbe_hw *hw); +s32 ngbe_init_ops_pf(struct ngbe_hw *hw); +void ngbe_map_device_id(struct ngbe_hw *hw); + +#endif /* _NGBE_HW_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_osdep.h b/drivers/net/ngbe/base/ngbe_osdep.h new file mode 100644 index 0000000000..215a953081 --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_osdep.h @@ -0,0 +1,183 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _NGBE_OS_H_ +#define _NGBE_OS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../ngbe_logs.h" + +#define RTE_LIBRTE_NGBE_TM DCPV(1, 0) +#define TMZ_PADDR(mz) ((mz)->iova) +#define TMZ_VADDR(mz) ((mz)->addr) +#define TDEV_NAME(eth_dev) ((eth_dev)->device->name) + +#define ASSERT(x) do { \ + if (!(x)) \ + PMD_DRV_LOG(ERR, "NGBE: %d", x); \ +} while (0) + +#define ngbe_unused __rte_unused + +#define usec_delay(x) rte_delay_us(x) +#define msec_delay(x) rte_delay_ms(x) +#define usleep(x) rte_delay_us(x) +#define msleep(x) rte_delay_ms(x) + +#define FALSE 0 +#define TRUE 1 + +#ifndef false +#define false 0 +#endif +#ifndef true +#define true 1 +#endif +#define min(a, b) RTE_MIN(a, b) +#define max(a, b) RTE_MAX(a, b) + +/* Bunch of defines for shared code bogosity */ + +static inline void UNREFERENCED(const char *a __rte_unused, ...) {} +#define UNREFERENCED_PARAMETER(args...) UNREFERENCED("", ##args) + +#define STATIC static + +typedef uint8_t u8; +typedef int8_t s8; +typedef uint16_t u16; +typedef int16_t s16; +typedef uint32_t u32; +typedef int32_t s32; +typedef uint64_t u64; +typedef int64_t s64; + +/* Little Endian defines */ +#ifndef __le16 +#define __le16 u16 +#define __le32 u32 +#define __le64 u64 +#endif +#ifndef __be16 +#define __be16 u16 +#define __be32 u32 +#define __be64 u64 +#endif + +/* Bit shift and mask */ +#define BIT_MASK4 (0x0000000FU) +#define BIT_MASK8 (0x000000FFU) +#define BIT_MASK16 (0x0000FFFFU) +#define BIT_MASK32 (0xFFFFFFFFU) +#define BIT_MASK64 (0xFFFFFFFFFFFFFFFFUL) + +#ifndef cpu_to_le32 +#define cpu_to_le16(v) rte_cpu_to_le_16((u16)(v)) +#define cpu_to_le32(v) rte_cpu_to_le_32((u32)(v)) +#define cpu_to_le64(v) rte_cpu_to_le_64((u64)(v)) +#define le_to_cpu16(v) rte_le_to_cpu_16((u16)(v)) +#define le_to_cpu32(v) rte_le_to_cpu_32((u32)(v)) +#define le_to_cpu64(v) rte_le_to_cpu_64((u64)(v)) + +#define cpu_to_be16(v) rte_cpu_to_be_16((u16)(v)) +#define cpu_to_be32(v) rte_cpu_to_be_32((u32)(v)) +#define cpu_to_be64(v) rte_cpu_to_be_64((u64)(v)) +#define be_to_cpu16(v) rte_be_to_cpu_16((u16)(v)) +#define be_to_cpu32(v) rte_be_to_cpu_32((u32)(v)) +#define be_to_cpu64(v) rte_be_to_cpu_64((u64)(v)) + +#define le_to_be16(v) rte_bswap16((u16)(v)) +#define le_to_be32(v) rte_bswap32((u32)(v)) +#define le_to_be64(v) rte_bswap64((u64)(v)) +#define be_to_le16(v) rte_bswap16((u16)(v)) +#define be_to_le32(v) rte_bswap32((u32)(v)) +#define be_to_le64(v) rte_bswap64((u64)(v)) + +#define npu_to_le16(v) (v) +#define npu_to_le32(v) (v) +#define npu_to_le64(v) (v) +#define le_to_npu16(v) (v) +#define le_to_npu32(v) (v) +#define le_to_npu64(v) (v) + +#define npu_to_be16(v) le_to_be16((u16)(v)) +#define npu_to_be32(v) le_to_be32((u32)(v)) +#define npu_to_be64(v) le_to_be64((u64)(v)) +#define be_to_npu16(v) be_to_le16((u16)(v)) +#define be_to_npu32(v) be_to_le32((u32)(v)) +#define be_to_npu64(v) be_to_le64((u64)(v)) +#endif /* !cpu_to_le32 */ + +static inline u16 REVERT_BIT_MASK16(u16 mask) +{ + mask = ((mask & 0x5555) << 1) | ((mask & 0xAAAA) >> 1); + mask = ((mask & 0x3333) << 2) | ((mask & 0xCCCC) >> 2); + mask = ((mask & 0x0F0F) << 4) | ((mask & 0xF0F0) >> 4); + return ((mask & 0x00FF) << 8) | ((mask & 0xFF00) >> 8); +} + +static inline u32 REVERT_BIT_MASK32(u32 mask) +{ + mask = ((mask & 0x55555555) << 1) | ((mask & 0xAAAAAAAA) >> 1); + mask = ((mask & 0x33333333) << 2) | ((mask & 0xCCCCCCCC) >> 2); + mask = ((mask & 0x0F0F0F0F) << 4) | ((mask & 0xF0F0F0F0) >> 4); + mask = ((mask & 0x00FF00FF) << 8) | ((mask & 0xFF00FF00) >> 8); + return ((mask & 0x0000FFFF) << 16) | ((mask & 0xFFFF0000) >> 16); +} + +static inline u64 REVERT_BIT_MASK64(u64 mask) +{ + mask = ((mask & 0x5555555555555555) << 1) | + ((mask & 0xAAAAAAAAAAAAAAAA) >> 1); + mask = ((mask & 0x3333333333333333) << 2) | + ((mask & 0xCCCCCCCCCCCCCCCC) >> 2); + mask = ((mask & 0x0F0F0F0F0F0F0F0F) << 4) | + ((mask & 0xF0F0F0F0F0F0F0F0) >> 4); + mask = ((mask & 0x00FF00FF00FF00FF) << 8) | + ((mask & 0xFF00FF00FF00FF00) >> 8); + mask = ((mask & 0x0000FFFF0000FFFF) << 16) | + ((mask & 0xFFFF0000FFFF0000) >> 16); + return ((mask & 0x00000000FFFFFFFF) << 32) | + ((mask & 0xFFFFFFFF00000000) >> 32); +} + +#define IOMEM + +#define prefetch(x) rte_prefetch0(x) + +#define ARRAY_SIZE(x) ((int32_t)RTE_DIM(x)) + +#ifndef MAX_UDELAY_MS +#define MAX_UDELAY_MS 5 +#endif + +#define ETH_ADDR_LEN 6 +#define ETH_FCS_LEN 4 + +/* Check whether address is multicast. This is little-endian specific check.*/ +#define NGBE_IS_MULTICAST(address) \ + rte_is_multicast_ether_addr(address) + +/* Check whether an address is broadcast. */ +#define NGBE_IS_BROADCAST(address) \ + rte_is_broadcast_ether_addr(address) + +#define ETH_P_8021Q 0x8100 +#define ETH_P_8021AD 0x88A8 + +#endif /* _NGBE_OS_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h new file mode 100644 index 0000000000..d172f2702f --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _NGBE_TYPE_H_ +#define _NGBE_TYPE_H_ + +#include "ngbe_status.h" +#include "ngbe_osdep.h" +#include "ngbe_devids.h" + +enum ngbe_mac_type { + ngbe_mac_unknown = 0, + ngbe_mac_em, + ngbe_mac_em_vf, + ngbe_num_macs +}; + +enum ngbe_phy_type { + ngbe_phy_unknown = 0, + ngbe_phy_none, + ngbe_phy_rtl, + ngbe_phy_mvl, + ngbe_phy_mvl_sfi, + ngbe_phy_yt8521s, + ngbe_phy_yt8521s_sfi, + ngbe_phy_zte, + ngbe_phy_cu_mtd, +}; + +enum ngbe_media_type { + ngbe_media_type_unknown = 0, + ngbe_media_type_fiber, + ngbe_media_type_fiber_qsfp, + ngbe_media_type_copper, + ngbe_media_type_backplane, + ngbe_media_type_cx4, + ngbe_media_type_virtual +}; + +struct ngbe_hw; + +/* Bus parameters */ +struct ngbe_bus_info { + void (*set_lan_id)(struct ngbe_hw *hw); + + u16 func; + u8 lan_id; +}; + +struct ngbe_mac_info { + enum ngbe_mac_type type; +}; + +struct ngbe_phy_info { + enum ngbe_media_type media_type; + enum ngbe_phy_type type; +}; + +struct ngbe_hw { + void IOMEM *hw_addr; + void *back; + struct ngbe_mac_info mac; + struct ngbe_phy_info phy; + struct ngbe_bus_info bus; + u16 device_id; + u16 vendor_id; + u16 sub_device_id; + u16 sub_system_id; + + bool is_pf; +}; + +#include "ngbe_regs.h" +#include "ngbe_dummy.h" + +#endif /* _NGBE_TYPE_H_ */ diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index e05766752a..a355c7dc29 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -8,9 +8,11 @@ #include #include "ngbe_logs.h" -#include +#include "base/ngbe.h" #include "ngbe_ethdev.h" +static int ngbe_dev_close(struct rte_eth_dev *dev); + /* * The set of PCI devices this driver supports */ @@ -34,6 +36,8 @@ static int eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) { struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); + struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); + int err; PMD_INIT_FUNC_TRACE(); @@ -42,7 +46,21 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) rte_eth_copy_pci_info(eth_dev, pci_dev); - return -EINVAL; + /* Vendor and Device ID need to be set before init of shared code */ + hw->device_id = pci_dev->id.device_id; + hw->vendor_id = pci_dev->id.vendor_id; + hw->sub_system_id = pci_dev->id.subsystem_device_id; + ngbe_map_device_id(hw); + hw->hw_addr = (void *)pci_dev->mem_resource[0].addr; + + /* Initialize the shared code (base driver) */ + err = ngbe_init_shared_code(hw); + if (err != 0) { + PMD_INIT_LOG(ERR, "Shared code init failed: %d", err); + return -EIO; + } + + return 0; } static int @@ -53,9 +71,9 @@ eth_ngbe_dev_uninit(struct rte_eth_dev *eth_dev) if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; - RTE_SET_USED(eth_dev); + ngbe_dev_close(eth_dev); - return -EINVAL; + return 0; } static int @@ -86,6 +104,19 @@ static struct rte_pci_driver rte_ngbe_pmd = { .remove = eth_ngbe_pci_remove, }; +/* + * Reset and stop device. + */ +static int +ngbe_dev_close(struct rte_eth_dev *dev) +{ + PMD_INIT_FUNC_TRACE(); + + RTE_SET_USED(dev); + + return -EINVAL; +} + RTE_PMD_REGISTER_PCI(net_ngbe, rte_ngbe_pmd); RTE_PMD_REGISTER_PCI_TABLE(net_ngbe, pci_id_ngbe_map); RTE_PMD_REGISTER_KMOD_DEP(net_ngbe, "* igb_uio | uio_pci_generic | vfio-pci"); diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h index 38f55f7fb1..d4d02c6bd8 100644 --- a/drivers/net/ngbe/ngbe_ethdev.h +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -10,7 +10,24 @@ * Structure to store private data for each driver instance (for each port). */ struct ngbe_adapter { - void *back; + struct ngbe_hw hw; }; +static inline struct ngbe_adapter * +ngbe_dev_adapter(struct rte_eth_dev *dev) +{ + struct ngbe_adapter *ad = dev->data->dev_private; + + return ad; +} + +static inline struct ngbe_hw * +ngbe_dev_hw(struct rte_eth_dev *dev) +{ + struct ngbe_adapter *ad = ngbe_dev_adapter(dev); + struct ngbe_hw *hw = &ad->hw; + + return hw; +} + #endif /* _NGBE_ETHDEV_H_ */ From patchwork Thu Jun 17 10:59:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94331 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id ED08EA0C4D; Thu, 17 Jun 2021 12:58:54 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4F6D441121; Thu, 17 Jun 2021 12:58:22 +0200 (CEST) Received: from smtpbg506.qq.com (smtpbg506.qq.com [203.205.250.33]) by mails.dpdk.org (Postfix) with ESMTP id B0651410FC for ; Thu, 17 Jun 2021 12:58:19 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927495tpdjpa6h Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:14 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: ChTsRoALjQDaJpQ4lAf0tM2Y8EguggKeq/vHfipXaceItB0qLXxCL7B01rvuK tYAbxvtWXyGAzfT0gpF1fvbydbq555kBiqyrTH5fjOcT0gC8pgftzAljpXU/Z/tAYJC/02M zXyYoOsF3AXozV3uzktX7MHX+LtTpPA09BpCZPRf7QQz3a79daosgZweNl4DBJAM5gtAD0H e44CGAp/fOp16z3VsIB4Tkr3YW9Z0xa0rg8+snWs7IX8BCYTQ1n/D7JleERqo2/ihzntzjL V/UmKyRC4f2bKnDyBnQ442NFttB9CZ0bwPcfSBxJ28KQmdXGtHTYSwl2pcb6NvX2gC4SYnb U4Tgl041uzCWs1Yan/lOyt+yFheTlbTAG/ZDcBW X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:52 +0800 Message-Id: <20210617110005.4132926-7-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign5 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 06/19] net/ngbe: init and validate EEPROM X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Reset swfw lock before NVM access, init EEPROM and validate the checksum. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/base/meson.build | 2 + drivers/net/ngbe/base/ngbe_dummy.h | 23 ++++ drivers/net/ngbe/base/ngbe_eeprom.c | 203 ++++++++++++++++++++++++++++ drivers/net/ngbe/base/ngbe_eeprom.h | 17 +++ drivers/net/ngbe/base/ngbe_hw.c | 83 ++++++++++++ drivers/net/ngbe/base/ngbe_hw.h | 3 + drivers/net/ngbe/base/ngbe_mng.c | 198 +++++++++++++++++++++++++++ drivers/net/ngbe/base/ngbe_mng.h | 65 +++++++++ drivers/net/ngbe/base/ngbe_type.h | 24 ++++ drivers/net/ngbe/ngbe_ethdev.c | 39 ++++++ 10 files changed, 657 insertions(+) create mode 100644 drivers/net/ngbe/base/ngbe_eeprom.c create mode 100644 drivers/net/ngbe/base/ngbe_eeprom.h create mode 100644 drivers/net/ngbe/base/ngbe_mng.c create mode 100644 drivers/net/ngbe/base/ngbe_mng.h diff --git a/drivers/net/ngbe/base/meson.build b/drivers/net/ngbe/base/meson.build index fdbfa99916..ddd122ec45 100644 --- a/drivers/net/ngbe/base/meson.build +++ b/drivers/net/ngbe/base/meson.build @@ -2,7 +2,9 @@ # Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. sources = [ + 'ngbe_eeprom.c', 'ngbe_hw.c', + 'ngbe_mng.c', ] error_cflags = [] diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h index 75b4e50bca..ade03eae81 100644 --- a/drivers/net/ngbe/base/ngbe_dummy.h +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -28,9 +28,32 @@ static inline void ngbe_bus_set_lan_id_dummy(struct ngbe_hw *TUP0) { } +/* struct ngbe_rom_operations */ +static inline s32 ngbe_rom_init_params_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_rom_validate_checksum_dummy(struct ngbe_hw *TUP0, + u16 *TUP1) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_mac_acquire_swfw_sync_dummy(struct ngbe_hw *TUP0, + u32 TUP1) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline void ngbe_mac_release_swfw_sync_dummy(struct ngbe_hw *TUP0, + u32 TUP1) +{ +} static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) { hw->bus.set_lan_id = ngbe_bus_set_lan_id_dummy; + hw->rom.init_params = ngbe_rom_init_params_dummy; + hw->rom.validate_checksum = ngbe_rom_validate_checksum_dummy; + hw->mac.acquire_swfw_sync = ngbe_mac_acquire_swfw_sync_dummy; + hw->mac.release_swfw_sync = ngbe_mac_release_swfw_sync_dummy; } #endif /* _NGBE_TYPE_DUMMY_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_eeprom.c b/drivers/net/ngbe/base/ngbe_eeprom.c new file mode 100644 index 0000000000..0ebbb7a29e --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_eeprom.c @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#include "ngbe_hw.h" +#include "ngbe_mng.h" +#include "ngbe_eeprom.h" + +/** + * ngbe_init_eeprom_params - Initialize EEPROM params + * @hw: pointer to hardware structure + * + * Initializes the EEPROM parameters ngbe_rom_info within the + * ngbe_hw struct in order to set up EEPROM access. + **/ +s32 ngbe_init_eeprom_params(struct ngbe_hw *hw) +{ + struct ngbe_rom_info *eeprom = &hw->rom; + u32 eec; + u16 eeprom_size; + + DEBUGFUNC("ngbe_init_eeprom_params"); + + if (eeprom->type != ngbe_eeprom_unknown) + return 0; + + eeprom->type = ngbe_eeprom_none; + /* Set default semaphore delay to 10ms which is a well + * tested value + */ + eeprom->semaphore_delay = 10; /*ms*/ + /* Clear EEPROM page size, it will be initialized as needed */ + eeprom->word_page_size = 0; + + /* + * Check for EEPROM present first. + * If not present leave as none + */ + eec = rd32(hw, NGBE_SPISTAT); + if (!(eec & NGBE_SPISTAT_BPFLASH)) { + eeprom->type = ngbe_eeprom_flash; + + /* + * SPI EEPROM is assumed here. This code would need to + * change if a future EEPROM is not SPI. + */ + eeprom_size = 4096; + eeprom->word_size = eeprom_size >> 1; + } + + eeprom->address_bits = 16; + eeprom->sw_addr = 0x80; + + DEBUGOUT("eeprom params: type = %d, size = %d, address bits: " + "%d %d\n", eeprom->type, eeprom->word_size, + eeprom->address_bits, eeprom->sw_addr); + + return 0; +} + +/** + * ngbe_get_eeprom_semaphore - Get hardware semaphore + * @hw: pointer to hardware structure + * + * Sets the hardware semaphores so EEPROM access can occur for bit-bang method + **/ +s32 ngbe_get_eeprom_semaphore(struct ngbe_hw *hw) +{ + s32 status = NGBE_ERR_EEPROM; + u32 timeout = 2000; + u32 i; + u32 swsm; + + DEBUGFUNC("ngbe_get_eeprom_semaphore"); + + + /* Get SMBI software semaphore between device drivers first */ + for (i = 0; i < timeout; i++) { + /* + * If the SMBI bit is 0 when we read it, then the bit will be + * set and we have the semaphore + */ + swsm = rd32(hw, NGBE_SWSEM); + if (!(swsm & NGBE_SWSEM_PF)) { + status = 0; + break; + } + usec_delay(50); + } + + if (i == timeout) { + DEBUGOUT("Driver can't access the eeprom - SMBI Semaphore " + "not granted.\n"); + /* + * this release is particularly important because our attempts + * above to get the semaphore may have succeeded, and if there + * was a timeout, we should unconditionally clear the semaphore + * bits to free the driver to make progress + */ + ngbe_release_eeprom_semaphore(hw); + + usec_delay(50); + /* + * one last try + * If the SMBI bit is 0 when we read it, then the bit will be + * set and we have the semaphore + */ + swsm = rd32(hw, NGBE_SWSEM); + if (!(swsm & NGBE_SWSEM_PF)) + status = 0; + } + + /* Now get the semaphore between SW/FW through the SWESMBI bit */ + if (status == 0) { + for (i = 0; i < timeout; i++) { + /* Set the SW EEPROM semaphore bit to request access */ + wr32m(hw, NGBE_MNGSWSYNC, + NGBE_MNGSWSYNC_REQ, NGBE_MNGSWSYNC_REQ); + + /* + * If we set the bit successfully then we got the + * semaphore. + */ + swsm = rd32(hw, NGBE_MNGSWSYNC); + if (swsm & NGBE_MNGSWSYNC_REQ) + break; + + usec_delay(50); + } + + /* + * Release semaphores and return error if SW EEPROM semaphore + * was not granted because we don't have access to the EEPROM + */ + if (i >= timeout) { + DEBUGOUT("SWESMBI Software EEPROM semaphore not granted.\n"); + ngbe_release_eeprom_semaphore(hw); + status = NGBE_ERR_EEPROM; + } + } else { + DEBUGOUT("Software semaphore SMBI between device drivers " + "not granted.\n"); + } + + return status; +} + +/** + * ngbe_release_eeprom_semaphore - Release hardware semaphore + * @hw: pointer to hardware structure + * + * This function clears hardware semaphore bits. + **/ +void ngbe_release_eeprom_semaphore(struct ngbe_hw *hw) +{ + DEBUGFUNC("ngbe_release_eeprom_semaphore"); + + wr32m(hw, NGBE_MNGSWSYNC, NGBE_MNGSWSYNC_REQ, 0); + wr32m(hw, NGBE_SWSEM, NGBE_SWSEM_PF, 0); + ngbe_flush(hw); +} + +/** + * ngbe_validate_eeprom_checksum_em - Validate EEPROM checksum + * @hw: pointer to hardware structure + * @checksum_val: calculated checksum + * + * Performs checksum calculation and validates the EEPROM checksum. If the + * caller does not need checksum_val, the value can be NULL. + **/ +s32 ngbe_validate_eeprom_checksum_em(struct ngbe_hw *hw, + u16 *checksum_val) +{ + u32 eeprom_cksum_devcap = 0; + int err = 0; + + DEBUGFUNC("ngbe_validate_eeprom_checksum_em"); + UNREFERENCED_PARAMETER(checksum_val); + + /* Check EEPROM only once */ + if (hw->bus.lan_id == 0) { + wr32(hw, NGBE_CALSUM_CAP_STATUS, 0x0); + wr32(hw, NGBE_EEPROM_VERSION_STORE_REG, 0x0); + } else { + eeprom_cksum_devcap = rd32(hw, NGBE_CALSUM_CAP_STATUS); + hw->rom.saved_version = rd32(hw, NGBE_EEPROM_VERSION_STORE_REG); + } + + if (hw->bus.lan_id == 0 || eeprom_cksum_devcap == 0) { + err = ngbe_hic_check_cap(hw); + if (err != 0) { + PMD_INIT_LOG(ERR, + "The EEPROM checksum is not valid: %d", err); + return -EIO; + } + } + + hw->rom.cksum_devcap = eeprom_cksum_devcap & 0xffff; + + return err; +} + diff --git a/drivers/net/ngbe/base/ngbe_eeprom.h b/drivers/net/ngbe/base/ngbe_eeprom.h new file mode 100644 index 0000000000..0c2819df4a --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_eeprom.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _NGBE_EEPROM_H_ +#define _NGBE_EEPROM_H_ + +#define NGBE_CALSUM_CAP_STATUS 0x10224 +#define NGBE_EEPROM_VERSION_STORE_REG 0x1022C + +s32 ngbe_init_eeprom_params(struct ngbe_hw *hw); +s32 ngbe_validate_eeprom_checksum_em(struct ngbe_hw *hw, u16 *checksum_val); +s32 ngbe_get_eeprom_semaphore(struct ngbe_hw *hw); +void ngbe_release_eeprom_semaphore(struct ngbe_hw *hw); + +#endif /* _NGBE_EEPROM_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index 014bb0faee..de6b75e1c0 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -4,6 +4,8 @@ */ #include "ngbe_type.h" +#include "ngbe_eeprom.h" +#include "ngbe_mng.h" #include "ngbe_hw.h" /** @@ -25,6 +27,77 @@ void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw) bus->func = bus->lan_id; } +/** + * ngbe_acquire_swfw_sync - Acquire SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to acquire + * + * Acquires the SWFW semaphore through the MNGSEM register for the specified + * function (CSR, PHY0, PHY1, EEPROM, Flash) + **/ +s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask) +{ + u32 mngsem = 0; + u32 swmask = NGBE_MNGSEM_SW(mask); + u32 fwmask = NGBE_MNGSEM_FW(mask); + u32 timeout = 200; + u32 i; + + DEBUGFUNC("ngbe_acquire_swfw_sync"); + + for (i = 0; i < timeout; i++) { + /* + * SW NVM semaphore bit is used for access to all + * SW_FW_SYNC bits (not just NVM) + */ + if (ngbe_get_eeprom_semaphore(hw)) + return NGBE_ERR_SWFW_SYNC; + + mngsem = rd32(hw, NGBE_MNGSEM); + if (mngsem & (fwmask | swmask)) { + /* Resource is currently in use by FW or SW */ + ngbe_release_eeprom_semaphore(hw); + msec_delay(5); + } else { + mngsem |= swmask; + wr32(hw, NGBE_MNGSEM, mngsem); + ngbe_release_eeprom_semaphore(hw); + return 0; + } + } + + /* If time expired clear the bits holding the lock and retry */ + if (mngsem & (fwmask | swmask)) + ngbe_release_swfw_sync(hw, mngsem & (fwmask | swmask)); + + msec_delay(5); + return NGBE_ERR_SWFW_SYNC; +} + +/** + * ngbe_release_swfw_sync - Release SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to release + * + * Releases the SWFW semaphore through the MNGSEM register for the specified + * function (CSR, PHY0, PHY1, EEPROM, Flash) + **/ +void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask) +{ + u32 mngsem; + u32 swmask = mask; + + DEBUGFUNC("ngbe_release_swfw_sync"); + + ngbe_get_eeprom_semaphore(hw); + + mngsem = rd32(hw, NGBE_MNGSEM); + mngsem &= ~swmask; + wr32(hw, NGBE_MNGSEM, mngsem); + + ngbe_release_eeprom_semaphore(hw); +} + /** * ngbe_set_mac_type - Sets MAC type * @hw: pointer to the HW structure @@ -134,12 +207,22 @@ void ngbe_map_device_id(struct ngbe_hw *hw) s32 ngbe_init_ops_pf(struct ngbe_hw *hw) { struct ngbe_bus_info *bus = &hw->bus; + struct ngbe_mac_info *mac = &hw->mac; + struct ngbe_rom_info *rom = &hw->rom; DEBUGFUNC("ngbe_init_ops_pf"); /* BUS */ bus->set_lan_id = ngbe_set_lan_id_multi_port; + /* MAC */ + mac->acquire_swfw_sync = ngbe_acquire_swfw_sync; + mac->release_swfw_sync = ngbe_release_swfw_sync; + + /* EEPROM */ + rom->init_params = ngbe_init_eeprom_params; + rom->validate_checksum = ngbe_validate_eeprom_checksum_em; + return 0; } diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h index 7d5de49248..5e508fb67f 100644 --- a/drivers/net/ngbe/base/ngbe_hw.h +++ b/drivers/net/ngbe/base/ngbe_hw.h @@ -10,6 +10,9 @@ void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw); +s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask); +void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask); + s32 ngbe_init_shared_code(struct ngbe_hw *hw); s32 ngbe_set_mac_type(struct ngbe_hw *hw); s32 ngbe_init_ops_pf(struct ngbe_hw *hw); diff --git a/drivers/net/ngbe/base/ngbe_mng.c b/drivers/net/ngbe/base/ngbe_mng.c new file mode 100644 index 0000000000..87891a91e1 --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_mng.c @@ -0,0 +1,198 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#include "ngbe_type.h" +#include "ngbe_mng.h" + +/** + * ngbe_hic_unlocked - Issue command to manageability block unlocked + * @hw: pointer to the HW structure + * @buffer: command to write and where the return status will be placed + * @length: length of buffer, must be multiple of 4 bytes + * @timeout: time in ms to wait for command completion + * + * Communicates with the manageability block. On success return 0 + * else returns semaphore error when encountering an error acquiring + * semaphore or NGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + * + * This function assumes that the NGBE_MNGSEM_SWMBX semaphore is held + * by the caller. + **/ +static s32 +ngbe_hic_unlocked(struct ngbe_hw *hw, u32 *buffer, u32 length, u32 timeout) +{ + u32 value, loop; + u16 i, dword_len; + + DEBUGFUNC("ngbe_hic_unlocked"); + + if (!length || length > NGBE_PMMBX_BSIZE) { + DEBUGOUT("Buffer length failure buffersize=%d.\n", length); + return NGBE_ERR_HOST_INTERFACE_COMMAND; + } + + /* Calculate length in DWORDs. We must be DWORD aligned */ + if (length % sizeof(u32)) { + DEBUGOUT("Buffer length failure, not aligned to dword"); + return NGBE_ERR_INVALID_ARGUMENT; + } + + dword_len = length >> 2; + + /* The device driver writes the relevant command block + * into the ram area. + */ + for (i = 0; i < dword_len; i++) { + wr32a(hw, NGBE_MNGMBX, i, cpu_to_le32(buffer[i])); + buffer[i] = rd32a(hw, NGBE_MNGMBX, i); + } + ngbe_flush(hw); + + /* Setting this bit tells the ARC that a new command is pending. */ + wr32m(hw, NGBE_MNGMBXCTL, + NGBE_MNGMBXCTL_SWRDY, NGBE_MNGMBXCTL_SWRDY); + + /* Check command completion */ + loop = po32m(hw, NGBE_MNGMBXCTL, + NGBE_MNGMBXCTL_FWRDY, NGBE_MNGMBXCTL_FWRDY, + &value, timeout, 1000); + if (!loop || !(value & NGBE_MNGMBXCTL_FWACK)) { + DEBUGOUT("Command has failed with no status valid.\n"); + return NGBE_ERR_HOST_INTERFACE_COMMAND; + } + + return 0; +} + +/** + * ngbe_host_interface_command - Issue command to manageability block + * @hw: pointer to the HW structure + * @buffer: contains the command to write and where the return status will + * be placed + * @length: length of buffer, must be multiple of 4 bytes + * @timeout: time in ms to wait for command completion + * @return_data: read and return data from the buffer (true) or not (false) + * Needed because FW structures are big endian and decoding of + * these fields can be 8 bit or 16 bit based on command. Decoding + * is not easily understood without making a table of commands. + * So we will leave this up to the caller to read back the data + * in these cases. + * + * Communicates with the manageability block. On success return 0 + * else returns semaphore error when encountering an error acquiring + * semaphore or NGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + **/ +static s32 +ngbe_host_interface_command(struct ngbe_hw *hw, u32 *buffer, + u32 length, u32 timeout, bool return_data) +{ + u32 hdr_size = sizeof(struct ngbe_hic_hdr); + struct ngbe_hic_hdr *resp = (struct ngbe_hic_hdr *)buffer; + u16 buf_len; + s32 err; + u32 bi; + u32 dword_len; + + DEBUGFUNC("ngbe_host_interface_command"); + + if (length == 0 || length > NGBE_PMMBX_BSIZE) { + DEBUGOUT("Buffer length failure buffersize=%d.\n", length); + return NGBE_ERR_HOST_INTERFACE_COMMAND; + } + + /* Take management host interface semaphore */ + err = hw->mac.acquire_swfw_sync(hw, NGBE_MNGSEM_SWMBX); + if (err) + return err; + + err = ngbe_hic_unlocked(hw, buffer, length, timeout); + if (err) + goto rel_out; + + if (!return_data) + goto rel_out; + + /* Calculate length in DWORDs */ + dword_len = hdr_size >> 2; + + /* first pull in the header so we know the buffer length */ + for (bi = 0; bi < dword_len; bi++) + buffer[bi] = rd32a(hw, NGBE_MNGMBX, bi); + + /* + * If there is any thing in data position pull it in + * Read Flash command requires reading buffer length from + * two byes instead of one byte + */ + if (resp->cmd == 0x30) { + for (; bi < dword_len + 2; bi++) + buffer[bi] = rd32a(hw, NGBE_MNGMBX, bi); + + buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3) + & 0xF00) | resp->buf_len; + hdr_size += (2 << 2); + } else { + buf_len = resp->buf_len; + } + if (!buf_len) + goto rel_out; + + if (length < buf_len + hdr_size) { + DEBUGOUT("Buffer not large enough for reply message.\n"); + err = NGBE_ERR_HOST_INTERFACE_COMMAND; + goto rel_out; + } + + /* Calculate length in DWORDs, add 3 for odd lengths */ + dword_len = (buf_len + 3) >> 2; + + /* Pull in the rest of the buffer (bi is where we left off) */ + for (; bi <= dword_len; bi++) + buffer[bi] = rd32a(hw, NGBE_MNGMBX, bi); + +rel_out: + hw->mac.release_swfw_sync(hw, NGBE_MNGSEM_SWMBX); + + return err; +} + +s32 ngbe_hic_check_cap(struct ngbe_hw *hw) +{ + struct ngbe_hic_read_shadow_ram command; + s32 err; + int i; + + DEBUGFUNC("\n"); + + command.hdr.req.cmd = FW_EEPROM_CHECK_STATUS; + command.hdr.req.buf_lenh = 0; + command.hdr.req.buf_lenl = 0; + command.hdr.req.checksum = FW_DEFAULT_CHECKSUM; + + /* convert offset from words to bytes */ + command.address = 0; + /* one word */ + command.length = 0; + + for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { + err = ngbe_host_interface_command(hw, (u32 *)&command, + sizeof(command), + NGBE_HI_COMMAND_TIMEOUT, true); + if (err) + continue; + + command.hdr.rsp.ret_status &= 0x1F; + if (command.hdr.rsp.ret_status != + FW_CEM_RESP_STATUS_SUCCESS) + err = NGBE_ERR_HOST_INTERFACE_COMMAND; + + break; + } + + if (!err && command.address != FW_CHECKSUM_CAP_ST_PASS) + err = NGBE_ERR_EEPROM_CHECKSUM; + + return err; +} diff --git a/drivers/net/ngbe/base/ngbe_mng.h b/drivers/net/ngbe/base/ngbe_mng.h new file mode 100644 index 0000000000..383e0dc0d1 --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_mng.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _NGBE_MNG_H_ +#define _NGBE_MNG_H_ + +#include "ngbe_type.h" + +#define NGBE_PMMBX_QSIZE 64 /* Num of dwords in range */ +#define NGBE_PMMBX_BSIZE (NGBE_PMMBX_QSIZE * 4) +#define NGBE_HI_COMMAND_TIMEOUT 5000 /* Process HI command limit */ + +/* CEM Support */ +#define FW_CEM_MAX_RETRIES 3 +#define FW_CEM_RESP_STATUS_SUCCESS 0x1 +#define FW_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */ +#define FW_EEPROM_CHECK_STATUS 0xE9 + +#define FW_CHECKSUM_CAP_ST_PASS 0x80658383 +#define FW_CHECKSUM_CAP_ST_FAIL 0x70657376 + +/* Host Interface Command Structures */ +struct ngbe_hic_hdr { + u8 cmd; + u8 buf_len; + union { + u8 cmd_resv; + u8 ret_status; + } cmd_or_resp; + u8 checksum; +}; + +struct ngbe_hic_hdr2_req { + u8 cmd; + u8 buf_lenh; + u8 buf_lenl; + u8 checksum; +}; + +struct ngbe_hic_hdr2_rsp { + u8 cmd; + u8 buf_lenl; + u8 ret_status; /* 7-5: high bits of buf_len, 4-0: status */ + u8 checksum; +}; + +union ngbe_hic_hdr2 { + struct ngbe_hic_hdr2_req req; + struct ngbe_hic_hdr2_rsp rsp; +}; + +/* These need to be dword aligned */ +struct ngbe_hic_read_shadow_ram { + union ngbe_hic_hdr2 hdr; + u32 address; + u16 length; + u16 pad2; + u16 data; + u16 pad3; +}; + +s32 ngbe_hic_check_cap(struct ngbe_hw *hw); +#endif /* _NGBE_MNG_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index d172f2702f..c727338bd5 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -10,6 +10,13 @@ #include "ngbe_osdep.h" #include "ngbe_devids.h" +enum ngbe_eeprom_type { + ngbe_eeprom_unknown = 0, + ngbe_eeprom_spi, + ngbe_eeprom_flash, + ngbe_eeprom_none /* No NVM support */ +}; + enum ngbe_mac_type { ngbe_mac_unknown = 0, ngbe_mac_em, @@ -49,7 +56,23 @@ struct ngbe_bus_info { u8 lan_id; }; +struct ngbe_rom_info { + s32 (*init_params)(struct ngbe_hw *hw); + s32 (*validate_checksum)(struct ngbe_hw *hw, u16 *checksum_val); + + enum ngbe_eeprom_type type; + u32 semaphore_delay; + u16 word_size; + u16 address_bits; + u16 word_page_size; + u32 sw_addr; + u32 saved_version; + u16 cksum_devcap; +}; + struct ngbe_mac_info { + s32 (*acquire_swfw_sync)(struct ngbe_hw *hw, u32 mask); + void (*release_swfw_sync)(struct ngbe_hw *hw, u32 mask); enum ngbe_mac_type type; }; @@ -63,6 +86,7 @@ struct ngbe_hw { void *back; struct ngbe_mac_info mac; struct ngbe_phy_info phy; + struct ngbe_rom_info rom; struct ngbe_bus_info bus; u16 device_id; u16 vendor_id; diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index a355c7dc29..c779c46dd5 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -32,6 +32,29 @@ static const struct rte_pci_id pci_id_ngbe_map[] = { { .vendor_id = 0, /* sentinel */ }, }; +/* + * Ensure that all locks are released before first NVM or PHY access + */ +static void +ngbe_swfw_lock_reset(struct ngbe_hw *hw) +{ + uint16_t mask; + + /* + * These ones are more tricky since they are common to all ports; but + * swfw_sync retries last long enough (1s) to be almost sure that if + * lock can not be taken it is due to an improper lock of the + * semaphore. + */ + mask = NGBE_MNGSEM_SWPHY | + NGBE_MNGSEM_SWMBX | + NGBE_MNGSEM_SWFLASH; + if (hw->mac.acquire_swfw_sync(hw, mask) < 0) + PMD_DRV_LOG(DEBUG, "SWFW common locks released"); + + hw->mac.release_swfw_sync(hw, mask); +} + static int eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) { @@ -60,6 +83,22 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) return -EIO; } + /* Unlock any pending hardware semaphore */ + ngbe_swfw_lock_reset(hw); + + err = hw->rom.init_params(hw); + if (err != 0) { + PMD_INIT_LOG(ERR, "The EEPROM init failed: %d", err); + return -EIO; + } + + /* Make sure we have a good EEPROM before we read from it */ + err = hw->rom.validate_checksum(hw, NULL); + if (err != 0) { + PMD_INIT_LOG(ERR, "The EEPROM checksum is not valid: %d", err); + return -EIO; + } + return 0; } From patchwork Thu Jun 17 10:59:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94332 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 02790A0C4D; Thu, 17 Jun 2021 12:59:02 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6FBC141134; Thu, 17 Jun 2021 12:58:23 +0200 (CEST) Received: from smtpbgeu2.qq.com (smtpbgeu2.qq.com [18.194.254.142]) by mails.dpdk.org (Postfix) with ESMTP id 5FB4341123 for ; Thu, 17 Jun 2021 12:58:22 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927497t7konr96 Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:16 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: GqceBTtlgSw3hRuznktQy+BOryp+y3W7xaat4CKWK3JLNlF8AoeAv3N1IqI8T oO9oL51x5OXzlH1UNN1Y1iFtfcjeJ34nHxJNiaA2rijSWXOwAN751DC+YD6mdrelTSXQaw+ 8Entp/hgMyvej3+s315moFNFycgF2uFm2OSOI4wWhVgz6HAaZu5tmksMDHJgeaSv58Y5o2l DU80j3nwVX05+gqgSoZEs2GXtiNnIiCqziji2EEXlJ9jojAtndmUQb4ZIEJ9Qsnwx8kfwWk sVee/0EUlhi9OEG8A5F6efIjrA0JWUeRIAhfz4+x+Oxaf9Wq2GzX6Xip1pTRYse4ic4KZ7Y 9ZBGy3egnKniv9EQ9v8qYnm3QIO3A== X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:53 +0800 Message-Id: <20210617110005.4132926-8-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign1 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 07/19] net/ngbe: add HW initialization X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Initialize the hardware by resetting the hardware in base code. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/base/ngbe_dummy.h | 21 +++ drivers/net/ngbe/base/ngbe_hw.c | 235 +++++++++++++++++++++++++++++ drivers/net/ngbe/base/ngbe_hw.h | 9 ++ drivers/net/ngbe/base/ngbe_type.h | 30 ++++ drivers/net/ngbe/ngbe_ethdev.c | 17 +++ 5 files changed, 312 insertions(+) diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h index ade03eae81..d0081acc2b 100644 --- a/drivers/net/ngbe/base/ngbe_dummy.h +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -38,6 +38,19 @@ static inline s32 ngbe_rom_validate_checksum_dummy(struct ngbe_hw *TUP0, { return NGBE_ERR_OPS_DUMMY; } +/* struct ngbe_mac_operations */ +static inline s32 ngbe_mac_init_hw_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_mac_reset_hw_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_mac_stop_hw_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline s32 ngbe_mac_acquire_swfw_sync_dummy(struct ngbe_hw *TUP0, u32 TUP1) { @@ -47,13 +60,21 @@ static inline void ngbe_mac_release_swfw_sync_dummy(struct ngbe_hw *TUP0, u32 TUP1) { } +static inline s32 ngbe_mac_init_thermal_ssth_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) { hw->bus.set_lan_id = ngbe_bus_set_lan_id_dummy; hw->rom.init_params = ngbe_rom_init_params_dummy; hw->rom.validate_checksum = ngbe_rom_validate_checksum_dummy; + hw->mac.init_hw = ngbe_mac_init_hw_dummy; + hw->mac.reset_hw = ngbe_mac_reset_hw_dummy; + hw->mac.stop_hw = ngbe_mac_stop_hw_dummy; hw->mac.acquire_swfw_sync = ngbe_mac_acquire_swfw_sync_dummy; hw->mac.release_swfw_sync = ngbe_mac_release_swfw_sync_dummy; + hw->mac.init_thermal_sensor_thresh = ngbe_mac_init_thermal_ssth_dummy; } #endif /* _NGBE_TYPE_DUMMY_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index de6b75e1c0..9fa40f7de1 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -8,6 +8,133 @@ #include "ngbe_mng.h" #include "ngbe_hw.h" +/** + * ngbe_init_hw - Generic hardware initialization + * @hw: pointer to hardware structure + * + * Initialize the hardware by resetting the hardware, filling the bus info + * structure and media type, clears all on chip counters, initializes receive + * address registers, multicast table, VLAN filter table, calls routine to set + * up link and flow control settings, and leaves transmit and receive units + * disabled and uninitialized + **/ +s32 ngbe_init_hw(struct ngbe_hw *hw) +{ + s32 status; + + DEBUGFUNC("ngbe_init_hw"); + + /* Reset the hardware */ + status = hw->mac.reset_hw(hw); + + if (status != 0) + DEBUGOUT("Failed to initialize HW, STATUS = %d\n", status); + + return status; +} + +static void +ngbe_reset_misc_em(struct ngbe_hw *hw) +{ + int i; + + wr32(hw, NGBE_ISBADDRL, hw->isb_dma & 0xFFFFFFFF); + wr32(hw, NGBE_ISBADDRH, hw->isb_dma >> 32); + + /* receive packets that size > 2048 */ + wr32m(hw, NGBE_MACRXCFG, + NGBE_MACRXCFG_JUMBO, NGBE_MACRXCFG_JUMBO); + + wr32m(hw, NGBE_FRMSZ, NGBE_FRMSZ_MAX_MASK, + NGBE_FRMSZ_MAX(NGBE_FRAME_SIZE_DFT)); + + /* clear counters on read */ + wr32m(hw, NGBE_MACCNTCTL, + NGBE_MACCNTCTL_RC, NGBE_MACCNTCTL_RC); + + wr32m(hw, NGBE_RXFCCFG, + NGBE_RXFCCFG_FC, NGBE_RXFCCFG_FC); + wr32m(hw, NGBE_TXFCCFG, + NGBE_TXFCCFG_FC, NGBE_TXFCCFG_FC); + + wr32m(hw, NGBE_MACRXFLT, + NGBE_MACRXFLT_PROMISC, NGBE_MACRXFLT_PROMISC); + + wr32m(hw, NGBE_RSTSTAT, + NGBE_RSTSTAT_TMRINIT_MASK, NGBE_RSTSTAT_TMRINIT(30)); + + /* errata 4: initialize mng flex tbl and wakeup flex tbl*/ + wr32(hw, NGBE_MNGFLEXSEL, 0); + for (i = 0; i < 16; i++) { + wr32(hw, NGBE_MNGFLEXDWL(i), 0); + wr32(hw, NGBE_MNGFLEXDWH(i), 0); + wr32(hw, NGBE_MNGFLEXMSK(i), 0); + } + wr32(hw, NGBE_LANFLEXSEL, 0); + for (i = 0; i < 16; i++) { + wr32(hw, NGBE_LANFLEXDWL(i), 0); + wr32(hw, NGBE_LANFLEXDWH(i), 0); + wr32(hw, NGBE_LANFLEXMSK(i), 0); + } + + /* set pause frame dst mac addr */ + wr32(hw, NGBE_RXPBPFCDMACL, 0xC2000001); + wr32(hw, NGBE_RXPBPFCDMACH, 0x0180); + + wr32(hw, NGBE_MDIOMODE, 0xF); + + wr32m(hw, NGBE_GPIE, NGBE_GPIE_MSIX, NGBE_GPIE_MSIX); + + if ((hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_M88E1512_SFP || + (hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_YT8521S_SFP) { + /* gpio0 is used to power on/off control*/ + wr32(hw, NGBE_GPIODIR, NGBE_GPIODIR_DDR(1)); + wr32(hw, NGBE_GPIODATA, NGBE_GPIOBIT_0); + } + + hw->mac.init_thermal_sensor_thresh(hw); + + /* enable mac transmiter */ + wr32m(hw, NGBE_MACTXCFG, NGBE_MACTXCFG_TE, NGBE_MACTXCFG_TE); + + /* sellect GMII */ + wr32m(hw, NGBE_MACTXCFG, + NGBE_MACTXCFG_SPEED_MASK, NGBE_MACTXCFG_SPEED_1G); + + for (i = 0; i < 4; i++) + wr32m(hw, NGBE_IVAR(i), 0x80808080, 0); +} + +/** + * ngbe_reset_hw_em - Perform hardware reset + * @hw: pointer to hardware structure + * + * Resets the hardware by resetting the transmit and receive units, masks + * and clears all interrupts, perform a PHY reset, and perform a link (MAC) + * reset. + **/ +s32 ngbe_reset_hw_em(struct ngbe_hw *hw) +{ + s32 status; + + DEBUGFUNC("ngbe_reset_hw_em"); + + /* Call adapter stop to disable tx/rx and clear interrupts */ + status = hw->mac.stop_hw(hw); + if (status != 0) + return status; + + wr32(hw, NGBE_RST, NGBE_RST_LAN(hw->bus.lan_id)); + ngbe_flush(hw); + msec_delay(50); + + ngbe_reset_misc_em(hw); + + msec_delay(50); + + return status; +} + /** * ngbe_set_lan_id_multi_port - Set LAN id for PCIe multiple port devices * @hw: pointer to the HW structure @@ -27,6 +154,57 @@ void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw) bus->func = bus->lan_id; } +/** + * ngbe_stop_hw - Generic stop Tx/Rx units + * @hw: pointer to hardware structure + * + * Sets the adapter_stopped flag within ngbe_hw struct. Clears interrupts, + * disables transmit and receive units. The adapter_stopped flag is used by + * the shared code and drivers to determine if the adapter is in a stopped + * state and should not touch the hardware. + **/ +s32 ngbe_stop_hw(struct ngbe_hw *hw) +{ + u32 reg_val; + u16 i; + + DEBUGFUNC("ngbe_stop_hw"); + + /* + * Set the adapter_stopped flag so other driver functions stop touching + * the hardware + */ + hw->adapter_stopped = true; + + /* Disable the receive unit */ + ngbe_disable_rx(hw); + + /* Clear interrupt mask to stop interrupts from being generated */ + wr32(hw, NGBE_IENMISC, 0); + wr32(hw, NGBE_IMS(0), NGBE_IMS_MASK); + + /* Clear any pending interrupts, flush previous writes */ + wr32(hw, NGBE_ICRMISC, NGBE_ICRMISC_MASK); + wr32(hw, NGBE_ICR(0), NGBE_ICR_MASK); + + /* Disable the transmit unit. Each queue must be disabled. */ + for (i = 0; i < hw->mac.max_tx_queues; i++) + wr32(hw, NGBE_TXCFG(i), NGBE_TXCFG_FLUSH); + + /* Disable the receive unit by stopping each queue */ + for (i = 0; i < hw->mac.max_rx_queues; i++) { + reg_val = rd32(hw, NGBE_RXCFG(i)); + reg_val &= ~NGBE_RXCFG_ENA; + wr32(hw, NGBE_RXCFG(i), reg_val); + } + + /* flush all queues disables */ + ngbe_flush(hw); + msec_delay(2); + + return 0; +} + /** * ngbe_acquire_swfw_sync - Acquire SWFW semaphore * @hw: pointer to hardware structure @@ -98,6 +276,54 @@ void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask) ngbe_release_eeprom_semaphore(hw); } +/** + * ngbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds + * @hw: pointer to hardware structure + * + * Inits the thermal sensor thresholds according to the NVM map + * and save off the threshold and location values into mac.thermal_sensor_data + **/ +s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw) +{ + struct ngbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data; + + DEBUGFUNC("ngbe_init_thermal_sensor_thresh"); + + memset(data, 0, sizeof(struct ngbe_thermal_sensor_data)); + + if (hw->bus.lan_id != 0) + return NGBE_NOT_IMPLEMENTED; + + wr32(hw, NGBE_TSINTR, + NGBE_TSINTR_AEN | NGBE_TSINTR_DEN); + wr32(hw, NGBE_TSEN, NGBE_TSEN_ENA); + + + data->sensor[0].alarm_thresh = 115; + wr32(hw, NGBE_TSATHRE, 0x344); + data->sensor[0].dalarm_thresh = 110; + wr32(hw, NGBE_TSDTHRE, 0x330); + + return 0; +} + +void ngbe_disable_rx(struct ngbe_hw *hw) +{ + u32 pfdtxgswc; + + pfdtxgswc = rd32(hw, NGBE_PSRCTL); + if (pfdtxgswc & NGBE_PSRCTL_LBENA) { + pfdtxgswc &= ~NGBE_PSRCTL_LBENA; + wr32(hw, NGBE_PSRCTL, pfdtxgswc); + hw->mac.set_lben = true; + } else { + hw->mac.set_lben = false; + } + + wr32m(hw, NGBE_PBRXCTL, NGBE_PBRXCTL_ENA, 0); + wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, 0); +} + /** * ngbe_set_mac_type - Sets MAC type * @hw: pointer to the HW structure @@ -216,13 +442,22 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) bus->set_lan_id = ngbe_set_lan_id_multi_port; /* MAC */ + mac->init_hw = ngbe_init_hw; + mac->reset_hw = ngbe_reset_hw_em; + mac->stop_hw = ngbe_stop_hw; mac->acquire_swfw_sync = ngbe_acquire_swfw_sync; mac->release_swfw_sync = ngbe_release_swfw_sync; + /* Manageability interface */ + mac->init_thermal_sensor_thresh = ngbe_init_thermal_sensor_thresh; + /* EEPROM */ rom->init_params = ngbe_init_eeprom_params; rom->validate_checksum = ngbe_validate_eeprom_checksum_em; + mac->max_rx_queues = NGBE_EM_MAX_RX_QUEUES; + mac->max_tx_queues = NGBE_EM_MAX_TX_QUEUES; + return 0; } diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h index 5e508fb67f..39b2fe696b 100644 --- a/drivers/net/ngbe/base/ngbe_hw.h +++ b/drivers/net/ngbe/base/ngbe_hw.h @@ -8,11 +8,20 @@ #include "ngbe_type.h" +#define NGBE_EM_MAX_TX_QUEUES 8 +#define NGBE_EM_MAX_RX_QUEUES 8 + +s32 ngbe_init_hw(struct ngbe_hw *hw); +s32 ngbe_reset_hw_em(struct ngbe_hw *hw); +s32 ngbe_stop_hw(struct ngbe_hw *hw); + void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw); s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask); void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask); +s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw); +void ngbe_disable_rx(struct ngbe_hw *hw); s32 ngbe_init_shared_code(struct ngbe_hw *hw); s32 ngbe_set_mac_type(struct ngbe_hw *hw); s32 ngbe_init_ops_pf(struct ngbe_hw *hw); diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index c727338bd5..55c686c0a3 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -6,10 +6,25 @@ #ifndef _NGBE_TYPE_H_ #define _NGBE_TYPE_H_ +#define NGBE_FRAME_SIZE_DFT (1522) /* Default frame size, +FCS */ + +#define NGBE_ALIGN 128 /* as intel did */ +#define NGBE_ISB_SIZE 16 + #include "ngbe_status.h" #include "ngbe_osdep.h" #include "ngbe_devids.h" +struct ngbe_thermal_diode_data { + s16 temp; + s16 alarm_thresh; + s16 dalarm_thresh; +}; + +struct ngbe_thermal_sensor_data { + struct ngbe_thermal_diode_data sensor[1]; +}; + enum ngbe_eeprom_type { ngbe_eeprom_unknown = 0, ngbe_eeprom_spi, @@ -71,9 +86,20 @@ struct ngbe_rom_info { }; struct ngbe_mac_info { + s32 (*init_hw)(struct ngbe_hw *hw); + s32 (*reset_hw)(struct ngbe_hw *hw); + s32 (*stop_hw)(struct ngbe_hw *hw); s32 (*acquire_swfw_sync)(struct ngbe_hw *hw, u32 mask); void (*release_swfw_sync)(struct ngbe_hw *hw, u32 mask); + + /* Manageability interface */ + s32 (*init_thermal_sensor_thresh)(struct ngbe_hw *hw); + enum ngbe_mac_type type; + u32 max_tx_queues; + u32 max_rx_queues; + struct ngbe_thermal_sensor_data thermal_sensor_data; + bool set_lben; }; struct ngbe_phy_info { @@ -92,6 +118,10 @@ struct ngbe_hw { u16 vendor_id; u16 sub_device_id; u16 sub_system_id; + bool adapter_stopped; + + uint64_t isb_dma; + void IOMEM *isb_mem; bool is_pf; }; diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index c779c46dd5..31d4dda976 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -60,6 +60,7 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) { struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); + const struct rte_memzone *mz; int err; PMD_INIT_FUNC_TRACE(); @@ -76,6 +77,15 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) ngbe_map_device_id(hw); hw->hw_addr = (void *)pci_dev->mem_resource[0].addr; + /* Reserve memory for interrupt status block */ + mz = rte_eth_dma_zone_reserve(eth_dev, "ngbe_driver", -1, + NGBE_ISB_SIZE, NGBE_ALIGN, SOCKET_ID_ANY); + if (mz == NULL) + return -ENOMEM; + + hw->isb_dma = TMZ_PADDR(mz); + hw->isb_mem = TMZ_VADDR(mz); + /* Initialize the shared code (base driver) */ err = ngbe_init_shared_code(hw); if (err != 0) { @@ -99,6 +109,13 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) return -EIO; } + err = hw->mac.init_hw(hw); + + if (err != 0) { + PMD_INIT_LOG(ERR, "Hardware Initialization Failure: %d", err); + return -EIO; + } + return 0; } From patchwork Thu Jun 17 10:59:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94333 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D2CC3A0C4D; Thu, 17 Jun 2021 12:59:10 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0A09A41139; Thu, 17 Jun 2021 12:58:27 +0200 (CEST) Received: from smtpbgau2.qq.com (smtpbgau2.qq.com [54.206.34.216]) by mails.dpdk.org (Postfix) with ESMTP id 7C3DD41136 for ; Thu, 17 Jun 2021 12:58:24 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927499tmuhuiac Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:18 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: PAtBXkQ2bGBlEDPZc3Oho6FtHxw9Jf9jSfOfG/rYoVvsBYNjbuqFm5hjA56xb zNengHWTu+FwMy66NotKvZ8WKVjr/x/0B98N8oA1ST+fqtkXrkrEBrB3QTvX7Pw3y4wSZ++ DK+tZUU/Ol1Dfnks7BQaoQqRZfH3Qpledzb58vONszzChnGdgA7L1pjXB9Jd7laUu/zSAdN K3wHMRXsRb3LFtnfAn3yGQNHcLIsnK4tUxEKHVi6dnbDN4BmWxX1ij9MprTtQ3gb/mwCnpa lUu/vBtF6ogu9DzctZ/28nMxXQWDeNzALx9+eAU8+dJ8Oh5WpZEAEpODQ1Bh/UX/fXgtRz8 JH2VHerHI1MMUlJvOOrfRN1VOmobw== X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:54 +0800 Message-Id: <20210617110005.4132926-9-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign5 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 08/19] net/ngbe: identify PHY and reset PHY X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Identify PHY to get the PHY type, and perform a PHY reset. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/base/meson.build | 4 + drivers/net/ngbe/base/ngbe_dummy.h | 40 +++ drivers/net/ngbe/base/ngbe_hw.c | 40 ++- drivers/net/ngbe/base/ngbe_hw.h | 2 + drivers/net/ngbe/base/ngbe_phy.c | 426 +++++++++++++++++++++++++++ drivers/net/ngbe/base/ngbe_phy.h | 60 ++++ drivers/net/ngbe/base/ngbe_phy_mvl.c | 89 ++++++ drivers/net/ngbe/base/ngbe_phy_mvl.h | 92 ++++++ drivers/net/ngbe/base/ngbe_phy_rtl.c | 65 ++++ drivers/net/ngbe/base/ngbe_phy_rtl.h | 83 ++++++ drivers/net/ngbe/base/ngbe_phy_yt.c | 112 +++++++ drivers/net/ngbe/base/ngbe_phy_yt.h | 67 +++++ drivers/net/ngbe/base/ngbe_type.h | 17 ++ 13 files changed, 1096 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ngbe/base/ngbe_phy.c create mode 100644 drivers/net/ngbe/base/ngbe_phy.h create mode 100644 drivers/net/ngbe/base/ngbe_phy_mvl.c create mode 100644 drivers/net/ngbe/base/ngbe_phy_mvl.h create mode 100644 drivers/net/ngbe/base/ngbe_phy_rtl.c create mode 100644 drivers/net/ngbe/base/ngbe_phy_rtl.h create mode 100644 drivers/net/ngbe/base/ngbe_phy_yt.c create mode 100644 drivers/net/ngbe/base/ngbe_phy_yt.h diff --git a/drivers/net/ngbe/base/meson.build b/drivers/net/ngbe/base/meson.build index ddd122ec45..146134f671 100644 --- a/drivers/net/ngbe/base/meson.build +++ b/drivers/net/ngbe/base/meson.build @@ -5,6 +5,10 @@ sources = [ 'ngbe_eeprom.c', 'ngbe_hw.c', 'ngbe_mng.c', + 'ngbe_phy.c', + 'ngbe_phy_rtl.c', + 'ngbe_phy_mvl.c', + 'ngbe_phy_yt.c', ] error_cflags = [] diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h index d0081acc2b..15017cfd82 100644 --- a/drivers/net/ngbe/base/ngbe_dummy.h +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -64,6 +64,39 @@ static inline s32 ngbe_mac_init_thermal_ssth_dummy(struct ngbe_hw *TUP0) { return NGBE_ERR_OPS_DUMMY; } +static inline s32 ngbe_mac_check_overtemp_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} +/* struct ngbe_phy_operations */ +static inline s32 ngbe_phy_identify_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_phy_reset_hw_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_phy_read_reg_dummy(struct ngbe_hw *TUP0, u32 TUP1, + u32 TUP2, u16 *TUP3) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_phy_write_reg_dummy(struct ngbe_hw *TUP0, u32 TUP1, + u32 TUP2, u16 TUP3) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_phy_read_reg_unlocked_dummy(struct ngbe_hw *TUP0, + u32 TUP1, u32 TUP2, u16 *TUP3) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_phy_write_reg_unlocked_dummy(struct ngbe_hw *TUP0, + u32 TUP1, u32 TUP2, u16 TUP3) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) { hw->bus.set_lan_id = ngbe_bus_set_lan_id_dummy; @@ -75,6 +108,13 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) hw->mac.acquire_swfw_sync = ngbe_mac_acquire_swfw_sync_dummy; hw->mac.release_swfw_sync = ngbe_mac_release_swfw_sync_dummy; hw->mac.init_thermal_sensor_thresh = ngbe_mac_init_thermal_ssth_dummy; + hw->mac.check_overtemp = ngbe_mac_check_overtemp_dummy; + hw->phy.identify = ngbe_phy_identify_dummy; + hw->phy.reset_hw = ngbe_phy_reset_hw_dummy; + hw->phy.read_reg = ngbe_phy_read_reg_dummy; + hw->phy.write_reg = ngbe_phy_write_reg_dummy; + hw->phy.read_reg_unlocked = ngbe_phy_read_reg_unlocked_dummy; + hw->phy.write_reg_unlocked = ngbe_phy_write_reg_unlocked_dummy; } #endif /* _NGBE_TYPE_DUMMY_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index 9fa40f7de1..5723213209 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -4,6 +4,7 @@ */ #include "ngbe_type.h" +#include "ngbe_phy.h" #include "ngbe_eeprom.h" #include "ngbe_mng.h" #include "ngbe_hw.h" @@ -94,7 +95,7 @@ ngbe_reset_misc_em(struct ngbe_hw *hw) hw->mac.init_thermal_sensor_thresh(hw); - /* enable mac transmiter */ + /* enable mac transmitter */ wr32m(hw, NGBE_MACTXCFG, NGBE_MACTXCFG_TE, NGBE_MACTXCFG_TE); /* sellect GMII */ @@ -124,6 +125,15 @@ s32 ngbe_reset_hw_em(struct ngbe_hw *hw) if (status != 0) return status; + /* Identify PHY and related function pointers */ + status = ngbe_init_phy(hw); + if (status) + return status; + + /* Reset PHY */ + if (!hw->phy.reset_disable) + hw->phy.reset_hw(hw); + wr32(hw, NGBE_RST, NGBE_RST_LAN(hw->bus.lan_id)); ngbe_flush(hw); msec_delay(50); @@ -307,6 +317,24 @@ s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw) return 0; } +s32 ngbe_mac_check_overtemp(struct ngbe_hw *hw) +{ + s32 status = 0; + u32 ts_state; + + DEBUGFUNC("ngbe_mac_check_overtemp"); + + /* Check that the LASI temp alarm status was triggered */ + ts_state = rd32(hw, NGBE_TSALM); + + if (ts_state & NGBE_TSALM_HI) + status = NGBE_ERR_UNDERTEMP; + else if (ts_state & NGBE_TSALM_LO) + status = NGBE_ERR_OVERTEMP; + + return status; +} + void ngbe_disable_rx(struct ngbe_hw *hw) { u32 pfdtxgswc; @@ -434,6 +462,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) { struct ngbe_bus_info *bus = &hw->bus; struct ngbe_mac_info *mac = &hw->mac; + struct ngbe_phy_info *phy = &hw->phy; struct ngbe_rom_info *rom = &hw->rom; DEBUGFUNC("ngbe_init_ops_pf"); @@ -441,6 +470,14 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) /* BUS */ bus->set_lan_id = ngbe_set_lan_id_multi_port; + /* PHY */ + phy->identify = ngbe_identify_phy; + phy->read_reg = ngbe_read_phy_reg; + phy->write_reg = ngbe_write_phy_reg; + phy->read_reg_unlocked = ngbe_read_phy_reg_mdi; + phy->write_reg_unlocked = ngbe_write_phy_reg_mdi; + phy->reset_hw = ngbe_reset_phy; + /* MAC */ mac->init_hw = ngbe_init_hw; mac->reset_hw = ngbe_reset_hw_em; @@ -450,6 +487,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) /* Manageability interface */ mac->init_thermal_sensor_thresh = ngbe_init_thermal_sensor_thresh; + mac->check_overtemp = ngbe_mac_check_overtemp; /* EEPROM */ rom->init_params = ngbe_init_eeprom_params; diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h index 39b2fe696b..3c8e646bb7 100644 --- a/drivers/net/ngbe/base/ngbe_hw.h +++ b/drivers/net/ngbe/base/ngbe_hw.h @@ -21,10 +21,12 @@ s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask); void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask); s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw); +s32 ngbe_mac_check_overtemp(struct ngbe_hw *hw); void ngbe_disable_rx(struct ngbe_hw *hw); s32 ngbe_init_shared_code(struct ngbe_hw *hw); s32 ngbe_set_mac_type(struct ngbe_hw *hw); s32 ngbe_init_ops_pf(struct ngbe_hw *hw); +s32 ngbe_init_phy(struct ngbe_hw *hw); void ngbe_map_device_id(struct ngbe_hw *hw); #endif /* _NGBE_HW_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_phy.c b/drivers/net/ngbe/base/ngbe_phy.c new file mode 100644 index 0000000000..0467e1e66e --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_phy.c @@ -0,0 +1,426 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#include "ngbe_hw.h" +#include "ngbe_phy.h" + +s32 ngbe_mdi_map_register(mdi_reg_t *reg, mdi_reg_22_t *reg22) +{ + bool match = 1; + switch (reg->device_type) { + case NGBE_MD_DEV_PMA_PMD: + switch (reg->addr) { + case NGBE_MD_PHY_ID_HIGH: + case NGBE_MD_PHY_ID_LOW: + reg22->page = 0; + reg22->addr = reg->addr; + reg22->device_type = 0; + break; + default: + match = 0; + } + break; + default: + match = 0; + break; + } + + if (!match) { + reg22->page = reg->device_type; + reg22->device_type = reg->device_type; + reg22->addr = reg->addr; + } + + return 0; +} + +/** + * ngbe_probe_phy - Identify a single address for a PHY + * @hw: pointer to hardware structure + * @phy_addr: PHY address to probe + * + * Returns true if PHY found + */ +static bool ngbe_probe_phy(struct ngbe_hw *hw, u16 phy_addr) +{ + if (!ngbe_validate_phy_addr(hw, phy_addr)) { + DEBUGOUT("Unable to validate PHY address 0x%04X\n", + phy_addr); + return false; + } + + if (ngbe_get_phy_id(hw)) + return false; + + hw->phy.type = ngbe_get_phy_type_from_id(hw); + if (hw->phy.type == ngbe_phy_unknown) + return false; + + return true; +} + +/** + * ngbe_identify_phy - Get physical layer module + * @hw: pointer to hardware structure + * + * Determines the physical layer module found on the current adapter. + **/ +s32 ngbe_identify_phy(struct ngbe_hw *hw) +{ + s32 err = NGBE_ERR_PHY_ADDR_INVALID; + u16 phy_addr; + + DEBUGFUNC("ngbe_identify_phy"); + + if (hw->phy.type != ngbe_phy_unknown) + return 0; + + /* select clause22 */ + wr32(hw, NGBE_MDIOMODE, NGBE_MDIOMODE_MASK); + + for (phy_addr = 0; phy_addr < NGBE_MAX_PHY_ADDR; phy_addr++) { + if (ngbe_probe_phy(hw, phy_addr)) { + err = 0; + break; + } + } + + return err; +} + +/** + * ngbe_check_reset_blocked - check status of MNG FW veto bit + * @hw: pointer to the hardware structure + * + * This function checks the STAT.MNGVETO bit to see if there are + * any constraints on link from manageability. For MAC's that don't + * have this bit just return faluse since the link can not be blocked + * via this method. + **/ +s32 ngbe_check_reset_blocked(struct ngbe_hw *hw) +{ + u32 mmngc; + + DEBUGFUNC("ngbe_check_reset_blocked"); + + mmngc = rd32(hw, NGBE_STAT); + if (mmngc & NGBE_STAT_MNGVETO) { + DEBUGOUT("MNG_VETO bit detected.\n"); + return true; + } + + return false; +} + +/** + * ngbe_validate_phy_addr - Determines phy address is valid + * @hw: pointer to hardware structure + * @phy_addr: PHY address + * + **/ +bool ngbe_validate_phy_addr(struct ngbe_hw *hw, u32 phy_addr) +{ + u16 phy_id = 0; + bool valid = false; + + DEBUGFUNC("ngbe_validate_phy_addr"); + + if (hw->sub_device_id == NGBE_SUB_DEV_ID_EM_YT8521S_SFP) + return true; + + hw->phy.addr = phy_addr; + hw->phy.read_reg(hw, NGBE_MD_PHY_ID_HIGH, + NGBE_MD_DEV_PMA_PMD, &phy_id); + + if (phy_id != 0xFFFF && phy_id != 0x0) + valid = true; + + DEBUGOUT("PHY ID HIGH is 0x%04X\n", phy_id); + + return valid; +} + +/** + * ngbe_get_phy_id - Get the phy ID + * @hw: pointer to hardware structure + * + **/ +s32 ngbe_get_phy_id(struct ngbe_hw *hw) +{ + u32 err; + u16 phy_id_high = 0; + u16 phy_id_low = 0; + + DEBUGFUNC("ngbe_get_phy_id"); + + err = hw->phy.read_reg(hw, NGBE_MD_PHY_ID_HIGH, + NGBE_MD_DEV_PMA_PMD, + &phy_id_high); + hw->phy.id = (u32)(phy_id_high << 16); + + err = hw->phy.read_reg(hw, NGBE_MD_PHY_ID_LOW, + NGBE_MD_DEV_PMA_PMD, + &phy_id_low); + hw->phy.id |= (u32)(phy_id_low & NGBE_PHY_REVISION_MASK); + hw->phy.revision = (u32)(phy_id_low & ~NGBE_PHY_REVISION_MASK); + + DEBUGOUT("PHY_ID_HIGH 0x%04X, PHY_ID_LOW 0x%04X\n", + phy_id_high, phy_id_low); + + return err; +} + +/** + * ngbe_get_phy_type_from_id - Get the phy type + * @phy_id: PHY ID information + * + **/ +enum ngbe_phy_type ngbe_get_phy_type_from_id(struct ngbe_hw *hw) +{ + enum ngbe_phy_type phy_type; + + DEBUGFUNC("ngbe_get_phy_type_from_id"); + + switch (hw->phy.id) { + case NGBE_PHYID_RTL: + phy_type = ngbe_phy_rtl; + break; + case NGBE_PHYID_MVL: + if (hw->phy.media_type == ngbe_media_type_fiber) + phy_type = ngbe_phy_mvl_sfi; + else + phy_type = ngbe_phy_mvl; + break; + case NGBE_PHYID_YT: + if (hw->phy.media_type == ngbe_media_type_fiber) + phy_type = ngbe_phy_yt8521s_sfi; + else + phy_type = ngbe_phy_yt8521s; + break; + default: + phy_type = ngbe_phy_unknown; + break; + } + + return phy_type; +} + +/** + * ngbe_reset_phy - Performs a PHY reset + * @hw: pointer to hardware structure + **/ +s32 ngbe_reset_phy(struct ngbe_hw *hw) +{ + s32 err = 0; + + DEBUGFUNC("ngbe_reset_phy"); + + if (hw->phy.type == ngbe_phy_unknown) + err = ngbe_identify_phy(hw); + + if (err != 0 || hw->phy.type == ngbe_phy_none) + return err; + + /* Don't reset PHY if it's shut down due to overtemp. */ + if (hw->mac.check_overtemp(hw) == NGBE_ERR_OVERTEMP) + return err; + + /* Blocked by MNG FW so bail */ + if (ngbe_check_reset_blocked(hw)) + return err; + + switch (hw->phy.type) { + case ngbe_phy_rtl: + err = ngbe_reset_phy_rtl(hw); + break; + case ngbe_phy_mvl: + case ngbe_phy_mvl_sfi: + err = ngbe_reset_phy_mvl(hw); + break; + case ngbe_phy_yt8521s: + case ngbe_phy_yt8521s_sfi: + err = ngbe_reset_phy_yt(hw); + break; + default: + break; + } + + return err; +} + +/** + * ngbe_read_phy_mdi - Reads a value from a specified PHY register without + * the SWFW lock + * @hw: pointer to hardware structure + * @reg_addr: 32 bit address of PHY register to read + * @device_type: 5 bit device type + * @phy_data: Pointer to read data from PHY register + **/ +s32 ngbe_read_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, + u16 *phy_data) +{ + u32 command, data; + + /* Setup and write the address cycle command */ + command = NGBE_MDIOSCA_REG(reg_addr) | + NGBE_MDIOSCA_DEV(device_type) | + NGBE_MDIOSCA_PORT(hw->phy.addr); + wr32(hw, NGBE_MDIOSCA, command); + + command = NGBE_MDIOSCD_CMD_READ | + NGBE_MDIOSCD_BUSY | + NGBE_MDIOSCD_CLOCK(6); + wr32(hw, NGBE_MDIOSCD, command); + + /* + * Check every 10 usec to see if the address cycle completed. + * The MDI Command bit will clear when the operation is + * complete + */ + if (!po32m(hw, NGBE_MDIOSCD, NGBE_MDIOSCD_BUSY, + 0, NULL, 100, 100)) { + DEBUGOUT("PHY address command did not complete\n"); + return NGBE_ERR_PHY; + } + + data = rd32(hw, NGBE_MDIOSCD); + *phy_data = (u16)NGBE_MDIOSCD_DAT_R(data); + + return 0; +} + +/** + * ngbe_read_phy_reg - Reads a value from a specified PHY register + * using the SWFW lock - this function is needed in most cases + * @hw: pointer to hardware structure + * @reg_addr: 32 bit address of PHY register to read + * @device_type: 5 bit device type + * @phy_data: Pointer to read data from PHY register + **/ +s32 ngbe_read_phy_reg(struct ngbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data) +{ + s32 err; + u32 gssr = hw->phy.phy_semaphore_mask; + + DEBUGFUNC("ngbe_read_phy_reg"); + + if (hw->mac.acquire_swfw_sync(hw, gssr)) + return NGBE_ERR_SWFW_SYNC; + + err = hw->phy.read_reg_unlocked(hw, reg_addr, device_type, + phy_data); + + hw->mac.release_swfw_sync(hw, gssr); + + return err; +} + +/** + * ngbe_write_phy_reg_mdi - Writes a value to specified PHY register + * without SWFW lock + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: 5 bit device type + * @phy_data: Data to write to the PHY register + **/ +s32 ngbe_write_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data) +{ + u32 command; + + /* write command */ + command = NGBE_MDIOSCA_REG(reg_addr) | + NGBE_MDIOSCA_DEV(device_type) | + NGBE_MDIOSCA_PORT(hw->phy.addr); + wr32(hw, NGBE_MDIOSCA, command); + + command = NGBE_MDIOSCD_CMD_WRITE | + NGBE_MDIOSCD_DAT(phy_data) | + NGBE_MDIOSCD_BUSY | + NGBE_MDIOSCD_CLOCK(6); + wr32(hw, NGBE_MDIOSCD, command); + + /* wait for completion */ + if (!po32m(hw, NGBE_MDIOSCD, NGBE_MDIOSCD_BUSY, + 0, NULL, 100, 100)) { + TLOG_DEBUG("PHY write cmd didn't complete\n"); + return NGBE_ERR_PHY; + } + + return 0; +} + +/** + * ngbe_write_phy_reg - Writes a value to specified PHY register + * using SWFW lock- this function is needed in most cases + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: 5 bit device type + * @phy_data: Data to write to the PHY register + **/ +s32 ngbe_write_phy_reg(struct ngbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data) +{ + s32 err; + u32 gssr = hw->phy.phy_semaphore_mask; + + DEBUGFUNC("ngbe_write_phy_reg"); + + if (hw->mac.acquire_swfw_sync(hw, gssr)) + err = NGBE_ERR_SWFW_SYNC; + + err = hw->phy.write_reg_unlocked(hw, reg_addr, device_type, + phy_data); + + hw->mac.release_swfw_sync(hw, gssr); + + return err; +} + +/** + * ngbe_init_phy - PHY specific init + * @hw: pointer to hardware structure + * + * Initialize any function pointers that were not able to be + * set during init_shared_code because the PHY type was + * not known. + * + **/ +s32 ngbe_init_phy(struct ngbe_hw *hw) +{ + struct ngbe_phy_info *phy = &hw->phy; + s32 err = 0; + + DEBUGFUNC("ngbe_init_phy"); + + hw->phy.addr = 0; + + switch (hw->sub_device_id) { + case NGBE_SUB_DEV_ID_EM_RTL_SGMII: + hw->phy.read_reg_unlocked = ngbe_read_phy_reg_rtl; + hw->phy.write_reg_unlocked = ngbe_write_phy_reg_rtl; + break; + case NGBE_SUB_DEV_ID_EM_MVL_RGMII: + case NGBE_SUB_DEV_ID_EM_MVL_SFP: + hw->phy.read_reg_unlocked = ngbe_read_phy_reg_mvl; + hw->phy.write_reg_unlocked = ngbe_write_phy_reg_mvl; + break; + case NGBE_SUB_DEV_ID_EM_YT8521S_SFP: + hw->phy.read_reg_unlocked = ngbe_read_phy_reg_yt; + hw->phy.write_reg_unlocked = ngbe_write_phy_reg_yt; + break; + default: + break; + } + + hw->phy.phy_semaphore_mask = NGBE_MNGSEM_SWPHY; + + /* Identify the PHY */ + err = phy->identify(hw); + + return err; +} + diff --git a/drivers/net/ngbe/base/ngbe_phy.h b/drivers/net/ngbe/base/ngbe_phy.h new file mode 100644 index 0000000000..59d9efe025 --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_phy.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _NGBE_PHY_H_ +#define _NGBE_PHY_H_ + +#include "ngbe_type.h" +#include "ngbe_phy_rtl.h" +#include "ngbe_phy_mvl.h" +#include "ngbe_phy_yt.h" + +/****************************************************************************** + * PHY MDIO Registers: + ******************************************************************************/ +#define NGBE_MAX_PHY_ADDR 32 + +/* (dev_type = 1) */ +#define NGBE_MD_DEV_PMA_PMD 0x1 +#define NGBE_MD_PHY_ID_HIGH 0x2 /* PHY ID High Reg*/ +#define NGBE_MD_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/ +#define NGBE_PHY_REVISION_MASK 0xFFFFFFF0 + +/* IEEE 802.3 Clause 22 */ +struct mdi_reg_22 { + u16 page; + u16 addr; + u16 device_type; +}; +typedef struct mdi_reg_22 mdi_reg_22_t; + +/* IEEE 802.3ae Clause 45 */ +struct mdi_reg { + u16 device_type; + u16 addr; +}; +typedef struct mdi_reg mdi_reg_t; + +#define NGBE_MD22_PHY_ID_HIGH 0x2 /* PHY ID High Reg*/ +#define NGBE_MD22_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/ + +s32 ngbe_mdi_map_register(mdi_reg_t *reg, mdi_reg_22_t *reg22); + +bool ngbe_validate_phy_addr(struct ngbe_hw *hw, u32 phy_addr); +enum ngbe_phy_type ngbe_get_phy_type_from_id(struct ngbe_hw *hw); +s32 ngbe_get_phy_id(struct ngbe_hw *hw); +s32 ngbe_identify_phy(struct ngbe_hw *hw); +s32 ngbe_reset_phy(struct ngbe_hw *hw); +s32 ngbe_read_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, + u16 *phy_data); +s32 ngbe_write_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, + u16 phy_data); +s32 ngbe_read_phy_reg(struct ngbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data); +s32 ngbe_write_phy_reg(struct ngbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data); +s32 ngbe_check_reset_blocked(struct ngbe_hw *hw); + +#endif /* _NGBE_PHY_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.c b/drivers/net/ngbe/base/ngbe_phy_mvl.c new file mode 100644 index 0000000000..40419a61f6 --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_phy_mvl.c @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + */ + +#include "ngbe_phy_mvl.h" + +#define MVL_PHY_RST_WAIT_PERIOD 5 + +s32 ngbe_read_phy_reg_mvl(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 *phy_data) +{ + mdi_reg_t reg; + mdi_reg_22_t reg22; + + reg.device_type = device_type; + reg.addr = reg_addr; + + if (hw->phy.media_type == ngbe_media_type_fiber) + ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 1); + else + ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 0); + + ngbe_mdi_map_register(®, ®22); + + ngbe_read_phy_reg_mdi(hw, reg22.addr, reg22.device_type, phy_data); + + return 0; +} + +s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 phy_data) +{ + mdi_reg_t reg; + mdi_reg_22_t reg22; + + reg.device_type = device_type; + reg.addr = reg_addr; + + if (hw->phy.media_type == ngbe_media_type_fiber) + ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 1); + else + ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 0); + + ngbe_mdi_map_register(®, ®22); + + ngbe_write_phy_reg_mdi(hw, reg22.addr, reg22.device_type, phy_data); + + return 0; +} + +s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw) +{ + u32 i; + u16 ctrl = 0; + s32 status = 0; + + DEBUGFUNC("ngbe_reset_phy_mvl"); + + if (hw->phy.type != ngbe_phy_mvl && hw->phy.type != ngbe_phy_mvl_sfi) + return NGBE_ERR_PHY_TYPE; + + /* select page 18 reg 20 */ + status = ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 18); + + /* mode select to RGMII-to-copper or RGMII-to-sfi*/ + if (hw->phy.type == ngbe_phy_mvl) + ctrl = MVL_GEN_CTL_MODE_COPPER; + else + ctrl = MVL_GEN_CTL_MODE_FIBER; + status = ngbe_write_phy_reg_mdi(hw, MVL_GEN_CTL, 0, ctrl); + /* mode reset */ + ctrl |= MVL_GEN_CTL_RESET; + status = ngbe_write_phy_reg_mdi(hw, MVL_GEN_CTL, 0, ctrl); + + for (i = 0; i < MVL_PHY_RST_WAIT_PERIOD; i++) { + status = ngbe_read_phy_reg_mdi(hw, MVL_GEN_CTL, 0, &ctrl); + if (!(ctrl & MVL_GEN_CTL_RESET)) + break; + msleep(1); + } + + if (i == MVL_PHY_RST_WAIT_PERIOD) { + DEBUGOUT("PHY reset polling failed to complete.\n"); + return NGBE_ERR_RESET_FAILED; + } + + return status; +} + diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.h b/drivers/net/ngbe/base/ngbe_phy_mvl.h new file mode 100644 index 0000000000..a88ace9ec1 --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_phy_mvl.h @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + */ + +#include "ngbe_phy.h" + +#ifndef _NGBE_PHY_MVL_H_ +#define _NGBE_PHY_MVL_H_ + +#define NGBE_PHYID_MVL 0x01410DD0U + +/* Page 0 for Copper, Page 1 for Fiber */ +#define MVL_CTRL 0x0 +#define MVL_CTRL_RESET MS16(15, 0x1) +#define MVL_CTRL_ANE MS16(12, 0x1) +#define MVL_CTRL_RESTART_AN MS16(9, 0x1) +#define MVL_ANA 0x4 +/* copper */ +#define MVL_CANA_ASM_PAUSE MS16(11, 0x1) +#define MVL_CANA_PAUSE MS16(10, 0x1) +#define MVL_PHY_100BASET_FULL MS16(8, 0x1) +#define MVL_PHY_100BASET_HALF MS16(7, 0x1) +#define MVL_PHY_10BASET_FULL MS16(6, 0x1) +#define MVL_PHY_10BASET_HALF MS16(5, 0x1) +/* fiber */ +#define MVL_FANA_PAUSE_MASK MS16(7, 0x3) +#define MVL_FANA_SYM_PAUSE LS16(1, 7, 0x3) +#define MVL_FANA_ASM_PAUSE LS16(2, 7, 0x3) +#define MVL_PHY_1000BASEX_HALF MS16(6, 0x1) +#define MVL_PHY_1000BASEX_FULL MS16(5, 0x1) +#define MVL_LPAR 0x5 +#define MVL_CLPAR_ASM_PAUSE MS(11, 0x1) +#define MVL_CLPAR_PAUSE MS(10, 0x1) +#define MVL_FLPAR_PAUSE_MASK MS(7, 0x3) +#define MVL_PHY_1000BASET 0x9 +#define MVL_PHY_1000BASET_FULL MS16(9, 0x1) +#define MVL_PHY_1000BASET_HALF MS16(8, 0x1) +#define MVL_CTRL1 0x10 +#define MVL_CTRL1_INTR_POL MS16(2, 0x1) +#define MVL_PHYSR 0x11 +#define MVL_PHYSR_SPEED_MASK MS16(14, 0x3) +#define MVL_PHYSR_SPEED_1000M LS16(2, 14, 0x3) +#define MVL_PHYSR_SPEED_100M LS16(1, 14, 0x3) +#define MVL_PHYSR_SPEED_10M LS16(0, 14, 0x3) +#define MVL_PHYSR_LINK MS16(10, 0x1) +#define MVL_INTR_EN 0x12 +#define MVL_INTR_EN_ANC MS16(11, 0x1) +#define MVL_INTR_EN_LSC MS16(10, 0x1) +#define MVL_INTR 0x13 +#define MVL_INTR_ANC MS16(11, 0x1) +#define MVL_INTR_LSC MS16(10, 0x1) + +/* Page 2 */ +#define MVL_RGM_CTL2 0x15 +#define MVL_RGM_CTL2_TTC MS16(4, 0x1) +#define MVL_RGM_CTL2_RTC MS16(5, 0x1) +/* Page 3 */ +#define MVL_LEDFCR 0x10 +#define MVL_LEDFCR_CTL1 MS16(4, 0xF) +#define MVL_LEDFCR_CTL1_CONF LS16(6, 4, 0xF) +#define MVL_LEDFCR_CTL0 MS16(0, 0xF) +#define MVL_LEDFCR_CTL0_CONF LS16(1, 0, 0xF) +#define MVL_LEDPCR 0x11 +#define MVL_LEDPCR_CTL1 MS16(2, 0x3) +#define MVL_LEDPCR_CTL1_CONF LS16(1, 2, 0x3) +#define MVL_LEDPCR_CTL0 MS16(0, 0x3) +#define MVL_LEDPCR_CTL0_CONF LS16(1, 0, 0x3) +#define MVL_LEDTCR 0x12 +#define MVL_LEDTCR_INTR_POL MS16(11, 0x1) +#define MVL_LEDTCR_INTR_EN MS16(7, 0x1) +/* Page 18 */ +#define MVL_GEN_CTL 0x14 +#define MVL_GEN_CTL_RESET MS16(15, 0x1) +#define MVL_GEN_CTL_MODE(v) LS16(v, 0, 0x7) +#define MVL_GEN_CTL_MODE_COPPER LS16(0, 0, 0x7) +#define MVL_GEN_CTL_MODE_FIBER LS16(2, 0, 0x7) + +/* reg 22 */ +#define MVL_PAGE_SEL 22 + +/* reg 19_0 INT status*/ +#define MVL_PHY_ANC 0x0800 +#define MVL_PHY_LSC 0x0400 + +s32 ngbe_read_phy_reg_mvl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, + u16 *phy_data); +s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, + u16 phy_data); + +s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw); + +#endif /* _NGBE_PHY_MVL_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.c b/drivers/net/ngbe/base/ngbe_phy_rtl.c new file mode 100644 index 0000000000..0703ad9396 --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_phy_rtl.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + */ + +#include "ngbe_phy_rtl.h" + +#define RTL_PHY_RST_WAIT_PERIOD 5 + +s32 ngbe_read_phy_reg_rtl(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 *phy_data) +{ + mdi_reg_t reg; + mdi_reg_22_t reg22; + + reg.device_type = device_type; + reg.addr = reg_addr; + ngbe_mdi_map_register(®, ®22); + + wr32(hw, NGBE_PHY_CONFIG(RTL_PAGE_SELECT), reg22.page); + *phy_data = 0xFFFF & rd32(hw, NGBE_PHY_CONFIG(reg22.addr)); + + return 0; +} + +s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 phy_data) +{ + mdi_reg_t reg; + mdi_reg_22_t reg22; + + reg.device_type = device_type; + reg.addr = reg_addr; + ngbe_mdi_map_register(®, ®22); + + wr32(hw, NGBE_PHY_CONFIG(RTL_PAGE_SELECT), reg22.page); + wr32(hw, NGBE_PHY_CONFIG(reg22.addr), phy_data); + + return 0; +} + +s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw) +{ + u16 value = 0, i; + s32 status = 0; + + DEBUGFUNC("ngbe_reset_phy_rtl"); + + value |= RTL_BMCR_RESET; + status = hw->phy.write_reg(hw, RTL_BMCR, RTL_DEV_ZERO, value); + + for (i = 0; i < RTL_PHY_RST_WAIT_PERIOD; i++) { + status = hw->phy.read_reg(hw, RTL_BMCR, RTL_DEV_ZERO, &value); + if (!(value & RTL_BMCR_RESET)) + break; + msleep(1); + } + + if (i == RTL_PHY_RST_WAIT_PERIOD) { + DEBUGOUT("PHY reset polling failed to complete.\n"); + return NGBE_ERR_RESET_FAILED; + } + + return status; +} + diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.h b/drivers/net/ngbe/base/ngbe_phy_rtl.h new file mode 100644 index 0000000000..ecb60b0ddd --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_phy_rtl.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + */ + +#include "ngbe_phy.h" + +#ifndef _NGBE_PHY_RTL_H_ +#define _NGBE_PHY_RTL_H_ + +#define NGBE_PHYID_RTL 0x001CC800U + +/* Page 0 */ +#define RTL_DEV_ZERO 0 +#define RTL_BMCR 0x0 +#define RTL_BMCR_RESET MS16(15, 0x1) +#define RTL_BMCR_SPEED_SELECT0 MS16(13, 0x1) +#define RTL_BMCR_ANE MS16(12, 0x1) +#define RTL_BMCR_RESTART_AN MS16(9, 0x1) +#define RTL_BMCR_DUPLEX MS16(8, 0x1) +#define RTL_BMCR_SPEED_SELECT1 MS16(6, 0x1) +#define RTL_BMSR 0x1 +#define RTL_BMSR_ANC MS16(5, 0x1) +#define RTL_ID1_OFFSET 0x2 +#define RTL_ID2_OFFSET 0x3 +#define RTL_ID_MASK 0xFFFFFC00U +#define RTL_ANAR 0x4 +#define RTL_ANAR_APAUSE MS16(11, 0x1) +#define RTL_ANAR_PAUSE MS16(10, 0x1) +#define RTL_ANAR_100F MS16(8, 0x1) +#define RTL_ANAR_100H MS16(7, 0x1) +#define RTL_ANAR_10F MS16(6, 0x1) +#define RTL_ANAR_10H MS16(5, 0x1) +#define RTL_ANLPAR 0x5 +#define RTL_ANLPAR_LP MS16(10, 0x3) +#define RTL_GBCR 0x9 +#define RTL_GBCR_1000F MS16(9, 0x1) +/* Page 0xa42*/ +#define RTL_GSR 0x10 +#define RTL_GSR_ST MS16(0, 0x7) +#define RTL_GSR_ST_LANON MS16(0, 0x3) +#define RTL_INER 0x12 +#define RTL_INER_LSC MS16(4, 0x1) +#define RTL_INER_ANC MS16(3, 0x1) +/* Page 0xa43*/ +#define RTL_PHYSR 0x1A +#define RTL_PHYSR_SPEED_MASK MS16(4, 0x3) +#define RTL_PHYSR_SPEED_RES LS16(3, 4, 0x3) +#define RTL_PHYSR_SPEED_1000M LS16(2, 4, 0x3) +#define RTL_PHYSR_SPEED_100M LS16(1, 4, 0x3) +#define RTL_PHYSR_SPEED_10M LS16(0, 4, 0x3) +#define RTL_PHYSR_DP MS16(3, 0x1) +#define RTL_PHYSR_RTLS MS16(2, 0x1) +#define RTL_INSR 0x1D +#define RTL_INSR_ACCESS MS16(5, 0x1) +#define RTL_INSR_LSC MS16(4, 0x1) +#define RTL_INSR_ANC MS16(3, 0x1) +/* Page 0xa46*/ +#define RTL_SCR 0x14 +#define RTL_SCR_EXTINI MS16(1, 0x1) +#define RTL_SCR_EFUSE MS16(0, 0x1) +/* Page 0xa47*/ +/* Page 0xd04*/ +#define RTL_LCR 0x10 +#define RTL_EEELCR 0x11 +#define RTL_LPCR 0x12 + +/* INTERNAL PHY CONTROL */ +#define RTL_PAGE_SELECT 31 +#define NGBE_INTERNAL_PHY_OFFSET_MAX 32 +#define NGBE_INTERNAL_PHY_ID 0x000732 + +#define NGBE_INTPHY_LED0 0x0010 +#define NGBE_INTPHY_LED1 0x0040 +#define NGBE_INTPHY_LED2 0x2000 + +s32 ngbe_read_phy_reg_rtl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, + u16 *phy_data); +s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, + u16 phy_data); + +s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw); + +#endif /* _NGBE_PHY_RTL_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.c b/drivers/net/ngbe/base/ngbe_phy_yt.c new file mode 100644 index 0000000000..84b20de45c --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_phy_yt.c @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + */ + +#include "ngbe_phy_yt.h" + +#define YT_PHY_RST_WAIT_PERIOD 5 + +s32 ngbe_read_phy_reg_yt(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 *phy_data) +{ + mdi_reg_t reg; + mdi_reg_22_t reg22; + + reg.device_type = device_type; + reg.addr = reg_addr; + + ngbe_mdi_map_register(®, ®22); + + /* Read MII reg according to media type */ + if (hw->phy.media_type == ngbe_media_type_fiber) { + ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, + reg22.device_type, YT_SMI_PHY_SDS); + ngbe_read_phy_reg_mdi(hw, reg22.addr, + reg22.device_type, phy_data); + ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, + reg22.device_type, 0); + } else { + ngbe_read_phy_reg_mdi(hw, reg22.addr, + reg22.device_type, phy_data); + } + + return 0; +} + +s32 ngbe_write_phy_reg_yt(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 phy_data) +{ + mdi_reg_t reg; + mdi_reg_22_t reg22; + + reg.device_type = device_type; + reg.addr = reg_addr; + + ngbe_mdi_map_register(®, ®22); + + /* Write MII reg according to media type */ + if (hw->phy.media_type == ngbe_media_type_fiber) { + ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, + reg22.device_type, YT_SMI_PHY_SDS); + ngbe_write_phy_reg_mdi(hw, reg22.addr, + reg22.device_type, phy_data); + ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, + reg22.device_type, 0); + } else { + ngbe_write_phy_reg_mdi(hw, reg22.addr, + reg22.device_type, phy_data); + } + + return 0; +} + +s32 ngbe_read_phy_reg_ext_yt(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 *phy_data) +{ + ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr); + ngbe_read_phy_reg_mdi(hw, 0x1F, device_type, phy_data); + + return 0; +} + +s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 phy_data) +{ + ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr); + ngbe_write_phy_reg_mdi(hw, 0x1F, device_type, phy_data); + + return 0; +} + +s32 ngbe_reset_phy_yt(struct ngbe_hw *hw) +{ + u32 i; + u16 ctrl = 0; + s32 status = 0; + + DEBUGFUNC("ngbe_reset_phy_yt"); + + if (hw->phy.type != ngbe_phy_yt8521s && + hw->phy.type != ngbe_phy_yt8521s_sfi) + return NGBE_ERR_PHY_TYPE; + + status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl); + /* sds software reset */ + ctrl |= YT_BCR_RESET; + status = hw->phy.write_reg(hw, YT_BCR, 0, ctrl); + + for (i = 0; i < YT_PHY_RST_WAIT_PERIOD; i++) { + status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl); + if (!(ctrl & YT_BCR_RESET)) + break; + msleep(1); + } + + if (i == YT_PHY_RST_WAIT_PERIOD) { + DEBUGOUT("PHY reset polling failed to complete.\n"); + return NGBE_ERR_RESET_FAILED; + } + + return status; +} + diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.h b/drivers/net/ngbe/base/ngbe_phy_yt.h new file mode 100644 index 0000000000..80fd420a63 --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_phy_yt.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + */ + +#include "ngbe_phy.h" + +#ifndef _NGBE_PHY_YT_H_ +#define _NGBE_PHY_YT_H_ + +#define NGBE_PHYID_YT 0x00000110U + +/* Common EXT */ +#define YT_SMI_PHY 0xA000 +#define YT_SMI_PHY_SDS MS16(1, 0x1) /* 0 for UTP */ +#define YT_CHIP 0xA001 +#define YT_CHIP_SW_RST MS16(15, 0x1) +#define YT_CHIP_SW_LDO_EN MS16(6, 0x1) +#define YT_CHIP_MODE_SEL(v) LS16(v, 0, 0x7) +#define YT_RGMII_CONF1 0xA003 +#define YT_RGMII_CONF1_RXDELAY MS16(10, 0xF) +#define YT_RGMII_CONF1_TXDELAY_FE MS16(4, 0xF) +#define YT_RGMII_CONF1_TXDELAY MS16(0, 0x1) +#define YT_MISC 0xA006 +#define YT_MISC_FIBER_PRIO MS16(8, 0x1) /* 0 for UTP */ + +/* MII common registers in UTP and SDS */ +#define YT_BCR 0x0 +#define YT_BCR_RESET MS16(15, 0x1) +#define YT_BCR_PWDN MS16(11, 0x1) +#define YT_ANA 0x4 +/* copper */ +#define YT_ANA_100BASET_FULL MS16(8, 0x1) +#define YT_ANA_10BASET_FULL MS16(6, 0x1) +/* fiber */ +#define YT_FANA_PAUSE_MASK MS16(7, 0x3) + +#define YT_LPAR 0x5 +#define YT_CLPAR_ASM_PAUSE MS(11, 0x1) +#define YT_CLPAR_PAUSE MS(10, 0x1) +#define YT_FLPAR_PAUSE_MASK MS(7, 0x3) + +#define YT_MS_CTRL 0x9 +#define YT_MS_1000BASET_FULL MS16(9, 0x1) +#define YT_SPST 0x11 +#define YT_SPST_SPEED_MASK MS16(14, 0x3) +#define YT_SPST_SPEED_1000M LS16(2, 14, 0x3) +#define YT_SPST_SPEED_100M LS16(1, 14, 0x3) +#define YT_SPST_SPEED_10M LS16(0, 14, 0x3) +#define YT_SPST_LINK MS16(10, 0x1) + +/* UTP only */ +#define YT_INTR 0x12 +#define YT_INTR_ENA_MASK MS16(2, 0x3) +#define YT_INTR_STATUS 0x13 + +s32 ngbe_read_phy_reg_yt(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, + u16 *phy_data); +s32 ngbe_write_phy_reg_yt(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, + u16 phy_data); +s32 ngbe_read_phy_reg_ext_yt(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 *phy_data); +s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 phy_data); + +s32 ngbe_reset_phy_yt(struct ngbe_hw *hw); + +#endif /* _NGBE_PHY_YT_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index 55c686c0a3..8ed14560c3 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -94,6 +94,7 @@ struct ngbe_mac_info { /* Manageability interface */ s32 (*init_thermal_sensor_thresh)(struct ngbe_hw *hw); + s32 (*check_overtemp)(struct ngbe_hw *hw); enum ngbe_mac_type type; u32 max_tx_queues; @@ -103,8 +104,24 @@ struct ngbe_mac_info { }; struct ngbe_phy_info { + s32 (*identify)(struct ngbe_hw *hw); + s32 (*reset_hw)(struct ngbe_hw *hw); + s32 (*read_reg)(struct ngbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data); + s32 (*write_reg)(struct ngbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data); + s32 (*read_reg_unlocked)(struct ngbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data); + s32 (*write_reg_unlocked)(struct ngbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data); + enum ngbe_media_type media_type; enum ngbe_phy_type type; + u32 addr; + u32 id; + u32 revision; + u32 phy_semaphore_mask; + bool reset_disable; }; struct ngbe_hw { From patchwork Thu Jun 17 10:59:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94334 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B63EFA0C4D; Thu, 17 Jun 2021 12:59:19 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 863B041145; Thu, 17 Jun 2021 12:58:28 +0200 (CEST) Received: from smtpbgau1.qq.com (smtpbgau1.qq.com [54.206.16.166]) by mails.dpdk.org (Postfix) with ESMTP id B1C5A40687 for ; Thu, 17 Jun 2021 12:58:25 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927501ty5i8vyx Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:20 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: 6Urm6peds7VCMIus9ImH74NrRjRYnIpqQhiZTzt1DaoiRFASujgxGs5y7rSRT E52GhzeNAqt+Rw23tsnQBdzZNt/0x2afPIFNQVOCbEWK4tWeIGf0tgTgySHwOFKb+wXkxIQ AFpM3OjMh9tjkxmhplVhIbQmCnE597FgY+UMM3BTUUE4LY/02fhDcT39GhkV5LNvnDUp8t2 DEPg8Xd0yuRMzmj6Te05gp2gSQqEpwZkcJuiNxedoxJETgAKPeT9MEsPrqT7Iw4W9PM+Els ihuRVLe2A+dHBRIQ5AAMTJE4NXdZXkhGSgy5Dqt30lLJkXh9/3KUQ1DO43bpkK9/3U1hiZ1 EjYCKiP+lK57nV+grNq8yFZ7T15Hg== X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:55 +0800 Message-Id: <20210617110005.4132926-10-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign1 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 09/19] net/ngbe: store MAC address X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Store MAC addresses and init receive address filters. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/base/ngbe_dummy.h | 33 +++ drivers/net/ngbe/base/ngbe_hw.c | 323 +++++++++++++++++++++++++++++ drivers/net/ngbe/base/ngbe_hw.h | 13 ++ drivers/net/ngbe/base/ngbe_type.h | 19 ++ drivers/net/ngbe/ngbe_ethdev.c | 25 +++ drivers/net/ngbe/ngbe_ethdev.h | 2 + 6 files changed, 415 insertions(+) diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h index 15017cfd82..8462d6d1cb 100644 --- a/drivers/net/ngbe/base/ngbe_dummy.h +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -51,6 +51,10 @@ static inline s32 ngbe_mac_stop_hw_dummy(struct ngbe_hw *TUP0) { return NGBE_ERR_OPS_DUMMY; } +static inline s32 ngbe_mac_get_mac_addr_dummy(struct ngbe_hw *TUP0, u8 *TUP1) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline s32 ngbe_mac_acquire_swfw_sync_dummy(struct ngbe_hw *TUP0, u32 TUP1) { @@ -60,6 +64,29 @@ static inline void ngbe_mac_release_swfw_sync_dummy(struct ngbe_hw *TUP0, u32 TUP1) { } +static inline s32 ngbe_mac_set_rar_dummy(struct ngbe_hw *TUP0, u32 TUP1, + u8 *TUP2, u32 TUP3, u32 TUP4) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_mac_clear_rar_dummy(struct ngbe_hw *TUP0, u32 TUP1) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_mac_set_vmdq_dummy(struct ngbe_hw *TUP0, u32 TUP1, + u32 TUP2) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_mac_clear_vmdq_dummy(struct ngbe_hw *TUP0, u32 TUP1, + u32 TUP2) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_mac_init_rx_addrs_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline s32 ngbe_mac_init_thermal_ssth_dummy(struct ngbe_hw *TUP0) { return NGBE_ERR_OPS_DUMMY; @@ -105,8 +132,14 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) hw->mac.init_hw = ngbe_mac_init_hw_dummy; hw->mac.reset_hw = ngbe_mac_reset_hw_dummy; hw->mac.stop_hw = ngbe_mac_stop_hw_dummy; + hw->mac.get_mac_addr = ngbe_mac_get_mac_addr_dummy; hw->mac.acquire_swfw_sync = ngbe_mac_acquire_swfw_sync_dummy; hw->mac.release_swfw_sync = ngbe_mac_release_swfw_sync_dummy; + hw->mac.set_rar = ngbe_mac_set_rar_dummy; + hw->mac.clear_rar = ngbe_mac_clear_rar_dummy; + hw->mac.set_vmdq = ngbe_mac_set_vmdq_dummy; + hw->mac.clear_vmdq = ngbe_mac_clear_vmdq_dummy; + hw->mac.init_rx_addrs = ngbe_mac_init_rx_addrs_dummy; hw->mac.init_thermal_sensor_thresh = ngbe_mac_init_thermal_ssth_dummy; hw->mac.check_overtemp = ngbe_mac_check_overtemp_dummy; hw->phy.identify = ngbe_phy_identify_dummy; diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index 5723213209..7f20d6c807 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -142,9 +142,49 @@ s32 ngbe_reset_hw_em(struct ngbe_hw *hw) msec_delay(50); + /* Store the permanent mac address */ + hw->mac.get_mac_addr(hw, hw->mac.perm_addr); + + /* + * Store MAC address from RAR0, clear receive address registers, and + * clear the multicast table. + */ + hw->mac.num_rar_entries = NGBE_EM_RAR_ENTRIES; + hw->mac.init_rx_addrs(hw); + return status; } +/** + * ngbe_get_mac_addr - Generic get MAC address + * @hw: pointer to hardware structure + * @mac_addr: Adapter MAC address + * + * Reads the adapter's MAC address from first Receive Address Register (RAR0) + * A reset of the adapter must be performed prior to calling this function + * in order for the MAC address to have been loaded from the EEPROM into RAR0 + **/ +s32 ngbe_get_mac_addr(struct ngbe_hw *hw, u8 *mac_addr) +{ + u32 rar_high; + u32 rar_low; + u16 i; + + DEBUGFUNC("ngbe_get_mac_addr"); + + wr32(hw, NGBE_ETHADDRIDX, 0); + rar_high = rd32(hw, NGBE_ETHADDRH); + rar_low = rd32(hw, NGBE_ETHADDRL); + + for (i = 0; i < 2; i++) + mac_addr[i] = (u8)(rar_high >> (1 - i) * 8); + + for (i = 0; i < 4; i++) + mac_addr[i + 2] = (u8)(rar_low >> (3 - i) * 8); + + return 0; +} + /** * ngbe_set_lan_id_multi_port - Set LAN id for PCIe multiple port devices * @hw: pointer to the HW structure @@ -215,6 +255,196 @@ s32 ngbe_stop_hw(struct ngbe_hw *hw) return 0; } +/** + * ngbe_validate_mac_addr - Validate MAC address + * @mac_addr: pointer to MAC address. + * + * Tests a MAC address to ensure it is a valid Individual Address. + **/ +s32 ngbe_validate_mac_addr(u8 *mac_addr) +{ + s32 status = 0; + + DEBUGFUNC("ngbe_validate_mac_addr"); + + /* Make sure it is not a multicast address */ + if (NGBE_IS_MULTICAST((struct rte_ether_addr *)mac_addr)) { + status = NGBE_ERR_INVALID_MAC_ADDR; + /* Not a broadcast address */ + } else if (NGBE_IS_BROADCAST((struct rte_ether_addr *)mac_addr)) { + status = NGBE_ERR_INVALID_MAC_ADDR; + /* Reject the zero address */ + } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 && + mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) { + status = NGBE_ERR_INVALID_MAC_ADDR; + } + return status; +} + +/** + * ngbe_set_rar - Set Rx address register + * @hw: pointer to hardware structure + * @index: Receive address register to write + * @addr: Address to put into receive address register + * @vmdq: VMDq "set" or "pool" index + * @enable_addr: set flag that address is active + * + * Puts an ethernet address into a receive address register. + **/ +s32 ngbe_set_rar(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq, + u32 enable_addr) +{ + u32 rar_low, rar_high; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ngbe_set_rar"); + + /* Make sure we are using a valid rar index range */ + if (index >= rar_entries) { + DEBUGOUT("RAR index %d is out of range.\n", index); + return NGBE_ERR_INVALID_ARGUMENT; + } + + /* setup VMDq pool selection before this RAR gets enabled */ + hw->mac.set_vmdq(hw, index, vmdq); + + /* + * HW expects these in little endian so we reverse the byte + * order from network order (big endian) to little endian + */ + rar_low = NGBE_ETHADDRL_AD0(addr[5]) | + NGBE_ETHADDRL_AD1(addr[4]) | + NGBE_ETHADDRL_AD2(addr[3]) | + NGBE_ETHADDRL_AD3(addr[2]); + /* + * Some parts put the VMDq setting in the extra RAH bits, + * so save everything except the lower 16 bits that hold part + * of the address and the address valid bit. + */ + rar_high = rd32(hw, NGBE_ETHADDRH); + rar_high &= ~NGBE_ETHADDRH_AD_MASK; + rar_high |= (NGBE_ETHADDRH_AD4(addr[1]) | + NGBE_ETHADDRH_AD5(addr[0])); + + rar_high &= ~NGBE_ETHADDRH_VLD; + if (enable_addr != 0) + rar_high |= NGBE_ETHADDRH_VLD; + + wr32(hw, NGBE_ETHADDRIDX, index); + wr32(hw, NGBE_ETHADDRL, rar_low); + wr32(hw, NGBE_ETHADDRH, rar_high); + + return 0; +} + +/** + * ngbe_clear_rar - Remove Rx address register + * @hw: pointer to hardware structure + * @index: Receive address register to write + * + * Clears an ethernet address from a receive address register. + **/ +s32 ngbe_clear_rar(struct ngbe_hw *hw, u32 index) +{ + u32 rar_high; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ngbe_clear_rar"); + + /* Make sure we are using a valid rar index range */ + if (index >= rar_entries) { + DEBUGOUT("RAR index %d is out of range.\n", index); + return NGBE_ERR_INVALID_ARGUMENT; + } + + /* + * Some parts put the VMDq setting in the extra RAH bits, + * so save everything except the lower 16 bits that hold part + * of the address and the address valid bit. + */ + wr32(hw, NGBE_ETHADDRIDX, index); + rar_high = rd32(hw, NGBE_ETHADDRH); + rar_high &= ~(NGBE_ETHADDRH_AD_MASK | NGBE_ETHADDRH_VLD); + + wr32(hw, NGBE_ETHADDRL, 0); + wr32(hw, NGBE_ETHADDRH, rar_high); + + /* clear VMDq pool/queue selection for this RAR */ + hw->mac.clear_vmdq(hw, index, BIT_MASK32); + + return 0; +} + +/** + * ngbe_init_rx_addrs - Initializes receive address filters. + * @hw: pointer to hardware structure + * + * Places the MAC address in receive address register 0 and clears the rest + * of the receive address registers. Clears the multicast table. Assumes + * the receiver is in reset when the routine is called. + **/ +s32 ngbe_init_rx_addrs(struct ngbe_hw *hw) +{ + u32 i; + u32 psrctl; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ngbe_init_rx_addrs"); + + /* + * If the current mac address is valid, assume it is a software override + * to the permanent address. + * Otherwise, use the permanent address from the eeprom. + */ + if (ngbe_validate_mac_addr(hw->mac.addr) == + NGBE_ERR_INVALID_MAC_ADDR) { + /* Get the MAC address from the RAR0 for later reference */ + hw->mac.get_mac_addr(hw, hw->mac.addr); + + DEBUGOUT(" Keeping Current RAR0 Addr =%.2X %.2X %.2X ", + hw->mac.addr[0], hw->mac.addr[1], + hw->mac.addr[2]); + DEBUGOUT("%.2X %.2X %.2X\n", hw->mac.addr[3], + hw->mac.addr[4], hw->mac.addr[5]); + } else { + /* Setup the receive address. */ + DEBUGOUT("Overriding MAC Address in RAR[0]\n"); + DEBUGOUT(" New MAC Addr =%.2X %.2X %.2X ", + hw->mac.addr[0], hw->mac.addr[1], + hw->mac.addr[2]); + DEBUGOUT("%.2X %.2X %.2X\n", hw->mac.addr[3], + hw->mac.addr[4], hw->mac.addr[5]); + + hw->mac.set_rar(hw, 0, hw->mac.addr, 0, true); + } + + /* clear VMDq pool/queue selection for RAR 0 */ + hw->mac.clear_vmdq(hw, 0, BIT_MASK32); + + /* Zero out the other receive addresses. */ + DEBUGOUT("Clearing RAR[1-%d]\n", rar_entries - 1); + for (i = 1; i < rar_entries; i++) { + wr32(hw, NGBE_ETHADDRIDX, i); + wr32(hw, NGBE_ETHADDRL, 0); + wr32(hw, NGBE_ETHADDRH, 0); + } + + /* Clear the MTA */ + hw->addr_ctrl.mta_in_use = 0; + psrctl = rd32(hw, NGBE_PSRCTL); + psrctl &= ~(NGBE_PSRCTL_ADHF12_MASK | NGBE_PSRCTL_MCHFENA); + psrctl |= NGBE_PSRCTL_ADHF12(hw->mac.mc_filter_type); + wr32(hw, NGBE_PSRCTL, psrctl); + + DEBUGOUT(" Clearing MTA\n"); + for (i = 0; i < hw->mac.mcft_size; i++) + wr32(hw, NGBE_MCADDRTBL(i), 0); + + ngbe_init_uta_tables(hw); + + return 0; +} + /** * ngbe_acquire_swfw_sync - Acquire SWFW semaphore * @hw: pointer to hardware structure @@ -286,6 +516,89 @@ void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask) ngbe_release_eeprom_semaphore(hw); } +/** + * ngbe_clear_vmdq - Disassociate a VMDq pool index from a rx address + * @hw: pointer to hardware struct + * @rar: receive address register index to disassociate + * @vmdq: VMDq pool index to remove from the rar + **/ +s32 ngbe_clear_vmdq(struct ngbe_hw *hw, u32 rar, u32 vmdq) +{ + u32 mpsar; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ngbe_clear_vmdq"); + + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + DEBUGOUT("RAR index %d is out of range.\n", rar); + return NGBE_ERR_INVALID_ARGUMENT; + } + + wr32(hw, NGBE_ETHADDRIDX, rar); + mpsar = rd32(hw, NGBE_ETHADDRASS); + + if (NGBE_REMOVED(hw->hw_addr)) + goto done; + + if (!mpsar) + goto done; + + mpsar &= ~(1 << vmdq); + wr32(hw, NGBE_ETHADDRASS, mpsar); + + /* was that the last pool using this rar? */ + if (mpsar == 0 && rar != 0) + hw->mac.clear_rar(hw, rar); +done: + return 0; +} + +/** + * ngbe_set_vmdq - Associate a VMDq pool index with a rx address + * @hw: pointer to hardware struct + * @rar: receive address register index to associate with a VMDq index + * @vmdq: VMDq pool index + **/ +s32 ngbe_set_vmdq(struct ngbe_hw *hw, u32 rar, u32 vmdq) +{ + u32 mpsar; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ngbe_set_vmdq"); + + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + DEBUGOUT("RAR index %d is out of range.\n", rar); + return NGBE_ERR_INVALID_ARGUMENT; + } + + wr32(hw, NGBE_ETHADDRIDX, rar); + + mpsar = rd32(hw, NGBE_ETHADDRASS); + mpsar |= 1 << vmdq; + wr32(hw, NGBE_ETHADDRASS, mpsar); + + return 0; +} + +/** + * ngbe_init_uta_tables - Initialize the Unicast Table Array + * @hw: pointer to hardware structure + **/ +s32 ngbe_init_uta_tables(struct ngbe_hw *hw) +{ + int i; + + DEBUGFUNC("ngbe_init_uta_tables"); + DEBUGOUT(" Clearing UTA\n"); + + for (i = 0; i < 128; i++) + wr32(hw, NGBE_UCADDRTBL(i), 0); + + return 0; +} + /** * ngbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds * @hw: pointer to hardware structure @@ -481,10 +794,18 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) /* MAC */ mac->init_hw = ngbe_init_hw; mac->reset_hw = ngbe_reset_hw_em; + mac->get_mac_addr = ngbe_get_mac_addr; mac->stop_hw = ngbe_stop_hw; mac->acquire_swfw_sync = ngbe_acquire_swfw_sync; mac->release_swfw_sync = ngbe_release_swfw_sync; + /* RAR */ + mac->set_rar = ngbe_set_rar; + mac->clear_rar = ngbe_clear_rar; + mac->init_rx_addrs = ngbe_init_rx_addrs; + mac->set_vmdq = ngbe_set_vmdq; + mac->clear_vmdq = ngbe_clear_vmdq; + /* Manageability interface */ mac->init_thermal_sensor_thresh = ngbe_init_thermal_sensor_thresh; mac->check_overtemp = ngbe_mac_check_overtemp; @@ -493,6 +814,8 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) rom->init_params = ngbe_init_eeprom_params; rom->validate_checksum = ngbe_validate_eeprom_checksum_em; + mac->mcft_size = NGBE_EM_MC_TBL_SIZE; + mac->num_rar_entries = NGBE_EM_RAR_ENTRIES; mac->max_rx_queues = NGBE_EM_MAX_RX_QUEUES; mac->max_tx_queues = NGBE_EM_MAX_TX_QUEUES; diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h index 3c8e646bb7..0b3d60ae29 100644 --- a/drivers/net/ngbe/base/ngbe_hw.h +++ b/drivers/net/ngbe/base/ngbe_hw.h @@ -10,16 +10,29 @@ #define NGBE_EM_MAX_TX_QUEUES 8 #define NGBE_EM_MAX_RX_QUEUES 8 +#define NGBE_EM_RAR_ENTRIES 32 +#define NGBE_EM_MC_TBL_SIZE 32 s32 ngbe_init_hw(struct ngbe_hw *hw); s32 ngbe_reset_hw_em(struct ngbe_hw *hw); s32 ngbe_stop_hw(struct ngbe_hw *hw); +s32 ngbe_get_mac_addr(struct ngbe_hw *hw, u8 *mac_addr); void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw); +s32 ngbe_set_rar(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq, + u32 enable_addr); +s32 ngbe_clear_rar(struct ngbe_hw *hw, u32 index); +s32 ngbe_init_rx_addrs(struct ngbe_hw *hw); + +s32 ngbe_validate_mac_addr(u8 *mac_addr); s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask); void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask); +s32 ngbe_set_vmdq(struct ngbe_hw *hw, u32 rar, u32 vmdq); +s32 ngbe_clear_vmdq(struct ngbe_hw *hw, u32 rar, u32 vmdq); +s32 ngbe_init_uta_tables(struct ngbe_hw *hw); + s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw); s32 ngbe_mac_check_overtemp(struct ngbe_hw *hw); void ngbe_disable_rx(struct ngbe_hw *hw); diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index 8ed14560c3..517db3380d 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -63,6 +63,10 @@ enum ngbe_media_type { struct ngbe_hw; +struct ngbe_addr_filter_info { + u32 mta_in_use; +}; + /* Bus parameters */ struct ngbe_bus_info { void (*set_lan_id)(struct ngbe_hw *hw); @@ -89,14 +93,28 @@ struct ngbe_mac_info { s32 (*init_hw)(struct ngbe_hw *hw); s32 (*reset_hw)(struct ngbe_hw *hw); s32 (*stop_hw)(struct ngbe_hw *hw); + s32 (*get_mac_addr)(struct ngbe_hw *hw, u8 *mac_addr); s32 (*acquire_swfw_sync)(struct ngbe_hw *hw, u32 mask); void (*release_swfw_sync)(struct ngbe_hw *hw, u32 mask); + /* RAR */ + s32 (*set_rar)(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq, + u32 enable_addr); + s32 (*clear_rar)(struct ngbe_hw *hw, u32 index); + s32 (*set_vmdq)(struct ngbe_hw *hw, u32 rar, u32 vmdq); + s32 (*clear_vmdq)(struct ngbe_hw *hw, u32 rar, u32 vmdq); + s32 (*init_rx_addrs)(struct ngbe_hw *hw); + /* Manageability interface */ s32 (*init_thermal_sensor_thresh)(struct ngbe_hw *hw); s32 (*check_overtemp)(struct ngbe_hw *hw); enum ngbe_mac_type type; + u8 addr[ETH_ADDR_LEN]; + u8 perm_addr[ETH_ADDR_LEN]; + s32 mc_filter_type; + u32 mcft_size; + u32 num_rar_entries; u32 max_tx_queues; u32 max_rx_queues; struct ngbe_thermal_sensor_data thermal_sensor_data; @@ -128,6 +146,7 @@ struct ngbe_hw { void IOMEM *hw_addr; void *back; struct ngbe_mac_info mac; + struct ngbe_addr_filter_info addr_ctrl; struct ngbe_phy_info phy; struct ngbe_rom_info rom; struct ngbe_bus_info bus; diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index 31d4dda976..deca64137d 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -116,6 +116,31 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) return -EIO; } + /* Allocate memory for storing MAC addresses */ + eth_dev->data->mac_addrs = rte_zmalloc("ngbe", RTE_ETHER_ADDR_LEN * + hw->mac.num_rar_entries, 0); + if (eth_dev->data->mac_addrs == NULL) { + PMD_INIT_LOG(ERR, + "Failed to allocate %u bytes needed to store " + "MAC addresses", + RTE_ETHER_ADDR_LEN * hw->mac.num_rar_entries); + return -ENOMEM; + } + + /* Copy the permanent MAC address */ + rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.perm_addr, + ð_dev->data->mac_addrs[0]); + + /* Allocate memory for storing hash filter MAC addresses */ + eth_dev->data->hash_mac_addrs = rte_zmalloc("ngbe", + RTE_ETHER_ADDR_LEN * NGBE_VMDQ_NUM_UC_MAC, 0); + if (eth_dev->data->hash_mac_addrs == NULL) { + PMD_INIT_LOG(ERR, + "Failed to allocate %d bytes needed to store MAC addresses", + RTE_ETHER_ADDR_LEN * NGBE_VMDQ_NUM_UC_MAC); + return -ENOMEM; + } + return 0; } diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h index d4d02c6bd8..87cc1cff6b 100644 --- a/drivers/net/ngbe/ngbe_ethdev.h +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -30,4 +30,6 @@ ngbe_dev_hw(struct rte_eth_dev *dev) return hw; } +#define NGBE_VMDQ_NUM_UC_MAC 4096 /* Maximum nb. of UC MAC addr. */ + #endif /* _NGBE_ETHDEV_H_ */ From patchwork Thu Jun 17 10:59:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94335 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C54CCA0C4D; Thu, 17 Jun 2021 12:59:25 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 99A2D4114A; Thu, 17 Jun 2021 12:58:29 +0200 (CEST) Received: from smtpbg511.qq.com (smtpbg511.qq.com [203.205.250.109]) by mails.dpdk.org (Postfix) with ESMTP id 9A8D9410E7 for ; Thu, 17 Jun 2021 12:58:26 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927503t0ef9w95 Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:22 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: O02On8uoBFMh3K2p5VxQh9S9yhszNy/17Z4nY7u3b5GyN70Nj7TYAIclU+fQz TYKqi/pjIkVhrW1fKtkcnjdUptGV+3ZQsS9pzjgqlELnypHMeuq8DMHG5bqIAUzmupiYp23 kGjM8AD16iKCYwD4rXIhOv3VYx5MD+PiNfHW6ibQ3D0G7Rh9DOmlv5PRMCrykBWzDqsZp0N 2/VcNIjKIEYY8L8I/2YxeRKbec28PAwKDEtoAK/KGPJ7A4/0yzPM+VR+3BPJVeke5R1f0V9 gAql9E0HUr1XbVTIc0Rau5okOAeDK6cy+CXur8tXGaoj20gjx14JSRvgD8W0pYoKlBd1NTj +TeTDcuQd/GMjZpbGk4Q5qBij5DpA== X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:56 +0800 Message-Id: <20210617110005.4132926-11-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign2 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 10/19] net/ngbe: support link update X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Register to handle device interrupt. Signed-off-by: Jiawen Wu --- doc/guides/nics/features/ngbe.ini | 3 + doc/guides/nics/ngbe.rst | 5 + drivers/net/ngbe/base/ngbe_dummy.h | 6 + drivers/net/ngbe/base/ngbe_type.h | 11 + drivers/net/ngbe/ngbe_ethdev.c | 376 ++++++++++++++++++++++++++++- drivers/net/ngbe/ngbe_ethdev.h | 34 +++ 6 files changed, 434 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/features/ngbe.ini b/doc/guides/nics/features/ngbe.ini index 977286ac04..291a542a42 100644 --- a/doc/guides/nics/features/ngbe.ini +++ b/doc/guides/nics/features/ngbe.ini @@ -4,6 +4,9 @@ ; Refer to default.ini for the full list of available PMD features. ; [Features] +Speed capabilities = Y +Link status = Y +Link status event = Y Multiprocess aware = Y Linux = Y ARMv8 = Y diff --git a/doc/guides/nics/ngbe.rst b/doc/guides/nics/ngbe.rst index 54d0665db9..0918cc2918 100644 --- a/doc/guides/nics/ngbe.rst +++ b/doc/guides/nics/ngbe.rst @@ -8,6 +8,11 @@ The NGBE PMD (librte_pmd_ngbe) provides poll mode driver support for Wangxun 1 Gigabit Ethernet NICs. +Features +-------- + +- Link state information + Prerequisites ------------- diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h index 8462d6d1cb..4273e5af36 100644 --- a/drivers/net/ngbe/base/ngbe_dummy.h +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -64,6 +64,11 @@ static inline void ngbe_mac_release_swfw_sync_dummy(struct ngbe_hw *TUP0, u32 TUP1) { } +static inline s32 ngbe_mac_check_link_dummy(struct ngbe_hw *TUP0, u32 *TUP1, + bool *TUP3, bool TUP4) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline s32 ngbe_mac_set_rar_dummy(struct ngbe_hw *TUP0, u32 TUP1, u8 *TUP2, u32 TUP3, u32 TUP4) { @@ -135,6 +140,7 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) hw->mac.get_mac_addr = ngbe_mac_get_mac_addr_dummy; hw->mac.acquire_swfw_sync = ngbe_mac_acquire_swfw_sync_dummy; hw->mac.release_swfw_sync = ngbe_mac_release_swfw_sync_dummy; + hw->mac.check_link = ngbe_mac_check_link_dummy; hw->mac.set_rar = ngbe_mac_set_rar_dummy; hw->mac.clear_rar = ngbe_mac_clear_rar_dummy; hw->mac.set_vmdq = ngbe_mac_set_vmdq_dummy; diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index 517db3380d..04c1cac422 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -97,6 +97,8 @@ struct ngbe_mac_info { s32 (*acquire_swfw_sync)(struct ngbe_hw *hw, u32 mask); void (*release_swfw_sync)(struct ngbe_hw *hw, u32 mask); + s32 (*check_link)(struct ngbe_hw *hw, u32 *speed, + bool *link_up, bool link_up_wait_to_complete); /* RAR */ s32 (*set_rar)(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr); @@ -117,6 +119,7 @@ struct ngbe_mac_info { u32 num_rar_entries; u32 max_tx_queues; u32 max_rx_queues; + bool get_link_status; struct ngbe_thermal_sensor_data thermal_sensor_data; bool set_lben; }; @@ -142,6 +145,14 @@ struct ngbe_phy_info { bool reset_disable; }; +enum ngbe_isb_idx { + NGBE_ISB_HEADER, + NGBE_ISB_MISC, + NGBE_ISB_VEC0, + NGBE_ISB_VEC1, + NGBE_ISB_MAX +}; + struct ngbe_hw { void IOMEM *hw_addr; void *back; diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index deca64137d..c952023e8b 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -7,12 +7,17 @@ #include #include +#include + #include "ngbe_logs.h" #include "base/ngbe.h" #include "ngbe_ethdev.h" static int ngbe_dev_close(struct rte_eth_dev *dev); +static void ngbe_dev_interrupt_handler(void *param); +static void ngbe_dev_interrupt_delayed_handler(void *param); + /* * The set of PCI devices this driver supports */ @@ -32,6 +37,28 @@ static const struct rte_pci_id pci_id_ngbe_map[] = { { .vendor_id = 0, /* sentinel */ }, }; +static const struct eth_dev_ops ngbe_eth_dev_ops; + +static inline void +ngbe_enable_intr(struct rte_eth_dev *dev) +{ + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + struct ngbe_hw *hw = ngbe_dev_hw(dev); + + wr32(hw, NGBE_IENMISC, intr->mask_misc); + wr32(hw, NGBE_IMC(0), intr->mask & BIT_MASK32); + ngbe_flush(hw); +} + +static void +ngbe_disable_intr(struct ngbe_hw *hw) +{ + PMD_INIT_FUNC_TRACE(); + + wr32(hw, NGBE_IMS(0), NGBE_IMS_MASK); + ngbe_flush(hw); +} + /* * Ensure that all locks are released before first NVM or PHY access */ @@ -60,11 +87,15 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) { struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; const struct rte_memzone *mz; + uint32_t ctrl_ext; int err; PMD_INIT_FUNC_TRACE(); + eth_dev->dev_ops = &ngbe_eth_dev_ops; + if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; @@ -116,6 +147,9 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) return -EIO; } + /* disable interrupt */ + ngbe_disable_intr(hw); + /* Allocate memory for storing MAC addresses */ eth_dev->data->mac_addrs = rte_zmalloc("ngbe", RTE_ETHER_ADDR_LEN * hw->mac.num_rar_entries, 0); @@ -141,6 +175,23 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) return -ENOMEM; } + ctrl_ext = rd32(hw, NGBE_PORTCTL); + /* let hardware know driver is loaded */ + ctrl_ext |= NGBE_PORTCTL_DRVLOAD; + /* Set PF Reset Done bit so PF/VF Mail Ops can work */ + ctrl_ext |= NGBE_PORTCTL_RSTDONE; + wr32(hw, NGBE_PORTCTL, ctrl_ext); + ngbe_flush(hw); + + rte_intr_callback_register(intr_handle, + ngbe_dev_interrupt_handler, eth_dev); + + /* enable uio/vfio intr/eventfd mapping */ + rte_intr_enable(intr_handle); + + /* enable support intr */ + ngbe_enable_intr(eth_dev); + return 0; } @@ -180,11 +231,25 @@ static int eth_ngbe_pci_remove(struct rte_pci_device *pci_dev) static struct rte_pci_driver rte_ngbe_pmd = { .id_table = pci_id_ngbe_map, - .drv_flags = RTE_PCI_DRV_NEED_MAPPING, + .drv_flags = RTE_PCI_DRV_NEED_MAPPING | + RTE_PCI_DRV_INTR_LSC, .probe = eth_ngbe_pci_probe, .remove = eth_ngbe_pci_remove, }; +static int +ngbe_dev_configure(struct rte_eth_dev *dev) +{ + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + + PMD_INIT_FUNC_TRACE(); + + /* set flag to update link status after init */ + intr->flags |= NGBE_FLAG_NEED_LINK_UPDATE; + + return 0; +} + /* * Reset and stop device. */ @@ -198,6 +263,315 @@ ngbe_dev_close(struct rte_eth_dev *dev) return -EINVAL; } +static int +ngbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) +{ + RTE_SET_USED(dev); + + dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_100M | + ETH_LINK_SPEED_10M; + + return 0; +} + +/* return 0 means link status changed, -1 means not changed */ +int +ngbe_dev_link_update_share(struct rte_eth_dev *dev, + int wait_to_complete) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct rte_eth_link link; + u32 link_speed = NGBE_LINK_SPEED_UNKNOWN; + u32 lan_speed = 0; + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + bool link_up; + int err; + int wait = 1; + + memset(&link, 0, sizeof(link)); + link.link_status = ETH_LINK_DOWN; + link.link_speed = ETH_SPEED_NUM_NONE; + link.link_duplex = ETH_LINK_HALF_DUPLEX; + link.link_autoneg = !(dev->data->dev_conf.link_speeds & + ~ETH_LINK_SPEED_AUTONEG); + + hw->mac.get_link_status = true; + + if (intr->flags & NGBE_FLAG_NEED_LINK_CONFIG) + return rte_eth_linkstatus_set(dev, &link); + + /* check if it needs to wait to complete, if lsc interrupt is enabled */ + if (wait_to_complete == 0 || dev->data->dev_conf.intr_conf.lsc != 0) + wait = 0; + + err = hw->mac.check_link(hw, &link_speed, &link_up, wait); + + if (err != 0) { + link.link_speed = ETH_SPEED_NUM_100M; + link.link_duplex = ETH_LINK_FULL_DUPLEX; + return rte_eth_linkstatus_set(dev, &link); + } + + if (!link_up) + return rte_eth_linkstatus_set(dev, &link); + + intr->flags &= ~NGBE_FLAG_NEED_LINK_CONFIG; + link.link_status = ETH_LINK_UP; + link.link_duplex = ETH_LINK_FULL_DUPLEX; + + switch (link_speed) { + default: + case NGBE_LINK_SPEED_UNKNOWN: + link.link_duplex = ETH_LINK_FULL_DUPLEX; + link.link_speed = ETH_SPEED_NUM_100M; + break; + + case NGBE_LINK_SPEED_10M_FULL: + link.link_speed = ETH_SPEED_NUM_10M; + lan_speed = 0; + break; + + case NGBE_LINK_SPEED_100M_FULL: + link.link_speed = ETH_SPEED_NUM_100M; + lan_speed = 1; + break; + + case NGBE_LINK_SPEED_1GB_FULL: + link.link_speed = ETH_SPEED_NUM_1G; + lan_speed = 2; + break; + } + + if (hw->is_pf) { + wr32m(hw, NGBE_LAN_SPEED, NGBE_LAN_SPEED_MASK, lan_speed); + if (link_speed & (NGBE_LINK_SPEED_1GB_FULL | + NGBE_LINK_SPEED_100M_FULL | NGBE_LINK_SPEED_10M_FULL)) { + wr32m(hw, NGBE_MACTXCFG, NGBE_MACTXCFG_SPEED_MASK, + NGBE_MACTXCFG_SPEED_1G | NGBE_MACTXCFG_TE); + } + } + + return rte_eth_linkstatus_set(dev, &link); +} + +static int +ngbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete) +{ + return ngbe_dev_link_update_share(dev, wait_to_complete); +} + +/* + * It reads ICR and sets flag for the link_update. + * + * @param dev + * Pointer to struct rte_eth_dev. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ngbe_dev_interrupt_get_status(struct rte_eth_dev *dev) +{ + uint32_t eicr; + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + + /* clear all cause mask */ + ngbe_disable_intr(hw); + + /* read-on-clear nic registers here */ + eicr = ((u32 *)hw->isb_mem)[NGBE_ISB_MISC]; + PMD_DRV_LOG(DEBUG, "eicr %x", eicr); + + intr->flags = 0; + + /* set flag for async link update */ + if (eicr & NGBE_ICRMISC_PHY) + intr->flags |= NGBE_FLAG_NEED_LINK_UPDATE; + + if (eicr & NGBE_ICRMISC_VFMBX) + intr->flags |= NGBE_FLAG_MAILBOX; + + if (eicr & NGBE_ICRMISC_LNKSEC) + intr->flags |= NGBE_FLAG_MACSEC; + + if (eicr & NGBE_ICRMISC_GPIO) + intr->flags |= NGBE_FLAG_NEED_LINK_UPDATE; + + return 0; +} + +/** + * It gets and then prints the link status. + * + * @param dev + * Pointer to struct rte_eth_dev. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static void +ngbe_dev_link_status_print(struct rte_eth_dev *dev) +{ + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_eth_link link; + + rte_eth_linkstatus_get(dev, &link); + + if (link.link_status == ETH_LINK_UP) { + PMD_INIT_LOG(INFO, "Port %d: Link Up - speed %u Mbps - %s", + (int)(dev->data->port_id), + (unsigned int)link.link_speed, + link.link_duplex == ETH_LINK_FULL_DUPLEX ? + "full-duplex" : "half-duplex"); + } else { + PMD_INIT_LOG(INFO, " Port %d: Link Down", + (int)(dev->data->port_id)); + } + PMD_INIT_LOG(DEBUG, "PCI Address: " PCI_PRI_FMT, + pci_dev->addr.domain, + pci_dev->addr.bus, + pci_dev->addr.devid, + pci_dev->addr.function); +} + +/* + * It executes link_update after knowing an interrupt occurred. + * + * @param dev + * Pointer to struct rte_eth_dev. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ngbe_dev_interrupt_action(struct rte_eth_dev *dev) +{ + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + int64_t timeout; + + PMD_DRV_LOG(DEBUG, "intr action type %d", intr->flags); + + if (intr->flags & NGBE_FLAG_NEED_LINK_UPDATE) { + struct rte_eth_link link; + + /*get the link status before link update, for predicting later*/ + rte_eth_linkstatus_get(dev, &link); + + ngbe_dev_link_update(dev, 0); + + /* likely to up */ + if (link.link_status != ETH_LINK_UP) + /* handle it 1 sec later, wait it being stable */ + timeout = NGBE_LINK_UP_CHECK_TIMEOUT; + /* likely to down */ + else + /* handle it 4 sec later, wait it being stable */ + timeout = NGBE_LINK_DOWN_CHECK_TIMEOUT; + + ngbe_dev_link_status_print(dev); + if (rte_eal_alarm_set(timeout * 1000, + ngbe_dev_interrupt_delayed_handler, + (void *)dev) < 0) { + PMD_DRV_LOG(ERR, "Error setting alarm"); + } else { + /* remember original mask */ + intr->mask_misc_orig = intr->mask_misc; + /* only disable lsc interrupt */ + intr->mask_misc &= ~NGBE_ICRMISC_PHY; + + intr->mask_orig = intr->mask; + /* only disable all misc interrupts */ + intr->mask &= ~(1ULL << NGBE_MISC_VEC_ID); + } + } + + PMD_DRV_LOG(DEBUG, "enable intr immediately"); + ngbe_enable_intr(dev); + + return 0; +} + +/** + * Interrupt handler which shall be registered for alarm callback for delayed + * handling specific interrupt to wait for the stable nic state. As the + * NIC interrupt state is not stable for ngbe after link is just down, + * it needs to wait 4 seconds to get the stable status. + * + * @param handle + * Pointer to interrupt handle. + * @param param + * The address of parameter (struct rte_eth_dev *) registered before. + * + * @return + * void + */ +static void +ngbe_dev_interrupt_delayed_handler(void *param) +{ + struct rte_eth_dev *dev = (struct rte_eth_dev *)param; + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + struct ngbe_hw *hw = ngbe_dev_hw(dev); + uint32_t eicr; + + ngbe_disable_intr(hw); + + eicr = ((u32 *)hw->isb_mem)[NGBE_ISB_MISC]; + + if (intr->flags & NGBE_FLAG_NEED_LINK_UPDATE) { + ngbe_dev_link_update(dev, 0); + intr->flags &= ~NGBE_FLAG_NEED_LINK_UPDATE; + ngbe_dev_link_status_print(dev); + rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, + NULL); + } + + if (intr->flags & NGBE_FLAG_MACSEC) { + rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_MACSEC, + NULL); + intr->flags &= ~NGBE_FLAG_MACSEC; + } + + /* restore original mask */ + intr->mask_misc = intr->mask_misc_orig; + intr->mask_misc_orig = 0; + intr->mask = intr->mask_orig; + intr->mask_orig = 0; + + PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr); + ngbe_enable_intr(dev); +} + +/** + * Interrupt handler triggered by NIC for handling + * specific interrupt. + * + * @param handle + * Pointer to interrupt handle. + * @param param + * The address of parameter (struct rte_eth_dev *) registered before. + * + * @return + * void + */ +static void +ngbe_dev_interrupt_handler(void *param) +{ + struct rte_eth_dev *dev = (struct rte_eth_dev *)param; + + ngbe_dev_interrupt_get_status(dev); + ngbe_dev_interrupt_action(dev); +} + +static const struct eth_dev_ops ngbe_eth_dev_ops = { + .dev_configure = ngbe_dev_configure, + .dev_infos_get = ngbe_dev_info_get, + .link_update = ngbe_dev_link_update, +}; + RTE_PMD_REGISTER_PCI(net_ngbe, rte_ngbe_pmd); RTE_PMD_REGISTER_PCI_TABLE(net_ngbe, pci_id_ngbe_map); RTE_PMD_REGISTER_KMOD_DEP(net_ngbe, "* igb_uio | uio_pci_generic | vfio-pci"); diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h index 87cc1cff6b..b67508a3de 100644 --- a/drivers/net/ngbe/ngbe_ethdev.h +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -6,11 +6,30 @@ #ifndef _NGBE_ETHDEV_H_ #define _NGBE_ETHDEV_H_ +/* need update link, bit flag */ +#define NGBE_FLAG_NEED_LINK_UPDATE (uint32_t)(1 << 0) +#define NGBE_FLAG_MAILBOX (uint32_t)(1 << 1) +#define NGBE_FLAG_PHY_INTERRUPT (uint32_t)(1 << 2) +#define NGBE_FLAG_MACSEC (uint32_t)(1 << 3) +#define NGBE_FLAG_NEED_LINK_CONFIG (uint32_t)(1 << 4) + +#define NGBE_MISC_VEC_ID RTE_INTR_VEC_ZERO_OFFSET + +/* structure for interrupt relative data */ +struct ngbe_interrupt { + uint32_t flags; + uint32_t mask_misc; + uint32_t mask_misc_orig; /* save mask during delayed handler */ + uint64_t mask; + uint64_t mask_orig; /* save mask during delayed handler */ +}; + /* * Structure to store private data for each driver instance (for each port). */ struct ngbe_adapter { struct ngbe_hw hw; + struct ngbe_interrupt intr; }; static inline struct ngbe_adapter * @@ -30,6 +49,21 @@ ngbe_dev_hw(struct rte_eth_dev *dev) return hw; } +static inline struct ngbe_interrupt * +ngbe_dev_intr(struct rte_eth_dev *dev) +{ + struct ngbe_adapter *ad = ngbe_dev_adapter(dev); + struct ngbe_interrupt *intr = &ad->intr; + + return intr; +} + +int +ngbe_dev_link_update_share(struct rte_eth_dev *dev, + int wait_to_complete); + +#define NGBE_LINK_DOWN_CHECK_TIMEOUT 4000 /* ms */ +#define NGBE_LINK_UP_CHECK_TIMEOUT 1000 /* ms */ #define NGBE_VMDQ_NUM_UC_MAC 4096 /* Maximum nb. of UC MAC addr. */ #endif /* _NGBE_ETHDEV_H_ */ From patchwork Thu Jun 17 10:59:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94336 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 69C4CA0C4D; Thu, 17 Jun 2021 12:59:34 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 14F2341154; Thu, 17 Jun 2021 12:58:31 +0200 (CEST) Received: from smtpproxy21.qq.com (smtpbg702.qq.com [203.205.195.102]) by mails.dpdk.org (Postfix) with ESMTP id 18BFC41102 for ; Thu, 17 Jun 2021 12:58:28 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927504tw5ef78f Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:24 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: W55xVYr4DdaksjvUgKJ0Ru0Gtp3Sy/X2qAxiD3BbNSeQoxfShfhvci8hrh0Vu H+g3Wh6vGXtUsBMfvnyTouvZrumZI5V/kYBaTXzJmsOELCwklNo31N7JULl9dlY+c2OF7e7 IWulmBGb4q1/ahXehpJT2T1sX6zYDiRbkAdLUUJdhPa87QC4wvbXIBYxrPM/i1EhBl3QnZn L8j4BExPcHo0t8xTsYsj6CA+6QQAfGMHj0NFegR/65JfNjgGz2sSybF7mfF/X7SGFxkt0/3 k1bP8CMxRMEPkYKZUEXmFiQb+UsPZ/MMVkr8Vs6azj8eLaExVH+oI2azXSN/1DLZLcKBFlz R8Vj5eHEyqwyadCr19Vk2JkDkjtOA== X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:57 +0800 Message-Id: <20210617110005.4132926-12-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign6 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 11/19] net/ngbe: setup the check PHY link X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Setup PHY, determine link and speed status from PHY. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/base/ngbe_dummy.h | 18 +++ drivers/net/ngbe/base/ngbe_hw.c | 53 +++++++++ drivers/net/ngbe/base/ngbe_hw.h | 6 + drivers/net/ngbe/base/ngbe_phy.c | 22 ++++ drivers/net/ngbe/base/ngbe_phy.h | 2 + drivers/net/ngbe/base/ngbe_phy_mvl.c | 98 ++++++++++++++++ drivers/net/ngbe/base/ngbe_phy_mvl.h | 4 + drivers/net/ngbe/base/ngbe_phy_rtl.c | 166 +++++++++++++++++++++++++++ drivers/net/ngbe/base/ngbe_phy_rtl.h | 4 + drivers/net/ngbe/base/ngbe_phy_yt.c | 134 +++++++++++++++++++++ drivers/net/ngbe/base/ngbe_phy_yt.h | 8 ++ drivers/net/ngbe/base/ngbe_type.h | 11 ++ 12 files changed, 526 insertions(+) diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h index 4273e5af36..709e01659c 100644 --- a/drivers/net/ngbe/base/ngbe_dummy.h +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -64,6 +64,11 @@ static inline void ngbe_mac_release_swfw_sync_dummy(struct ngbe_hw *TUP0, u32 TUP1) { } +static inline s32 ngbe_mac_setup_link_dummy(struct ngbe_hw *TUP0, u32 TUP1, + bool TUP2) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline s32 ngbe_mac_check_link_dummy(struct ngbe_hw *TUP0, u32 *TUP1, bool *TUP3, bool TUP4) { @@ -129,6 +134,16 @@ static inline s32 ngbe_phy_write_reg_unlocked_dummy(struct ngbe_hw *TUP0, { return NGBE_ERR_OPS_DUMMY; } +static inline s32 ngbe_phy_setup_link_dummy(struct ngbe_hw *TUP0, + u32 TUP1, bool TUP2) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_phy_check_link_dummy(struct ngbe_hw *TUP0, u32 *TUP1, + bool *TUP2) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) { hw->bus.set_lan_id = ngbe_bus_set_lan_id_dummy; @@ -140,6 +155,7 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) hw->mac.get_mac_addr = ngbe_mac_get_mac_addr_dummy; hw->mac.acquire_swfw_sync = ngbe_mac_acquire_swfw_sync_dummy; hw->mac.release_swfw_sync = ngbe_mac_release_swfw_sync_dummy; + hw->mac.setup_link = ngbe_mac_setup_link_dummy; hw->mac.check_link = ngbe_mac_check_link_dummy; hw->mac.set_rar = ngbe_mac_set_rar_dummy; hw->mac.clear_rar = ngbe_mac_clear_rar_dummy; @@ -154,6 +170,8 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) hw->phy.write_reg = ngbe_phy_write_reg_dummy; hw->phy.read_reg_unlocked = ngbe_phy_read_reg_unlocked_dummy; hw->phy.write_reg_unlocked = ngbe_phy_write_reg_unlocked_dummy; + hw->phy.setup_link = ngbe_phy_setup_link_dummy; + hw->phy.check_link = ngbe_phy_check_link_dummy; } #endif /* _NGBE_TYPE_DUMMY_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index 7f20d6c807..331fc752ff 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -599,6 +599,54 @@ s32 ngbe_init_uta_tables(struct ngbe_hw *hw) return 0; } +/** + * ngbe_check_mac_link_em - Determine link and speed status + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @link_up: true when link is up + * @link_up_wait_to_complete: bool used to wait for link up or not + * + * Reads the links register to determine if link is up and the current speed + **/ +s32 ngbe_check_mac_link_em(struct ngbe_hw *hw, u32 *speed, + bool *link_up, bool link_up_wait_to_complete) +{ + u32 i, reg; + s32 status = 0; + + DEBUGFUNC("ngbe_check_mac_link_em"); + + reg = rd32(hw, NGBE_GPIOINTSTAT); + wr32(hw, NGBE_GPIOEOI, reg); + + if (link_up_wait_to_complete) { + for (i = 0; i < hw->mac.max_link_up_time; i++) { + status = hw->phy.check_link(hw, speed, link_up); + if (*link_up) + break; + msec_delay(100); + } + } else { + status = hw->phy.check_link(hw, speed, link_up); + } + + return status; +} + +s32 ngbe_setup_mac_link_em(struct ngbe_hw *hw, + u32 speed, + bool autoneg_wait_to_complete) +{ + s32 status; + + DEBUGFUNC("\n"); + + /* Setup the PHY according to input speed */ + status = hw->phy.setup_link(hw, speed, autoneg_wait_to_complete); + + return status; +} + /** * ngbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds * @hw: pointer to hardware structure @@ -806,6 +854,10 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) mac->set_vmdq = ngbe_set_vmdq; mac->clear_vmdq = ngbe_clear_vmdq; + /* Link */ + mac->check_link = ngbe_check_mac_link_em; + mac->setup_link = ngbe_setup_mac_link_em; + /* Manageability interface */ mac->init_thermal_sensor_thresh = ngbe_init_thermal_sensor_thresh; mac->check_overtemp = ngbe_mac_check_overtemp; @@ -853,6 +905,7 @@ s32 ngbe_init_shared_code(struct ngbe_hw *hw) status = NGBE_ERR_DEVICE_NOT_SUPPORTED; break; } + hw->mac.max_link_up_time = NGBE_LINK_UP_TIME; hw->bus.set_lan_id(hw); diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h index 0b3d60ae29..1689223168 100644 --- a/drivers/net/ngbe/base/ngbe_hw.h +++ b/drivers/net/ngbe/base/ngbe_hw.h @@ -20,6 +20,12 @@ s32 ngbe_get_mac_addr(struct ngbe_hw *hw, u8 *mac_addr); void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw); +s32 ngbe_check_mac_link_em(struct ngbe_hw *hw, u32 *speed, + bool *link_up, bool link_up_wait_to_complete); +s32 ngbe_setup_mac_link_em(struct ngbe_hw *hw, + u32 speed, + bool autoneg_wait_to_complete); + s32 ngbe_set_rar(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr); s32 ngbe_clear_rar(struct ngbe_hw *hw, u32 index); diff --git a/drivers/net/ngbe/base/ngbe_phy.c b/drivers/net/ngbe/base/ngbe_phy.c index 0467e1e66e..471656cc51 100644 --- a/drivers/net/ngbe/base/ngbe_phy.c +++ b/drivers/net/ngbe/base/ngbe_phy.c @@ -420,7 +420,29 @@ s32 ngbe_init_phy(struct ngbe_hw *hw) /* Identify the PHY */ err = phy->identify(hw); + if (err == NGBE_ERR_PHY_ADDR_INVALID) + goto init_phy_ops_out; + /* Set necessary function pointers based on PHY type */ + switch (hw->phy.type) { + case ngbe_phy_rtl: + hw->phy.check_link = ngbe_check_phy_link_rtl; + hw->phy.setup_link = ngbe_setup_phy_link_rtl; + break; + case ngbe_phy_mvl: + case ngbe_phy_mvl_sfi: + hw->phy.check_link = ngbe_check_phy_link_mvl; + hw->phy.setup_link = ngbe_setup_phy_link_mvl; + break; + case ngbe_phy_yt8521s: + case ngbe_phy_yt8521s_sfi: + hw->phy.check_link = ngbe_check_phy_link_yt; + hw->phy.setup_link = ngbe_setup_phy_link_yt; + default: + break; + } + +init_phy_ops_out: return err; } diff --git a/drivers/net/ngbe/base/ngbe_phy.h b/drivers/net/ngbe/base/ngbe_phy.h index 59d9efe025..96e47b5bb9 100644 --- a/drivers/net/ngbe/base/ngbe_phy.h +++ b/drivers/net/ngbe/base/ngbe_phy.h @@ -22,6 +22,8 @@ #define NGBE_MD_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/ #define NGBE_PHY_REVISION_MASK 0xFFFFFFF0 +#define NGBE_MII_AUTONEG_REG 0x0 + /* IEEE 802.3 Clause 22 */ struct mdi_reg_22 { u16 page; diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.c b/drivers/net/ngbe/base/ngbe_phy_mvl.c index 40419a61f6..a1c055e238 100644 --- a/drivers/net/ngbe/base/ngbe_phy_mvl.c +++ b/drivers/net/ngbe/base/ngbe_phy_mvl.c @@ -48,6 +48,64 @@ s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw, return 0; } +s32 ngbe_setup_phy_link_mvl(struct ngbe_hw *hw, u32 speed, + bool autoneg_wait_to_complete) +{ + u16 value_r4 = 0; + u16 value_r9 = 0; + u16 value; + + DEBUGFUNC("ngbe_setup_phy_link_mvl"); + UNREFERENCED_PARAMETER(autoneg_wait_to_complete); + + hw->phy.autoneg_advertised = 0; + + if (hw->phy.type == ngbe_phy_mvl) { + if (speed & NGBE_LINK_SPEED_1GB_FULL) { + value_r9 |= MVL_PHY_1000BASET_FULL; + hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL; + } + + if (speed & NGBE_LINK_SPEED_100M_FULL) { + value_r4 |= MVL_PHY_100BASET_FULL; + hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL; + } + + if (speed & NGBE_LINK_SPEED_10M_FULL) { + value_r4 |= MVL_PHY_10BASET_FULL; + hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_10M_FULL; + } + + hw->phy.read_reg(hw, MVL_ANA, 0, &value); + value &= ~(MVL_PHY_100BASET_FULL | + MVL_PHY_100BASET_HALF | + MVL_PHY_10BASET_FULL | + MVL_PHY_10BASET_HALF); + value_r4 |= value; + hw->phy.write_reg(hw, MVL_ANA, 0, value_r4); + + hw->phy.read_reg(hw, MVL_PHY_1000BASET, 0, &value); + value &= ~(MVL_PHY_1000BASET_FULL | + MVL_PHY_1000BASET_HALF); + value_r9 |= value; + hw->phy.write_reg(hw, MVL_PHY_1000BASET, 0, value_r9); + } else { + hw->phy.autoneg_advertised = 1; + + hw->phy.read_reg(hw, MVL_ANA, 0, &value); + value &= ~(MVL_PHY_1000BASEX_HALF | MVL_PHY_1000BASEX_FULL); + value |= MVL_PHY_1000BASEX_FULL; + hw->phy.write_reg(hw, MVL_ANA, 0, value); + } + + value = MVL_CTRL_RESTART_AN | MVL_CTRL_ANE; + ngbe_write_phy_reg_mdi(hw, MVL_CTRL, 0, value); + + hw->phy.read_reg(hw, MVL_INTR, 0, &value); + + return 0; +} + s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw) { u32 i; @@ -87,3 +145,43 @@ s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw) return status; } +s32 ngbe_check_phy_link_mvl(struct ngbe_hw *hw, + u32 *speed, bool *link_up) +{ + s32 status = 0; + u16 phy_link = 0; + u16 phy_speed = 0; + u16 phy_data = 0; + u16 insr = 0; + + DEBUGFUNC("ngbe_check_phy_link_mvl"); + + /* Initialize speed and link to default case */ + *link_up = false; + *speed = NGBE_LINK_SPEED_UNKNOWN; + + hw->phy.read_reg(hw, MVL_INTR, 0, &insr); + + /* + * Check current speed and link status of the PHY register. + * This is a vendor specific register and may have to + * be changed for other copper PHYs. + */ + status = hw->phy.read_reg(hw, MVL_PHYSR, 0, &phy_data); + phy_link = phy_data & MVL_PHYSR_LINK; + phy_speed = phy_data & MVL_PHYSR_SPEED_MASK; + + if (phy_link == MVL_PHYSR_LINK) { + *link_up = true; + + if (phy_speed == MVL_PHYSR_SPEED_1000M) + *speed = NGBE_LINK_SPEED_1GB_FULL; + else if (phy_speed == MVL_PHYSR_SPEED_100M) + *speed = NGBE_LINK_SPEED_100M_FULL; + else if (phy_speed == MVL_PHYSR_SPEED_10M) + *speed = NGBE_LINK_SPEED_10M_FULL; + } + + return status; +} + diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.h b/drivers/net/ngbe/base/ngbe_phy_mvl.h index a88ace9ec1..a663a429dd 100644 --- a/drivers/net/ngbe/base/ngbe_phy_mvl.h +++ b/drivers/net/ngbe/base/ngbe_phy_mvl.h @@ -89,4 +89,8 @@ s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw); +s32 ngbe_check_phy_link_mvl(struct ngbe_hw *hw, + u32 *speed, bool *link_up); +s32 ngbe_setup_phy_link_mvl(struct ngbe_hw *hw, + u32 speed, bool autoneg_wait_to_complete); #endif /* _NGBE_PHY_MVL_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.c b/drivers/net/ngbe/base/ngbe_phy_rtl.c index 0703ad9396..3401fc7e92 100644 --- a/drivers/net/ngbe/base/ngbe_phy_rtl.c +++ b/drivers/net/ngbe/base/ngbe_phy_rtl.c @@ -38,6 +38,134 @@ s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw, return 0; } +/** + * ngbe_setup_phy_link_rtl - Set and restart auto-neg + * @hw: pointer to hardware structure + * + * Restart auto-negotiation and PHY and waits for completion. + **/ +s32 ngbe_setup_phy_link_rtl(struct ngbe_hw *hw, + u32 speed, bool autoneg_wait_to_complete) +{ + u16 autoneg_reg = NGBE_MII_AUTONEG_REG; + u16 value = 0; + + DEBUGFUNC("ngbe_setup_phy_link_rtl"); + + UNREFERENCED_PARAMETER(autoneg_wait_to_complete); + + hw->phy.read_reg(hw, RTL_INSR, 0xa43, &autoneg_reg); + + if (!hw->mac.autoneg) { + hw->phy.reset_hw(hw); + + switch (speed) { + case NGBE_LINK_SPEED_1GB_FULL: + value = RTL_BMCR_SPEED_SELECT1; + break; + case NGBE_LINK_SPEED_100M_FULL: + value = RTL_BMCR_SPEED_SELECT0; + break; + case NGBE_LINK_SPEED_10M_FULL: + value = 0; + break; + default: + value = RTL_BMCR_SPEED_SELECT1 | RTL_BMCR_SPEED_SELECT0; + DEBUGOUT("unknown speed = 0x%x.\n", speed); + break; + } + /* duplex full */ + value |= RTL_BMCR_DUPLEX; + hw->phy.write_reg(hw, RTL_BMCR, RTL_DEV_ZERO, value); + + goto skip_an; + } + + /* + * Clear autoneg_advertised and set new values based on input link + * speed. + */ + if (speed) { + hw->phy.autoneg_advertised = 0; + + if (speed & NGBE_LINK_SPEED_1GB_FULL) + hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL; + + if (speed & NGBE_LINK_SPEED_100M_FULL) + hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL; + + if (speed & NGBE_LINK_SPEED_10M_FULL) + hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_10M_FULL; + } + + /* disable 10/100M Half Duplex */ + hw->phy.read_reg(hw, RTL_ANAR, RTL_DEV_ZERO, &autoneg_reg); + autoneg_reg &= 0xFF5F; + hw->phy.write_reg(hw, RTL_ANAR, RTL_DEV_ZERO, autoneg_reg); + + /* set advertise enable according to input speed */ + if (!(speed & NGBE_LINK_SPEED_1GB_FULL)) { + hw->phy.read_reg(hw, RTL_GBCR, + RTL_DEV_ZERO, &autoneg_reg); + autoneg_reg &= ~RTL_GBCR_1000F; + hw->phy.write_reg(hw, RTL_GBCR, + RTL_DEV_ZERO, autoneg_reg); + } else { + hw->phy.read_reg(hw, RTL_GBCR, + RTL_DEV_ZERO, &autoneg_reg); + autoneg_reg |= RTL_GBCR_1000F; + hw->phy.write_reg(hw, RTL_GBCR, + RTL_DEV_ZERO, autoneg_reg); + } + + if (!(speed & NGBE_LINK_SPEED_100M_FULL)) { + hw->phy.read_reg(hw, RTL_ANAR, + RTL_DEV_ZERO, &autoneg_reg); + autoneg_reg &= ~RTL_ANAR_100F; + autoneg_reg &= ~RTL_ANAR_100H; + hw->phy.write_reg(hw, RTL_ANAR, + RTL_DEV_ZERO, autoneg_reg); + } else { + hw->phy.read_reg(hw, RTL_ANAR, + RTL_DEV_ZERO, &autoneg_reg); + autoneg_reg |= RTL_ANAR_100F; + hw->phy.write_reg(hw, RTL_ANAR, + RTL_DEV_ZERO, autoneg_reg); + } + + if (!(speed & NGBE_LINK_SPEED_10M_FULL)) { + hw->phy.read_reg(hw, RTL_ANAR, + RTL_DEV_ZERO, &autoneg_reg); + autoneg_reg &= ~RTL_ANAR_10F; + autoneg_reg &= ~RTL_ANAR_10H; + hw->phy.write_reg(hw, RTL_ANAR, + RTL_DEV_ZERO, autoneg_reg); + } else { + hw->phy.read_reg(hw, RTL_ANAR, + RTL_DEV_ZERO, &autoneg_reg); + autoneg_reg |= RTL_ANAR_10F; + hw->phy.write_reg(hw, RTL_ANAR, + RTL_DEV_ZERO, autoneg_reg); + } + + /* restart AN and wait AN done interrupt */ + autoneg_reg = RTL_BMCR_RESTART_AN | RTL_BMCR_ANE; + hw->phy.write_reg(hw, RTL_BMCR, RTL_DEV_ZERO, autoneg_reg); + +skip_an: + autoneg_reg = 0x205B; + hw->phy.write_reg(hw, RTL_LCR, 0xd04, autoneg_reg); + hw->phy.write_reg(hw, RTL_EEELCR, 0xd04, 0); + + hw->phy.read_reg(hw, RTL_LPCR, 0xd04, &autoneg_reg); + autoneg_reg = autoneg_reg & 0xFFFC; + /* act led blinking mode set to 60ms */ + autoneg_reg |= 0x2; + hw->phy.write_reg(hw, RTL_LPCR, 0xd04, autoneg_reg); + + return 0; +} + s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw) { u16 value = 0, i; @@ -63,3 +191,41 @@ s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw) return status; } +s32 ngbe_check_phy_link_rtl(struct ngbe_hw *hw, u32 *speed, bool *link_up) +{ + s32 status = 0; + u16 phy_link = 0; + u16 phy_speed = 0; + u16 phy_data = 0; + u16 insr = 0; + + DEBUGFUNC("ngbe_check_phy_link_rtl"); + + hw->phy.read_reg(hw, RTL_INSR, 0xa43, &insr); + + /* Initialize speed and link to default case */ + *link_up = false; + *speed = NGBE_LINK_SPEED_UNKNOWN; + + /* + * Check current speed and link status of the PHY register. + * This is a vendor specific register and may have to + * be changed for other copper PHYs. + */ + status = hw->phy.read_reg(hw, RTL_PHYSR, 0xa43, &phy_data); + phy_link = phy_data & RTL_PHYSR_RTLS; + phy_speed = phy_data & (RTL_PHYSR_SPEED_MASK | RTL_PHYSR_DP); + if (phy_link == RTL_PHYSR_RTLS) { + *link_up = true; + + if (phy_speed == (RTL_PHYSR_SPEED_1000M | RTL_PHYSR_DP)) + *speed = NGBE_LINK_SPEED_1GB_FULL; + else if (phy_speed == (RTL_PHYSR_SPEED_100M | RTL_PHYSR_DP)) + *speed = NGBE_LINK_SPEED_100M_FULL; + else if (phy_speed == (RTL_PHYSR_SPEED_10M | RTL_PHYSR_DP)) + *speed = NGBE_LINK_SPEED_10M_FULL; + } + + return status; +} + diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.h b/drivers/net/ngbe/base/ngbe_phy_rtl.h index ecb60b0ddd..e8bc4a1bd7 100644 --- a/drivers/net/ngbe/base/ngbe_phy_rtl.h +++ b/drivers/net/ngbe/base/ngbe_phy_rtl.h @@ -78,6 +78,10 @@ s32 ngbe_read_phy_reg_rtl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, u16 phy_data); +s32 ngbe_setup_phy_link_rtl(struct ngbe_hw *hw, + u32 speed, bool autoneg_wait_to_complete); s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw); +s32 ngbe_check_phy_link_rtl(struct ngbe_hw *hw, + u32 *speed, bool *link_up); #endif /* _NGBE_PHY_RTL_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.c b/drivers/net/ngbe/base/ngbe_phy_yt.c index 84b20de45c..f518dc0af6 100644 --- a/drivers/net/ngbe/base/ngbe_phy_yt.c +++ b/drivers/net/ngbe/base/ngbe_phy_yt.c @@ -78,6 +78,104 @@ s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw, return 0; } +s32 ngbe_read_phy_reg_sds_ext_yt(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 *phy_data) +{ + ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, YT_SMI_PHY_SDS); + ngbe_read_phy_reg_ext_yt(hw, reg_addr, device_type, phy_data); + ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, 0); + + return 0; +} + +s32 ngbe_write_phy_reg_sds_ext_yt(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 phy_data) +{ + ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, YT_SMI_PHY_SDS); + ngbe_write_phy_reg_ext_yt(hw, reg_addr, device_type, phy_data); + ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, 0); + + return 0; +} + +s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed, + bool autoneg_wait_to_complete) +{ + u16 value_r4 = 0; + u16 value_r9 = 0; + u16 value; + + DEBUGFUNC("ngbe_setup_phy_link_yt"); + UNREFERENCED_PARAMETER(autoneg_wait_to_complete); + + hw->phy.autoneg_advertised = 0; + + if (hw->phy.type == ngbe_phy_yt8521s) { + /*disable 100/10base-T Self-negotiation ability*/ + hw->phy.read_reg(hw, YT_ANA, 0, &value); + value &= ~(YT_ANA_100BASET_FULL | YT_ANA_10BASET_FULL); + hw->phy.write_reg(hw, YT_ANA, 0, value); + + /*disable 1000base-T Self-negotiation ability*/ + hw->phy.read_reg(hw, YT_MS_CTRL, 0, &value); + value &= ~YT_MS_1000BASET_FULL; + hw->phy.write_reg(hw, YT_MS_CTRL, 0, value); + + if (speed & NGBE_LINK_SPEED_1GB_FULL) { + hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL; + value_r9 |= YT_MS_1000BASET_FULL; + } + if (speed & NGBE_LINK_SPEED_100M_FULL) { + hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL; + value_r4 |= YT_ANA_100BASET_FULL; + } + if (speed & NGBE_LINK_SPEED_10M_FULL) { + hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_10M_FULL; + value_r4 |= YT_ANA_10BASET_FULL; + } + + /* enable 1000base-T Self-negotiation ability */ + hw->phy.read_reg(hw, YT_MS_CTRL, 0, &value); + value |= value_r9; + hw->phy.write_reg(hw, YT_MS_CTRL, 0, value); + + /* enable 100/10base-T Self-negotiation ability */ + hw->phy.read_reg(hw, YT_ANA, 0, &value); + value |= value_r4; + hw->phy.write_reg(hw, YT_ANA, 0, value); + + /* software reset to make the above configuration take effect*/ + hw->phy.read_reg(hw, YT_BCR, 0, &value); + value |= YT_BCR_RESET; + hw->phy.write_reg(hw, YT_BCR, 0, value); + } else { + hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL; + + /* RGMII_Config1 : Config rx and tx training delay */ + value = YT_RGMII_CONF1_RXDELAY | + YT_RGMII_CONF1_TXDELAY_FE | + YT_RGMII_CONF1_TXDELAY; + ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value); + value = YT_CHIP_MODE_SEL(1) | + YT_CHIP_SW_LDO_EN | + YT_CHIP_SW_RST; + ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value); + + /* software reset */ + ngbe_write_phy_reg_sds_ext_yt(hw, 0x0, 0, 0x9140); + + /* power on phy */ + hw->phy.read_reg(hw, YT_BCR, 0, &value); + value &= ~YT_BCR_PWDN; + hw->phy.write_reg(hw, YT_BCR, 0, value); + } + + ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0); + ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &value); + + return 0; +} + s32 ngbe_reset_phy_yt(struct ngbe_hw *hw) { u32 i; @@ -110,3 +208,39 @@ s32 ngbe_reset_phy_yt(struct ngbe_hw *hw) return status; } +s32 ngbe_check_phy_link_yt(struct ngbe_hw *hw, + u32 *speed, bool *link_up) +{ + s32 status = 0; + u16 phy_link = 0; + u16 phy_speed = 0; + u16 phy_data = 0; + u16 insr = 0; + + DEBUGFUNC("ngbe_check_phy_link_yt"); + + /* Initialize speed and link to default case */ + *link_up = false; + *speed = NGBE_LINK_SPEED_UNKNOWN; + + ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0); + ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &insr); + + status = hw->phy.read_reg(hw, YT_SPST, 0, &phy_data); + phy_link = phy_data & YT_SPST_LINK; + phy_speed = phy_data & YT_SPST_SPEED_MASK; + + if (phy_link) { + *link_up = true; + + if (phy_speed == YT_SPST_SPEED_1000M) + *speed = NGBE_LINK_SPEED_1GB_FULL; + else if (phy_speed == YT_SPST_SPEED_100M) + *speed = NGBE_LINK_SPEED_100M_FULL; + else if (phy_speed == YT_SPST_SPEED_10M) + *speed = NGBE_LINK_SPEED_10M_FULL; + } + + return status; +} + diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.h b/drivers/net/ngbe/base/ngbe_phy_yt.h index 80fd420a63..26820ecb92 100644 --- a/drivers/net/ngbe/base/ngbe_phy_yt.h +++ b/drivers/net/ngbe/base/ngbe_phy_yt.h @@ -61,7 +61,15 @@ s32 ngbe_read_phy_reg_ext_yt(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, u16 *phy_data); s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, u16 phy_data); +s32 ngbe_read_phy_reg_sds_ext_yt(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 *phy_data); +s32 ngbe_write_phy_reg_sds_ext_yt(struct ngbe_hw *hw, + u32 reg_addr, u32 device_type, u16 phy_data); s32 ngbe_reset_phy_yt(struct ngbe_hw *hw); +s32 ngbe_check_phy_link_yt(struct ngbe_hw *hw, + u32 *speed, bool *link_up); +s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, + u32 speed, bool autoneg_wait_to_complete); #endif /* _NGBE_PHY_YT_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index 04c1cac422..626c6e2eec 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -6,6 +6,8 @@ #ifndef _NGBE_TYPE_H_ #define _NGBE_TYPE_H_ +#define NGBE_LINK_UP_TIME 90 /* 9.0 Seconds */ + #define NGBE_FRAME_SIZE_DFT (1522) /* Default frame size, +FCS */ #define NGBE_ALIGN 128 /* as intel did */ @@ -97,6 +99,8 @@ struct ngbe_mac_info { s32 (*acquire_swfw_sync)(struct ngbe_hw *hw, u32 mask); void (*release_swfw_sync)(struct ngbe_hw *hw, u32 mask); + s32 (*setup_link)(struct ngbe_hw *hw, u32 speed, + bool autoneg_wait_to_complete); s32 (*check_link)(struct ngbe_hw *hw, u32 *speed, bool *link_up, bool link_up_wait_to_complete); /* RAR */ @@ -122,6 +126,9 @@ struct ngbe_mac_info { bool get_link_status; struct ngbe_thermal_sensor_data thermal_sensor_data; bool set_lben; + u32 max_link_up_time; + + bool autoneg; }; struct ngbe_phy_info { @@ -135,6 +142,9 @@ struct ngbe_phy_info { u32 device_type, u16 *phy_data); s32 (*write_reg_unlocked)(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, u16 phy_data); + s32 (*setup_link)(struct ngbe_hw *hw, u32 speed, + bool autoneg_wait_to_complete); + s32 (*check_link)(struct ngbe_hw *hw, u32 *speed, bool *link_up); enum ngbe_media_type media_type; enum ngbe_phy_type type; @@ -143,6 +153,7 @@ struct ngbe_phy_info { u32 revision; u32 phy_semaphore_mask; bool reset_disable; + u32 autoneg_advertised; }; enum ngbe_isb_idx { From patchwork Thu Jun 17 10:59:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94337 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 8944BA0C4D; Thu, 17 Jun 2021 12:59:40 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1D2D941140; Thu, 17 Jun 2021 12:58:35 +0200 (CEST) Received: from smtpbgbr2.qq.com (smtpbgbr2.qq.com [54.207.22.56]) by mails.dpdk.org (Postfix) with ESMTP id 4791341159 for ; Thu, 17 Jun 2021 12:58:32 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927506trnggv1o Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:26 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: YKCDl5A3/ap6M8oDPuBU/NwnGUSe/zEHuwEVBLBI9GRksCLMKGDZOgDSlrKq2 C26JO3G0bIuxmUDLwy/UaoqJ82kg49ZsbZvZAX0pb7ETGuBelttyxwjsj5UE7MM/3gLsQ8J 9XBAdDFTmwSbn26/Xe16KXckeeEgl67ykMsg30dXzCaMyzfFuPPg3Fp7DfV/DeiwC1EstbC Q6t705ENaWgzTbmFSeCvtXDwIi6iHEQLd8p7RBN6waKr4lsuPOyr1PjIst+rZKWvoWY2W3J u/4e8iurfNXwDnIP90gsDvpH4Hs1cIv5v+OvJjCZmz63Nh2y31y/BMIITe/p+6KsBdi+NYn E73S1UaTt6hgLdbR2NfHiorQEg71XNM1eC7wlob X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:58 +0800 Message-Id: <20210617110005.4132926-13-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign5 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 12/19] net/ngbe: add Rx queue setup and release X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Setup device Rx queue and release Rx queue. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/meson.build | 1 + drivers/net/ngbe/ngbe_ethdev.c | 37 +++- drivers/net/ngbe/ngbe_ethdev.h | 16 ++ drivers/net/ngbe/ngbe_rxtx.c | 308 +++++++++++++++++++++++++++++++++ drivers/net/ngbe/ngbe_rxtx.h | 96 ++++++++++ 5 files changed, 457 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ngbe/ngbe_rxtx.c create mode 100644 drivers/net/ngbe/ngbe_rxtx.h diff --git a/drivers/net/ngbe/meson.build b/drivers/net/ngbe/meson.build index 81173fa7f0..9e75b82f1c 100644 --- a/drivers/net/ngbe/meson.build +++ b/drivers/net/ngbe/meson.build @@ -12,6 +12,7 @@ objs = [base_objs] sources = files( 'ngbe_ethdev.c', + 'ngbe_rxtx.c', ) includes += include_directories('base') diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index c952023e8b..e73606c5f3 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -12,6 +12,7 @@ #include "ngbe_logs.h" #include "base/ngbe.h" #include "ngbe_ethdev.h" +#include "ngbe_rxtx.h" static int ngbe_dev_close(struct rte_eth_dev *dev); @@ -37,6 +38,12 @@ static const struct rte_pci_id pci_id_ngbe_map[] = { { .vendor_id = 0, /* sentinel */ }, }; +static const struct rte_eth_desc_lim rx_desc_lim = { + .nb_max = NGBE_RING_DESC_MAX, + .nb_min = NGBE_RING_DESC_MIN, + .nb_align = NGBE_RXD_ALIGN, +}; + static const struct eth_dev_ops ngbe_eth_dev_ops; static inline void @@ -241,12 +248,19 @@ static int ngbe_dev_configure(struct rte_eth_dev *dev) { struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + struct ngbe_adapter *adapter = ngbe_dev_adapter(dev); PMD_INIT_FUNC_TRACE(); /* set flag to update link status after init */ intr->flags |= NGBE_FLAG_NEED_LINK_UPDATE; + /* + * Initialize to TRUE. If any of Rx queues doesn't meet the bulk + * allocation Rx preconditions we will reset it. + */ + adapter->rx_bulk_alloc_allowed = true; + return 0; } @@ -266,11 +280,30 @@ ngbe_dev_close(struct rte_eth_dev *dev) static int ngbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { - RTE_SET_USED(dev); + struct ngbe_hw *hw = ngbe_dev_hw(dev); + + dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues; + + dev_info->default_rxconf = (struct rte_eth_rxconf) { + .rx_thresh = { + .pthresh = NGBE_DEFAULT_RX_PTHRESH, + .hthresh = NGBE_DEFAULT_RX_HTHRESH, + .wthresh = NGBE_DEFAULT_RX_WTHRESH, + }, + .rx_free_thresh = NGBE_DEFAULT_RX_FREE_THRESH, + .rx_drop_en = 0, + .offloads = 0, + }; + + dev_info->rx_desc_lim = rx_desc_lim; dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_100M | ETH_LINK_SPEED_10M; + /* Driver-preferred Rx/Tx parameters */ + dev_info->default_rxportconf.nb_queues = 1; + dev_info->default_rxportconf.ring_size = 256; + return 0; } @@ -570,6 +603,8 @@ static const struct eth_dev_ops ngbe_eth_dev_ops = { .dev_configure = ngbe_dev_configure, .dev_infos_get = ngbe_dev_info_get, .link_update = ngbe_dev_link_update, + .rx_queue_setup = ngbe_dev_rx_queue_setup, + .rx_queue_release = ngbe_dev_rx_queue_release, }; RTE_PMD_REGISTER_PCI(net_ngbe, rte_ngbe_pmd); diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h index b67508a3de..6580d288c8 100644 --- a/drivers/net/ngbe/ngbe_ethdev.h +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -30,6 +30,7 @@ struct ngbe_interrupt { struct ngbe_adapter { struct ngbe_hw hw; struct ngbe_interrupt intr; + bool rx_bulk_alloc_allowed; }; static inline struct ngbe_adapter * @@ -58,6 +59,13 @@ ngbe_dev_intr(struct rte_eth_dev *dev) return intr; } +void ngbe_dev_rx_queue_release(void *rxq); + +int ngbe_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id, + uint16_t nb_rx_desc, unsigned int socket_id, + const struct rte_eth_rxconf *rx_conf, + struct rte_mempool *mb_pool); + int ngbe_dev_link_update_share(struct rte_eth_dev *dev, int wait_to_complete); @@ -66,4 +74,12 @@ ngbe_dev_link_update_share(struct rte_eth_dev *dev, #define NGBE_LINK_UP_CHECK_TIMEOUT 1000 /* ms */ #define NGBE_VMDQ_NUM_UC_MAC 4096 /* Maximum nb. of UC MAC addr. */ +/* + * Default values for Rx/Tx configuration + */ +#define NGBE_DEFAULT_RX_FREE_THRESH 32 +#define NGBE_DEFAULT_RX_PTHRESH 8 +#define NGBE_DEFAULT_RX_HTHRESH 8 +#define NGBE_DEFAULT_RX_WTHRESH 0 + #endif /* _NGBE_ETHDEV_H_ */ diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c new file mode 100644 index 0000000000..df0b64dc01 --- /dev/null +++ b/drivers/net/ngbe/ngbe_rxtx.c @@ -0,0 +1,308 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#include + +#include +#include +#include +#include + +#include "ngbe_logs.h" +#include "base/ngbe.h" +#include "ngbe_ethdev.h" +#include "ngbe_rxtx.h" + +/** + * ngbe_free_sc_cluster - free the not-yet-completed scattered cluster + * + * The "next" pointer of the last segment of (not-yet-completed) RSC clusters + * in the sw_sc_ring is not set to NULL but rather points to the next + * mbuf of this RSC aggregation (that has not been completed yet and still + * resides on the HW ring). So, instead of calling for rte_pktmbuf_free() we + * will just free first "nb_segs" segments of the cluster explicitly by calling + * an rte_pktmbuf_free_seg(). + * + * @m scattered cluster head + */ +static void __rte_cold +ngbe_free_sc_cluster(struct rte_mbuf *m) +{ + uint16_t i, nb_segs = m->nb_segs; + struct rte_mbuf *next_seg; + + for (i = 0; i < nb_segs; i++) { + next_seg = m->next; + rte_pktmbuf_free_seg(m); + m = next_seg; + } +} + +static void __rte_cold +ngbe_rx_queue_release_mbufs(struct ngbe_rx_queue *rxq) +{ + unsigned int i; + + if (rxq->sw_ring != NULL) { + for (i = 0; i < rxq->nb_rx_desc; i++) { + if (rxq->sw_ring[i].mbuf != NULL) { + rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf); + rxq->sw_ring[i].mbuf = NULL; + } + } + if (rxq->rx_nb_avail) { + for (i = 0; i < rxq->rx_nb_avail; ++i) { + struct rte_mbuf *mb; + + mb = rxq->rx_stage[rxq->rx_next_avail + i]; + rte_pktmbuf_free_seg(mb); + } + rxq->rx_nb_avail = 0; + } + } + + if (rxq->sw_sc_ring != NULL) + for (i = 0; i < rxq->nb_rx_desc; i++) + if (rxq->sw_sc_ring[i].fbuf) { + ngbe_free_sc_cluster(rxq->sw_sc_ring[i].fbuf); + rxq->sw_sc_ring[i].fbuf = NULL; + } +} + +static void __rte_cold +ngbe_rx_queue_release(struct ngbe_rx_queue *rxq) +{ + if (rxq != NULL) { + ngbe_rx_queue_release_mbufs(rxq); + rte_free(rxq->sw_ring); + rte_free(rxq->sw_sc_ring); + rte_free(rxq); + } +} + +void __rte_cold +ngbe_dev_rx_queue_release(void *rxq) +{ + ngbe_rx_queue_release(rxq); +} + +/* + * Check if Rx Burst Bulk Alloc function can be used. + * Return + * 0: the preconditions are satisfied and the bulk allocation function + * can be used. + * -EINVAL: the preconditions are NOT satisfied and the default Rx burst + * function must be used. + */ +static inline int __rte_cold +check_rx_burst_bulk_alloc_preconditions(struct ngbe_rx_queue *rxq) +{ + int ret = 0; + + /* + * Make sure the following pre-conditions are satisfied: + * rxq->rx_free_thresh >= RTE_PMD_NGBE_RX_MAX_BURST + * rxq->rx_free_thresh < rxq->nb_rx_desc + * (rxq->nb_rx_desc % rxq->rx_free_thresh) == 0 + * Scattered packets are not supported. This should be checked + * outside of this function. + */ + if (!(rxq->rx_free_thresh >= RTE_PMD_NGBE_RX_MAX_BURST)) { + PMD_INIT_LOG(DEBUG, "Rx Burst Bulk Alloc Preconditions: " + "rxq->rx_free_thresh=%d, " + "RTE_PMD_NGBE_RX_MAX_BURST=%d", + rxq->rx_free_thresh, RTE_PMD_NGBE_RX_MAX_BURST); + ret = -EINVAL; + } else if (!(rxq->rx_free_thresh < rxq->nb_rx_desc)) { + PMD_INIT_LOG(DEBUG, "Rx Burst Bulk Alloc Preconditions: " + "rxq->rx_free_thresh=%d, " + "rxq->nb_rx_desc=%d", + rxq->rx_free_thresh, rxq->nb_rx_desc); + ret = -EINVAL; + } else if (!((rxq->nb_rx_desc % rxq->rx_free_thresh) == 0)) { + PMD_INIT_LOG(DEBUG, "Rx Burst Bulk Alloc Preconditions: " + "rxq->nb_rx_desc=%d, " + "rxq->rx_free_thresh=%d", + rxq->nb_rx_desc, rxq->rx_free_thresh); + ret = -EINVAL; + } + + return ret; +} + +/* Reset dynamic ngbe_rx_queue fields back to defaults */ +static void __rte_cold +ngbe_reset_rx_queue(struct ngbe_adapter *adapter, struct ngbe_rx_queue *rxq) +{ + static const struct ngbe_rx_desc zeroed_desc = { + {{0}, {0} }, {{0}, {0} } }; + unsigned int i; + uint16_t len = rxq->nb_rx_desc; + + /* + * By default, the Rx queue setup function allocates enough memory for + * NGBE_RING_DESC_MAX. The Rx Burst bulk allocation function requires + * extra memory at the end of the descriptor ring to be zero'd out. + */ + if (adapter->rx_bulk_alloc_allowed) + /* zero out extra memory */ + len += RTE_PMD_NGBE_RX_MAX_BURST; + + /* + * Zero out HW ring memory. Zero out extra memory at the end of + * the H/W ring so look-ahead logic in Rx Burst bulk alloc function + * reads extra memory as zeros. + */ + for (i = 0; i < len; i++) + rxq->rx_ring[i] = zeroed_desc; + + /* + * initialize extra software ring entries. Space for these extra + * entries is always allocated + */ + memset(&rxq->fake_mbuf, 0x0, sizeof(rxq->fake_mbuf)); + for (i = rxq->nb_rx_desc; i < len; ++i) + rxq->sw_ring[i].mbuf = &rxq->fake_mbuf; + + rxq->rx_nb_avail = 0; + rxq->rx_next_avail = 0; + rxq->rx_free_trigger = (uint16_t)(rxq->rx_free_thresh - 1); + rxq->rx_tail = 0; + rxq->nb_rx_hold = 0; + rxq->pkt_first_seg = NULL; + rxq->pkt_last_seg = NULL; +} + +int __rte_cold +ngbe_dev_rx_queue_setup(struct rte_eth_dev *dev, + uint16_t queue_idx, + uint16_t nb_desc, + unsigned int socket_id, + const struct rte_eth_rxconf *rx_conf, + struct rte_mempool *mp) +{ + const struct rte_memzone *rz; + struct ngbe_rx_queue *rxq; + struct ngbe_hw *hw; + uint16_t len; + struct ngbe_adapter *adapter = ngbe_dev_adapter(dev); + + PMD_INIT_FUNC_TRACE(); + hw = ngbe_dev_hw(dev); + + /* + * Validate number of receive descriptors. + * It must not exceed hardware maximum, and must be multiple + * of NGBE_ALIGN. + */ + if (nb_desc % NGBE_RXD_ALIGN != 0 || + nb_desc > NGBE_RING_DESC_MAX || + nb_desc < NGBE_RING_DESC_MIN) { + return -EINVAL; + } + + /* Free memory prior to re-allocation if needed... */ + if (dev->data->rx_queues[queue_idx] != NULL) { + ngbe_rx_queue_release(dev->data->rx_queues[queue_idx]); + dev->data->rx_queues[queue_idx] = NULL; + } + + /* First allocate the Rx queue data structure */ + rxq = rte_zmalloc_socket("ethdev RX queue", + sizeof(struct ngbe_rx_queue), + RTE_CACHE_LINE_SIZE, socket_id); + if (rxq == NULL) + return -ENOMEM; + rxq->mb_pool = mp; + rxq->nb_rx_desc = nb_desc; + rxq->rx_free_thresh = rx_conf->rx_free_thresh; + rxq->queue_id = queue_idx; + rxq->reg_idx = queue_idx; + rxq->port_id = dev->data->port_id; + rxq->drop_en = rx_conf->rx_drop_en; + rxq->rx_deferred_start = rx_conf->rx_deferred_start; + + /* + * Allocate Rx ring hardware descriptors. A memzone large enough to + * handle the maximum ring size is allocated in order to allow for + * resizing in later calls to the queue setup function. + */ + rz = rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, + RX_RING_SZ, NGBE_ALIGN, socket_id); + if (rz == NULL) { + ngbe_rx_queue_release(rxq); + return -ENOMEM; + } + + /* + * Zero init all the descriptors in the ring. + */ + memset(rz->addr, 0, RX_RING_SZ); + + rxq->rdt_reg_addr = NGBE_REG_ADDR(hw, NGBE_RXWP(rxq->reg_idx)); + rxq->rdh_reg_addr = NGBE_REG_ADDR(hw, NGBE_RXRP(rxq->reg_idx)); + + rxq->rx_ring_phys_addr = TMZ_PADDR(rz); + rxq->rx_ring = (struct ngbe_rx_desc *)TMZ_VADDR(rz); + + /* + * Certain constraints must be met in order to use the bulk buffer + * allocation Rx burst function. If any of Rx queues doesn't meet them + * the feature should be disabled for the whole port. + */ + if (check_rx_burst_bulk_alloc_preconditions(rxq)) { + PMD_INIT_LOG(DEBUG, "queue[%d] doesn't meet Rx Bulk Alloc " + "preconditions - canceling the feature for " + "the whole port[%d]", + rxq->queue_id, rxq->port_id); + adapter->rx_bulk_alloc_allowed = false; + } + + /* + * Allocate software ring. Allow for space at the end of the + * S/W ring to make sure look-ahead logic in bulk alloc Rx burst + * function does not access an invalid memory region. + */ + len = nb_desc; + if (adapter->rx_bulk_alloc_allowed) + len += RTE_PMD_NGBE_RX_MAX_BURST; + + rxq->sw_ring = rte_zmalloc_socket("rxq->sw_ring", + sizeof(struct ngbe_rx_entry) * len, + RTE_CACHE_LINE_SIZE, socket_id); + if (rxq->sw_ring == NULL) { + ngbe_rx_queue_release(rxq); + return -ENOMEM; + } + + /* + * Always allocate even if it's not going to be needed in order to + * simplify the code. + * + * This ring is used in Scattered Rx cases and Scattered Rx may + * be requested in ngbe_dev_rx_init(), which is called later from + * dev_start() flow. + */ + rxq->sw_sc_ring = + rte_zmalloc_socket("rxq->sw_sc_ring", + sizeof(struct ngbe_scattered_rx_entry) * len, + RTE_CACHE_LINE_SIZE, socket_id); + if (rxq->sw_sc_ring == NULL) { + ngbe_rx_queue_release(rxq); + return -ENOMEM; + } + + PMD_INIT_LOG(DEBUG, "sw_ring=%p sw_sc_ring=%p hw_ring=%p " + "dma_addr=0x%" PRIx64, + rxq->sw_ring, rxq->sw_sc_ring, rxq->rx_ring, + rxq->rx_ring_phys_addr); + + dev->data->rx_queues[queue_idx] = rxq; + + ngbe_reset_rx_queue(adapter, rxq); + + return 0; +} + diff --git a/drivers/net/ngbe/ngbe_rxtx.h b/drivers/net/ngbe/ngbe_rxtx.h new file mode 100644 index 0000000000..92b9a9fd1b --- /dev/null +++ b/drivers/net/ngbe/ngbe_rxtx.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _NGBE_RXTX_H_ +#define _NGBE_RXTX_H_ + +/***************************************************************************** + * Receive Descriptor + *****************************************************************************/ +struct ngbe_rx_desc { + struct { + union { + rte_le32_t dw0; + struct { + rte_le16_t pkt; + rte_le16_t hdr; + } lo; + }; + union { + rte_le32_t dw1; + struct { + rte_le16_t ipid; + rte_le16_t csum; + } hi; + }; + } qw0; /* also as r.pkt_addr */ + struct { + union { + rte_le32_t dw2; + struct { + rte_le32_t status; + } lo; + }; + union { + rte_le32_t dw3; + struct { + rte_le16_t len; + rte_le16_t tag; + } hi; + }; + } qw1; /* also as r.hdr_addr */ +}; + +#define RTE_PMD_NGBE_RX_MAX_BURST 32 + +#define RX_RING_SZ ((NGBE_RING_DESC_MAX + RTE_PMD_NGBE_RX_MAX_BURST) * \ + sizeof(struct ngbe_rx_desc)) + + +/** + * Structure associated with each descriptor of the Rx ring of a Rx queue. + */ +struct ngbe_rx_entry { + struct rte_mbuf *mbuf; /**< mbuf associated with Rx descriptor. */ +}; + +struct ngbe_scattered_rx_entry { + struct rte_mbuf *fbuf; /**< First segment of the fragmented packet. */ +}; + +/** + * Structure associated with each Rx queue. + */ +struct ngbe_rx_queue { + struct rte_mempool *mb_pool; /**< mbuf pool to populate Rx ring. */ + volatile struct ngbe_rx_desc *rx_ring; /**< Rx ring virtual address. */ + uint64_t rx_ring_phys_addr; /**< Rx ring DMA address. */ + volatile uint32_t *rdt_reg_addr; /**< RDT register address. */ + volatile uint32_t *rdh_reg_addr; /**< RDH register address. */ + struct ngbe_rx_entry *sw_ring; /**< address of Rx software ring. */ + /**< address of scattered Rx software ring. */ + struct ngbe_scattered_rx_entry *sw_sc_ring; + struct rte_mbuf *pkt_first_seg; /**< First segment of current packet. */ + struct rte_mbuf *pkt_last_seg; /**< Last segment of current packet. */ + uint16_t nb_rx_desc; /**< number of Rx descriptors. */ + uint16_t rx_tail; /**< current value of RDT register. */ + uint16_t nb_rx_hold; /**< number of held free Rx desc. */ + uint16_t rx_nb_avail; /**< nr of staged pkts ready to ret to app */ + uint16_t rx_next_avail; /**< idx of next staged pkt to ret to app */ + uint16_t rx_free_trigger; /**< triggers rx buffer allocation */ + uint16_t rx_free_thresh; /**< max free Rx desc to hold. */ + uint16_t queue_id; /**< RX queue index. */ + uint16_t reg_idx; /**< RX queue register index. */ + /**< Packet type mask for different NICs. */ + uint16_t port_id; /**< Device port identifier. */ + uint8_t drop_en; /**< If not 0, set SRRCTL.Drop_En. */ + uint8_t rx_deferred_start; /**< not in global dev start. */ + /** need to alloc dummy mbuf, for wraparound when scanning hw ring */ + struct rte_mbuf fake_mbuf; + /** hold packets to return to application */ + struct rte_mbuf *rx_stage[RTE_PMD_NGBE_RX_MAX_BURST * 2]; +}; + +#endif /* _NGBE_RXTX_H_ */ From patchwork Thu Jun 17 10:59:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94338 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id CD021A0C4D; Thu, 17 Jun 2021 12:59:47 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 788AD41163; Thu, 17 Jun 2021 12:58:36 +0200 (CEST) Received: from smtpbgau1.qq.com (smtpbgau1.qq.com [54.206.16.166]) by mails.dpdk.org (Postfix) with ESMTP id B4C1F41120 for ; Thu, 17 Jun 2021 12:58:34 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927508ta0qakwu Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:28 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: pLTyZv4M7ZIJVBS7X/nIn+MpxBMKJv5z1lIrp3vKo9+Es3uN1v8/NOZDfX4+C elpsaXkm7bbiI1zHdxJqsrc4qFjHKHKxTCm3EtWQ/MDNdRqBTJJ90ao+bvzkTGaXiUuHI3n FwV7UkMkAmEvGl+0n9nv7u73XuUCVLMPeLYWVvCBiFUWD+IKmT+/NWFB/GSmCpXIieW/5oG II4uL4keqjSM1RfgEfbX/oe3h/A0PFhbdjfzY+aFiUHyAYWt0U2AZ4r/uZhxpennGJRf/pl RZJGQWpy0nNEo13j1UMeGElrjT50b/YnRw3Tp6QeL9vMHm/IHcwBqTPGbepdZQ4Bpu5ygUK pzej9zOci98NLoEDxmL6mITChKF4G7y0TWDxMN1 X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 18:59:59 +0800 Message-Id: <20210617110005.4132926-14-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign5 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 13/19] net/ngbe: add Tx queue setup and release X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Setup device Tx queue and release Tx queue. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/ngbe_ethdev.c | 24 ++++ drivers/net/ngbe/ngbe_ethdev.h | 11 ++ drivers/net/ngbe/ngbe_rxtx.c | 206 +++++++++++++++++++++++++++++++++ drivers/net/ngbe/ngbe_rxtx.h | 95 +++++++++++++++ 4 files changed, 336 insertions(+) diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index e73606c5f3..d6f93cfe46 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -44,6 +44,14 @@ static const struct rte_eth_desc_lim rx_desc_lim = { .nb_align = NGBE_RXD_ALIGN, }; +static const struct rte_eth_desc_lim tx_desc_lim = { + .nb_max = NGBE_RING_DESC_MAX, + .nb_min = NGBE_RING_DESC_MIN, + .nb_align = NGBE_TXD_ALIGN, + .nb_seg_max = NGBE_TX_MAX_SEG, + .nb_mtu_seg_max = NGBE_TX_MAX_SEG, +}; + static const struct eth_dev_ops ngbe_eth_dev_ops; static inline void @@ -283,6 +291,7 @@ ngbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) struct ngbe_hw *hw = ngbe_dev_hw(dev); dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues; + dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues; dev_info->default_rxconf = (struct rte_eth_rxconf) { .rx_thresh = { @@ -295,14 +304,27 @@ ngbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) .offloads = 0, }; + dev_info->default_txconf = (struct rte_eth_txconf) { + .tx_thresh = { + .pthresh = NGBE_DEFAULT_TX_PTHRESH, + .hthresh = NGBE_DEFAULT_TX_HTHRESH, + .wthresh = NGBE_DEFAULT_TX_WTHRESH, + }, + .tx_free_thresh = NGBE_DEFAULT_TX_FREE_THRESH, + .offloads = 0, + }; + dev_info->rx_desc_lim = rx_desc_lim; + dev_info->tx_desc_lim = tx_desc_lim; dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_100M | ETH_LINK_SPEED_10M; /* Driver-preferred Rx/Tx parameters */ dev_info->default_rxportconf.nb_queues = 1; + dev_info->default_txportconf.nb_queues = 1; dev_info->default_rxportconf.ring_size = 256; + dev_info->default_txportconf.ring_size = 256; return 0; } @@ -605,6 +627,8 @@ static const struct eth_dev_ops ngbe_eth_dev_ops = { .link_update = ngbe_dev_link_update, .rx_queue_setup = ngbe_dev_rx_queue_setup, .rx_queue_release = ngbe_dev_rx_queue_release, + .tx_queue_setup = ngbe_dev_tx_queue_setup, + .tx_queue_release = ngbe_dev_tx_queue_release, }; RTE_PMD_REGISTER_PCI(net_ngbe, rte_ngbe_pmd); diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h index 6580d288c8..131671c313 100644 --- a/drivers/net/ngbe/ngbe_ethdev.h +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -61,11 +61,17 @@ ngbe_dev_intr(struct rte_eth_dev *dev) void ngbe_dev_rx_queue_release(void *rxq); +void ngbe_dev_tx_queue_release(void *txq); + int ngbe_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id, uint16_t nb_rx_desc, unsigned int socket_id, const struct rte_eth_rxconf *rx_conf, struct rte_mempool *mb_pool); +int ngbe_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id, + uint16_t nb_tx_desc, unsigned int socket_id, + const struct rte_eth_txconf *tx_conf); + int ngbe_dev_link_update_share(struct rte_eth_dev *dev, int wait_to_complete); @@ -82,4 +88,9 @@ ngbe_dev_link_update_share(struct rte_eth_dev *dev, #define NGBE_DEFAULT_RX_HTHRESH 8 #define NGBE_DEFAULT_RX_WTHRESH 0 +#define NGBE_DEFAULT_TX_FREE_THRESH 32 +#define NGBE_DEFAULT_TX_PTHRESH 32 +#define NGBE_DEFAULT_TX_HTHRESH 0 +#define NGBE_DEFAULT_TX_WTHRESH 0 + #endif /* _NGBE_ETHDEV_H_ */ diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c index df0b64dc01..da9150b2f1 100644 --- a/drivers/net/ngbe/ngbe_rxtx.c +++ b/drivers/net/ngbe/ngbe_rxtx.c @@ -15,6 +15,212 @@ #include "ngbe_ethdev.h" #include "ngbe_rxtx.h" +/********************************************************************* + * + * Queue management functions + * + **********************************************************************/ + +static void __rte_cold +ngbe_tx_queue_release_mbufs(struct ngbe_tx_queue *txq) +{ + unsigned int i; + + if (txq->sw_ring != NULL) { + for (i = 0; i < txq->nb_tx_desc; i++) { + if (txq->sw_ring[i].mbuf != NULL) { + rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf); + txq->sw_ring[i].mbuf = NULL; + } + } + } +} + +static void __rte_cold +ngbe_tx_free_swring(struct ngbe_tx_queue *txq) +{ + if (txq != NULL) + rte_free(txq->sw_ring); +} + +static void __rte_cold +ngbe_tx_queue_release(struct ngbe_tx_queue *txq) +{ + if (txq != NULL) { + if (txq->ops != NULL) { + txq->ops->release_mbufs(txq); + txq->ops->free_swring(txq); + } + rte_free(txq); + } +} + +void __rte_cold +ngbe_dev_tx_queue_release(void *txq) +{ + ngbe_tx_queue_release(txq); +} + +/* (Re)set dynamic ngbe_tx_queue fields to defaults */ +static void __rte_cold +ngbe_reset_tx_queue(struct ngbe_tx_queue *txq) +{ + static const struct ngbe_tx_desc zeroed_desc = {0}; + struct ngbe_tx_entry *txe = txq->sw_ring; + uint16_t prev, i; + + /* Zero out HW ring memory */ + for (i = 0; i < txq->nb_tx_desc; i++) + txq->tx_ring[i] = zeroed_desc; + + /* Initialize SW ring entries */ + prev = (uint16_t)(txq->nb_tx_desc - 1); + for (i = 0; i < txq->nb_tx_desc; i++) { + /* the ring can also be modified by hardware */ + volatile struct ngbe_tx_desc *txd = &txq->tx_ring[i]; + + txd->dw3 = rte_cpu_to_le_32(NGBE_TXD_DD); + txe[i].mbuf = NULL; + txe[i].last_id = i; + txe[prev].next_id = i; + prev = i; + } + + txq->tx_next_dd = (uint16_t)(txq->tx_free_thresh - 1); + txq->tx_tail = 0; + + /* + * Always allow 1 descriptor to be un-allocated to avoid + * a H/W race condition + */ + txq->last_desc_cleaned = (uint16_t)(txq->nb_tx_desc - 1); + txq->nb_tx_free = (uint16_t)(txq->nb_tx_desc - 1); + txq->ctx_curr = 0; + memset((void *)&txq->ctx_cache, 0, + NGBE_CTX_NUM * sizeof(struct ngbe_ctx_info)); +} + +static const struct ngbe_txq_ops def_txq_ops = { + .release_mbufs = ngbe_tx_queue_release_mbufs, + .free_swring = ngbe_tx_free_swring, + .reset = ngbe_reset_tx_queue, +}; + +int __rte_cold +ngbe_dev_tx_queue_setup(struct rte_eth_dev *dev, + uint16_t queue_idx, + uint16_t nb_desc, + unsigned int socket_id, + const struct rte_eth_txconf *tx_conf) +{ + const struct rte_memzone *tz; + struct ngbe_tx_queue *txq; + struct ngbe_hw *hw; + uint16_t tx_free_thresh; + + PMD_INIT_FUNC_TRACE(); + hw = ngbe_dev_hw(dev); + + /* + * Validate number of transmit descriptors. + * It must not exceed hardware maximum, and must be multiple + * of NGBE_ALIGN. + */ + if (nb_desc % NGBE_TXD_ALIGN != 0 || + nb_desc > NGBE_RING_DESC_MAX || + nb_desc < NGBE_RING_DESC_MIN) { + return -EINVAL; + } + + /* + * The Tx descriptor ring will be cleaned after txq->tx_free_thresh + * descriptors are used or if the number of descriptors required + * to transmit a packet is greater than the number of free Tx + * descriptors. + * One descriptor in the Tx ring is used as a sentinel to avoid a + * H/W race condition, hence the maximum threshold constraints. + * When set to zero use default values. + */ + tx_free_thresh = (uint16_t)((tx_conf->tx_free_thresh) ? + tx_conf->tx_free_thresh : DEFAULT_TX_FREE_THRESH); + if (tx_free_thresh >= (nb_desc - 3)) { + PMD_INIT_LOG(ERR, "tx_free_thresh must be less than the number of " + "TX descriptors minus 3. (tx_free_thresh=%u " + "port=%d queue=%d)", + (unsigned int)tx_free_thresh, + (int)dev->data->port_id, (int)queue_idx); + return -(EINVAL); + } + + if (nb_desc % tx_free_thresh != 0) { + PMD_INIT_LOG(ERR, "tx_free_thresh must be a divisor of the " + "number of Tx descriptors. (tx_free_thresh=%u " + "port=%d queue=%d)", (unsigned int)tx_free_thresh, + (int)dev->data->port_id, (int)queue_idx); + return -(EINVAL); + } + + /* Free memory prior to re-allocation if needed... */ + if (dev->data->tx_queues[queue_idx] != NULL) { + ngbe_tx_queue_release(dev->data->tx_queues[queue_idx]); + dev->data->tx_queues[queue_idx] = NULL; + } + + /* First allocate the Tx queue data structure */ + txq = rte_zmalloc_socket("ethdev Tx queue", + sizeof(struct ngbe_tx_queue), + RTE_CACHE_LINE_SIZE, socket_id); + if (txq == NULL) + return -ENOMEM; + + /* + * Allocate Tx ring hardware descriptors. A memzone large enough to + * handle the maximum ring size is allocated in order to allow for + * resizing in later calls to the queue setup function. + */ + tz = rte_eth_dma_zone_reserve(dev, "tx_ring", queue_idx, + sizeof(struct ngbe_tx_desc) * NGBE_RING_DESC_MAX, + NGBE_ALIGN, socket_id); + if (tz == NULL) { + ngbe_tx_queue_release(txq); + return -ENOMEM; + } + + txq->nb_tx_desc = nb_desc; + txq->tx_free_thresh = tx_free_thresh; + txq->pthresh = tx_conf->tx_thresh.pthresh; + txq->hthresh = tx_conf->tx_thresh.hthresh; + txq->wthresh = tx_conf->tx_thresh.wthresh; + txq->queue_id = queue_idx; + txq->reg_idx = queue_idx; + txq->port_id = dev->data->port_id; + txq->ops = &def_txq_ops; + txq->tx_deferred_start = tx_conf->tx_deferred_start; + + txq->tdt_reg_addr = NGBE_REG_ADDR(hw, NGBE_TXWP(txq->reg_idx)); + txq->tdc_reg_addr = NGBE_REG_ADDR(hw, NGBE_TXCFG(txq->reg_idx)); + + txq->tx_ring_phys_addr = TMZ_PADDR(tz); + txq->tx_ring = (struct ngbe_tx_desc *)TMZ_VADDR(tz); + + /* Allocate software ring */ + txq->sw_ring = rte_zmalloc_socket("txq->sw_ring", + sizeof(struct ngbe_tx_entry) * nb_desc, + RTE_CACHE_LINE_SIZE, socket_id); + if (txq->sw_ring == NULL) { + ngbe_tx_queue_release(txq); + return -ENOMEM; + } + PMD_INIT_LOG(DEBUG, "sw_ring=%p hw_ring=%p dma_addr=0x%" PRIx64, + txq->sw_ring, txq->tx_ring, txq->tx_ring_phys_addr); + + txq->ops->reset(txq); + + dev->data->tx_queues[queue_idx] = txq; + + return 0; +} + /** * ngbe_free_sc_cluster - free the not-yet-completed scattered cluster * diff --git a/drivers/net/ngbe/ngbe_rxtx.h b/drivers/net/ngbe/ngbe_rxtx.h index 92b9a9fd1b..0f2c185dbf 100644 --- a/drivers/net/ngbe/ngbe_rxtx.h +++ b/drivers/net/ngbe/ngbe_rxtx.h @@ -43,11 +43,41 @@ struct ngbe_rx_desc { } qw1; /* also as r.hdr_addr */ }; +/***************************************************************************** + * Transmit Descriptor + *****************************************************************************/ +/** + * Transmit Context Descriptor (NGBE_TXD_TYP=CTXT) + **/ +struct ngbe_tx_ctx_desc { + rte_le32_t dw0; /* w.vlan_macip_lens */ + rte_le32_t dw1; /* w.seqnum_seed */ + rte_le32_t dw2; /* w.type_tucmd_mlhl */ + rte_le32_t dw3; /* w.mss_l4len_idx */ +}; + +/* @ngbe_tx_ctx_desc.dw3 */ +#define NGBE_TXD_DD MS(0, 0x1) /* descriptor done */ + +/** + * Transmit Data Descriptor (NGBE_TXD_TYP=DATA) + **/ +struct ngbe_tx_desc { + rte_le64_t qw0; /* r.buffer_addr , w.reserved */ + rte_le32_t dw2; /* r.cmd_type_len, w.nxtseq_seed */ + rte_le32_t dw3; /* r.olinfo_status, w.status */ +}; + #define RTE_PMD_NGBE_RX_MAX_BURST 32 #define RX_RING_SZ ((NGBE_RING_DESC_MAX + RTE_PMD_NGBE_RX_MAX_BURST) * \ sizeof(struct ngbe_rx_desc)) +#define NGBE_TX_MAX_SEG 40 + +#ifndef DEFAULT_TX_FREE_THRESH +#define DEFAULT_TX_FREE_THRESH 32 +#endif /** * Structure associated with each descriptor of the Rx ring of a Rx queue. @@ -60,6 +90,15 @@ struct ngbe_scattered_rx_entry { struct rte_mbuf *fbuf; /**< First segment of the fragmented packet. */ }; +/** + * Structure associated with each descriptor of the Tx ring of a Tx queue. + */ +struct ngbe_tx_entry { + struct rte_mbuf *mbuf; /**< mbuf associated with Tx desc, if any. */ + uint16_t next_id; /**< Index of next descriptor in ring. */ + uint16_t last_id; /**< Index of last scattered descriptor. */ +}; + /** * Structure associated with each Rx queue. */ @@ -93,4 +132,60 @@ struct ngbe_rx_queue { struct rte_mbuf *rx_stage[RTE_PMD_NGBE_RX_MAX_BURST * 2]; }; +/** + * NGBE CTX Constants + */ +enum ngbe_ctx_num { + NGBE_CTX_0 = 0, /**< CTX0 */ + NGBE_CTX_1 = 1, /**< CTX1 */ + NGBE_CTX_NUM = 2, /**< CTX NUMBER */ +}; + +/** + * Structure to check if new context need be built + */ +struct ngbe_ctx_info { + uint64_t flags; /**< ol_flags for context build. */ +}; + +/** + * Structure associated with each Tx queue. + */ +struct ngbe_tx_queue { + /** Tx ring virtual address. */ + volatile struct ngbe_tx_desc *tx_ring; + uint64_t tx_ring_phys_addr; /**< Tx ring DMA address. */ + struct ngbe_tx_entry *sw_ring; /**< address of SW ring for scalar PMD.*/ + volatile uint32_t *tdt_reg_addr; /**< Address of TDT register. */ + volatile uint32_t *tdc_reg_addr; /**< Address of TDC register. */ + uint16_t nb_tx_desc; /**< number of Tx descriptors. */ + uint16_t tx_tail; /**< current value of TDT reg. */ + /**< Start freeing Tx buffers if there are less free descriptors than + * this value. + */ + uint16_t tx_free_thresh; + /** Index to last Tx descriptor to have been cleaned. */ + uint16_t last_desc_cleaned; + /** Total number of Tx descriptors ready to be allocated. */ + uint16_t nb_tx_free; + uint16_t tx_next_dd; /**< next desc to scan for DD bit */ + uint16_t queue_id; /**< Tx queue index. */ + uint16_t reg_idx; /**< Tx queue register index. */ + uint16_t port_id; /**< Device port identifier. */ + uint8_t pthresh; /**< Prefetch threshold register. */ + uint8_t hthresh; /**< Host threshold register. */ + uint8_t wthresh; /**< Write-back threshold reg. */ + uint32_t ctx_curr; /**< Hardware context states. */ + /** Hardware context0 history. */ + struct ngbe_ctx_info ctx_cache[NGBE_CTX_NUM]; + const struct ngbe_txq_ops *ops; /**< txq ops */ + uint8_t tx_deferred_start; /**< not in global dev start. */ +}; + +struct ngbe_txq_ops { + void (*release_mbufs)(struct ngbe_tx_queue *txq); + void (*free_swring)(struct ngbe_tx_queue *txq); + void (*reset)(struct ngbe_tx_queue *txq); +}; + #endif /* _NGBE_RXTX_H_ */ From patchwork Thu Jun 17 11:00:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94340 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B902EA0C4D; Thu, 17 Jun 2021 12:59:58 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C4C9641168; Thu, 17 Jun 2021 12:58:38 +0200 (CEST) Received: from smtpbgau1.qq.com (smtpbgau1.qq.com [54.206.16.166]) by mails.dpdk.org (Postfix) with ESMTP id 1EB0D4115C for ; Thu, 17 Jun 2021 12:58:35 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927510tvv2a0ul Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:30 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: VvqLbp3JaDNJd4EkO4vlIycaRciYOm5hLoBGGuwilU3VJwI7x8DnNCMTLqc4a aaT4gpTKdaEWp7+ZKfaWgccKZrmaEDnqczSF9aYcWLWjxO5xa4jNAvG7LwUuLAfPfS8o0O9 nzYgxiD9lyQl3nvDGUVl7iDHam8NvpjZNbDagotGc8tbsp2O8tRWbYmTZiHtP/UYr+8XhcV MKPvpUtefAmf3/RwKZ9XALBZOekf7GtkIBMwhmLqPueoeD2aogV3bTeU0lw2+7+UMXZ0WaG E1PwOyb2oG7XFKPt5BQr2xwxCxbeRxTSVhcXHaf/QbNPRaZic/Keyvr2gdF4bPz+FY5IAZm mfV7qHexJfjuvVrNveFRJlZTGTMVidkYcImhK04 X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 19:00:00 +0800 Message-Id: <20210617110005.4132926-15-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign1 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 14/19] net/ngbe: add simple Rx flow X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Initialize device with the simplest receive function. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/ngbe_ethdev.c | 1 + drivers/net/ngbe/ngbe_ethdev.h | 3 + drivers/net/ngbe/ngbe_rxtx.c | 168 +++++++++++++++++++++++++++++++++ drivers/net/ngbe/ngbe_rxtx.h | 81 ++++++++++++++++ 4 files changed, 253 insertions(+) diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index d6f93cfe46..269186acc0 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -110,6 +110,7 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) PMD_INIT_FUNC_TRACE(); eth_dev->dev_ops = &ngbe_eth_dev_ops; + eth_dev->rx_pkt_burst = &ngbe_recv_pkts; if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h index 131671c313..8fb7c8a19b 100644 --- a/drivers/net/ngbe/ngbe_ethdev.h +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -72,6 +72,9 @@ int ngbe_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id, uint16_t nb_tx_desc, unsigned int socket_id, const struct rte_eth_txconf *tx_conf); +uint16_t ngbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, + uint16_t nb_pkts); + int ngbe_dev_link_update_share(struct rte_eth_dev *dev, int wait_to_complete); diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c index da9150b2f1..f97fceaf7c 100644 --- a/drivers/net/ngbe/ngbe_rxtx.c +++ b/drivers/net/ngbe/ngbe_rxtx.c @@ -15,6 +15,174 @@ #include "ngbe_ethdev.h" #include "ngbe_rxtx.h" +/* + * Prefetch a cache line into all cache levels. + */ +#define rte_ngbe_prefetch(p) rte_prefetch0(p) + +/********************************************************************* + * + * Rx functions + * + **********************************************************************/ +uint16_t +ngbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, + uint16_t nb_pkts) +{ + struct ngbe_rx_queue *rxq; + volatile struct ngbe_rx_desc *rx_ring; + volatile struct ngbe_rx_desc *rxdp; + struct ngbe_rx_entry *sw_ring; + struct ngbe_rx_entry *rxe; + struct rte_mbuf *rxm; + struct rte_mbuf *nmb; + struct ngbe_rx_desc rxd; + uint64_t dma_addr; + uint32_t staterr; + uint16_t pkt_len; + uint16_t rx_id; + uint16_t nb_rx; + uint16_t nb_hold; + + nb_rx = 0; + nb_hold = 0; + rxq = rx_queue; + rx_id = rxq->rx_tail; + rx_ring = rxq->rx_ring; + sw_ring = rxq->sw_ring; + struct rte_eth_dev *dev = &rte_eth_devices[rxq->port_id]; + while (nb_rx < nb_pkts) { + /* + * The order of operations here is important as the DD status + * bit must not be read after any other descriptor fields. + * rx_ring and rxdp are pointing to volatile data so the order + * of accesses cannot be reordered by the compiler. If they were + * not volatile, they could be reordered which could lead to + * using invalid descriptor fields when read from rxd. + */ + rxdp = &rx_ring[rx_id]; + staterr = rxdp->qw1.lo.status; + if (!(staterr & rte_cpu_to_le_32(NGBE_RXD_STAT_DD))) + break; + rxd = *rxdp; + + /* + * End of packet. + * + * If the NGBE_RXD_STAT_EOP flag is not set, the Rx packet + * is likely to be invalid and to be dropped by the various + * validation checks performed by the network stack. + * + * Allocate a new mbuf to replenish the RX ring descriptor. + * If the allocation fails: + * - arrange for that Rx descriptor to be the first one + * being parsed the next time the receive function is + * invoked [on the same queue]. + * + * - Stop parsing the Rx ring and return immediately. + * + * This policy do not drop the packet received in the Rx + * descriptor for which the allocation of a new mbuf failed. + * Thus, it allows that packet to be later retrieved if + * mbuf have been freed in the mean time. + * As a side effect, holding Rx descriptors instead of + * systematically giving them back to the NIC may lead to + * Rx ring exhaustion situations. + * However, the NIC can gracefully prevent such situations + * to happen by sending specific "back-pressure" flow control + * frames to its peer(s). + */ + PMD_RX_LOG(DEBUG, "port_id=%u queue_id=%u rx_id=%u " + "ext_err_stat=0x%08x pkt_len=%u", + (uint16_t)rxq->port_id, (uint16_t)rxq->queue_id, + (uint16_t)rx_id, (uint32_t)staterr, + (uint16_t)rte_le_to_cpu_16(rxd.qw1.hi.len)); + + nmb = rte_mbuf_raw_alloc(rxq->mb_pool); + if (nmb == NULL) { + PMD_RX_LOG(DEBUG, "Rx mbuf alloc failed port_id=%u " + "queue_id=%u", (uint16_t)rxq->port_id, + (uint16_t)rxq->queue_id); + dev->data->rx_mbuf_alloc_failed++; + break; + } + + nb_hold++; + rxe = &sw_ring[rx_id]; + rx_id++; + if (rx_id == rxq->nb_rx_desc) + rx_id = 0; + + /* Prefetch next mbuf while processing current one. */ + rte_ngbe_prefetch(sw_ring[rx_id].mbuf); + + /* + * When next Rx descriptor is on a cache-line boundary, + * prefetch the next 4 Rx descriptors and the next 8 pointers + * to mbufs. + */ + if ((rx_id & 0x3) == 0) { + rte_ngbe_prefetch(&rx_ring[rx_id]); + rte_ngbe_prefetch(&sw_ring[rx_id]); + } + + rxm = rxe->mbuf; + rxe->mbuf = nmb; + dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova_default(nmb)); + NGBE_RXD_HDRADDR(rxdp, 0); + NGBE_RXD_PKTADDR(rxdp, dma_addr); + + /* + * Initialize the returned mbuf. + * setup generic mbuf fields: + * - number of segments, + * - next segment, + * - packet length, + * - Rx port identifier. + */ + pkt_len = (uint16_t)(rte_le_to_cpu_16(rxd.qw1.hi.len)); + rxm->data_off = RTE_PKTMBUF_HEADROOM; + rte_packet_prefetch((char *)rxm->buf_addr + rxm->data_off); + rxm->nb_segs = 1; + rxm->next = NULL; + rxm->pkt_len = pkt_len; + rxm->data_len = pkt_len; + rxm->port = rxq->port_id; + + /* + * Store the mbuf address into the next entry of the array + * of returned packets. + */ + rx_pkts[nb_rx++] = rxm; + } + rxq->rx_tail = rx_id; + + /* + * If the number of free Rx descriptors is greater than the Rx free + * threshold of the queue, advance the Receive Descriptor Tail (RDT) + * register. + * Update the RDT with the value of the last processed Rx descriptor + * minus 1, to guarantee that the RDT register is never equal to the + * RDH register, which creates a "full" ring situation from the + * hardware point of view... + */ + nb_hold = (uint16_t)(nb_hold + rxq->nb_rx_hold); + if (nb_hold > rxq->rx_free_thresh) { + PMD_RX_LOG(DEBUG, "port_id=%u queue_id=%u rx_tail=%u " + "nb_hold=%u nb_rx=%u", + (uint16_t)rxq->port_id, (uint16_t)rxq->queue_id, + (uint16_t)rx_id, (uint16_t)nb_hold, + (uint16_t)nb_rx); + rx_id = (uint16_t)((rx_id == 0) ? + (rxq->nb_rx_desc - 1) : (rx_id - 1)); + ngbe_set32(rxq->rdt_reg_addr, rx_id); + nb_hold = 0; + } + rxq->nb_rx_hold = nb_hold; + return nb_rx; +} + + /********************************************************************* * * Queue management functions diff --git a/drivers/net/ngbe/ngbe_rxtx.h b/drivers/net/ngbe/ngbe_rxtx.h index 0f2c185dbf..1c8fd76f12 100644 --- a/drivers/net/ngbe/ngbe_rxtx.h +++ b/drivers/net/ngbe/ngbe_rxtx.h @@ -43,6 +43,85 @@ struct ngbe_rx_desc { } qw1; /* also as r.hdr_addr */ }; +/* @ngbe_rx_desc.qw0 */ +#define NGBE_RXD_PKTADDR(rxd, v) \ + (((volatile __le64 *)(rxd))[0] = cpu_to_le64(v)) + +/* @ngbe_rx_desc.qw1 */ +#define NGBE_RXD_HDRADDR(rxd, v) \ + (((volatile __le64 *)(rxd))[1] = cpu_to_le64(v)) + +/* @ngbe_rx_desc.dw0 */ +#define NGBE_RXD_RSSTYPE(dw) RS(dw, 0, 0xF) +#define NGBE_RSSTYPE_NONE 0 +#define NGBE_RSSTYPE_IPV4TCP 1 +#define NGBE_RSSTYPE_IPV4 2 +#define NGBE_RSSTYPE_IPV6TCP 3 +#define NGBE_RSSTYPE_IPV4SCTP 4 +#define NGBE_RSSTYPE_IPV6 5 +#define NGBE_RSSTYPE_IPV6SCTP 6 +#define NGBE_RSSTYPE_IPV4UDP 7 +#define NGBE_RSSTYPE_IPV6UDP 8 +#define NGBE_RSSTYPE_FDIR 15 +#define NGBE_RXD_SECTYPE(dw) RS(dw, 4, 0x3) +#define NGBE_RXD_SECTYPE_NONE LS(0, 4, 0x3) +#define NGBE_RXD_SECTYPE_IPSECESP LS(2, 4, 0x3) +#define NGBE_RXD_SECTYPE_IPSECAH LS(3, 4, 0x3) +#define NGBE_RXD_TPIDSEL(dw) RS(dw, 6, 0x7) +#define NGBE_RXD_PTID(dw) RS(dw, 9, 0xFF) +#define NGBE_RXD_RSCCNT(dw) RS(dw, 17, 0xF) +#define NGBE_RXD_HDRLEN(dw) RS(dw, 21, 0x3FF) +#define NGBE_RXD_SPH MS(31, 0x1) + +/* @ngbe_rx_desc.dw1 */ +/** bit 0-31, as rss hash when **/ +#define NGBE_RXD_RSSHASH(rxd) ((rxd)->qw0.dw1) + +/** bit 0-31, as ip csum when **/ +#define NGBE_RXD_IPID(rxd) ((rxd)->qw0.hi.ipid) +#define NGBE_RXD_CSUM(rxd) ((rxd)->qw0.hi.csum) + +/* @ngbe_rx_desc.dw2 */ +#define NGBE_RXD_STATUS(rxd) ((rxd)->qw1.lo.status) +/** bit 0-1 **/ +#define NGBE_RXD_STAT_DD MS(0, 0x1) /* Descriptor Done */ +#define NGBE_RXD_STAT_EOP MS(1, 0x1) /* End of Packet */ +/** bit 2-31, when EOP=0 **/ +#define NGBE_RXD_NEXTP_RESV(v) LS(v, 2, 0x3) +#define NGBE_RXD_NEXTP(dw) RS(dw, 4, 0xFFFF) /* Next Descriptor */ +/** bit 2-31, when EOP=1 **/ +#define NGBE_RXD_PKT_CLS_MASK MS(2, 0x7) /* Packet Class */ +#define NGBE_RXD_PKT_CLS_TC_RSS LS(0, 2, 0x7) /* RSS Hash */ +#define NGBE_RXD_PKT_CLS_FLM LS(1, 2, 0x7) /* FDir Match */ +#define NGBE_RXD_PKT_CLS_SYN LS(2, 2, 0x7) /* TCP Sync */ +#define NGBE_RXD_PKT_CLS_5TUPLE LS(3, 2, 0x7) /* 5 Tuple */ +#define NGBE_RXD_PKT_CLS_ETF LS(4, 2, 0x7) /* Ethertype Filter */ +#define NGBE_RXD_STAT_VLAN MS(5, 0x1) /* IEEE VLAN Packet */ +#define NGBE_RXD_STAT_UDPCS MS(6, 0x1) /* UDP xsum calculated */ +#define NGBE_RXD_STAT_L4CS MS(7, 0x1) /* L4 xsum calculated */ +#define NGBE_RXD_STAT_IPCS MS(8, 0x1) /* IP xsum calculated */ +#define NGBE_RXD_STAT_PIF MS(9, 0x1) /* Non-unicast address */ +#define NGBE_RXD_STAT_EIPCS MS(10, 0x1) /* Encap IP xsum calculated */ +#define NGBE_RXD_STAT_VEXT MS(11, 0x1) /* Multi-VLAN */ +#define NGBE_RXD_STAT_IPV6EX MS(12, 0x1) /* IPv6 with option header */ +#define NGBE_RXD_STAT_LLINT MS(13, 0x1) /* Pkt caused LLI */ +#define NGBE_RXD_STAT_1588 MS(14, 0x1) /* IEEE1588 Time Stamp */ +#define NGBE_RXD_STAT_SECP MS(15, 0x1) /* Security Processing */ +#define NGBE_RXD_STAT_LB MS(16, 0x1) /* Loopback Status */ +/*** bit 17-30, when PTYPE=IP ***/ +#define NGBE_RXD_STAT_BMC MS(17, 0x1) /* PTYPE=IP, BMC status */ +#define NGBE_RXD_ERR_HBO MS(23, 0x1) /* Header Buffer Overflow */ +#define NGBE_RXD_ERR_EIPCS MS(26, 0x1) /* Encap IP header error */ +#define NGBE_RXD_ERR_SECERR MS(27, 0x1) /* macsec or ipsec error */ +#define NGBE_RXD_ERR_RXE MS(29, 0x1) /* Any MAC Error */ +#define NGBE_RXD_ERR_L4CS MS(30, 0x1) /* TCP/UDP xsum error */ +#define NGBE_RXD_ERR_IPCS MS(31, 0x1) /* IP xsum error */ +#define NGBE_RXD_ERR_CSUM(dw) RS(dw, 30, 0x3) + +/* @ngbe_rx_desc.dw3 */ +#define NGBE_RXD_LENGTH(rxd) ((rxd)->qw1.hi.len) +#define NGBE_RXD_VLAN(rxd) ((rxd)->qw1.hi.tag) + /***************************************************************************** * Transmit Descriptor *****************************************************************************/ @@ -73,6 +152,8 @@ struct ngbe_tx_desc { #define RX_RING_SZ ((NGBE_RING_DESC_MAX + RTE_PMD_NGBE_RX_MAX_BURST) * \ sizeof(struct ngbe_rx_desc)) +#define rte_packet_prefetch(p) rte_prefetch1(p) + #define NGBE_TX_MAX_SEG 40 #ifndef DEFAULT_TX_FREE_THRESH From patchwork Thu Jun 17 11:00:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94339 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 5D774A0C4D; Thu, 17 Jun 2021 12:59:53 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A57AE41164; Thu, 17 Jun 2021 12:58:37 +0200 (CEST) Received: from smtpbgeu2.qq.com (smtpbgeu2.qq.com [18.194.254.142]) by mails.dpdk.org (Postfix) with ESMTP id EBFCD410F4 for ; Thu, 17 Jun 2021 12:58:35 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927512tw1v30re Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:32 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: d+oHhNLBBfvnDWbadDsqKF7DIqXzeFo5RqX43KSvEM2Fgq5D+QwaD4jacT/nN bVtj3Vlr5tnZEemzUUtRM7JKiOnxsGpJcN4nGEk5sF0zlpg2ZIuI5I/d4X8hc3n4XlQZ45s gx30i8gOXuicWaEkeIC5wC/Nk43d1JsQ+esz+AoFHY9Z6b/ojUVhkYlPuDfXkl5GnDvrKr8 +lcQenYp/6aG7eHaaPIQ+NHzRgv/D83uXfvaca2wIHmg1Fu5TND3EfcatpBJumFKFOTx0Bd CKtV+7io63/rnob+Wn6w20tgGN1Fvp+PyHiI8xDkeOc0/Ab8fRaE+KP6ewdSqpvlrwyk9BA Pk2Z1jK/zrsj1QRvjIFyCMgWMMyTg== X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 19:00:01 +0800 Message-Id: <20210617110005.4132926-16-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign5 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 15/19] net/ngbe: add simple Tx flow X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Initialize device with the simplest transmit functions. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/ngbe_ethdev.c | 1 + drivers/net/ngbe/ngbe_ethdev.h | 3 + drivers/net/ngbe/ngbe_rxtx.c | 228 +++++++++++++++++++++++++++++++++ drivers/net/ngbe/ngbe_rxtx.h | 27 ++++ 4 files changed, 259 insertions(+) diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index 269186acc0..6b4d5ac65b 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -111,6 +111,7 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) eth_dev->dev_ops = &ngbe_eth_dev_ops; eth_dev->rx_pkt_burst = &ngbe_recv_pkts; + eth_dev->tx_pkt_burst = &ngbe_xmit_pkts_simple; if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h index 8fb7c8a19b..c52cac2ca1 100644 --- a/drivers/net/ngbe/ngbe_ethdev.h +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -75,6 +75,9 @@ int ngbe_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id, uint16_t ngbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); +uint16_t ngbe_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts, + uint16_t nb_pkts); + int ngbe_dev_link_update_share(struct rte_eth_dev *dev, int wait_to_complete); diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c index f97fceaf7c..6dde996659 100644 --- a/drivers/net/ngbe/ngbe_rxtx.c +++ b/drivers/net/ngbe/ngbe_rxtx.c @@ -20,6 +20,234 @@ */ #define rte_ngbe_prefetch(p) rte_prefetch0(p) +/********************************************************************* + * + * Tx functions + * + **********************************************************************/ + +/* + * Check for descriptors with their DD bit set and free mbufs. + * Return the total number of buffers freed. + */ +static __rte_always_inline int +ngbe_tx_free_bufs(struct ngbe_tx_queue *txq) +{ + struct ngbe_tx_entry *txep; + uint32_t status; + int i, nb_free = 0; + struct rte_mbuf *m, *free[RTE_NGBE_TX_MAX_FREE_BUF_SZ]; + + /* check DD bit on threshold descriptor */ + status = txq->tx_ring[txq->tx_next_dd].dw3; + if (!(status & rte_cpu_to_le_32(NGBE_TXD_DD))) { + if (txq->nb_tx_free >> 1 < txq->tx_free_thresh) + ngbe_set32_masked(txq->tdc_reg_addr, + NGBE_TXCFG_FLUSH, NGBE_TXCFG_FLUSH); + return 0; + } + + /* + * first buffer to free from S/W ring is at index + * tx_next_dd - (tx_free_thresh-1) + */ + txep = &txq->sw_ring[txq->tx_next_dd - (txq->tx_free_thresh - 1)]; + for (i = 0; i < txq->tx_free_thresh; ++i, ++txep) { + /* free buffers one at a time */ + m = rte_pktmbuf_prefree_seg(txep->mbuf); + txep->mbuf = NULL; + + if (unlikely(m == NULL)) + continue; + + if (nb_free >= RTE_NGBE_TX_MAX_FREE_BUF_SZ || + (nb_free > 0 && m->pool != free[0]->pool)) { + rte_mempool_put_bulk(free[0]->pool, + (void **)free, nb_free); + nb_free = 0; + } + + free[nb_free++] = m; + } + + if (nb_free > 0) + rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free); + + /* buffers were freed, update counters */ + txq->nb_tx_free = (uint16_t)(txq->nb_tx_free + txq->tx_free_thresh); + txq->tx_next_dd = (uint16_t)(txq->tx_next_dd + txq->tx_free_thresh); + if (txq->tx_next_dd >= txq->nb_tx_desc) + txq->tx_next_dd = (uint16_t)(txq->tx_free_thresh - 1); + + return txq->tx_free_thresh; +} + +/* Populate 4 descriptors with data from 4 mbufs */ +static inline void +tx4(volatile struct ngbe_tx_desc *txdp, struct rte_mbuf **pkts) +{ + uint64_t buf_dma_addr; + uint32_t pkt_len; + int i; + + for (i = 0; i < 4; ++i, ++txdp, ++pkts) { + buf_dma_addr = rte_mbuf_data_iova(*pkts); + pkt_len = (*pkts)->data_len; + + /* write data to descriptor */ + txdp->qw0 = rte_cpu_to_le_64(buf_dma_addr); + txdp->dw2 = cpu_to_le32(NGBE_TXD_FLAGS | + NGBE_TXD_DATLEN(pkt_len)); + txdp->dw3 = cpu_to_le32(NGBE_TXD_PAYLEN(pkt_len)); + + rte_prefetch0(&(*pkts)->pool); + } +} + +/* Populate 1 descriptor with data from 1 mbuf */ +static inline void +tx1(volatile struct ngbe_tx_desc *txdp, struct rte_mbuf **pkts) +{ + uint64_t buf_dma_addr; + uint32_t pkt_len; + + buf_dma_addr = rte_mbuf_data_iova(*pkts); + pkt_len = (*pkts)->data_len; + + /* write data to descriptor */ + txdp->qw0 = cpu_to_le64(buf_dma_addr); + txdp->dw2 = cpu_to_le32(NGBE_TXD_FLAGS | + NGBE_TXD_DATLEN(pkt_len)); + txdp->dw3 = cpu_to_le32(NGBE_TXD_PAYLEN(pkt_len)); + + rte_prefetch0(&(*pkts)->pool); +} + +/* + * Fill H/W descriptor ring with mbuf data. + * Copy mbuf pointers to the S/W ring. + */ +static inline void +ngbe_tx_fill_hw_ring(struct ngbe_tx_queue *txq, struct rte_mbuf **pkts, + uint16_t nb_pkts) +{ + volatile struct ngbe_tx_desc *txdp = &txq->tx_ring[txq->tx_tail]; + struct ngbe_tx_entry *txep = &txq->sw_ring[txq->tx_tail]; + const int N_PER_LOOP = 4; + const int N_PER_LOOP_MASK = N_PER_LOOP - 1; + int mainpart, leftover; + int i, j; + + /* + * Process most of the packets in chunks of N pkts. Any + * leftover packets will get processed one at a time. + */ + mainpart = (nb_pkts & ((uint32_t)~N_PER_LOOP_MASK)); + leftover = (nb_pkts & ((uint32_t)N_PER_LOOP_MASK)); + for (i = 0; i < mainpart; i += N_PER_LOOP) { + /* Copy N mbuf pointers to the S/W ring */ + for (j = 0; j < N_PER_LOOP; ++j) + (txep + i + j)->mbuf = *(pkts + i + j); + tx4(txdp + i, pkts + i); + } + + if (unlikely(leftover > 0)) { + for (i = 0; i < leftover; ++i) { + (txep + mainpart + i)->mbuf = *(pkts + mainpart + i); + tx1(txdp + mainpart + i, pkts + mainpart + i); + } + } +} + +static inline uint16_t +tx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, + uint16_t nb_pkts) +{ + struct ngbe_tx_queue *txq = (struct ngbe_tx_queue *)tx_queue; + uint16_t n = 0; + + /* + * Begin scanning the H/W ring for done descriptors when the + * number of available descriptors drops below tx_free_thresh. + * For each done descriptor, free the associated buffer. + */ + if (txq->nb_tx_free < txq->tx_free_thresh) + ngbe_tx_free_bufs(txq); + + /* Only use descriptors that are available */ + nb_pkts = (uint16_t)RTE_MIN(txq->nb_tx_free, nb_pkts); + if (unlikely(nb_pkts == 0)) + return 0; + + /* Use exactly nb_pkts descriptors */ + txq->nb_tx_free = (uint16_t)(txq->nb_tx_free - nb_pkts); + + /* + * At this point, we know there are enough descriptors in the + * ring to transmit all the packets. This assumes that each + * mbuf contains a single segment, and that no new offloads + * are expected, which would require a new context descriptor. + */ + + /* + * See if we're going to wrap-around. If so, handle the top + * of the descriptor ring first, then do the bottom. If not, + * the processing looks just like the "bottom" part anyway... + */ + if ((txq->tx_tail + nb_pkts) > txq->nb_tx_desc) { + n = (uint16_t)(txq->nb_tx_desc - txq->tx_tail); + ngbe_tx_fill_hw_ring(txq, tx_pkts, n); + txq->tx_tail = 0; + } + + /* Fill H/W descriptor ring with mbuf data */ + ngbe_tx_fill_hw_ring(txq, tx_pkts + n, (uint16_t)(nb_pkts - n)); + txq->tx_tail = (uint16_t)(txq->tx_tail + (nb_pkts - n)); + + /* + * Check for wrap-around. This would only happen if we used + * up to the last descriptor in the ring, no more, no less. + */ + if (txq->tx_tail >= txq->nb_tx_desc) + txq->tx_tail = 0; + + PMD_TX_LOG(DEBUG, "port_id=%u queue_id=%u tx_tail=%u nb_tx=%u", + (uint16_t)txq->port_id, (uint16_t)txq->queue_id, + (uint16_t)txq->tx_tail, (uint16_t)nb_pkts); + + /* update tail pointer */ + rte_wmb(); + ngbe_set32_relaxed(txq->tdt_reg_addr, txq->tx_tail); + + return nb_pkts; +} + +uint16_t +ngbe_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts, + uint16_t nb_pkts) +{ + uint16_t nb_tx; + + /* Try to transmit at least chunks of TX_MAX_BURST pkts */ + if (likely(nb_pkts <= RTE_PMD_NGBE_TX_MAX_BURST)) + return tx_xmit_pkts(tx_queue, tx_pkts, nb_pkts); + + /* transmit more than the max burst, in chunks of TX_MAX_BURST */ + nb_tx = 0; + while (nb_pkts) { + uint16_t ret, n; + + n = (uint16_t)RTE_MIN(nb_pkts, RTE_PMD_NGBE_TX_MAX_BURST); + ret = tx_xmit_pkts(tx_queue, &tx_pkts[nb_tx], n); + nb_tx = (uint16_t)(nb_tx + ret); + nb_pkts = (uint16_t)(nb_pkts - ret); + if (ret < n) + break; + } + + return nb_tx; +} + /********************************************************************* * * Rx functions diff --git a/drivers/net/ngbe/ngbe_rxtx.h b/drivers/net/ngbe/ngbe_rxtx.h index 1c8fd76f12..616b41a300 100644 --- a/drivers/net/ngbe/ngbe_rxtx.h +++ b/drivers/net/ngbe/ngbe_rxtx.h @@ -147,7 +147,34 @@ struct ngbe_tx_desc { rte_le32_t dw3; /* r.olinfo_status, w.status */ }; +/* @ngbe_tx_desc.dw2 */ +#define NGBE_TXD_DATLEN(v) ((0xFFFF & (v))) /* data buffer length */ +#define NGBE_TXD_1588 ((0x1) << 19) /* IEEE1588 time stamp */ +#define NGBE_TXD_DATA ((0x0) << 20) /* data descriptor */ +#define NGBE_TXD_EOP ((0x1) << 24) /* End of Packet */ +#define NGBE_TXD_FCS ((0x1) << 25) /* Insert FCS */ +#define NGBE_TXD_LINKSEC ((0x1) << 26) /* Insert LinkSec */ +#define NGBE_TXD_ECU ((0x1) << 28) /* forward to ECU */ +#define NGBE_TXD_CNTAG ((0x1) << 29) /* insert CN tag */ +#define NGBE_TXD_VLE ((0x1) << 30) /* insert VLAN tag */ +#define NGBE_TXD_TSE ((0x1) << 31) /* transmit segmentation */ + +#define NGBE_TXD_FLAGS (NGBE_TXD_FCS | NGBE_TXD_EOP) + +/* @ngbe_tx_desc.dw3 */ +#define NGBE_TXD_DD_UNUSED NGBE_TXD_DD +#define NGBE_TXD_IDX_UNUSED(v) NGBE_TXD_IDX(v) +#define NGBE_TXD_CC ((0x1) << 7) /* check context */ +#define NGBE_TXD_IPSEC ((0x1) << 8) /* request ipsec offload */ +#define NGBE_TXD_L4CS ((0x1) << 9) /* insert TCP/UDP/SCTP csum */ +#define NGBE_TXD_IPCS ((0x1) << 10) /* insert IPv4 csum */ +#define NGBE_TXD_EIPCS ((0x1) << 11) /* insert outer IP csum */ +#define NGBE_TXD_MNGFLT ((0x1) << 12) /* enable management filter */ +#define NGBE_TXD_PAYLEN(v) ((0x7FFFF & (v)) << 13) /* payload length */ + +#define RTE_PMD_NGBE_TX_MAX_BURST 32 #define RTE_PMD_NGBE_RX_MAX_BURST 32 +#define RTE_NGBE_TX_MAX_FREE_BUF_SZ 64 #define RX_RING_SZ ((NGBE_RING_DESC_MAX + RTE_PMD_NGBE_RX_MAX_BURST) * \ sizeof(struct ngbe_rx_desc)) From patchwork Thu Jun 17 11:00:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94342 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C6DCFA0C4D; Thu, 17 Jun 2021 13:00:12 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 962FF4113E; Thu, 17 Jun 2021 12:58:43 +0200 (CEST) Received: from smtpbgau2.qq.com (smtpbgau2.qq.com [54.206.34.216]) by mails.dpdk.org (Postfix) with ESMTP id 9971F4115F for ; Thu, 17 Jun 2021 12:58:39 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927514tk8frv4h Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:34 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: 6/UcbRTcplQToHjNnGtbv94wPM9hSCbkN8IQryJ93CRLBBrlMC11QbTAlBuh/ fb/u+Jwx6aHWlUvV29gSX0yZ/9WtOM/RWmTlgSxL5U9m21nyEfF1Zl0e5eKE6/O+fqWvCAa 7kuvfV/W/FcYiNccjOkVcUnmTYBHkkcK1+qlw3i3VidBF/n+L12AJCeGNd9w8ZQcI/wWrt4 4Ses3TvbwRc+I53g27lExyVTLFeiMIA9B1FN4K6t715+pKqH2oZPgnmFjejvvMf3P2mLN9D prPnbQy2FdnMAePkPvJRiwDp/LRau/rHtMWoRUfFtYr8CzU7QdXNYJDKkwnac4CKvvIbatP n6TRdpGGDhvUZ42fXad14YlGhdnLw== X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 19:00:02 +0800 Message-Id: <20210617110005.4132926-17-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign7 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 16/19] net/ngbe: add device start and stop operations X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Setup MSI-X interrupt, complete PHY configuration and set device link speed to start device. Disable interrupt, stop hardware and clear queues to stop device. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/base/ngbe_dummy.h | 16 + drivers/net/ngbe/base/ngbe_hw.c | 49 +++ drivers/net/ngbe/base/ngbe_hw.h | 4 + drivers/net/ngbe/base/ngbe_phy.c | 3 + drivers/net/ngbe/base/ngbe_phy_mvl.c | 64 ++++ drivers/net/ngbe/base/ngbe_phy_mvl.h | 1 + drivers/net/ngbe/base/ngbe_phy_rtl.c | 58 ++++ drivers/net/ngbe/base/ngbe_phy_rtl.h | 2 + drivers/net/ngbe/base/ngbe_phy_yt.c | 26 ++ drivers/net/ngbe/base/ngbe_phy_yt.h | 1 + drivers/net/ngbe/base/ngbe_type.h | 9 + drivers/net/ngbe/ngbe_ethdev.c | 473 ++++++++++++++++++++++++++- drivers/net/ngbe/ngbe_ethdev.h | 17 + drivers/net/ngbe/ngbe_rxtx.c | 59 ++++ 14 files changed, 781 insertions(+), 1 deletion(-) diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h index 709e01659c..dfc7b13192 100644 --- a/drivers/net/ngbe/base/ngbe_dummy.h +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -47,6 +47,10 @@ static inline s32 ngbe_mac_reset_hw_dummy(struct ngbe_hw *TUP0) { return NGBE_ERR_OPS_DUMMY; } +static inline s32 ngbe_mac_start_hw_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline s32 ngbe_mac_stop_hw_dummy(struct ngbe_hw *TUP0) { return NGBE_ERR_OPS_DUMMY; @@ -74,6 +78,11 @@ static inline s32 ngbe_mac_check_link_dummy(struct ngbe_hw *TUP0, u32 *TUP1, { return NGBE_ERR_OPS_DUMMY; } +static inline s32 ngbe_mac_get_link_capabilities_dummy(struct ngbe_hw *TUP0, + u32 *TUP1, bool *TUP2) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline s32 ngbe_mac_set_rar_dummy(struct ngbe_hw *TUP0, u32 TUP1, u8 *TUP2, u32 TUP3, u32 TUP4) { @@ -110,6 +119,10 @@ static inline s32 ngbe_phy_identify_dummy(struct ngbe_hw *TUP0) { return NGBE_ERR_OPS_DUMMY; } +static inline s32 ngbe_phy_init_hw_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline s32 ngbe_phy_reset_hw_dummy(struct ngbe_hw *TUP0) { return NGBE_ERR_OPS_DUMMY; @@ -151,12 +164,14 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) hw->rom.validate_checksum = ngbe_rom_validate_checksum_dummy; hw->mac.init_hw = ngbe_mac_init_hw_dummy; hw->mac.reset_hw = ngbe_mac_reset_hw_dummy; + hw->mac.start_hw = ngbe_mac_start_hw_dummy; hw->mac.stop_hw = ngbe_mac_stop_hw_dummy; hw->mac.get_mac_addr = ngbe_mac_get_mac_addr_dummy; hw->mac.acquire_swfw_sync = ngbe_mac_acquire_swfw_sync_dummy; hw->mac.release_swfw_sync = ngbe_mac_release_swfw_sync_dummy; hw->mac.setup_link = ngbe_mac_setup_link_dummy; hw->mac.check_link = ngbe_mac_check_link_dummy; + hw->mac.get_link_capabilities = ngbe_mac_get_link_capabilities_dummy; hw->mac.set_rar = ngbe_mac_set_rar_dummy; hw->mac.clear_rar = ngbe_mac_clear_rar_dummy; hw->mac.set_vmdq = ngbe_mac_set_vmdq_dummy; @@ -165,6 +180,7 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) hw->mac.init_thermal_sensor_thresh = ngbe_mac_init_thermal_ssth_dummy; hw->mac.check_overtemp = ngbe_mac_check_overtemp_dummy; hw->phy.identify = ngbe_phy_identify_dummy; + hw->phy.init_hw = ngbe_phy_init_hw_dummy; hw->phy.reset_hw = ngbe_phy_reset_hw_dummy; hw->phy.read_reg = ngbe_phy_read_reg_dummy; hw->phy.write_reg = ngbe_phy_write_reg_dummy; diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index 331fc752ff..22ce4e52b9 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -9,6 +9,22 @@ #include "ngbe_mng.h" #include "ngbe_hw.h" +/** + * ngbe_start_hw - Prepare hardware for Tx/Rx + * @hw: pointer to hardware structure + * + * Starts the hardware. + **/ +s32 ngbe_start_hw(struct ngbe_hw *hw) +{ + DEBUGFUNC("ngbe_start_hw"); + + /* Clear adapter stopped flag */ + hw->adapter_stopped = false; + + return 0; +} + /** * ngbe_init_hw - Generic hardware initialization * @hw: pointer to hardware structure @@ -27,6 +43,10 @@ s32 ngbe_init_hw(struct ngbe_hw *hw) /* Reset the hardware */ status = hw->mac.reset_hw(hw); + if (status == 0) { + /* Start the HW */ + status = hw->mac.start_hw(hw); + } if (status != 0) DEBUGOUT("Failed to initialize HW, STATUS = %d\n", status); @@ -633,6 +653,29 @@ s32 ngbe_check_mac_link_em(struct ngbe_hw *hw, u32 *speed, return status; } +s32 ngbe_get_link_capabilities_em(struct ngbe_hw *hw, + u32 *speed, + bool *autoneg) +{ + s32 status = 0; + + DEBUGFUNC("\n"); + + hw->mac.autoneg = *autoneg; + + switch (hw->sub_device_id) { + case NGBE_SUB_DEV_ID_EM_RTL_SGMII: + *speed = NGBE_LINK_SPEED_1GB_FULL | + NGBE_LINK_SPEED_100M_FULL | + NGBE_LINK_SPEED_10M_FULL; + break; + default: + break; + } + + return status; +} + s32 ngbe_setup_mac_link_em(struct ngbe_hw *hw, u32 speed, bool autoneg_wait_to_complete) @@ -842,6 +885,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) /* MAC */ mac->init_hw = ngbe_init_hw; mac->reset_hw = ngbe_reset_hw_em; + mac->start_hw = ngbe_start_hw; mac->get_mac_addr = ngbe_get_mac_addr; mac->stop_hw = ngbe_stop_hw; mac->acquire_swfw_sync = ngbe_acquire_swfw_sync; @@ -855,6 +899,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) mac->clear_vmdq = ngbe_clear_vmdq; /* Link */ + mac->get_link_capabilities = ngbe_get_link_capabilities_em; mac->check_link = ngbe_check_mac_link_em; mac->setup_link = ngbe_setup_mac_link_em; @@ -871,6 +916,10 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) mac->max_rx_queues = NGBE_EM_MAX_RX_QUEUES; mac->max_tx_queues = NGBE_EM_MAX_TX_QUEUES; + mac->default_speeds = NGBE_LINK_SPEED_10M_FULL | + NGBE_LINK_SPEED_100M_FULL | + NGBE_LINK_SPEED_1GB_FULL; + return 0; } diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h index 1689223168..4fee5735ac 100644 --- a/drivers/net/ngbe/base/ngbe_hw.h +++ b/drivers/net/ngbe/base/ngbe_hw.h @@ -14,6 +14,7 @@ #define NGBE_EM_MC_TBL_SIZE 32 s32 ngbe_init_hw(struct ngbe_hw *hw); +s32 ngbe_start_hw(struct ngbe_hw *hw); s32 ngbe_reset_hw_em(struct ngbe_hw *hw); s32 ngbe_stop_hw(struct ngbe_hw *hw); s32 ngbe_get_mac_addr(struct ngbe_hw *hw, u8 *mac_addr); @@ -22,6 +23,9 @@ void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw); s32 ngbe_check_mac_link_em(struct ngbe_hw *hw, u32 *speed, bool *link_up, bool link_up_wait_to_complete); +s32 ngbe_get_link_capabilities_em(struct ngbe_hw *hw, + u32 *speed, + bool *autoneg); s32 ngbe_setup_mac_link_em(struct ngbe_hw *hw, u32 speed, bool autoneg_wait_to_complete); diff --git a/drivers/net/ngbe/base/ngbe_phy.c b/drivers/net/ngbe/base/ngbe_phy.c index 471656cc51..0041cc9a90 100644 --- a/drivers/net/ngbe/base/ngbe_phy.c +++ b/drivers/net/ngbe/base/ngbe_phy.c @@ -426,16 +426,19 @@ s32 ngbe_init_phy(struct ngbe_hw *hw) /* Set necessary function pointers based on PHY type */ switch (hw->phy.type) { case ngbe_phy_rtl: + hw->phy.init_hw = ngbe_init_phy_rtl; hw->phy.check_link = ngbe_check_phy_link_rtl; hw->phy.setup_link = ngbe_setup_phy_link_rtl; break; case ngbe_phy_mvl: case ngbe_phy_mvl_sfi: + hw->phy.init_hw = ngbe_init_phy_mvl; hw->phy.check_link = ngbe_check_phy_link_mvl; hw->phy.setup_link = ngbe_setup_phy_link_mvl; break; case ngbe_phy_yt8521s: case ngbe_phy_yt8521s_sfi: + hw->phy.init_hw = ngbe_init_phy_yt; hw->phy.check_link = ngbe_check_phy_link_yt; hw->phy.setup_link = ngbe_setup_phy_link_yt; default: diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.c b/drivers/net/ngbe/base/ngbe_phy_mvl.c index a1c055e238..33d21edfce 100644 --- a/drivers/net/ngbe/base/ngbe_phy_mvl.c +++ b/drivers/net/ngbe/base/ngbe_phy_mvl.c @@ -48,6 +48,70 @@ s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw, return 0; } +s32 ngbe_init_phy_mvl(struct ngbe_hw *hw) +{ + s32 ret_val = 0; + u16 value = 0; + int i; + + DEBUGFUNC("ngbe_init_phy_mvl"); + + /* enable interrupts, only link status change and an done is allowed */ + ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 2); + ngbe_read_phy_reg_mdi(hw, MVL_RGM_CTL2, 0, &value); + value &= ~MVL_RGM_CTL2_TTC; + value |= MVL_RGM_CTL2_RTC; + ngbe_write_phy_reg_mdi(hw, MVL_RGM_CTL2, 0, value); + + hw->phy.write_reg(hw, MVL_CTRL, 0, MVL_CTRL_RESET); + for (i = 0; i < 15; i++) { + ngbe_read_phy_reg_mdi(hw, MVL_CTRL, 0, &value); + if (value & MVL_CTRL_RESET) + msleep(1); + else + break; + } + + if (i == 15) { + DEBUGOUT("phy reset exceeds maximum waiting period.\n"); + return NGBE_ERR_TIMEOUT; + } + + ret_val = hw->phy.reset_hw(hw); + if (ret_val) + return ret_val; + + /* set LED2 to interrupt output and INTn active low */ + ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 3); + ngbe_read_phy_reg_mdi(hw, MVL_LEDTCR, 0, &value); + value |= MVL_LEDTCR_INTR_EN; + value &= ~(MVL_LEDTCR_INTR_POL); + ngbe_write_phy_reg_mdi(hw, MVL_LEDTCR, 0, value); + + if (hw->phy.type == ngbe_phy_mvl_sfi) { + hw->phy.read_reg(hw, MVL_CTRL1, 0, &value); + value &= ~MVL_CTRL1_INTR_POL; + ngbe_write_phy_reg_mdi(hw, MVL_CTRL1, 0, value); + } + + /* enable link status change and AN complete interrupts */ + value = MVL_INTR_EN_ANC | MVL_INTR_EN_LSC; + hw->phy.write_reg(hw, MVL_INTR_EN, 0, value); + + /* LED control */ + ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 3); + ngbe_read_phy_reg_mdi(hw, MVL_LEDFCR, 0, &value); + value &= ~(MVL_LEDFCR_CTL0 | MVL_LEDFCR_CTL1); + value |= MVL_LEDFCR_CTL0_CONF | MVL_LEDFCR_CTL1_CONF; + ngbe_write_phy_reg_mdi(hw, MVL_LEDFCR, 0, value); + ngbe_read_phy_reg_mdi(hw, MVL_LEDPCR, 0, &value); + value &= ~(MVL_LEDPCR_CTL0 | MVL_LEDPCR_CTL1); + value |= MVL_LEDPCR_CTL0_CONF | MVL_LEDPCR_CTL1_CONF; + ngbe_write_phy_reg_mdi(hw, MVL_LEDPCR, 0, value); + + return ret_val; +} + s32 ngbe_setup_phy_link_mvl(struct ngbe_hw *hw, u32 speed, bool autoneg_wait_to_complete) { diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.h b/drivers/net/ngbe/base/ngbe_phy_mvl.h index a663a429dd..34cb1e838a 100644 --- a/drivers/net/ngbe/base/ngbe_phy_mvl.h +++ b/drivers/net/ngbe/base/ngbe_phy_mvl.h @@ -86,6 +86,7 @@ s32 ngbe_read_phy_reg_mvl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, u16 *phy_data); s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, u16 phy_data); +s32 ngbe_init_phy_mvl(struct ngbe_hw *hw); s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw); diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.c b/drivers/net/ngbe/base/ngbe_phy_rtl.c index 3401fc7e92..1cd576010e 100644 --- a/drivers/net/ngbe/base/ngbe_phy_rtl.c +++ b/drivers/net/ngbe/base/ngbe_phy_rtl.c @@ -38,6 +38,64 @@ s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw, return 0; } +s32 ngbe_init_phy_rtl(struct ngbe_hw *hw) +{ + int i; + u16 value = 0; + + /* enable interrupts, only link status change and an done is allowed */ + value = RTL_INER_LSC | RTL_INER_ANC; + hw->phy.write_reg(hw, RTL_INER, 0xa42, value); + + hw->phy.read_reg(hw, RTL_INSR, 0xa43, &value); + + for (i = 0; i < 15; i++) { + if (!rd32m(hw, NGBE_STAT, + NGBE_STAT_GPHY_IN_RST(hw->bus.lan_id))) + break; + + msec_delay(10); + } + if (i == 15) { + DEBUGOUT("GPhy reset exceeds maximum times.\n"); + return NGBE_ERR_PHY_TIMEOUT; + } + + for (i = 0; i < 1000; i++) { + hw->phy.read_reg(hw, RTL_INSR, 0xa43, &value); + if (value & RTL_INSR_ACCESS) + break; + } + + hw->phy.write_reg(hw, RTL_SCR, 0xa46, RTL_SCR_EFUSE); + for (i = 0; i < 1000; i++) { + hw->phy.read_reg(hw, RTL_INSR, 0xa43, &value); + if (value & RTL_INSR_ACCESS) + break; + } + if (i == 1000) + return NGBE_ERR_PHY_TIMEOUT; + + hw->phy.write_reg(hw, RTL_SCR, 0xa46, RTL_SCR_EXTINI); + for (i = 0; i < 1000; i++) { + hw->phy.read_reg(hw, RTL_INSR, 0xa43, &value); + if (value & RTL_INSR_ACCESS) + break; + } + if (i == 1000) + return NGBE_ERR_PHY_TIMEOUT; + + for (i = 0; i < 1000; i++) { + hw->phy.read_reg(hw, RTL_GSR, 0xa42, &value); + if ((value & RTL_GSR_ST) == RTL_GSR_ST_LANON) + break; + } + if (i == 1000) + return NGBE_ERR_PHY_TIMEOUT; + + return 0; +} + /** * ngbe_setup_phy_link_rtl - Set and restart auto-neg * @hw: pointer to hardware structure diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.h b/drivers/net/ngbe/base/ngbe_phy_rtl.h index e8bc4a1bd7..e6e7df5254 100644 --- a/drivers/net/ngbe/base/ngbe_phy_rtl.h +++ b/drivers/net/ngbe/base/ngbe_phy_rtl.h @@ -80,6 +80,8 @@ s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, s32 ngbe_setup_phy_link_rtl(struct ngbe_hw *hw, u32 speed, bool autoneg_wait_to_complete); + +s32 ngbe_init_phy_rtl(struct ngbe_hw *hw); s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw); s32 ngbe_check_phy_link_rtl(struct ngbe_hw *hw, u32 *speed, bool *link_up); diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.c b/drivers/net/ngbe/base/ngbe_phy_yt.c index f518dc0af6..94d3430fa4 100644 --- a/drivers/net/ngbe/base/ngbe_phy_yt.c +++ b/drivers/net/ngbe/base/ngbe_phy_yt.c @@ -98,6 +98,32 @@ s32 ngbe_write_phy_reg_sds_ext_yt(struct ngbe_hw *hw, return 0; } +s32 ngbe_init_phy_yt(struct ngbe_hw *hw) +{ + u16 value = 0; + + DEBUGFUNC("ngbe_init_phy_yt"); + + if (hw->phy.type != ngbe_phy_yt8521s_sfi) + return 0; + + /* select sds area register */ + ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0); + /* enable interrupts */ + ngbe_write_phy_reg_mdi(hw, YT_INTR, 0, YT_INTR_ENA_MASK); + + /* select fiber_to_rgmii first in multiplex */ + ngbe_read_phy_reg_ext_yt(hw, YT_MISC, 0, &value); + value |= YT_MISC_FIBER_PRIO; + ngbe_write_phy_reg_ext_yt(hw, YT_MISC, 0, value); + + hw->phy.read_reg(hw, YT_BCR, 0, &value); + value |= YT_BCR_PWDN; + hw->phy.write_reg(hw, YT_BCR, 0, value); + + return 0; +} + s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed, bool autoneg_wait_to_complete) { diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.h b/drivers/net/ngbe/base/ngbe_phy_yt.h index 26820ecb92..5babd841c1 100644 --- a/drivers/net/ngbe/base/ngbe_phy_yt.h +++ b/drivers/net/ngbe/base/ngbe_phy_yt.h @@ -65,6 +65,7 @@ s32 ngbe_read_phy_reg_sds_ext_yt(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, u16 *phy_data); s32 ngbe_write_phy_reg_sds_ext_yt(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, u16 phy_data); +s32 ngbe_init_phy_yt(struct ngbe_hw *hw); s32 ngbe_reset_phy_yt(struct ngbe_hw *hw); diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index 626c6e2eec..396c19b573 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -94,15 +94,20 @@ struct ngbe_rom_info { struct ngbe_mac_info { s32 (*init_hw)(struct ngbe_hw *hw); s32 (*reset_hw)(struct ngbe_hw *hw); + s32 (*start_hw)(struct ngbe_hw *hw); s32 (*stop_hw)(struct ngbe_hw *hw); s32 (*get_mac_addr)(struct ngbe_hw *hw, u8 *mac_addr); s32 (*acquire_swfw_sync)(struct ngbe_hw *hw, u32 mask); void (*release_swfw_sync)(struct ngbe_hw *hw, u32 mask); + /* Link */ s32 (*setup_link)(struct ngbe_hw *hw, u32 speed, bool autoneg_wait_to_complete); s32 (*check_link)(struct ngbe_hw *hw, u32 *speed, bool *link_up, bool link_up_wait_to_complete); + s32 (*get_link_capabilities)(struct ngbe_hw *hw, + u32 *speed, bool *autoneg); + /* RAR */ s32 (*set_rar)(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr); @@ -128,11 +133,13 @@ struct ngbe_mac_info { bool set_lben; u32 max_link_up_time; + u32 default_speeds; bool autoneg; }; struct ngbe_phy_info { s32 (*identify)(struct ngbe_hw *hw); + s32 (*init_hw)(struct ngbe_hw *hw); s32 (*reset_hw)(struct ngbe_hw *hw); s32 (*read_reg)(struct ngbe_hw *hw, u32 reg_addr, u32 device_type, u16 *phy_data); @@ -180,6 +187,8 @@ struct ngbe_hw { uint64_t isb_dma; void IOMEM *isb_mem; + u16 nb_rx_queues; + u16 nb_tx_queues; bool is_pf; }; diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index 6b4d5ac65b..008326631e 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -15,9 +15,17 @@ #include "ngbe_rxtx.h" static int ngbe_dev_close(struct rte_eth_dev *dev); - +static int ngbe_dev_link_update(struct rte_eth_dev *dev, + int wait_to_complete); + +static void ngbe_dev_link_status_print(struct rte_eth_dev *dev); +static int ngbe_dev_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on); +static int ngbe_dev_macsec_interrupt_setup(struct rte_eth_dev *dev); +static int ngbe_dev_misc_interrupt_setup(struct rte_eth_dev *dev); +static int ngbe_dev_rxq_interrupt_setup(struct rte_eth_dev *dev); static void ngbe_dev_interrupt_handler(void *param); static void ngbe_dev_interrupt_delayed_handler(void *param); +static void ngbe_configure_msix(struct rte_eth_dev *dev); /* * The set of PCI devices this driver supports @@ -54,6 +62,25 @@ static const struct rte_eth_desc_lim tx_desc_lim = { static const struct eth_dev_ops ngbe_eth_dev_ops; +static inline int32_t +ngbe_pf_reset_hw(struct ngbe_hw *hw) +{ + uint32_t ctrl_ext; + int32_t status; + + status = hw->mac.reset_hw(hw); + + ctrl_ext = rd32(hw, NGBE_PORTCTL); + /* Set PF Reset Done bit so PF/VF Mail Ops can work */ + ctrl_ext |= NGBE_PORTCTL_RSTDONE; + wr32(hw, NGBE_PORTCTL, ctrl_ext); + ngbe_flush(hw); + + if (status == NGBE_ERR_SFP_NOT_PRESENT) + status = 0; + return status; +} + static inline void ngbe_enable_intr(struct rte_eth_dev *dev) { @@ -200,6 +227,13 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) wr32(hw, NGBE_PORTCTL, ctrl_ext); ngbe_flush(hw); + PMD_INIT_LOG(DEBUG, "MAC: %d, PHY: %d", + (int)hw->mac.type, (int)hw->phy.type); + + PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x", + eth_dev->data->port_id, pci_dev->id.vendor_id, + pci_dev->id.device_id); + rte_intr_callback_register(intr_handle, ngbe_dev_interrupt_handler, eth_dev); @@ -274,6 +308,250 @@ ngbe_dev_configure(struct rte_eth_dev *dev) return 0; } +static void +ngbe_dev_phy_intr_setup(struct rte_eth_dev *dev) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + + wr32(hw, NGBE_GPIODIR, NGBE_GPIODIR_DDR(1)); + wr32(hw, NGBE_GPIOINTEN, NGBE_GPIOINTEN_INT(3)); + wr32(hw, NGBE_GPIOINTTYPE, NGBE_GPIOINTTYPE_LEVEL(0)); + if (hw->phy.type == ngbe_phy_yt8521s_sfi) + wr32(hw, NGBE_GPIOINTPOL, NGBE_GPIOINTPOL_ACT(0)); + else + wr32(hw, NGBE_GPIOINTPOL, NGBE_GPIOINTPOL_ACT(3)); + + intr->mask_misc |= NGBE_ICRMISC_GPIO; +} + +/* + * Configure device link speed and setup link. + * It returns 0 on success. + */ +static int +ngbe_dev_start(struct rte_eth_dev *dev) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + uint32_t intr_vector = 0; + int err; + bool link_up = false, negotiate = false; + uint32_t speed = 0; + uint32_t allowed_speeds = 0; + int status; + uint32_t *link_speeds; + + PMD_INIT_FUNC_TRACE(); + + /* disable uio/vfio intr/eventfd mapping */ + rte_intr_disable(intr_handle); + + /* stop adapter */ + hw->adapter_stopped = 0; + ngbe_stop_hw(hw); + + /* reinitialize adapter + * this calls reset and start + */ + hw->nb_rx_queues = dev->data->nb_rx_queues; + hw->nb_tx_queues = dev->data->nb_tx_queues; + status = ngbe_pf_reset_hw(hw); + if (status != 0) + return -1; + hw->mac.start_hw(hw); + hw->mac.get_link_status = true; + + ngbe_dev_phy_intr_setup(dev); + + /* check and configure queue intr-vector mapping */ + if ((rte_intr_cap_multiple(intr_handle) || + !RTE_ETH_DEV_SRIOV(dev).active) && + dev->data->dev_conf.intr_conf.rxq != 0) { + intr_vector = dev->data->nb_rx_queues; + if (rte_intr_efd_enable(intr_handle, intr_vector)) + return -1; + } + + if (rte_intr_dp_is_en(intr_handle) && intr_handle->intr_vec == NULL) { + intr_handle->intr_vec = + rte_zmalloc("intr_vec", + dev->data->nb_rx_queues * sizeof(int), 0); + if (intr_handle->intr_vec == NULL) { + PMD_INIT_LOG(ERR, "Failed to allocate %d rx_queues" + " intr_vec", dev->data->nb_rx_queues); + return -ENOMEM; + } + } + + /* confiugre MSI-X for sleep until Rx interrupt */ + ngbe_configure_msix(dev); + + /* initialize transmission unit */ + ngbe_dev_tx_init(dev); + + /* This can fail when allocating mbufs for descriptor rings */ + err = ngbe_dev_rx_init(dev); + if (err != 0) { + PMD_INIT_LOG(ERR, "Unable to initialize RX hardware"); + goto error; + } + + err = ngbe_dev_rxtx_start(dev); + if (err < 0) { + PMD_INIT_LOG(ERR, "Unable to start rxtx queues"); + goto error; + } + + err = hw->mac.check_link(hw, &speed, &link_up, 0); + if (err != 0) + goto error; + dev->data->dev_link.link_status = link_up; + + link_speeds = &dev->data->dev_conf.link_speeds; + if (*link_speeds == ETH_LINK_SPEED_AUTONEG) + negotiate = true; + + err = hw->mac.get_link_capabilities(hw, &speed, &negotiate); + if (err != 0) + goto error; + + allowed_speeds = 0; + if (hw->mac.default_speeds & NGBE_LINK_SPEED_1GB_FULL) + allowed_speeds |= ETH_LINK_SPEED_1G; + if (hw->mac.default_speeds & NGBE_LINK_SPEED_100M_FULL) + allowed_speeds |= ETH_LINK_SPEED_100M; + if (hw->mac.default_speeds & NGBE_LINK_SPEED_10M_FULL) + allowed_speeds |= ETH_LINK_SPEED_10M; + + if (*link_speeds & ~allowed_speeds) { + PMD_INIT_LOG(ERR, "Invalid link setting"); + goto error; + } + + speed = 0x0; + if (*link_speeds == ETH_LINK_SPEED_AUTONEG) { + speed = hw->mac.default_speeds; + } else { + if (*link_speeds & ETH_LINK_SPEED_1G) + speed |= NGBE_LINK_SPEED_1GB_FULL; + if (*link_speeds & ETH_LINK_SPEED_100M) + speed |= NGBE_LINK_SPEED_100M_FULL; + if (*link_speeds & ETH_LINK_SPEED_10M) + speed |= NGBE_LINK_SPEED_10M_FULL; + } + + hw->phy.init_hw(hw); + err = hw->mac.setup_link(hw, speed, link_up); + if (err != 0) + goto error; + + if (rte_intr_allow_others(intr_handle)) { + ngbe_dev_misc_interrupt_setup(dev); + /* check if lsc interrupt is enabled */ + if (dev->data->dev_conf.intr_conf.lsc != 0) + ngbe_dev_lsc_interrupt_setup(dev, TRUE); + else + ngbe_dev_lsc_interrupt_setup(dev, FALSE); + ngbe_dev_macsec_interrupt_setup(dev); + ngbe_set_ivar_map(hw, -1, 1, NGBE_MISC_VEC_ID); + } else { + rte_intr_callback_unregister(intr_handle, + ngbe_dev_interrupt_handler, dev); + if (dev->data->dev_conf.intr_conf.lsc != 0) + PMD_INIT_LOG(INFO, "lsc won't enable because of" + " no intr multiplex"); + } + + /* check if rxq interrupt is enabled */ + if (dev->data->dev_conf.intr_conf.rxq != 0 && + rte_intr_dp_is_en(intr_handle)) + ngbe_dev_rxq_interrupt_setup(dev); + + /* enable UIO/VFIO intr/eventfd mapping */ + rte_intr_enable(intr_handle); + + /* resume enabled intr since HW reset */ + ngbe_enable_intr(dev); + + if ((hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_M88E1512_SFP || + (hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_YT8521S_SFP) { + /* gpio0 is used to power on/off control*/ + wr32(hw, NGBE_GPIODATA, 0); + } + + /* + * Update link status right before return, because it may + * start link configuration process in a separate thread. + */ + ngbe_dev_link_update(dev, 0); + + return 0; + +error: + PMD_INIT_LOG(ERR, "failure in dev start: %d", err); + ngbe_dev_clear_queues(dev); + return -EIO; +} + +/* + * Stop device: disable rx and tx functions to allow for reconfiguring. + */ +static int +ngbe_dev_stop(struct rte_eth_dev *dev) +{ + struct rte_eth_link link; + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + + if (hw->adapter_stopped) + return 0; + + PMD_INIT_FUNC_TRACE(); + + if ((hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_M88E1512_SFP || + (hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_YT8521S_SFP) { + /* gpio0 is used to power on/off control*/ + wr32(hw, NGBE_GPIODATA, NGBE_GPIOBIT_0); + } + + /* disable interrupts */ + ngbe_disable_intr(hw); + + /* reset the NIC */ + ngbe_pf_reset_hw(hw); + hw->adapter_stopped = 0; + + /* stop adapter */ + ngbe_stop_hw(hw); + + ngbe_dev_clear_queues(dev); + + /* Clear recorded link status */ + memset(&link, 0, sizeof(link)); + rte_eth_linkstatus_set(dev, &link); + + if (!rte_intr_allow_others(intr_handle)) + /* resume to the default handler */ + rte_intr_callback_register(intr_handle, + ngbe_dev_interrupt_handler, + (void *)dev); + + /* Clean datapath event and queue/vec mapping */ + rte_intr_efd_disable(intr_handle); + if (intr_handle->intr_vec != NULL) { + rte_free(intr_handle->intr_vec); + intr_handle->intr_vec = NULL; + } + + hw->adapter_stopped = true; + dev->data->dev_started = 0; + + return 0; +} + /* * Reset and stop device. */ @@ -417,6 +695,106 @@ ngbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete) return ngbe_dev_link_update_share(dev, wait_to_complete); } +/** + * It clears the interrupt causes and enables the interrupt. + * It will be called once only during NIC initialized. + * + * @param dev + * Pointer to struct rte_eth_dev. + * @param on + * Enable or Disable. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ngbe_dev_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on) +{ + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + + ngbe_dev_link_status_print(dev); + if (on != 0) { + intr->mask_misc |= NGBE_ICRMISC_PHY; + intr->mask_misc |= NGBE_ICRMISC_GPIO; + } else { + intr->mask_misc &= ~NGBE_ICRMISC_PHY; + intr->mask_misc &= ~NGBE_ICRMISC_GPIO; + } + + return 0; +} + +/** + * It clears the interrupt causes and enables the interrupt. + * It will be called once only during NIC initialized. + * + * @param dev + * Pointer to struct rte_eth_dev. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ngbe_dev_misc_interrupt_setup(struct rte_eth_dev *dev) +{ + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + u64 mask; + + mask = NGBE_ICR_MASK; + mask &= (1ULL << NGBE_MISC_VEC_ID); + intr->mask |= mask; + intr->mask_misc |= NGBE_ICRMISC_GPIO; + + return 0; +} + +/** + * It clears the interrupt causes and enables the interrupt. + * It will be called once only during NIC initialized. + * + * @param dev + * Pointer to struct rte_eth_dev. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ngbe_dev_rxq_interrupt_setup(struct rte_eth_dev *dev) +{ + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + u64 mask; + + mask = NGBE_ICR_MASK; + mask &= ~((1ULL << NGBE_RX_VEC_START) - 1); + intr->mask |= mask; + + return 0; +} + +/** + * It clears the interrupt causes and enables the interrupt. + * It will be called once only during NIC initialized. + * + * @param dev + * Pointer to struct rte_eth_dev. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ngbe_dev_macsec_interrupt_setup(struct rte_eth_dev *dev) +{ + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + + intr->mask_misc |= NGBE_ICRMISC_LNKSEC; + + return 0; +} + /* * It reads ICR and sets flag for the link_update. * @@ -623,9 +1001,102 @@ ngbe_dev_interrupt_handler(void *param) ngbe_dev_interrupt_action(dev); } +/** + * set the IVAR registers, mapping interrupt causes to vectors + * @param hw + * pointer to ngbe_hw struct + * @direction + * 0 for Rx, 1 for Tx, -1 for other causes + * @queue + * queue to map the corresponding interrupt to + * @msix_vector + * the vector to map to the corresponding queue + */ +void +ngbe_set_ivar_map(struct ngbe_hw *hw, int8_t direction, + uint8_t queue, uint8_t msix_vector) +{ + uint32_t tmp, idx; + + if (direction == -1) { + /* other causes */ + msix_vector |= NGBE_IVARMISC_VLD; + idx = 0; + tmp = rd32(hw, NGBE_IVARMISC); + tmp &= ~(0xFF << idx); + tmp |= (msix_vector << idx); + wr32(hw, NGBE_IVARMISC, tmp); + } else { + /* rx or tx causes */ + /* Workround for ICR lost */ + idx = ((16 * (queue & 1)) + (8 * direction)); + tmp = rd32(hw, NGBE_IVAR(queue >> 1)); + tmp &= ~(0xFF << idx); + tmp |= (msix_vector << idx); + wr32(hw, NGBE_IVAR(queue >> 1), tmp); + } +} + +/** + * Sets up the hardware to properly generate MSI-X interrupts + * @hw + * board private structure + */ +static void +ngbe_configure_msix(struct rte_eth_dev *dev) +{ + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + struct ngbe_hw *hw = ngbe_dev_hw(dev); + uint32_t queue_id, base = NGBE_MISC_VEC_ID; + uint32_t vec = NGBE_MISC_VEC_ID; + uint32_t gpie; + + /* won't configure MSI-X register if no mapping is done + * between intr vector and event fd + * but if MSI-X has been enabled already, need to configure + * auto clean, auto mask and throttling. + */ + gpie = rd32(hw, NGBE_GPIE); + if (!rte_intr_dp_is_en(intr_handle) && + !(gpie & NGBE_GPIE_MSIX)) + return; + + if (rte_intr_allow_others(intr_handle)) { + base = NGBE_RX_VEC_START; + vec = base; + } + + /* setup GPIE for MSI-X mode */ + gpie = rd32(hw, NGBE_GPIE); + gpie |= NGBE_GPIE_MSIX; + wr32(hw, NGBE_GPIE, gpie); + + /* Populate the IVAR table and set the ITR values to the + * corresponding register. + */ + if (rte_intr_dp_is_en(intr_handle)) { + for (queue_id = 0; queue_id < dev->data->nb_rx_queues; + queue_id++) { + /* by default, 1:1 mapping */ + ngbe_set_ivar_map(hw, 0, queue_id, vec); + intr_handle->intr_vec[queue_id] = vec; + if (vec < base + intr_handle->nb_efd - 1) + vec++; + } + + ngbe_set_ivar_map(hw, -1, 1, NGBE_MISC_VEC_ID); + } + wr32(hw, NGBE_ITR(NGBE_MISC_VEC_ID), + NGBE_ITR_IVAL_1G(NGBE_QUEUE_ITR_INTERVAL_DEFAULT) + | NGBE_ITR_WRDSA); +} + static const struct eth_dev_ops ngbe_eth_dev_ops = { .dev_configure = ngbe_dev_configure, .dev_infos_get = ngbe_dev_info_get, + .dev_start = ngbe_dev_start, + .dev_stop = ngbe_dev_stop, .link_update = ngbe_dev_link_update, .rx_queue_setup = ngbe_dev_rx_queue_setup, .rx_queue_release = ngbe_dev_rx_queue_release, diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h index c52cac2ca1..5277f175cd 100644 --- a/drivers/net/ngbe/ngbe_ethdev.h +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -13,7 +13,10 @@ #define NGBE_FLAG_MACSEC (uint32_t)(1 << 3) #define NGBE_FLAG_NEED_LINK_CONFIG (uint32_t)(1 << 4) +#define NGBE_QUEUE_ITR_INTERVAL_DEFAULT 500 /* 500us */ + #define NGBE_MISC_VEC_ID RTE_INTR_VEC_ZERO_OFFSET +#define NGBE_RX_VEC_START RTE_INTR_VEC_RXTX_OFFSET /* structure for interrupt relative data */ struct ngbe_interrupt { @@ -59,6 +62,11 @@ ngbe_dev_intr(struct rte_eth_dev *dev) return intr; } +/* + * RX/TX function prototypes + */ +void ngbe_dev_clear_queues(struct rte_eth_dev *dev); + void ngbe_dev_rx_queue_release(void *rxq); void ngbe_dev_tx_queue_release(void *txq); @@ -72,12 +80,21 @@ int ngbe_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id, uint16_t nb_tx_desc, unsigned int socket_id, const struct rte_eth_txconf *tx_conf); +int ngbe_dev_rx_init(struct rte_eth_dev *dev); + +void ngbe_dev_tx_init(struct rte_eth_dev *dev); + +int ngbe_dev_rxtx_start(struct rte_eth_dev *dev); + uint16_t ngbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); uint16_t ngbe_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts); +void ngbe_set_ivar_map(struct ngbe_hw *hw, int8_t direction, + uint8_t queue, uint8_t msix_vector); + int ngbe_dev_link_update_share(struct rte_eth_dev *dev, int wait_to_complete); diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c index 6dde996659..d4680afaae 100644 --- a/drivers/net/ngbe/ngbe_rxtx.c +++ b/drivers/net/ngbe/ngbe_rxtx.c @@ -908,3 +908,62 @@ ngbe_dev_rx_queue_setup(struct rte_eth_dev *dev, return 0; } +void __rte_cold +ngbe_dev_clear_queues(struct rte_eth_dev *dev) +{ + unsigned int i; + struct ngbe_adapter *adapter = ngbe_dev_adapter(dev); + + PMD_INIT_FUNC_TRACE(); + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + struct ngbe_tx_queue *txq = dev->data->tx_queues[i]; + + if (txq != NULL) { + txq->ops->release_mbufs(txq); + txq->ops->reset(txq); + } + } + + for (i = 0; i < dev->data->nb_rx_queues; i++) { + struct ngbe_rx_queue *rxq = dev->data->rx_queues[i]; + + if (rxq != NULL) { + ngbe_rx_queue_release_mbufs(rxq); + ngbe_reset_rx_queue(adapter, rxq); + } + } +} + +/* + * Initializes Receive Unit. + */ +int __rte_cold +ngbe_dev_rx_init(struct rte_eth_dev *dev) +{ + RTE_SET_USED(dev); + + return -EINVAL; +} + +/* + * Initializes Transmit Unit. + */ +void __rte_cold +ngbe_dev_tx_init(struct rte_eth_dev *dev) +{ + RTE_SET_USED(dev); + +} + +/* + * Start Transmit and Receive Units. + */ +int __rte_cold +ngbe_dev_rxtx_start(struct rte_eth_dev *dev) +{ + RTE_SET_USED(dev); + + return -EINVAL; +} + From patchwork Thu Jun 17 11:00:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94341 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7BD6AA0C4D; Thu, 17 Jun 2021 13:00:06 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 804F84115F; Thu, 17 Jun 2021 12:58:42 +0200 (CEST) Received: from smtpbgeu1.qq.com (smtpbgeu1.qq.com [52.59.177.22]) by mails.dpdk.org (Postfix) with ESMTP id 6385241173 for ; Thu, 17 Jun 2021 12:58:40 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927516tzhabprn Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:36 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: JWfmZj3Ksqu3EL/yQOzTNqjOSA4esC17IJeOe3Deg5YCC+qM/QrQdA1iJim3i 2kga8jGGq6yKwsaCu10RnSoPTwrA4B5rG9PtYxNop24+04qAO7F6Tp/pQUskTMTTMGgsze0 YkN3vinFEk0g3OKVU2qXuZTpcNZ/Irn0Rs2JdzdtGs7VjHjHvA6WTyoPGCp3sTo7zu/XWWS LlxEzuvGn5SMPCDqQtEK0UKKLtiO82+MRJpEc3p7dg8gYfC3A9z/VH3I22vooDELii3pzkx sKGmympfJ6Cbu4GNYbqn1NtscoSP31oDnxsiJK+AaTVVp48dZmucfHV+h9Jd5eHO9w8kBBY mjwwAHRzkDtVFxyHxWtSbjH6Kc3bXtXCBIJKKVI X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 19:00:03 +0800 Message-Id: <20210617110005.4132926-18-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign6 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 17/19] net/ngbe: add Tx queue start and stop X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Initializes transmit unit, support to start and stop transmit unit for specified queues. Signed-off-by: Jiawen Wu --- doc/guides/nics/features/ngbe.ini | 1 + drivers/net/ngbe/base/ngbe_type.h | 1 + drivers/net/ngbe/ngbe_ethdev.c | 3 + drivers/net/ngbe/ngbe_ethdev.h | 7 ++ drivers/net/ngbe/ngbe_rxtx.c | 162 +++++++++++++++++++++++++++++- drivers/net/ngbe/ngbe_rxtx.h | 3 + 6 files changed, 175 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/features/ngbe.ini b/doc/guides/nics/features/ngbe.ini index 291a542a42..08d5f1b0dc 100644 --- a/doc/guides/nics/features/ngbe.ini +++ b/doc/guides/nics/features/ngbe.ini @@ -7,6 +7,7 @@ Speed capabilities = Y Link status = Y Link status event = Y +Queue start/stop = Y Multiprocess aware = Y Linux = Y ARMv8 = Y diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index 396c19b573..9312a1ee44 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -190,6 +190,7 @@ struct ngbe_hw { u16 nb_rx_queues; u16 nb_tx_queues; + u32 q_tx_regs[8 * 4]; bool is_pf; }; diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index 008326631e..bd32f20c38 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -601,6 +601,7 @@ ngbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) ETH_LINK_SPEED_10M; /* Driver-preferred Rx/Tx parameters */ + dev_info->default_txportconf.burst_size = 32; dev_info->default_rxportconf.nb_queues = 1; dev_info->default_txportconf.nb_queues = 1; dev_info->default_rxportconf.ring_size = 256; @@ -1098,6 +1099,8 @@ static const struct eth_dev_ops ngbe_eth_dev_ops = { .dev_start = ngbe_dev_start, .dev_stop = ngbe_dev_stop, .link_update = ngbe_dev_link_update, + .tx_queue_start = ngbe_dev_tx_queue_start, + .tx_queue_stop = ngbe_dev_tx_queue_stop, .rx_queue_setup = ngbe_dev_rx_queue_setup, .rx_queue_release = ngbe_dev_rx_queue_release, .tx_queue_setup = ngbe_dev_tx_queue_setup, diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h index 5277f175cd..40a28711f1 100644 --- a/drivers/net/ngbe/ngbe_ethdev.h +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -86,6 +86,13 @@ void ngbe_dev_tx_init(struct rte_eth_dev *dev); int ngbe_dev_rxtx_start(struct rte_eth_dev *dev); +void ngbe_dev_save_tx_queue(struct ngbe_hw *hw, uint16_t tx_queue_id); +void ngbe_dev_store_tx_queue(struct ngbe_hw *hw, uint16_t tx_queue_id); + +int ngbe_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id); + +int ngbe_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id); + uint16_t ngbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c index d4680afaae..b05cb0ec34 100644 --- a/drivers/net/ngbe/ngbe_rxtx.c +++ b/drivers/net/ngbe/ngbe_rxtx.c @@ -952,8 +952,32 @@ ngbe_dev_rx_init(struct rte_eth_dev *dev) void __rte_cold ngbe_dev_tx_init(struct rte_eth_dev *dev) { - RTE_SET_USED(dev); + struct ngbe_hw *hw; + struct ngbe_tx_queue *txq; + uint64_t bus_addr; + uint16_t i; + + PMD_INIT_FUNC_TRACE(); + hw = ngbe_dev_hw(dev); + wr32m(hw, NGBE_SECTXCTL, NGBE_SECTXCTL_ODSA, NGBE_SECTXCTL_ODSA); + wr32m(hw, NGBE_SECTXCTL, NGBE_SECTXCTL_XDSA, 0); + + /* Setup the Base and Length of the Tx Descriptor Rings */ + for (i = 0; i < dev->data->nb_tx_queues; i++) { + txq = dev->data->tx_queues[i]; + + bus_addr = txq->tx_ring_phys_addr; + wr32(hw, NGBE_TXBAL(txq->reg_idx), + (uint32_t)(bus_addr & BIT_MASK32)); + wr32(hw, NGBE_TXBAH(txq->reg_idx), + (uint32_t)(bus_addr >> 32)); + wr32m(hw, NGBE_TXCFG(txq->reg_idx), NGBE_TXCFG_BUFLEN_MASK, + NGBE_TXCFG_BUFLEN(txq->nb_tx_desc)); + /* Setup the HW Tx Head and TX Tail descriptor pointers */ + wr32(hw, NGBE_TXRP(txq->reg_idx), 0); + wr32(hw, NGBE_TXWP(txq->reg_idx), 0); + } } /* @@ -962,8 +986,142 @@ ngbe_dev_tx_init(struct rte_eth_dev *dev) int __rte_cold ngbe_dev_rxtx_start(struct rte_eth_dev *dev) { - RTE_SET_USED(dev); + struct ngbe_hw *hw; + struct ngbe_tx_queue *txq; + uint32_t dmatxctl; + uint16_t i; + int ret = 0; + + PMD_INIT_FUNC_TRACE(); + hw = ngbe_dev_hw(dev); + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + txq = dev->data->tx_queues[i]; + /* Setup Transmit Threshold Registers */ + wr32m(hw, NGBE_TXCFG(txq->reg_idx), + NGBE_TXCFG_HTHRESH_MASK | + NGBE_TXCFG_WTHRESH_MASK, + NGBE_TXCFG_HTHRESH(txq->hthresh) | + NGBE_TXCFG_WTHRESH(txq->wthresh)); + } + + dmatxctl = rd32(hw, NGBE_DMATXCTRL); + dmatxctl |= NGBE_DMATXCTRL_ENA; + wr32(hw, NGBE_DMATXCTRL, dmatxctl); + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + txq = dev->data->tx_queues[i]; + if (txq->tx_deferred_start == 0) { + ret = ngbe_dev_tx_queue_start(dev, i); + if (ret < 0) + return ret; + } + } return -EINVAL; } +void +ngbe_dev_save_tx_queue(struct ngbe_hw *hw, uint16_t tx_queue_id) +{ + u32 *reg = &hw->q_tx_regs[tx_queue_id * 8]; + *(reg++) = rd32(hw, NGBE_TXBAL(tx_queue_id)); + *(reg++) = rd32(hw, NGBE_TXBAH(tx_queue_id)); + *(reg++) = rd32(hw, NGBE_TXCFG(tx_queue_id)); +} + +void +ngbe_dev_store_tx_queue(struct ngbe_hw *hw, uint16_t tx_queue_id) +{ + u32 *reg = &hw->q_tx_regs[tx_queue_id * 8]; + wr32(hw, NGBE_TXBAL(tx_queue_id), *(reg++)); + wr32(hw, NGBE_TXBAH(tx_queue_id), *(reg++)); + wr32(hw, NGBE_TXCFG(tx_queue_id), *(reg++) & ~NGBE_TXCFG_ENA); +} + +/* + * Start Transmit Units for specified queue. + */ +int __rte_cold +ngbe_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct ngbe_tx_queue *txq; + uint32_t txdctl; + int poll_ms; + + PMD_INIT_FUNC_TRACE(); + + txq = dev->data->tx_queues[tx_queue_id]; + wr32m(hw, NGBE_TXCFG(txq->reg_idx), NGBE_TXCFG_ENA, NGBE_TXCFG_ENA); + + /* Wait until Tx Enable ready */ + poll_ms = RTE_NGBE_REGISTER_POLL_WAIT_10_MS; + do { + rte_delay_ms(1); + txdctl = rd32(hw, NGBE_TXCFG(txq->reg_idx)); + } while (--poll_ms && !(txdctl & NGBE_TXCFG_ENA)); + if (poll_ms == 0) + PMD_INIT_LOG(ERR, "Could not enable " + "Tx Queue %d", tx_queue_id); + + rte_wmb(); + wr32(hw, NGBE_TXWP(txq->reg_idx), txq->tx_tail); + dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; + + return 0; +} + +/* + * Stop Transmit Units for specified queue. + */ +int __rte_cold +ngbe_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct ngbe_tx_queue *txq; + uint32_t txdctl; + uint32_t txtdh, txtdt; + int poll_ms; + + PMD_INIT_FUNC_TRACE(); + + txq = dev->data->tx_queues[tx_queue_id]; + + /* Wait until Tx queue is empty */ + poll_ms = RTE_NGBE_REGISTER_POLL_WAIT_10_MS; + do { + rte_delay_us(RTE_NGBE_WAIT_100_US); + txtdh = rd32(hw, NGBE_TXRP(txq->reg_idx)); + txtdt = rd32(hw, NGBE_TXWP(txq->reg_idx)); + } while (--poll_ms && (txtdh != txtdt)); + if (poll_ms == 0) + PMD_INIT_LOG(ERR, + "Tx Queue %d is not empty when stopping.", + tx_queue_id); + + ngbe_dev_save_tx_queue(hw, txq->reg_idx); + wr32m(hw, NGBE_TXCFG(txq->reg_idx), NGBE_TXCFG_ENA, 0); + + /* Wait until Tx Enable bit clear */ + poll_ms = RTE_NGBE_REGISTER_POLL_WAIT_10_MS; + do { + rte_delay_ms(1); + txdctl = rd32(hw, NGBE_TXCFG(txq->reg_idx)); + } while (--poll_ms && (txdctl & NGBE_TXCFG_ENA)); + if (poll_ms == 0) + PMD_INIT_LOG(ERR, "Could not disable Tx Queue %d", + tx_queue_id); + + rte_delay_us(RTE_NGBE_WAIT_100_US); + ngbe_dev_store_tx_queue(hw, txq->reg_idx); + + if (txq->ops != NULL) { + txq->ops->release_mbufs(txq); + txq->ops->reset(txq); + } + dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; + + return 0; +} + diff --git a/drivers/net/ngbe/ngbe_rxtx.h b/drivers/net/ngbe/ngbe_rxtx.h index 616b41a300..d906b45a73 100644 --- a/drivers/net/ngbe/ngbe_rxtx.h +++ b/drivers/net/ngbe/ngbe_rxtx.h @@ -181,6 +181,9 @@ struct ngbe_tx_desc { #define rte_packet_prefetch(p) rte_prefetch1(p) +#define RTE_NGBE_REGISTER_POLL_WAIT_10_MS 10 +#define RTE_NGBE_WAIT_100_US 100 + #define NGBE_TX_MAX_SEG 40 #ifndef DEFAULT_TX_FREE_THRESH From patchwork Thu Jun 17 11:00:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94343 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 39BD9A0C4D; Thu, 17 Jun 2021 13:00:21 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 148E34117A; Thu, 17 Jun 2021 12:58:45 +0200 (CEST) Received: from smtpproxy21.qq.com (smtpbg702.qq.com [203.205.195.102]) by mails.dpdk.org (Postfix) with ESMTP id E443D410EC for ; Thu, 17 Jun 2021 12:58:41 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927518tkunbegc Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:37 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: YKCDl5A3/aohU8G+sFcxr+hNfnHznwwULXbC4jBSnM5m1xhVez7NmhLWTV72g DAVMUmGbMwrjxXQ8vA5c94xlmNibiYSHhk+PXz8lVVpd1a6ZFohsbxE7rn7TOut5a6INHVY xt5fVsFmbFYkG2lDhtODrV/JxBS+oWLFeLt+VKTOYWttgr42jSLlq3kf++t0hdmAqQHBG9+ 4z/gDCcqN310YbNib83RSS2cP6rOC/73/0B++1ZStlTvOVmrm4xVJLCYhwEXe3oYUyJOJoS zhwCGd+NvgZmghnhezHjjI2QKka+OWtimzeFO+thTpojFM6jCv7TfONhu8KZTYMNAD+/ySh f0RyeSkAnztNQnDcIqPWCFa/a9jY5qk5PN1+1ry X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 19:00:04 +0800 Message-Id: <20210617110005.4132926-19-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign6 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 18/19] net/ngbe: add Rx queue start and stop X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Initializes receive unit, support to start and stop receive unit for specified queues. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/base/ngbe_dummy.h | 15 ++ drivers/net/ngbe/base/ngbe_hw.c | 105 ++++++++++++++ drivers/net/ngbe/base/ngbe_hw.h | 4 + drivers/net/ngbe/base/ngbe_type.h | 4 + drivers/net/ngbe/ngbe_ethdev.c | 5 + drivers/net/ngbe/ngbe_ethdev.h | 6 + drivers/net/ngbe/ngbe_rxtx.c | 215 ++++++++++++++++++++++++++++- 7 files changed, 351 insertions(+), 3 deletions(-) diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h index dfc7b13192..384631b4f1 100644 --- a/drivers/net/ngbe/base/ngbe_dummy.h +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -59,6 +59,18 @@ static inline s32 ngbe_mac_get_mac_addr_dummy(struct ngbe_hw *TUP0, u8 *TUP1) { return NGBE_ERR_OPS_DUMMY; } +static inline s32 ngbe_mac_enable_rx_dma_dummy(struct ngbe_hw *TUP0, u32 TUP1) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_mac_disable_sec_rx_path_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_mac_enable_sec_rx_path_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline s32 ngbe_mac_acquire_swfw_sync_dummy(struct ngbe_hw *TUP0, u32 TUP1) { @@ -167,6 +179,9 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) hw->mac.start_hw = ngbe_mac_start_hw_dummy; hw->mac.stop_hw = ngbe_mac_stop_hw_dummy; hw->mac.get_mac_addr = ngbe_mac_get_mac_addr_dummy; + hw->mac.enable_rx_dma = ngbe_mac_enable_rx_dma_dummy; + hw->mac.disable_sec_rx_path = ngbe_mac_disable_sec_rx_path_dummy; + hw->mac.enable_sec_rx_path = ngbe_mac_enable_sec_rx_path_dummy; hw->mac.acquire_swfw_sync = ngbe_mac_acquire_swfw_sync_dummy; hw->mac.release_swfw_sync = ngbe_mac_release_swfw_sync_dummy; hw->mac.setup_link = ngbe_mac_setup_link_dummy; diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index 22ce4e52b9..45cbfaa76c 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -536,6 +536,63 @@ void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask) ngbe_release_eeprom_semaphore(hw); } +/** + * ngbe_disable_sec_rx_path - Stops the receive data path + * @hw: pointer to hardware structure + * + * Stops the receive data path and waits for the HW to internally empty + * the Rx security block + **/ +s32 ngbe_disable_sec_rx_path(struct ngbe_hw *hw) +{ +#define NGBE_MAX_SECRX_POLL 4000 + + int i; + u32 secrxreg; + + DEBUGFUNC("ngbe_disable_sec_rx_path"); + + + secrxreg = rd32(hw, NGBE_SECRXCTL); + secrxreg |= NGBE_SECRXCTL_XDSA; + wr32(hw, NGBE_SECRXCTL, secrxreg); + for (i = 0; i < NGBE_MAX_SECRX_POLL; i++) { + secrxreg = rd32(hw, NGBE_SECRXSTAT); + if (!(secrxreg & NGBE_SECRXSTAT_RDY)) + /* Use interrupt-safe sleep just in case */ + usec_delay(10); + else + break; + } + + /* For informational purposes only */ + if (i >= NGBE_MAX_SECRX_POLL) + DEBUGOUT("Rx unit being enabled before security " + "path fully disabled. Continuing with init.\n"); + + return 0; +} + +/** + * ngbe_enable_sec_rx_path - Enables the receive data path + * @hw: pointer to hardware structure + * + * Enables the receive data path. + **/ +s32 ngbe_enable_sec_rx_path(struct ngbe_hw *hw) +{ + u32 secrxreg; + + DEBUGFUNC("ngbe_enable_sec_rx_path"); + + secrxreg = rd32(hw, NGBE_SECRXCTL); + secrxreg &= ~NGBE_SECRXCTL_XDSA; + wr32(hw, NGBE_SECRXCTL, secrxreg); + ngbe_flush(hw); + + return 0; +} + /** * ngbe_clear_vmdq - Disassociate a VMDq pool index from a rx address * @hw: pointer to hardware struct @@ -756,6 +813,21 @@ void ngbe_disable_rx(struct ngbe_hw *hw) wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, 0); } +void ngbe_enable_rx(struct ngbe_hw *hw) +{ + u32 pfdtxgswc; + + wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, NGBE_MACRXCFG_ENA); + wr32m(hw, NGBE_PBRXCTL, NGBE_PBRXCTL_ENA, NGBE_PBRXCTL_ENA); + + if (hw->mac.set_lben) { + pfdtxgswc = rd32(hw, NGBE_PSRCTL); + pfdtxgswc |= NGBE_PSRCTL_LBENA; + wr32(hw, NGBE_PSRCTL, pfdtxgswc); + hw->mac.set_lben = false; + } +} + /** * ngbe_set_mac_type - Sets MAC type * @hw: pointer to the HW structure @@ -802,6 +874,36 @@ s32 ngbe_set_mac_type(struct ngbe_hw *hw) return err; } +/** + * ngbe_enable_rx_dma - Enable the Rx DMA unit + * @hw: pointer to hardware structure + * @regval: register value to write to RXCTRL + * + * Enables the Rx DMA unit + **/ +s32 ngbe_enable_rx_dma(struct ngbe_hw *hw, u32 regval) +{ + DEBUGFUNC("ngbe_enable_rx_dma"); + + /* + * Workaround silicon errata when enabling the Rx datapath. + * If traffic is incoming before we enable the Rx unit, it could hang + * the Rx DMA unit. Therefore, make sure the security engine is + * completely disabled prior to enabling the Rx unit. + */ + + hw->mac.disable_sec_rx_path(hw); + + if (regval & NGBE_PBRXCTL_ENA) + ngbe_enable_rx(hw); + else + ngbe_disable_rx(hw); + + hw->mac.enable_sec_rx_path(hw); + + return 0; +} + void ngbe_map_device_id(struct ngbe_hw *hw) { u16 oem = hw->sub_system_id & NGBE_OEM_MASK; @@ -886,11 +988,14 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) mac->init_hw = ngbe_init_hw; mac->reset_hw = ngbe_reset_hw_em; mac->start_hw = ngbe_start_hw; + mac->enable_rx_dma = ngbe_enable_rx_dma; mac->get_mac_addr = ngbe_get_mac_addr; mac->stop_hw = ngbe_stop_hw; mac->acquire_swfw_sync = ngbe_acquire_swfw_sync; mac->release_swfw_sync = ngbe_release_swfw_sync; + mac->disable_sec_rx_path = ngbe_disable_sec_rx_path; + mac->enable_sec_rx_path = ngbe_enable_sec_rx_path; /* RAR */ mac->set_rar = ngbe_set_rar; mac->clear_rar = ngbe_clear_rar; diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h index 4fee5735ac..01f41fe9b3 100644 --- a/drivers/net/ngbe/base/ngbe_hw.h +++ b/drivers/net/ngbe/base/ngbe_hw.h @@ -34,6 +34,8 @@ s32 ngbe_set_rar(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr); s32 ngbe_clear_rar(struct ngbe_hw *hw, u32 index); s32 ngbe_init_rx_addrs(struct ngbe_hw *hw); +s32 ngbe_disable_sec_rx_path(struct ngbe_hw *hw); +s32 ngbe_enable_sec_rx_path(struct ngbe_hw *hw); s32 ngbe_validate_mac_addr(u8 *mac_addr); s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask); @@ -46,10 +48,12 @@ s32 ngbe_init_uta_tables(struct ngbe_hw *hw); s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw); s32 ngbe_mac_check_overtemp(struct ngbe_hw *hw); void ngbe_disable_rx(struct ngbe_hw *hw); +void ngbe_enable_rx(struct ngbe_hw *hw); s32 ngbe_init_shared_code(struct ngbe_hw *hw); s32 ngbe_set_mac_type(struct ngbe_hw *hw); s32 ngbe_init_ops_pf(struct ngbe_hw *hw); s32 ngbe_init_phy(struct ngbe_hw *hw); +s32 ngbe_enable_rx_dma(struct ngbe_hw *hw, u32 regval); void ngbe_map_device_id(struct ngbe_hw *hw); #endif /* _NGBE_HW_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index 9312a1ee44..a06e6d240e 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -97,6 +97,9 @@ struct ngbe_mac_info { s32 (*start_hw)(struct ngbe_hw *hw); s32 (*stop_hw)(struct ngbe_hw *hw); s32 (*get_mac_addr)(struct ngbe_hw *hw, u8 *mac_addr); + s32 (*enable_rx_dma)(struct ngbe_hw *hw, u32 regval); + s32 (*disable_sec_rx_path)(struct ngbe_hw *hw); + s32 (*enable_sec_rx_path)(struct ngbe_hw *hw); s32 (*acquire_swfw_sync)(struct ngbe_hw *hw, u32 mask); void (*release_swfw_sync)(struct ngbe_hw *hw, u32 mask); @@ -190,6 +193,7 @@ struct ngbe_hw { u16 nb_rx_queues; u16 nb_tx_queues; + u32 q_rx_regs[8 * 4]; u32 q_tx_regs[8 * 4]; bool is_pf; }; diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index bd32f20c38..ef8ea5ecff 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -572,6 +572,8 @@ ngbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues; dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues; + dev_info->min_rx_bufsize = 1024; + dev_info->max_rx_pktlen = 15872; dev_info->default_rxconf = (struct rte_eth_rxconf) { .rx_thresh = { @@ -601,6 +603,7 @@ ngbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) ETH_LINK_SPEED_10M; /* Driver-preferred Rx/Tx parameters */ + dev_info->default_rxportconf.burst_size = 32; dev_info->default_txportconf.burst_size = 32; dev_info->default_rxportconf.nb_queues = 1; dev_info->default_txportconf.nb_queues = 1; @@ -1099,6 +1102,8 @@ static const struct eth_dev_ops ngbe_eth_dev_ops = { .dev_start = ngbe_dev_start, .dev_stop = ngbe_dev_stop, .link_update = ngbe_dev_link_update, + .rx_queue_start = ngbe_dev_rx_queue_start, + .rx_queue_stop = ngbe_dev_rx_queue_stop, .tx_queue_start = ngbe_dev_tx_queue_start, .tx_queue_stop = ngbe_dev_tx_queue_stop, .rx_queue_setup = ngbe_dev_rx_queue_setup, diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h index 40a28711f1..d576eef5d6 100644 --- a/drivers/net/ngbe/ngbe_ethdev.h +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -86,9 +86,15 @@ void ngbe_dev_tx_init(struct rte_eth_dev *dev); int ngbe_dev_rxtx_start(struct rte_eth_dev *dev); +void ngbe_dev_save_rx_queue(struct ngbe_hw *hw, uint16_t rx_queue_id); +void ngbe_dev_store_rx_queue(struct ngbe_hw *hw, uint16_t rx_queue_id); void ngbe_dev_save_tx_queue(struct ngbe_hw *hw, uint16_t tx_queue_id); void ngbe_dev_store_tx_queue(struct ngbe_hw *hw, uint16_t tx_queue_id); +int ngbe_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id); + +int ngbe_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id); + int ngbe_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id); int ngbe_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id); diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c index b05cb0ec34..0801424245 100644 --- a/drivers/net/ngbe/ngbe_rxtx.c +++ b/drivers/net/ngbe/ngbe_rxtx.c @@ -935,15 +935,111 @@ ngbe_dev_clear_queues(struct rte_eth_dev *dev) } } +static int __rte_cold +ngbe_alloc_rx_queue_mbufs(struct ngbe_rx_queue *rxq) +{ + struct ngbe_rx_entry *rxe = rxq->sw_ring; + uint64_t dma_addr; + unsigned int i; + + /* Initialize software ring entries */ + for (i = 0; i < rxq->nb_rx_desc; i++) { + /* the ring can also be modified by hardware */ + volatile struct ngbe_rx_desc *rxd; + struct rte_mbuf *mbuf = rte_mbuf_raw_alloc(rxq->mb_pool); + + if (mbuf == NULL) { + PMD_INIT_LOG(ERR, "Rx mbuf alloc failed queue_id=%u port_id=%u", + (unsigned int)rxq->queue_id, + (unsigned int)rxq->port_id); + return -ENOMEM; + } + + mbuf->data_off = RTE_PKTMBUF_HEADROOM; + mbuf->port = rxq->port_id; + + dma_addr = + rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf)); + rxd = &rxq->rx_ring[i]; + NGBE_RXD_HDRADDR(rxd, 0); + NGBE_RXD_PKTADDR(rxd, dma_addr); + rxe[i].mbuf = mbuf; + } + + return 0; +} + /* * Initializes Receive Unit. */ int __rte_cold ngbe_dev_rx_init(struct rte_eth_dev *dev) { - RTE_SET_USED(dev); + struct ngbe_hw *hw; + struct ngbe_rx_queue *rxq; + uint64_t bus_addr; + uint32_t fctrl; + uint32_t hlreg0; + uint32_t srrctl; + uint16_t buf_size; + uint16_t i; - return -EINVAL; + PMD_INIT_FUNC_TRACE(); + hw = ngbe_dev_hw(dev); + + /* + * Make sure receives are disabled while setting + * up the Rx context (registers, descriptor rings, etc.). + */ + wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, 0); + wr32m(hw, NGBE_PBRXCTL, NGBE_PBRXCTL_ENA, 0); + + /* Enable receipt of broadcasted frames */ + fctrl = rd32(hw, NGBE_PSRCTL); + fctrl |= NGBE_PSRCTL_BCA; + wr32(hw, NGBE_PSRCTL, fctrl); + + hlreg0 = rd32(hw, NGBE_SECRXCTL); + hlreg0 &= ~NGBE_SECRXCTL_XDSA; + wr32(hw, NGBE_SECRXCTL, hlreg0); + + wr32m(hw, NGBE_FRMSZ, NGBE_FRMSZ_MAX_MASK, + NGBE_FRMSZ_MAX(NGBE_FRAME_SIZE_DFT)); + + /* Setup Rx queues */ + for (i = 0; i < dev->data->nb_rx_queues; i++) { + rxq = dev->data->rx_queues[i]; + + /* Setup the Base and Length of the Rx Descriptor Rings */ + bus_addr = rxq->rx_ring_phys_addr; + wr32(hw, NGBE_RXBAL(rxq->reg_idx), + (uint32_t)(bus_addr & BIT_MASK32)); + wr32(hw, NGBE_RXBAH(rxq->reg_idx), + (uint32_t)(bus_addr >> 32)); + wr32(hw, NGBE_RXRP(rxq->reg_idx), 0); + wr32(hw, NGBE_RXWP(rxq->reg_idx), 0); + + srrctl = NGBE_RXCFG_RNGLEN(rxq->nb_rx_desc); + + /* Set if packets are dropped when no descriptors available */ + if (rxq->drop_en) + srrctl |= NGBE_RXCFG_DROP; + + /* + * Configure the Rx buffer size in the PKTLEN field of + * the RXCFG register of the queue. + * The value is in 1 KB resolution. Valid values can be from + * 1 KB to 16 KB. + */ + buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) - + RTE_PKTMBUF_HEADROOM); + buf_size = ROUND_DOWN(buf_size, 0x1 << 10); + srrctl |= NGBE_RXCFG_PKTLEN(buf_size); + + wr32(hw, NGBE_RXCFG(rxq->reg_idx), srrctl); + } + + return 0; } /* @@ -988,7 +1084,9 @@ ngbe_dev_rxtx_start(struct rte_eth_dev *dev) { struct ngbe_hw *hw; struct ngbe_tx_queue *txq; + struct ngbe_rx_queue *rxq; uint32_t dmatxctl; + uint32_t rxctrl; uint16_t i; int ret = 0; @@ -1018,7 +1116,39 @@ ngbe_dev_rxtx_start(struct rte_eth_dev *dev) } } - return -EINVAL; + for (i = 0; i < dev->data->nb_rx_queues; i++) { + rxq = dev->data->rx_queues[i]; + if (rxq->rx_deferred_start == 0) { + ret = ngbe_dev_rx_queue_start(dev, i); + if (ret < 0) + return ret; + } + } + + /* Enable Receive engine */ + rxctrl = rd32(hw, NGBE_PBRXCTL); + rxctrl |= NGBE_PBRXCTL_ENA; + hw->mac.enable_rx_dma(hw, rxctrl); + + return 0; +} + +void +ngbe_dev_save_rx_queue(struct ngbe_hw *hw, uint16_t rx_queue_id) +{ + u32 *reg = &hw->q_rx_regs[rx_queue_id * 8]; + *(reg++) = rd32(hw, NGBE_RXBAL(rx_queue_id)); + *(reg++) = rd32(hw, NGBE_RXBAH(rx_queue_id)); + *(reg++) = rd32(hw, NGBE_RXCFG(rx_queue_id)); +} + +void +ngbe_dev_store_rx_queue(struct ngbe_hw *hw, uint16_t rx_queue_id) +{ + u32 *reg = &hw->q_rx_regs[rx_queue_id * 8]; + wr32(hw, NGBE_RXBAL(rx_queue_id), *(reg++)); + wr32(hw, NGBE_RXBAH(rx_queue_id), *(reg++)); + wr32(hw, NGBE_RXCFG(rx_queue_id), *(reg++) & ~NGBE_RXCFG_ENA); } void @@ -1039,6 +1169,85 @@ ngbe_dev_store_tx_queue(struct ngbe_hw *hw, uint16_t tx_queue_id) wr32(hw, NGBE_TXCFG(tx_queue_id), *(reg++) & ~NGBE_TXCFG_ENA); } +/* + * Start Receive Units for specified queue. + */ +int __rte_cold +ngbe_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct ngbe_rx_queue *rxq; + uint32_t rxdctl; + int poll_ms; + + PMD_INIT_FUNC_TRACE(); + + rxq = dev->data->rx_queues[rx_queue_id]; + + /* Allocate buffers for descriptor rings */ + if (ngbe_alloc_rx_queue_mbufs(rxq) != 0) { + PMD_INIT_LOG(ERR, "Could not alloc mbuf for queue:%d", + rx_queue_id); + return -1; + } + rxdctl = rd32(hw, NGBE_RXCFG(rxq->reg_idx)); + rxdctl |= NGBE_RXCFG_ENA; + wr32(hw, NGBE_RXCFG(rxq->reg_idx), rxdctl); + + /* Wait until Rx Enable ready */ + poll_ms = RTE_NGBE_REGISTER_POLL_WAIT_10_MS; + do { + rte_delay_ms(1); + rxdctl = rd32(hw, NGBE_RXCFG(rxq->reg_idx)); + } while (--poll_ms && !(rxdctl & NGBE_RXCFG_ENA)); + if (poll_ms == 0) + PMD_INIT_LOG(ERR, "Could not enable Rx Queue %d", rx_queue_id); + rte_wmb(); + wr32(hw, NGBE_RXRP(rxq->reg_idx), 0); + wr32(hw, NGBE_RXWP(rxq->reg_idx), rxq->nb_rx_desc - 1); + dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; + + return 0; +} + +/* + * Stop Receive Units for specified queue. + */ +int __rte_cold +ngbe_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct ngbe_adapter *adapter = ngbe_dev_adapter(dev); + struct ngbe_rx_queue *rxq; + uint32_t rxdctl; + int poll_ms; + + PMD_INIT_FUNC_TRACE(); + + rxq = dev->data->rx_queues[rx_queue_id]; + + ngbe_dev_save_rx_queue(hw, rxq->reg_idx); + wr32m(hw, NGBE_RXCFG(rxq->reg_idx), NGBE_RXCFG_ENA, 0); + + /* Wait until Rx Enable bit clear */ + poll_ms = RTE_NGBE_REGISTER_POLL_WAIT_10_MS; + do { + rte_delay_ms(1); + rxdctl = rd32(hw, NGBE_RXCFG(rxq->reg_idx)); + } while (--poll_ms && (rxdctl & NGBE_RXCFG_ENA)); + if (poll_ms == 0) + PMD_INIT_LOG(ERR, "Could not disable Rx Queue %d", rx_queue_id); + + rte_delay_us(RTE_NGBE_WAIT_100_US); + ngbe_dev_store_rx_queue(hw, rxq->reg_idx); + + ngbe_rx_queue_release_mbufs(rxq); + ngbe_reset_rx_queue(adapter, rxq); + dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; + + return 0; +} + /* * Start Transmit Units for specified queue. */ From patchwork Thu Jun 17 11:00:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 94344 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 8E8E5A0C4D; Thu, 17 Jun 2021 13:00:27 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2EA9C410F3; Thu, 17 Jun 2021 12:58:48 +0200 (CEST) Received: from smtpbgsg2.qq.com (smtpbgsg2.qq.com [54.254.200.128]) by mails.dpdk.org (Postfix) with ESMTP id 6432441174 for ; Thu, 17 Jun 2021 12:58:46 +0200 (CEST) X-QQ-mid: bizesmtp46t1623927520tex607ex Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Thu, 17 Jun 2021 18:58:39 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: 0VmwRkEgV1FFuVSbpJlLEb8f/FC6WpQI2lODb35qZVouWtE8/eLLlI13s3a2o 7PG2F2tJBY8hQ7Ih9B8hUX8v2Ve+edDdg4bkT1/5YuRAkg5klBScFgcE34skjt4eAk+iMSo meXmibLWv1c2rlqpMhRFnaXB0IvluTCq8EvNRwp9pVe45jqXnx5w6uwQDkdQuKUERI89sxM SGlcE0rYf6jUTtKTSWEHm1Clg8XCp6TgQWpLrynaQZzDzWw+mTps6DimrTl+v73aHnf3v3/ K1ICY9DOLKtP4B6gvoah+U8IDBIzpTNMjNb6POnMCZSM0a12oDpbnvx0x+XgQSrADYR6/lW rGMGETYRHNQ4nyqp3pGWtCUHKqnVQtVcM8bSVTj X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Thu, 17 Jun 2021 19:00:05 +0800 Message-Id: <20210617110005.4132926-20-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617110005.4132926-1-jiawenwu@trustnetic.com> References: <20210617110005.4132926-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign5 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v6 19/19] net/ngbe: support to close and reset device X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Support to close and reset device. Signed-off-by: Jiawen Wu --- drivers/net/ngbe/ngbe_ethdev.c | 61 ++++++++++++++++++++++++++++++++-- drivers/net/ngbe/ngbe_ethdev.h | 2 ++ drivers/net/ngbe/ngbe_rxtx.c | 20 +++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index ef8ea5ecff..695c1d26c8 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -558,11 +558,66 @@ ngbe_dev_stop(struct rte_eth_dev *dev) static int ngbe_dev_close(struct rte_eth_dev *dev) { + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + int retries = 0; + int ret; + PMD_INIT_FUNC_TRACE(); - RTE_SET_USED(dev); + ngbe_pf_reset_hw(hw); + + ret = ngbe_dev_stop(dev); + + ngbe_dev_free_queues(dev); + + /* reprogram the RAR[0] in case user changed it. */ + ngbe_set_rar(hw, 0, hw->mac.addr, 0, true); + + /* Unlock any pending hardware semaphore */ + ngbe_swfw_lock_reset(hw); + + /* disable uio intr before callback unregister */ + rte_intr_disable(intr_handle); + + do { + ret = rte_intr_callback_unregister(intr_handle, + ngbe_dev_interrupt_handler, dev); + if (ret >= 0 || ret == -ENOENT) { + break; + } else if (ret != -EAGAIN) { + PMD_INIT_LOG(ERR, + "intr callback unregister failed: %d", + ret); + } + rte_delay_ms(100); + } while (retries++ < (10 + NGBE_LINK_UP_TIME)); + + rte_free(dev->data->mac_addrs); + dev->data->mac_addrs = NULL; + + rte_free(dev->data->hash_mac_addrs); + dev->data->hash_mac_addrs = NULL; + + return ret; +} + +/* + * Reset PF device. + */ +static int +ngbe_dev_reset(struct rte_eth_dev *dev) +{ + int ret; + + ret = eth_ngbe_dev_uninit(dev); + if (ret) + return ret; + + ret = eth_ngbe_dev_init(dev, NULL); - return -EINVAL; + return ret; } static int @@ -1101,6 +1156,8 @@ static const struct eth_dev_ops ngbe_eth_dev_ops = { .dev_infos_get = ngbe_dev_info_get, .dev_start = ngbe_dev_start, .dev_stop = ngbe_dev_stop, + .dev_close = ngbe_dev_close, + .dev_reset = ngbe_dev_reset, .link_update = ngbe_dev_link_update, .rx_queue_start = ngbe_dev_rx_queue_start, .rx_queue_stop = ngbe_dev_rx_queue_stop, diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h index d576eef5d6..3893853645 100644 --- a/drivers/net/ngbe/ngbe_ethdev.h +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -67,6 +67,8 @@ ngbe_dev_intr(struct rte_eth_dev *dev) */ void ngbe_dev_clear_queues(struct rte_eth_dev *dev); +void ngbe_dev_free_queues(struct rte_eth_dev *dev); + void ngbe_dev_rx_queue_release(void *rxq); void ngbe_dev_tx_queue_release(void *txq); diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c index 0801424245..62b1523c77 100644 --- a/drivers/net/ngbe/ngbe_rxtx.c +++ b/drivers/net/ngbe/ngbe_rxtx.c @@ -935,6 +935,26 @@ ngbe_dev_clear_queues(struct rte_eth_dev *dev) } } +void +ngbe_dev_free_queues(struct rte_eth_dev *dev) +{ + unsigned int i; + + PMD_INIT_FUNC_TRACE(); + + for (i = 0; i < dev->data->nb_rx_queues; i++) { + ngbe_dev_rx_queue_release(dev->data->rx_queues[i]); + dev->data->rx_queues[i] = NULL; + } + dev->data->nb_rx_queues = 0; + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + ngbe_dev_tx_queue_release(dev->data->tx_queues[i]); + dev->data->tx_queues[i] = NULL; + } + dev->data->nb_tx_queues = 0; +} + static int __rte_cold ngbe_alloc_rx_queue_mbufs(struct ngbe_rx_queue *rxq) {