DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/3] introduces the ENETC PMD
@ 2018-09-06  5:54 Gagandeep Singh
  2018-09-06  5:54 ` [dpdk-dev] [PATCH 1/3] doc: add usage doc for " Gagandeep Singh
                   ` (3 more replies)
  0 siblings, 4 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-06  5:54 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

This patch set introduces the PMD which integrates
with the existing PCI bus. Document is also part
of the set

Gagandeep Singh (3):
  doc: add usage doc for ENETC PMD
  net/enetc: add ENETC PMD with basic operations
  net/enetc: enable Rx and Tx

 MAINTAINERS                                 |   7 +
 config/common_base                          |   5 +
 config/common_linuxapp                      |   5 +
 doc/guides/nics/enetc.rst                   | 165 ++++++++
 doc/guides/nics/features/enetc.ini          |  10 +
 doc/guides/nics/index.rst                   |   1 +
 drivers/net/Makefile                        |   1 +
 drivers/net/enetc/Makefile                  |  25 ++
 drivers/net/enetc/base/enetc_hw.h           | 220 ++++++++++
 drivers/net/enetc/enetc.h                   | 111 +++++
 drivers/net/enetc/enetc_ethdev.c            | 271 ++++++++++++
 drivers/net/enetc/enetc_logs.h              |  40 ++
 drivers/net/enetc/enetc_rxtx.c              | 447 ++++++++++++++++++++
 drivers/net/enetc/meson.build               |  11 +
 drivers/net/enetc/rte_pmd_enetc_version.map |   4 +
 drivers/net/meson.build                     |   1 +
 mk/rte.app.mk                               |   1 +
 17 files changed, 1325 insertions(+)
 create mode 100644 doc/guides/nics/enetc.rst
 create mode 100644 doc/guides/nics/features/enetc.ini
 create mode 100644 drivers/net/enetc/Makefile
 create mode 100644 drivers/net/enetc/base/enetc_hw.h
 create mode 100644 drivers/net/enetc/enetc.h
 create mode 100644 drivers/net/enetc/enetc_ethdev.c
 create mode 100644 drivers/net/enetc/enetc_logs.h
 create mode 100644 drivers/net/enetc/enetc_rxtx.c
 create mode 100644 drivers/net/enetc/meson.build
 create mode 100644 drivers/net/enetc/rte_pmd_enetc_version.map

-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH 1/3] doc: add usage doc for ENETC PMD
  2018-09-06  5:54 [dpdk-dev] [PATCH 0/3] introduces the ENETC PMD Gagandeep Singh
@ 2018-09-06  5:54 ` Gagandeep Singh
  2018-09-06  5:54 ` [dpdk-dev] [PATCH 2/3] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-06  5:54 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

Add enetc usage document to compile and run the
DPDK application on enetc supported platform.
This document introduces the enetc driver, supported
platforms and supported features.

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 MAINTAINERS                        |   5 +
 doc/guides/nics/enetc.rst          | 164 +++++++++++++++++++++++++++++
 doc/guides/nics/features/enetc.ini |   8 ++
 doc/guides/nics/index.rst          |   1 +
 4 files changed, 178 insertions(+)
 create mode 100644 doc/guides/nics/enetc.rst
 create mode 100644 doc/guides/nics/features/enetc.ini

diff --git a/MAINTAINERS b/MAINTAINERS
index 9fd258fad..eaf75b7bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -627,6 +627,11 @@ F: drivers/net/nfp/
 F: doc/guides/nics/nfp.rst
 F: doc/guides/nics/features/nfp*.ini
 
+NXP enetc
+M: Gagandeep Singh <g.singh@nxp.com>
+F: doc/guides/nics/enetc.rst
+F: doc/guides/nics/features/enetc.ini
+
 NXP dpaa
 M: Hemant Agrawal <hemant.agrawal@nxp.com>
 M: Shreyansh Jain <shreyansh.jain@nxp.com>
diff --git a/doc/guides/nics/enetc.rst b/doc/guides/nics/enetc.rst
new file mode 100644
index 000000000..067cd474b
--- /dev/null
+++ b/doc/guides/nics/enetc.rst
@@ -0,0 +1,164 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+   Copyright 2018 NXP
+
+ENETC Poll Mode Driver
+======================
+
+The ENETC NIC PMD (**librte_pmd_enetc**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP LS1028** SoC.
+
+More information can be found at `NXP Official Website
+<https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/qoriq-layerscape-arm-processors/qoriq-layerscape-1028a-industrial-applications-processor:LS1028A>`_.
+
+ENETC
+-----
+
+This section provides an overview of the NXP ENETC
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- ENETC overview
+- ENETC features
+- PCI bus driver
+- NIC driver
+- Supported ENETC SoCs
+- Prerequisites
+- Driver compilation and testing
+
+ENETC Overview
+~~~~~~~~~~~~~~
+
+Reference: `NXP ENETC OVERVIEW <https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/qoriq-layerscape-arm-processors/qoriq-layerscape-1028a-industrial-applications-processor:LS1028A>`_.
+
+ENETC is a PCI Integrated End Point(IEP). IEP implements
+peripheral devices in an SoC such that software sees them as PCIe device.
+ENETC is an evolution of BDR(Buffer Descriptor Ring) based networking
+IPs, introducing several changes intended to bring NXP IP up to date
+with developments in the industry and support new areas like virtualization.
+A major development is the use of a PCI bus for presentation of the IP
+to software, which has implications to the software architecture.
+
+This infrastructure simplifies adding support for IEP and facilitates in following:
+
+- Device discovery and location
+- Resource requirement discovery and allocation (e.g. interrupt assignment,
+  device register address)
+- Event reporting
+
+ENETC Features
+~~~~~~~~~~~~~~
+
+
+NIC Driver (PMD)
+~~~~~~~~~~~~~~~~
+
+ENETC PMD is traditional DPDK PMD which provides necessary interface between
+RTE framework and ENETC internal drivers.
+
+- Driver registers the device vendor table in PCI subsystem.
+- RTE framework scans the PCI bus for connected devices.
+- This scanning will invoke the probe function of ENETC driver.
+- The probe function will set the basic device registers and also setups BD rings.
+- On packet Rx the respective BD Ring status bit is set which is then used for
+  packet processing.
+- Then Tx is done first followed by Rx.
+
+Supported ENETC SoCs
+~~~~~~~~~~~~~~~~~~~~
+
+- LS1028
+
+Prerequisites
+~~~~~~~~~~~~~
+
+There are three main pre-requisities for executing ENETC PMD on a ENETC
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/6.4-2017.08/aarch64-linux-gnu/>`_.
+
+2. **Linux Kernel**
+
+   It can be obtained from `NXP's Github hosting <https://github.com/qoriq-open-source/linux>`_.
+
+3. **Rootfile system**
+
+   Any *aarch64* supporting filesystem can be used. For example,
+   Ubuntu 15.10 (Wily) or 16.04 LTS (Xenial) userland which can be obtained
+   from `here <http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.1-base-arm64.tar.gz>`_.
+
+The following dependencies are not part of DPDK and must be installed
+separately:
+
+- **NXP Linux LSDK**
+
+  NXP Layerscape software development kit (LSDK) includes support for family
+  of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+  and corresponding boards.
+
+  It includes the Linux board support packages (BSPs) for NXP SoCs,
+  a fully operational tool chain, kernel and board specific modules.
+
+  LSDK and related information can be obtained from:  `LSDK <https://www.nxp.com/support/developer-resources/run-time-software/linux-software-and-development-tools/layerscape-software-development-kit:LAYERSCAPE-SDK>`_
+
+Driver compilation and testing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#. Please refer the document :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
+   to compile the driver. Please use target "arm64-armv8a-linuxapp-gcc" and disable the below config flags
+   while compilation:
+
+   - ``CONFIG_RTE_EAL_IGB_UIO=n``
+   - ``CONFIG_RTE_KNI_KMOD=n``
+   - ``CONFIG_RTE_LIBRTE_VHOST_NUMA=n``
+   - ``CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n``
+
+   Refer to the document :ref:`cross build dpdk for arm63 <configure_and_cross_compile_dpdk_build>` to
+   disable flags and for cross compilation
+
+#. To compile in performance mode, please also set ``CONFIG_RTE_CACHE_LINE_SIZE=64``
+
+#. Running l2fwd:
+
+   Follow instructions available in the document
+   :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
+   to run l2fwd.
+
+   - First unbind the ports from kernel
+
+     - echo vfio-pci > /sys/bus/pci/devices/0000\:00\:00.1/driver_override
+     - echo 0000:00:00.1 > /sys/bus/pci/drivers/fsl_enetc/unbind
+     - echo vfio-pci > /sys/bus/pci/devices/0000\:00\:00.0/driver_override
+     - echo 0000:00:00.0 > /sys/bus/pci/drivers/fsl_enetc/unbind
+   - Then bind them to VFIO, so that DPDK application can use them
+
+     - echo 0000:00:00.1 > /sys/bus/pci/drivers/vfio-pci/bind
+     - echo 0000:00:00.0 > /sys/bus/pci/drivers/vfio-pci/bind
+   - Mount Hugepages
+
+     - mkdir /mnt/hugepages
+     - mount -t hugetlbfs none /mnt/hugepages
+   - Run l2fwd application
+
+Example output:
+
+   .. code-block:: console
+
+      ./l2fwd -c 0x3 -n 1  --log-level=8 -- -p 0x3 -q 1 -T 0
+
+      .....
+      EAL: Registered [pci] bus.
+      EAL: Detected 2 lcore(s)
+      .....
+      EAL: Bus scan completed
+      .....
+      Configuring Port 0 (socket 0)
+      Port 0: 00:00:00:00:00:01
+      Configuring Port 1 (socket 0)
+      Port 1: 00:00:00:00:00:02
+      .....
+      Checking link statuses...
+      Port 0 Link Up - speed 0 Mbps - full-duplex
+      Port 1 Link Up - speed 0 Mbps - full-duplex
diff --git a/doc/guides/nics/features/enetc.ini b/doc/guides/nics/features/enetc.ini
new file mode 100644
index 000000000..fb1bf5989
--- /dev/null
+++ b/doc/guides/nics/features/enetc.ini
@@ -0,0 +1,8 @@
+;
+; Supported features of the 'enetc' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+ARMv8                = Y
+Usage doc            = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 59f6063dc..0323035d3 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -21,6 +21,7 @@ Network Interface Controller Drivers
     dpaa2
     e1000em
     ena
+    enetc
     enic
     fm10k
     i40e
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH 2/3] net/enetc: add ENETC PMD with basic operations
  2018-09-06  5:54 [dpdk-dev] [PATCH 0/3] introduces the ENETC PMD Gagandeep Singh
  2018-09-06  5:54 ` [dpdk-dev] [PATCH 1/3] doc: add usage doc for " Gagandeep Singh
@ 2018-09-06  5:54 ` Gagandeep Singh
  2018-09-19 12:15   ` Shreyansh Jain
  2018-09-06  5:54 ` [dpdk-dev] [PATCH 3/3] net/enetc: enable Rx and Tx Gagandeep Singh
  2018-09-13  9:41 ` [dpdk-dev] [PATCH v2 0/3] introduces the enetc PMD driver Gagandeep Singh
  3 siblings, 1 reply; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-06  5:54 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

This patch introduces the enetc PMD with basic
initialisation functions includes probe, teardown,
hardware intialisation

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 MAINTAINERS                                 |   1 +
 config/common_base                          |   5 +
 config/common_linuxapp                      |   5 +
 doc/guides/nics/enetc.rst                   |   1 +
 doc/guides/nics/features/enetc.ini          |   2 +
 drivers/net/Makefile                        |   1 +
 drivers/net/enetc/Makefile                  |  24 ++
 drivers/net/enetc/base/enetc_hw.h           | 220 ++++++++++++++++
 drivers/net/enetc/enetc.h                   | 111 ++++++++
 drivers/net/enetc/enetc_ethdev.c            | 269 ++++++++++++++++++++
 drivers/net/enetc/enetc_logs.h              |  40 +++
 drivers/net/enetc/meson.build               |  10 +
 drivers/net/enetc/rte_pmd_enetc_version.map |   4 +
 drivers/net/meson.build                     |   1 +
 mk/rte.app.mk                               |   1 +
 15 files changed, 695 insertions(+)
 create mode 100644 drivers/net/enetc/Makefile
 create mode 100644 drivers/net/enetc/base/enetc_hw.h
 create mode 100644 drivers/net/enetc/enetc.h
 create mode 100644 drivers/net/enetc/enetc_ethdev.c
 create mode 100644 drivers/net/enetc/enetc_logs.h
 create mode 100644 drivers/net/enetc/meson.build
 create mode 100644 drivers/net/enetc/rte_pmd_enetc_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index eaf75b7bf..fac43bd2a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -629,6 +629,7 @@ F: doc/guides/nics/features/nfp*.ini
 
 NXP enetc
 M: Gagandeep Singh <g.singh@nxp.com>
+F: drivers/net/enetc/
 F: doc/guides/nics/enetc.rst
 F: doc/guides/nics/features/enetc.ini
 
diff --git a/config/common_base b/config/common_base
index 4bcbaf923..474b1da4c 100644
--- a/config/common_base
+++ b/config/common_base
@@ -910,3 +910,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile NXP ENETC PMD Driver
+#
+CONFIG_RTE_LIBRTE_ENETC_PMD=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 9c5ea9d89..485e1467d 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -44,3 +44,8 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y
+
+#
+# NXP ENETC PMD Driver
+#
+CONFIG_RTE_LIBRTE_ENETC_PMD=y
diff --git a/doc/guides/nics/enetc.rst b/doc/guides/nics/enetc.rst
index 067cd474b..688a2fa71 100644
--- a/doc/guides/nics/enetc.rst
+++ b/doc/guides/nics/enetc.rst
@@ -49,6 +49,7 @@ This infrastructure simplifies adding support for IEP and facilitates in followi
 ENETC Features
 ~~~~~~~~~~~~~~
 
+- Link Status
 
 NIC Driver (PMD)
 ~~~~~~~~~~~~~~~~
diff --git a/doc/guides/nics/features/enetc.ini b/doc/guides/nics/features/enetc.ini
index fb1bf5989..83b20845a 100644
--- a/doc/guides/nics/features/enetc.ini
+++ b/doc/guides/nics/features/enetc.ini
@@ -4,5 +4,7 @@
 ; Refer to default.ini for the full list of available PMD features.
 ;
 [Features]
+Link status          = Y
+Linux VFIO           = Y
 ARMv8                = Y
 Usage doc            = Y
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 664398de9..3ad436045 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -24,6 +24,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
 endif
 DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += e1000
 DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
+DIRS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc
 DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe
 DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k
diff --git a/drivers/net/enetc/Makefile b/drivers/net/enetc/Makefile
new file mode 100644
index 000000000..3f4ba97da
--- /dev/null
+++ b/drivers/net/enetc/Makefile
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_enetc.a
+
+CFLAGS += -O3
+EXPORT_MAP := rte_pmd_enetc_version.map
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_ethdev.c
+
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_ethdev
+LDLIBS += -lrte_bus_pci
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h
new file mode 100644
index 000000000..806b26a2c
--- /dev/null
+++ b/drivers/net/enetc/base/enetc_hw.h
@@ -0,0 +1,220 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _ENETC_HW_H_
+#define _ENETC_HW_H_
+#include <rte_io.h>
+
+#define BIT(x)		((uint64_t)1 << ((x)))
+
+/* ENETC device IDs */
+#define ENETC_DEV_ID_VF		0xef00
+#define ENETC_DEV_ID		0xe100
+
+/* ENETC register block BAR */
+#define ENETC_BAR_REGS			0x0
+
+/* SI regs, offset: 0h */
+#define ENETC_SIMR			0x0
+#define ENETC_SIMR_EN			BIT(31)
+
+#define ENETC_SIPMAR0			0x80
+#define ENETC_SIPMAR1			0x84
+
+#define ENETC_SICAPR0			0x900
+#define ENETC_SICAPR1			0x904
+
+#define ENETC_SIMSITRV(n)		(0xB00 + (n) * 0x4)
+#define ENETC_SIMSIRRV(n)		(0xB80 + (n) * 0x4)
+
+#define ENETC_SICCAPR			0x1200
+
+/* enum for BD type */
+enum enetc_bdr_type {TX, RX};
+
+#define ENETC_BDR(type, n, off)		(0x8000 + (type) * 0x100 + (n) * 0x200 \
+							+ (off))
+/* RX BDR reg offsets */
+#define ENETC_RBMR		0x0 /* RX BDR mode register*/
+#define ENETC_RBMR_EN		BIT(31)
+
+#define ENETC_RBSR		0x4  /* Rx BDR status register*/
+#define ENETC_RBBSR		0x8  /* Rx BDR buffer size register*/
+#define ENETC_RBCIR		0xc  /* Rx BDR consumer index register*/
+#define ENETC_RBBAR0		0x10 /* Rx BDR base address register 0 */
+#define ENETC_RBBAR1		0x14 /* Rx BDR base address register 1*/
+#define ENETC_RBPIR		0x18 /* Rx BDR producer index register*/
+#define ENETC_RBLENR		0x20 /* Rx BDR length register*/
+#define ENETC_RBIER		0xa0 /* Rx BDR interrupt enable register*/
+#define ENETC_RBIER_RXTIE	BIT(0)
+#define ENETC_RBIDR		0xa4 /* Rx BDR interrupt detect register*/
+#define ENETC_RBICIR0		0xa8 /* Rx BDR inetrrupt coalescing register 0*/
+#define ENETC_RBICIR0_ICEN	BIT(31)
+
+
+#define ENETC_TBMR	0x0  /* Tx BDR mode register (TBMR) 32 RW */
+#define ENETC_TBSR	0x4  /* x BDR status register (TBSR) 32 RO */
+#define ENETC_TBBAR0	0x10 /* Tx BDR base address register 0 (TBBAR0) 32 RW */
+#define ENETC_TBBAR1	0x14 /* Tx BDR base address register 1 (TBBAR1) 32 RW */
+#define ENETC_TBCIR	0x18 /* Tx BDR consumer index register (TBCIR) 32 RW */
+#define ENETC_TBCISR	0x1C /* Tx BDR consumer index shadow register 32 RW */
+#define ENETC_TBIER	0xA0 /* Tx BDR interrupt enable register 32 RW */
+#define ENETC_TBIDR	0xA4 /* Tx BDR interrupt detect register 32 RO */
+#define ENETC_TBICR0	0xA8 /* Tx BDR interrupt coalescing register 0 32 RW */
+#define ENETC_TBICR1	0xAC /* Tx BDR interrupt coalescing register 1 32 RW */
+#define ENETC_TBLENR	0x20
+
+#define ENETC_TBCISR_IDX_MASK		0xffff
+#define ENETC_TBIER_TXFIE		BIT(1)
+
+#define ENETC_RTBLENR_LEN(n)		((n) & ~0x7)
+#define ENETC_TBMR_EN			BIT(31)
+
+/* Port regs, offset: 1_0000h */
+#define ENETC_PORT_BASE			0x10000
+#define ENETC_PMR			0x00000
+#define ENETC_PMR_EN			(BIT(16) | BIT(17) | BIT(18))
+#define ENETC_PSR			0x00004 /* RO */
+#define ENETC_PSIPMR			0x00018
+#define ENETC_PSIPMR_SET_UP(n)		(0x1 << (n)) /* n = SI index */
+#define ENETC_PSIPMR_SET_MP(n)		(0x1 << ((n) + 8))
+#define ENETC_PSIPMR_SET_VLAN_MP(n)	(0x1 << ((n) + 16))
+#define ENETC_PSIPMAR0(n)		(0x00100 + (n) * 0x20)
+#define ENETC_PSIPMAR1(n)		(0x00104 + (n) * 0x20)
+#define ENETC_PCAPR0			0x00900
+#define ENETC_PCAPR1			0x00904
+
+#define ENETC_PV0CFGR(n)		(0x00920 + (n) * 0x10)
+#define ENETC_PVCFGR_SET_TXBDR(val)	((val) & 0xff)
+#define ENETC_PVCFGR_SET_RXBDR(val)	(((val) & 0xff) << 16)
+
+#define ENETC_PM0_CMD_CFG		0x08008
+#define ENETC_PM0_TX_EN			BIT(0)
+#define ENETC_PM0_RX_EN			BIT(1)
+
+#define ENETC_PM0_MAXFRM		0x08014
+#define ENETC_SET_MAXFRM(val)		((val) << 16)
+
+/* Global regs, offset: 2_0000h */
+#define ENETC_GLOBAL_BASE		0x20000
+#define ENETC_G_EIPBRR0			0x00bf8
+#define ENETC_G_EIPBRR1			0x00bfc
+
+#define ETH_ADDR_LEN			6
+
+/* general register accessors */
+#define enetc_rd_reg(reg)	rte_read32((reg))
+#define enetc_wr_reg(reg, val)	rte_write32((val), (reg))
+#define enetc_rd(hw, off)	enetc_rd_reg((hw)->reg + (off))
+#define enetc_wr(hw, off, val)	enetc_wr_reg((hw)->reg + (off), val)
+/* port register accessors - PF only */
+#define enetc_port_rd(hw, off)		enetc_rd_reg((hw)->port + (off))
+#define enetc_port_wr(hw, off, val)	enetc_wr_reg((hw)->port + (off), val)
+/* global register accessors - PF only */
+#define enetc_global_rd(hw, off)	enetc_rd_reg((hw)->global + (off))
+#define enetc_global_wr(hw, off, val)	enetc_wr_reg((hw)->global + (off), val)
+/* BDR register accessors, see ENETC_BDR() */
+#define enetc_bdr_rd(hw, t, n, off) \
+				enetc_rd(hw, ENETC_BDR(t, n, off))
+#define enetc_bdr_wr(hw, t, n, off, val) \
+				enetc_wr(hw, ENETC_BDR(t, n, off), val)
+
+#define enetc_txbdr_rd(hw, n, off) enetc_bdr_rd(hw, TX, n, off)
+#define enetc_rxbdr_rd(hw, n, off) enetc_bdr_rd(hw, RX, n, off)
+#define enetc_txbdr_wr(hw, n, off, val) \
+				enetc_bdr_wr(hw, TX, n, off, val)
+#define enetc_rxbdr_wr(hw, n, off, val) \
+				enetc_bdr_wr(hw, RX, n, off, val)
+
+#define ENETC_TX_ADDR(txq, addr) ((void *)(txq->enetc_txbdr + addr))
+
+#define ENETC_TXBD_FLAGS_IE		BIT(13)
+#define ENETC_TXBD_FLAGS_F		BIT(15)
+
+/* ENETC Parsed values (Little Endian) */
+#define ENETC_PKT_TYPE_ETHER            0x0060
+#define ENETC_PKT_TYPE_IPV4             0x0000
+#define ENETC_PKT_TYPE_IPV6             0x0020
+#define ENETC_PKT_TYPE_IPV4_TCP \
+			(0x0010 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_TCP \
+			(0x0010 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_PKT_TYPE_IPV4_UDP \
+			(0x0011 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_UDP \
+			(0x0011 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_PKT_TYPE_IPV4_SCTP \
+			(0x0013 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_SCTP \
+			(0x0013 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_PKT_TYPE_IPV4_ICMP \
+			(0x0003 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_ICMP \
+			(0x0003 | ENETC_PKT_TYPE_IPV6)
+
+/* PCI device info */
+struct enetc_hw {
+	/* SI registers, used by all PCI functions */
+	void *reg;
+	/* Port registers, PF only */
+	void *port;
+	/* IP global registers, PF only */
+	void *global;
+};
+
+struct enetc_eth_mac_info {
+	uint8_t addr[ETH_ADDR_LEN];
+	uint8_t perm_addr[ETH_ADDR_LEN];
+	bool get_link_status;
+};
+
+struct enetc_eth_hw {
+	struct net_device *ndev;
+	struct enetc_hw hw;
+	uint16_t device_id;
+	uint16_t vendor_id;
+	uint8_t revision_id;
+	struct enetc_eth_mac_info mac;
+};
+
+/* Transmit Descriptor */
+struct enetc_tx_desc {
+	uint64_t addr;
+	uint16_t frm_len;
+	uint16_t buf_len;
+	uint32_t flags_errors;
+};
+
+/* TX Buffer Descriptors (BD) */
+struct enetc_tx_bd {
+	uint64_t addr;
+	uint16_t buf_len;
+	uint16_t frm_len;
+	uint16_t err_csum;
+	uint16_t flags;
+};
+
+/* RX buffer descriptor */
+union enetc_rx_bd {
+	struct {
+		uint64_t addr;
+		uint8_t reserved[8];
+	} w;
+	struct {
+		uint16_t inet_csum;
+		uint16_t parse_summary;
+		uint32_t rss_hash;
+		uint16_t buf_len;
+		uint16_t vlan_opt;
+		union {
+			struct {
+				uint16_t flags;
+				uint16_t error;
+			};
+			uint32_t lstatus;
+		};
+	} r;
+};
+
+#endif
diff --git a/drivers/net/enetc/enetc.h b/drivers/net/enetc/enetc.h
new file mode 100644
index 000000000..2dc9f042a
--- /dev/null
+++ b/drivers/net/enetc/enetc.h
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _ENETC_H_
+#define _ENETC_H_
+
+#include <rte_time.h>
+
+#include "base/enetc_hw.h"
+
+#define PCI_VENDOR_ID_FREESCALE 0x1957
+
+/* Max TX rings per ENETC. */
+#define MAX_TX_RINGS	2
+
+/* Max RX rings per ENTEC. */
+#define MAX_RX_RINGS	1
+
+/* Max BD counts per Ring. */
+#define MAX_BD_COUNT	256
+
+/*
+ * upper_32_bits - return bits 32-63 of a number
+ * @n: the number we're accessing
+ *
+ * A basic shift-right of a 64- or 32-bit quantity.  Use this to suppress
+ * the "right shift count >= width of type" warning when that quantity is
+ * 32-bits.
+ */
+#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
+
+/*
+ * lower_32_bits - return bits 0-31 of a number
+ * @n: the number we're accessing
+ */
+#define lower_32_bits(n) ((uint32_t)(n))
+
+#define ENETC_TXBD(BDR, i) (&(((struct enetc_tx_bd *)((BDR).bd_base))[i]))
+#define ENETC_RXBD(BDR, i) (&(((union enetc_rx_bd *)((BDR).bd_base))[i]))
+
+struct enetc_swbd {
+	struct rte_mbuf *buffer_addr;
+};
+
+struct enetc_bdr {
+	struct net_device *ndev;
+	struct rte_mempool *mb_pool;   /* mbuf pool to populate RX ring. */
+	void *bd_base;			/* points to Rx or Tx BD ring */
+	union {
+		void *tcir;
+		void *rcir;
+	};
+	uint16_t index;
+	int bd_count; /* # of BDs */
+	int next_to_use;
+	int next_to_clean;
+	struct enetc_swbd *q_swbd;
+	union {
+		void *tcisr; /* Tx */
+		int next_to_alloc; /* Rx */
+	};
+};
+
+/*
+ * Structure to store private data for each driver instance (for each port).
+ */
+struct enetc_eth_adapter {
+	struct net_device *ndev;
+	struct enetc_eth_hw hw;
+	uint16_t num_rx_rings, num_tx_rings;
+	uint16_t rx_bd_count, tx_bd_count;
+	struct enetc_bdr *tx_ring[MAX_TX_RINGS];
+	struct enetc_bdr *rx_ring[MAX_RX_RINGS];
+};
+
+#define ENETC_DEV_PRIVATE(adapter) \
+	((struct enetc_eth_adapter *)adapter)
+
+#define ENETC_DEV_PRIVATE_TO_HW(adapter) \
+	(&((struct enetc_eth_adapter *)adapter)->hw)
+
+#define ENETC_DEV_PRIVATE_TO_STATS(adapter) \
+	(&((struct enetc_eth_adapter *)adapter)->stats)
+
+#define ENETC_DEV_PRIVATE_TO_INTR(adapter) \
+	(&((struct enetc_eth_adapter *)adapter)->intr)
+
+#define ENETC_GET_HW_ADDR(reg, addr) ((void *)(reg + addr))
+#define ENETC_REG_READ(addr) (*(uint32_t *)addr)
+#define ENETC_REG_WRITE(addr, val) (*(uint32_t *)addr = val)
+#define ENETC_REG_WRITE_RELAXED(addr, val) (*(uint32_t *)addr = val)
+
+/*
+ * RX/TX ENETC function prototypes
+ */
+int enetc_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 enetc_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 enetc_xmit_pkts(void *txq, struct rte_mbuf **tx_pkts,
+		uint16_t nb_pkts);
+uint16_t enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts);
+
+#endif /* _ENETC_H_ */
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
new file mode 100644
index 000000000..06438835d
--- /dev/null
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -0,0 +1,269 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <stdbool.h>
+#include <rte_ethdev_pci.h>
+
+#include "enetc_logs.h"
+#include "enetc.h"
+
+int enetc_logtype_pmd;
+
+/* Functions Prototypes */
+static int enetc_dev_configure(struct rte_eth_dev *dev);
+static int enetc_dev_start(struct rte_eth_dev *dev);
+static void enetc_dev_stop(struct rte_eth_dev *dev);
+static void enetc_dev_close(struct rte_eth_dev *dev);
+static void enetc_dev_infos_get(struct rte_eth_dev *dev,
+			struct rte_eth_dev_info *dev_info);
+static int enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete);
+static int enetc_hardware_init(struct enetc_eth_hw *hw);
+
+/*
+ * The set of PCI devices this driver supports
+ */
+static const struct rte_pci_id pci_id_enetc_map[] = {
+	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID) },
+	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_VF) },
+	{ .vendor_id = 0, /* sentinel */ },
+};
+
+/* Features supported by this driver */
+static const struct eth_dev_ops enetc_ops = {
+	.dev_configure        = enetc_dev_configure,
+	.dev_start            = enetc_dev_start,
+	.dev_stop             = enetc_dev_stop,
+	.dev_close            = enetc_dev_close,
+	.link_update          = enetc_link_update,
+	.dev_infos_get        = enetc_dev_infos_get,
+};
+
+/**
+ * Initialisation of the enetc device
+ *
+ * @param eth_dev
+ *   - Pointer to the structure rte_eth_dev
+ *
+ * @return
+ *   - On success, zero.
+ *   - On failure, negative value.
+ */
+static int
+enetc_dev_init(struct rte_eth_dev *eth_dev)
+{
+	int error = 0, i;
+	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	struct enetc_eth_hw *hw =
+		ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+	struct enetc_eth_adapter *adapter =
+		ENETC_DEV_PRIVATE(eth_dev->data->dev_private);
+
+	PMD_INIT_FUNC_TRACE();
+	eth_dev->dev_ops = &enetc_ops;
+	eth_dev->rx_pkt_burst = NULL;
+	eth_dev->tx_pkt_burst = NULL;
+
+	rte_eth_copy_pci_info(eth_dev, pci_dev);
+
+	/* Retrieving and storing the HW base address of device */
+	hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
+
+	adapter->tx_bd_count = MAX_BD_COUNT;
+	adapter->rx_bd_count = MAX_BD_COUNT;
+
+	adapter->num_rx_rings = MAX_RX_RINGS;
+	adapter->num_tx_rings = MAX_TX_RINGS;
+
+	for (i = 0; i < adapter->num_rx_rings; i++) {
+		adapter->rx_ring[i] = rte_zmalloc(NULL,
+						sizeof(struct enetc_bdr), 0);
+		if (!adapter->rx_ring[i]) {
+			ENETC_PMD_ERR("Failed to allocate RX ring memory");
+			while (--i >= 0)
+				rte_free(adapter->rx_ring[i]);
+			error = -ENOMEM;
+			goto err_late;
+		}
+		adapter->rx_ring[i]->bd_count = adapter->rx_bd_count;
+	}
+
+	for (i = 0; i < adapter->num_tx_rings; i++) {
+		adapter->tx_ring[i] = rte_zmalloc(NULL,
+						sizeof(struct enetc_bdr), 0);
+		if (!adapter->tx_ring[i]) {
+			ENETC_PMD_ERR("Failed to allocate TX ring memory");
+			while (--i >= 0)
+				rte_free(adapter->tx_ring[i]);
+			error = -ENOMEM;
+			goto err_second;
+		}
+		adapter->tx_ring[i]->bd_count = adapter->tx_bd_count;
+	}
+
+	error = enetc_hardware_init(hw);
+	if (error != 0) {
+		ENETC_PMD_ERR("Hardware initialization failed");
+		goto err_first;
+	}
+
+	/* Allocate memory for storing MAC addresses */
+	eth_dev->data->mac_addrs = rte_zmalloc("enetc_eth",
+		ETHER_ADDR_LEN, 0);
+	if (!eth_dev->data->mac_addrs) {
+		ENETC_PMD_ERR("Failed to allocate %d bytes needed to "
+						"store MAC addresses",
+				ETHER_ADDR_LEN * 1);
+		error = -ENOMEM;
+		goto err_first;
+	}
+
+	/* Copy the permanent MAC address */
+	ether_addr_copy((struct ether_addr *)hw->mac.addr,
+						&eth_dev->data->mac_addrs[0]);
+
+	ENETC_PMD_DEBUG("port_id %d vendorID=0x%x deviceID=0x%x",
+			eth_dev->data->port_id, pci_dev->id.vendor_id,
+			pci_dev->id.device_id);
+	return 0;
+
+err_first:
+	for (i = 0; i < adapter->num_tx_rings; i++)
+		rte_free(adapter->tx_ring[i]);
+err_second:
+	for (i = 0; i < adapter->num_rx_rings; i++)
+		rte_free(adapter->rx_ring[i]);
+err_late:
+	return error;
+}
+
+static int
+enetc_dev_uninit(struct rte_eth_dev *eth_dev)
+{
+	return 0;
+}
+
+static int
+enetc_dev_configure(struct rte_eth_dev *dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	return 0;
+}
+
+static int
+enetc_dev_start(struct rte_eth_dev *dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	return 0;
+}
+
+static void
+enetc_dev_stop(struct rte_eth_dev *dev)
+{
+}
+
+static void
+enetc_dev_close(struct rte_eth_dev *dev)
+{
+}
+
+/* return 0 means link status changed, -1 means not changed */
+static int
+enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+	struct enetc_eth_hw *hw =
+		ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_eth_link link;
+
+	hw->mac.get_link_status = 1;
+
+	memset(&link, 0, sizeof(link));
+	rte_eth_linkstatus_get(dev, &link);
+
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
+	link.link_status = ETH_LINK_UP;
+	rte_eth_linkstatus_set(dev, &link);
+
+	return 0;
+}
+
+static int
+enetc_hardware_init(struct enetc_eth_hw *hw)
+{
+	uint32_t psipmr = 0;
+
+	/* Calculating and storing the base HW addresses */
+	hw->hw.port = hw->hw.reg + ENETC_PORT_BASE;
+	hw->hw.global = hw->hw.reg + ENETC_GLOBAL_BASE;
+
+	/* Enabling Station Interface */
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.reg, ENETC_SIMR),
+								ENETC_SIMR_EN);
+
+	/* Setting to accept broadcast packets for each inetrface */
+	psipmr |= ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0) |
+						ENETC_PSIPMR_SET_VLAN_MP(0);
+	psipmr |= ENETC_PSIPMR_SET_UP(1) | ENETC_PSIPMR_SET_MP(1) |
+						ENETC_PSIPMR_SET_VLAN_MP(1);
+	psipmr |= ENETC_PSIPMR_SET_UP(2) | ENETC_PSIPMR_SET_MP(2) |
+						ENETC_PSIPMR_SET_VLAN_MP(2);
+
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMR),
+			psipmr);
+
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PM0_CMD_CFG),
+			ENETC_PM0_TX_EN | ENETC_PM0_RX_EN);
+
+	/* Enable port */
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR),
+							ENETC_PMR_EN);
+
+	/* Enabling broadcast address */
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMAR0(0)),
+								0xFFFFFFFF);
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMAR1(0)),
+								0xFFFF << 16);
+
+	return 0;
+}
+
+static void
+enetc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
+{
+	struct enetc_eth_adapter *adapter =
+		ENETC_DEV_PRIVATE(dev->data->dev_private);
+
+	dev_info->max_rx_queues = adapter->num_rx_rings;
+	dev_info->max_tx_queues = adapter->num_tx_rings;
+	dev_info->max_rx_pktlen = 1500;
+}
+
+static int enetc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+	struct rte_pci_device *pci_dev)
+{
+	return rte_eth_dev_pci_generic_probe(pci_dev,
+		sizeof(struct enetc_eth_adapter), enetc_dev_init);
+}
+
+static int enetc_pci_remove(struct rte_pci_device *pci_dev)
+{
+	return rte_eth_dev_pci_generic_remove(pci_dev, enetc_dev_uninit);
+}
+
+static struct rte_pci_driver rte_enetc_pmd = {
+	.id_table = pci_id_enetc_map,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
+	.probe = enetc_pci_probe,
+	.remove = enetc_pci_remove,
+};
+
+RTE_PMD_REGISTER_PCI(net_enetc, rte_enetc_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(net_enetc, pci_id_enetc_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_enetc, "* vfio-pci");
+
+RTE_INIT(enetc_pmd_init_log)
+{
+	enetc_logtype_pmd = rte_log_register("pmd.net.enetc");
+	if (enetc_logtype_pmd >= 0)
+		rte_log_set_level(enetc_logtype_pmd, RTE_LOG_NOTICE);
+}
diff --git a/drivers/net/enetc/enetc_logs.h b/drivers/net/enetc/enetc_logs.h
new file mode 100644
index 000000000..c8a6c0cf3
--- /dev/null
+++ b/drivers/net/enetc/enetc_logs.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _ENETC_LOGS_H_
+#define _ENETC_LOGS_H_
+
+extern int enetc_logtype_pmd;
+
+#define ENETC_PMD_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, enetc_logtype_pmd, "enetc_net: " \
+		fmt "\n", ##args)
+
+#define ENETC_PMD_DEBUG(fmt, args...) \
+	rte_log(RTE_LOG_DEBUG, enetc_logtype_pmd, "enetc_net: %s(): "\
+		fmt "\n", __func__, ##args)
+
+#define PMD_INIT_FUNC_TRACE() ENETC_PMD_DEBUG(">>")
+
+#define ENETC_PMD_CRIT(fmt, args...) \
+	ENETC_PMD_LOG(CRIT, fmt, ## args)
+#define ENETC_PMD_INFO(fmt, args...) \
+	ENETC_PMD_LOG(INFO, fmt, ## args)
+#define ENETC_PMD_ERR(fmt, args...) \
+	ENETC_PMD_LOG(ERR, fmt, ## args)
+#define ENETC_PMD_WARN(fmt, args...) \
+	ENETC_PMD_LOG(WARNING, fmt, ## args)
+
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define ENETC_PMD_DP_LOG(level, fmt, args...) \
+	RTE_LOG_DP(level, PMD, fmt, ## args)
+
+#define ENETC_PMD_DP_DEBUG(fmt, args...) \
+	ENETC_PMD_DP_LOG(DEBUG, fmt, ## args)
+#define ENETC_PMD_DP_INFO(fmt, args...) \
+	ENETC_PMD_DP_LOG(INFO, fmt, ## args)
+#define ENETC_PMD_DP_WARN(fmt, args...) \
+	ENETC_PMD_DP_LOG(WARNING, fmt, ## args)
+
+#endif /* _ENETC_LOGS_H_*/
diff --git a/drivers/net/enetc/meson.build b/drivers/net/enetc/meson.build
new file mode 100644
index 000000000..506b174ed
--- /dev/null
+++ b/drivers/net/enetc/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+if host_machine.system() != 'linux'
+	build = false
+endif
+
+sources = files('enetc_ethdev.c')
+
+includes += include_directories('base')
diff --git a/drivers/net/enetc/rte_pmd_enetc_version.map b/drivers/net/enetc/rte_pmd_enetc_version.map
new file mode 100644
index 000000000..521e51f41
--- /dev/null
+++ b/drivers/net/enetc/rte_pmd_enetc_version.map
@@ -0,0 +1,4 @@
+DPDK_18.11 {
+
+	local: *;
+};
diff --git a/drivers/net/meson.build b/drivers/net/meson.build
index 9c28ed4da..65aa6f60c 100644
--- a/drivers/net/meson.build
+++ b/drivers/net/meson.build
@@ -11,6 +11,7 @@ drivers = ['af_packet',
 	'dpaa', 'dpaa2',
 	'e1000',
 	'ena',
+	'enetc',
 	'enic',
 	'failsafe',
 	'fm10k', 'i40e',
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index de33883be..154ae3b2c 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -135,6 +135,7 @@ endif
 _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD)        += -lrte_pmd_ena
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD)       += -lrte_pmd_enic
+_LDLIBS-$(CONFIG_RTE_LIBRTE_ENETC_PMD)      += -lrte_pmd_enetc
 _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD)      += -lrte_pmd_fm10k
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE)   += -lrte_pmd_failsafe
 _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD)       += -lrte_pmd_i40e
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH 3/3] net/enetc: enable Rx and Tx
  2018-09-06  5:54 [dpdk-dev] [PATCH 0/3] introduces the ENETC PMD Gagandeep Singh
  2018-09-06  5:54 ` [dpdk-dev] [PATCH 1/3] doc: add usage doc for " Gagandeep Singh
  2018-09-06  5:54 ` [dpdk-dev] [PATCH 2/3] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
@ 2018-09-06  5:54 ` Gagandeep Singh
  2018-09-13  9:41 ` [dpdk-dev] [PATCH v2 0/3] introduces the enetc PMD driver Gagandeep Singh
  3 siblings, 0 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-06  5:54 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

Add RX and TX queue setup, datapath functions
and enable the packet parsing

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 MAINTAINERS                      |   1 +
 drivers/net/enetc/Makefile       |   3 +-
 drivers/net/enetc/enetc_ethdev.c |   6 +-
 drivers/net/enetc/enetc_rxtx.c   | 447 +++++++++++++++++++++++++++++++
 drivers/net/enetc/meson.build    |   3 +-
 5 files changed, 456 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/enetc/enetc_rxtx.c

diff --git a/MAINTAINERS b/MAINTAINERS
index fac43bd2a..353b5eebb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -629,6 +629,7 @@ F: doc/guides/nics/features/nfp*.ini
 
 NXP enetc
 M: Gagandeep Singh <g.singh@nxp.com>
+M: Pankaj Chauhan <pankaj.chauhan@nxp.com>
 F: drivers/net/enetc/
 F: doc/guides/nics/enetc.rst
 F: doc/guides/nics/features/enetc.ini
diff --git a/drivers/net/enetc/Makefile b/drivers/net/enetc/Makefile
index 3f4ba97da..1f886831a 100644
--- a/drivers/net/enetc/Makefile
+++ b/drivers/net/enetc/Makefile
@@ -16,8 +16,9 @@ LIBABIVER := 1
 # all source are stored in SRCS-y
 #
 SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_rxtx.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_eal -lrte_mempool
 LDLIBS += -lrte_ethdev
 LDLIBS += -lrte_bus_pci
 
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index 06438835d..67106593f 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -37,6 +37,8 @@ static const struct eth_dev_ops enetc_ops = {
 	.dev_close            = enetc_dev_close,
 	.link_update          = enetc_link_update,
 	.dev_infos_get        = enetc_dev_infos_get,
+	.rx_queue_setup       = enetc_rx_queue_setup,
+	.tx_queue_setup       = enetc_tx_queue_setup,
 };
 
 /**
@@ -61,8 +63,8 @@ enetc_dev_init(struct rte_eth_dev *eth_dev)
 
 	PMD_INIT_FUNC_TRACE();
 	eth_dev->dev_ops = &enetc_ops;
-	eth_dev->rx_pkt_burst = NULL;
-	eth_dev->tx_pkt_burst = NULL;
+	eth_dev->rx_pkt_burst = &enetc_recv_pkts;
+	eth_dev->tx_pkt_burst = &enetc_xmit_pkts;
 
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 
diff --git a/drivers/net/enetc/enetc_rxtx.c b/drivers/net/enetc/enetc_rxtx.c
new file mode 100644
index 000000000..b01f64b0c
--- /dev/null
+++ b/drivers/net/enetc/enetc_rxtx.c
@@ -0,0 +1,447 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "rte_ethdev.h"
+#include "rte_malloc.h"
+#include "rte_memzone.h"
+
+#include "base/enetc_hw.h"
+#include "enetc.h"
+#include "enetc_logs.h"
+
+#define ENETC_RXBD_BUNDLE 8 /* Number of BDs to update at once */
+
+static inline int enetc_bd_unused(struct enetc_bdr *bdr)
+{
+	if (bdr->next_to_clean > bdr->next_to_use)
+		return bdr->next_to_clean - bdr->next_to_use - 1;
+
+	return bdr->bd_count + bdr->next_to_clean - bdr->next_to_use - 1;
+}
+
+static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring)
+{
+	int tx_frm_cnt = 0;
+	struct enetc_swbd *tx_swbd;
+	int i;
+
+	i = tx_ring->next_to_clean;
+	tx_swbd = &tx_ring->q_swbd[i];
+	while ((int)(enetc_rd_reg(tx_ring->tcisr) & ENETC_TBCISR_IDX_MASK) != i) {
+		rte_pktmbuf_free(tx_swbd->buffer_addr);
+		tx_swbd->buffer_addr = NULL;
+		tx_swbd++;
+		i++;
+		if (unlikely(i == tx_ring->bd_count)) {
+			i = 0;
+			tx_swbd = &tx_ring->q_swbd[0];
+		}
+
+		tx_frm_cnt++;
+	}
+	tx_ring->next_to_clean = i;
+	return tx_frm_cnt++;
+}
+
+uint16_t enetc_xmit_pkts(void *tx_queue,
+			struct rte_mbuf **tx_pkts,
+				uint16_t nb_pkts)
+{
+	struct enetc_swbd *tx_swbd;
+	int i, start;
+	struct enetc_tx_bd *txbd;
+	struct enetc_bdr *tx_ring = (struct enetc_bdr *)tx_queue;
+
+	i = tx_ring->next_to_use;
+	start = 0;
+	while (nb_pkts--) {
+		enetc_clean_tx_ring(tx_ring);
+
+		tx_ring->q_swbd[i].buffer_addr = tx_pkts[start];
+
+		txbd = ENETC_TXBD(*tx_ring, i);
+		tx_swbd = &tx_ring->q_swbd[i];
+		txbd->frm_len = tx_pkts[start]->pkt_len;
+		txbd->buf_len = txbd->frm_len;
+		txbd->flags = rte_cpu_to_le_16(ENETC_TXBD_FLAGS_F);
+		txbd->addr =
+		(uint64_t)rte_cpu_to_le_64(tx_swbd->buffer_addr->buf_addr +
+				tx_swbd->buffer_addr->data_off);
+		i++;
+		start++;
+		if (unlikely(i == tx_ring->bd_count))
+			i = 0;
+	}
+	tx_ring->next_to_use = i;
+	enetc_wr_reg(tx_ring->tcir, i);
+	return start;
+}
+
+static int enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt)
+{
+	struct enetc_swbd *rx_swbd;
+	union enetc_rx_bd *rxbd;
+	int i, j;
+
+	i = rx_ring->next_to_use;
+	rx_swbd = &rx_ring->q_swbd[i];
+	rxbd = ENETC_RXBD(*rx_ring, i);
+
+	for (j = 0; j < buff_cnt; j++) {
+		rx_swbd->buffer_addr =
+			rte_cpu_to_le_64(rte_mbuf_raw_alloc(rx_ring->mb_pool));
+		rxbd->w.addr = (uint64_t)rx_swbd->buffer_addr->buf_addr +
+						rx_swbd->buffer_addr->data_off;
+		/* clear 'R" as well */
+		rxbd->r.lstatus = 0;
+		rx_swbd++;
+		rxbd++;
+		i++;
+
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			rxbd = ENETC_RXBD(*rx_ring, 0);
+			rx_swbd = &rx_ring->q_swbd[i];
+		}
+	}
+	if (likely(j)) {
+		rx_ring->next_to_alloc = i;
+		rx_ring->next_to_use = i;
+		enetc_wr_reg(rx_ring->rcir, i);
+	}
+	return j;
+}
+
+
+static inline void __attribute__((hot))
+enetc_dev_rx_parse(struct rte_mbuf *m, uint16_t parse_results)
+{
+	ENETC_PMD_DP_DEBUG("parse summary = 0x%x   ", parse_results);
+
+	m->packet_type = RTE_PTYPE_UNKNOWN;
+	switch (parse_results) {
+	case ENETC_PKT_TYPE_ETHER:
+		m->packet_type = RTE_PTYPE_L2_ETHER;
+		break;
+	case ENETC_PKT_TYPE_IPV4:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+					RTE_PTYPE_L3_IPV4;
+		break;
+	case ENETC_PKT_TYPE_IPV6:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+					RTE_PTYPE_L3_IPV6;
+		break;
+	case ENETC_PKT_TYPE_IPV4_TCP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_TCP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_UDP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_UDP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_SCTP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_SCTP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_SCTP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_SCTP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_ICMP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_ICMP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_ICMP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_ICMP;
+		break;
+	/* More switch cases can be added */
+	default:
+		m->packet_type = RTE_PTYPE_UNKNOWN;
+	}
+}
+
+static int
+enetc_clean_rx_ring(struct enetc_bdr *rx_ring, struct rte_mbuf **rx_pkts,
+								int work_limit)
+{
+	int rx_frm_cnt = 0;
+	int cleaned_cnt, i;
+	struct enetc_swbd *rx_swbd;
+
+	cleaned_cnt = enetc_bd_unused(rx_ring);
+
+	/* next descriptor to process */
+	i = rx_ring->next_to_clean;
+	rx_swbd = &rx_ring->q_swbd[i];
+
+	while (likely(rx_frm_cnt < work_limit)) {
+		union enetc_rx_bd *rxbd;
+		uint32_t bd_status;
+
+		if (cleaned_cnt >= ENETC_RXBD_BUNDLE) {
+			int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt);
+
+			cleaned_cnt -= count;
+		}
+		rxbd = ENETC_RXBD(*rx_ring, i);
+		bd_status = rte_le_to_cpu_32(rxbd->r.lstatus);
+		if (!bd_status)
+			break;
+
+		rx_swbd->buffer_addr->pkt_len = rxbd->r.buf_len;
+		rx_swbd->buffer_addr->data_len = rxbd->r.buf_len;
+		rx_swbd->buffer_addr->hash.rss = rxbd->r.rss_hash;
+		rx_swbd->buffer_addr->ol_flags = 0;
+		enetc_dev_rx_parse(rx_swbd->buffer_addr, rxbd->r.parse_summary);
+
+		rx_pkts[rx_frm_cnt] = rx_swbd->buffer_addr;
+
+		cleaned_cnt++;
+		rx_swbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			rx_swbd = &rx_ring->q_swbd[i];
+		}
+		rx_ring->next_to_clean = i;
+		rx_frm_cnt++;
+	}
+
+	return rx_frm_cnt;
+}
+
+uint16_t enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
+			uint16_t nb_pkts)
+{
+	struct enetc_bdr *rx_ring = (struct enetc_bdr *)rxq;
+
+	return enetc_clean_rx_ring(rx_ring, rx_pkts, nb_pkts);
+}
+
+static int enetc_alloc_txbdr(struct enetc_bdr *txr)
+{
+	int size;
+
+	size = txr->bd_count * sizeof(struct enetc_swbd);
+	txr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (txr->q_swbd == NULL)
+		return -ENOMEM;
+
+	size = txr->bd_count * sizeof(struct enetc_tx_bd);
+	txr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+
+	if (txr->bd_base == NULL) {
+		rte_free(txr->q_swbd);
+		txr->q_swbd = NULL;
+		return -ENOMEM;
+	}
+	txr->next_to_clean = 0;
+	txr->next_to_use = 0;
+
+	return 0;
+}
+
+static void enetc_free_bdr(struct enetc_bdr *rxr)
+{
+	rte_free(rxr->q_swbd);
+	rte_free(rxr->bd_base);
+	rxr->q_swbd = NULL;
+	rxr->bd_base = NULL;
+}
+
+static int enetc_alloc_tx_resources(struct enetc_eth_adapter *priv)
+{
+	int i, err;
+
+	for (i = 0; i < priv->num_tx_rings; i++) {
+		err = enetc_alloc_txbdr(priv->tx_ring[i]);
+
+		if (err)
+			goto fail;
+		priv->tx_ring[i]->index = i;
+	}
+
+	return 0;
+
+fail:
+	while (i-- > 0)
+		enetc_free_bdr(priv->tx_ring[i]);
+
+	return err;
+}
+
+static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+{
+	int idx = tx_ring->index;
+	uint32_t tbmr;
+
+	enetc_txbdr_wr(hw, idx, ENETC_TBBAR0,
+			lower_32_bits((uint64_t)tx_ring->bd_base));
+
+	enetc_txbdr_wr(hw, idx, ENETC_TBBAR1,
+			upper_32_bits((uint64_t)tx_ring->bd_base));
+	enetc_txbdr_wr(hw, idx, ENETC_TBLENR,
+			ENETC_RTBLENR_LEN(tx_ring->bd_count));
+
+	tbmr = ENETC_TBMR_EN;
+	/* enable ring */
+	enetc_txbdr_wr(hw, idx, ENETC_TBMR, tbmr);
+
+	enetc_txbdr_wr(hw, idx, ENETC_TBCIR, 0);
+	enetc_txbdr_wr(hw, idx, ENETC_TBCISR, 0);
+	tx_ring->tcir = hw->reg + ENETC_BDR(TX, idx, ENETC_TBCIR);
+	tx_ring->tcisr = hw->reg + ENETC_BDR(TX, idx, ENETC_TBCISR);
+}
+
+static void enetc_setup_tx_bdrs(struct rte_eth_dev *dev)
+{
+	int i;
+	struct enetc_eth_adapter *priv =
+			ENETC_DEV_PRIVATE(dev->data->dev_private);
+
+	for (i = 0; i < priv->num_tx_rings; i++) {
+		enetc_setup_txbdr(&priv->hw.hw, priv->tx_ring[i]);
+		dev->data->tx_queues[i] = priv->tx_ring[i];
+	}
+}
+
+int enetc_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)
+{
+	struct enetc_eth_adapter *adapter =
+			ENETC_DEV_PRIVATE(dev->data->dev_private);
+	int err = 0;
+
+	err = enetc_alloc_tx_resources(adapter);
+	if (err)
+		goto err_alloc_tx;
+
+	enetc_setup_tx_bdrs(dev);
+
+err_alloc_tx:
+	return err;
+}
+
+static int enetc_alloc_rxbdr(struct enetc_bdr *rxr)
+{
+	int size;
+
+	size = rxr->bd_count * sizeof(struct enetc_swbd);
+	rxr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (rxr->q_swbd == NULL)
+		return -ENOMEM;
+
+	size = rxr->bd_count * sizeof(union enetc_rx_bd);
+	rxr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+
+	if (rxr->bd_base == NULL) {
+		rte_free(rxr->q_swbd);
+		rxr->q_swbd = NULL;
+		return -ENOMEM;
+	}
+
+	rxr->next_to_clean = 0;
+	rxr->next_to_use = 0;
+	rxr->next_to_alloc = 0;
+
+	return 0;
+}
+
+static int enetc_alloc_rx_resources(struct enetc_eth_adapter  *priv)
+{
+	int i, err;
+
+	for (i = 0; i < priv->num_rx_rings; i++) {
+		err = enetc_alloc_rxbdr(priv->rx_ring[i]);
+
+		if (err)
+			goto fail;
+
+		priv->rx_ring[i]->index = i;
+	}
+	return 0;
+fail:
+	while (i-- > 0)
+		enetc_free_bdr(priv->rx_ring[i]);
+
+	return err;
+}
+
+static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring,
+						struct rte_mempool *mb_pool)
+{
+	int idx = rx_ring->index;
+	uint16_t buf_size;
+
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBAR0,
+			lower_32_bits((uint64_t)rx_ring->bd_base));
+
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBAR1,
+			upper_32_bits((uint64_t)rx_ring->bd_base));
+
+	enetc_rxbdr_wr(hw, idx, ENETC_RBLENR,
+			ENETC_RTBLENR_LEN(rx_ring->bd_count));
+
+	rx_ring->mb_pool = mb_pool;
+
+	/* enable ring */
+	enetc_rxbdr_wr(hw, idx, ENETC_RBMR, ENETC_RBMR_EN);
+	enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
+	rx_ring->rcir = hw->reg + ENETC_BDR(RX, idx, ENETC_RBCIR);
+
+	enetc_refill_rx_ring(rx_ring, (enetc_bd_unused(rx_ring)));
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rx_ring->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
+
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBSR, buf_size);
+}
+
+static void enetc_setup_bdrs(struct rte_eth_dev *dev,
+					struct rte_mempool *mb_pool)
+{
+	int i;
+	struct enetc_eth_adapter *priv =
+			ENETC_DEV_PRIVATE(dev->data->dev_private);
+
+	for (i = 0; i < priv->num_rx_rings; i++) {
+		enetc_setup_rxbdr(&priv->hw.hw, priv->rx_ring[i], mb_pool);
+		dev->data->rx_queues[i] = priv->rx_ring[i];
+	}
+}
+
+
+int enetc_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)
+{
+	struct enetc_eth_adapter *adapter =
+			ENETC_DEV_PRIVATE(dev->data->dev_private);
+	int err = 0;
+
+	err = enetc_alloc_rx_resources(adapter);
+	if (err)
+		goto err_alloc_rx;
+
+	enetc_setup_bdrs(dev, mb_pool);
+
+err_alloc_rx:
+	return err;
+}
diff --git a/drivers/net/enetc/meson.build b/drivers/net/enetc/meson.build
index 506b174ed..733156bbf 100644
--- a/drivers/net/enetc/meson.build
+++ b/drivers/net/enetc/meson.build
@@ -5,6 +5,7 @@ if host_machine.system() != 'linux'
 	build = false
 endif
 
-sources = files('enetc_ethdev.c')
+sources = files('enetc_ethdev.c',
+		'enetc_rxtx.c')
 
 includes += include_directories('base')
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v2 0/3] introduces the enetc PMD driver
  2018-09-06  5:54 [dpdk-dev] [PATCH 0/3] introduces the ENETC PMD Gagandeep Singh
                   ` (2 preceding siblings ...)
  2018-09-06  5:54 ` [dpdk-dev] [PATCH 3/3] net/enetc: enable Rx and Tx Gagandeep Singh
@ 2018-09-13  9:41 ` Gagandeep Singh
  2018-09-13  9:41   ` [dpdk-dev] [PATCH v2 1/3] doc: add usage doc for ENETC PMD Gagandeep Singh
                     ` (3 more replies)
  3 siblings, 4 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-13  9:41 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

*ENETC* PMD driver which integrates with the existing PCI bus.
Document is also part of the set

Change-log:
document improvement
checkpatch warnings removed

Gagandeep Singh (3):
  doc: add usage doc for ENETC PMD
  net/enetc: add ENETC PMD with basic operations
  net/enetc: enable Rx and Tx

 MAINTAINERS                                 |   7 +
 config/common_base                          |   5 +
 config/common_linuxapp                      |   5 +
 doc/guides/nics/enetc.rst                   | 154 +++++++
 doc/guides/nics/features/enetc.ini          |  10 +
 doc/guides/nics/index.rst                   |   1 +
 drivers/net/Makefile                        |   1 +
 drivers/net/enetc/Makefile                  |  25 ++
 drivers/net/enetc/base/enetc_hw.h           | 220 ++++++++++
 drivers/net/enetc/enetc.h                   | 111 +++++
 drivers/net/enetc/enetc_ethdev.c            | 271 ++++++++++++
 drivers/net/enetc/enetc_logs.h              |  40 ++
 drivers/net/enetc/enetc_rxtx.c              | 447 ++++++++++++++++++++
 drivers/net/enetc/meson.build               |  11 +
 drivers/net/enetc/rte_pmd_enetc_version.map |   4 +
 drivers/net/meson.build                     |   1 +
 mk/rte.app.mk                               |   1 +
 17 files changed, 1314 insertions(+)
 create mode 100644 doc/guides/nics/enetc.rst
 create mode 100644 doc/guides/nics/features/enetc.ini
 create mode 100644 drivers/net/enetc/Makefile
 create mode 100644 drivers/net/enetc/base/enetc_hw.h
 create mode 100644 drivers/net/enetc/enetc.h
 create mode 100644 drivers/net/enetc/enetc_ethdev.c
 create mode 100644 drivers/net/enetc/enetc_logs.h
 create mode 100644 drivers/net/enetc/enetc_rxtx.c
 create mode 100644 drivers/net/enetc/meson.build
 create mode 100644 drivers/net/enetc/rte_pmd_enetc_version.map

-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v2 1/3] doc: add usage doc for ENETC PMD
  2018-09-13  9:41 ` [dpdk-dev] [PATCH v2 0/3] introduces the enetc PMD driver Gagandeep Singh
@ 2018-09-13  9:41   ` Gagandeep Singh
  2018-09-21 13:22     ` Ferruh Yigit
  2018-09-13  9:42   ` [dpdk-dev] [PATCH v2 2/3] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-13  9:41 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

Add enetc usage document to compile and run the
DPDK application on enetc supported platform.
This document introduces the enetc driver, supported
platforms and supported features.

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 MAINTAINERS                        |   5 +
 doc/guides/nics/enetc.rst          | 153 +++++++++++++++++++++++++++++
 doc/guides/nics/features/enetc.ini |   8 ++
 doc/guides/nics/index.rst          |   1 +
 4 files changed, 167 insertions(+)
 create mode 100644 doc/guides/nics/enetc.rst
 create mode 100644 doc/guides/nics/features/enetc.ini

diff --git a/MAINTAINERS b/MAINTAINERS
index 9fd258fad..b999230cc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -643,6 +643,11 @@ F: drivers/net/dpaa2/
 F: doc/guides/nics/dpaa2.rst
 F: doc/guides/nics/features/dpaa2.ini
 
+NXP enetc
+M: Gagandeep Singh <g.singh@nxp.com>
+F: doc/guides/nics/enetc.rst
+F: doc/guides/nics/features/enetc.ini
+
 QLogic bnx2x
 M: Harish Patil <harish.patil@cavium.com>
 M: Rasesh Mody <rasesh.mody@cavium.com>
diff --git a/doc/guides/nics/enetc.rst b/doc/guides/nics/enetc.rst
new file mode 100644
index 000000000..da775ebeb
--- /dev/null
+++ b/doc/guides/nics/enetc.rst
@@ -0,0 +1,153 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+   Copyright 2018 NXP
+
+ENETC Poll Mode Driver
+======================
+
+The ENETC NIC PMD (**librte_pmd_enetc**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP LS1028** SoC.
+
+More information can be found at `NXP Official Website
+<https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/qoriq-layerscape-arm-processors/qoriq-layerscape-1028a-industrial-applications-processor:LS1028A>`_.
+
+ENETC
+-----
+
+This section provides an overview of the NXP ENETC
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- ENETC overview
+- ENETC features
+- PCI bus driver
+- NIC driver
+- Supported ENETC SoCs
+- Prerequisites
+- Driver compilation and testing
+
+ENETC Overview
+~~~~~~~~~~~~~~
+
+ENETC is a PCI Integrated End Point(IEP). IEP implements
+peripheral devices in an SoC such that software sees them as PCIe device.
+ENETC is an evolution of BDR(Buffer Descriptor Ring) based networking
+IPs.
+
+This infrastructure simplifies adding support for IEP and facilitates in following:
+
+- Device discovery and location
+- Resource requirement discovery and allocation (e.g. interrupt assignment,
+  device register address)
+- Event reporting
+
+ENETC Features
+~~~~~~~~~~~~~~
+
+
+NIC Driver (PMD)
+~~~~~~~~~~~~~~~~
+
+ENETC PMD is traditional DPDK PMD which provides necessary interface between
+RTE framework and ENETC internal drivers.
+
+- Driver registers the device vendor table in PCI subsystem.
+- RTE framework scans the PCI bus for connected devices.
+- This scanning will invoke the probe function of ENETC driver.
+- The probe function will set the basic device registers and also setups BD rings.
+- On packet Rx the respective BD Ring status bit is set which is then used for
+  packet processing.
+- Then Tx is done first followed by Rx.
+
+Supported ENETC SoCs
+~~~~~~~~~~~~~~~~~~~~
+
+- LS1028
+
+Prerequisites
+~~~~~~~~~~~~~
+
+There are three main pre-requisities for executing ENETC PMD on a ENETC
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-i686_aarch64-linux-gnu.tar.xz>`_.
+
+2. **Linux Kernel**
+
+   It can be obtained from `NXP's Github hosting <https://source.codeaurora.org/external/qoriq/qoriq-components/linux>`_.
+
+3. **Rootfile system**
+
+   Any *aarch64* supporting filesystem can be used. For example,
+   Ubuntu 16.04 LTS (Xenial) or 18.04 (Bionic) userland which can be obtained
+   from `here <http://cdimage.ubuntu.com/ubuntu-base/releases/18.04/release/ubuntu-base-18.04.1-base-arm64.tar.gz>`_.
+
+The following dependencies are not part of DPDK and must be installed
+separately:
+
+- **NXP Linux LSDK**
+
+  NXP Layerscape software development kit (LSDK) includes support for family
+  of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+  and corresponding boards.
+
+  It includes the Linux board support packages (BSPs) for NXP SoCs,
+  a fully operational tool chain, kernel and board specific modules.
+
+  LSDK and related information can be obtained from:  `LSDK <https://www.nxp.com/support/developer-resources/run-time-software/linux-software-and-development-tools/layerscape-software-development-kit:LAYERSCAPE-SDK>`_
+
+Driver compilation and testing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#. Please refer the document :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
+   to compile the driver. Use target "arm64-armv8a-linuxapp-gcc" in make command
+
+#. Refer to the document :ref:`cross build dpdk for arm64 <configure_and_cross_compile_dpdk_build>` to
+   disable flags and for cross compilation
+
+#. To compile in performance mode, please set ``CONFIG_RTE_CACHE_LINE_SIZE=64``
+
+#. Running l2fwd:
+
+   Follow instructions available in the document
+   :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
+   to run l2fwd.
+
+   - First unbind the ports from kernel
+
+     - echo vfio-pci > /sys/bus/pci/devices/0000\:00\:00.1/driver_override
+     - echo 0000:00:00.1 > /sys/bus/pci/drivers/fsl_enetc/unbind
+     - echo vfio-pci > /sys/bus/pci/devices/0000\:00\:00.0/driver_override
+     - echo 0000:00:00.0 > /sys/bus/pci/drivers/fsl_enetc/unbind
+   - Then bind them to VFIO, so that DPDK application can use them
+
+     - echo 0000:00:00.1 > /sys/bus/pci/drivers/vfio-pci/bind
+     - echo 0000:00:00.0 > /sys/bus/pci/drivers/vfio-pci/bind
+   - Mount Hugepages
+
+     - mkdir /mnt/hugepages
+     - mount -t hugetlbfs none /mnt/hugepages
+   - Run l2fwd application
+
+Example output:
+
+   .. code-block:: console
+
+      ./l2fwd -c 0x3 -n 1  --log-level=8 -- -p 0x3 -q 1 -T 0
+
+      .....
+      EAL: Registered [pci] bus.
+      EAL: Detected 2 lcore(s)
+      .....
+      EAL: Bus scan completed
+      .....
+      Configuring Port 0 (socket 0)
+      Port 0: 00:00:00:00:00:01
+      Configuring Port 1 (socket 0)
+      Port 1: 00:00:00:00:00:02
+      .....
+      Checking link statuses...
+      Port 0 Link Up - speed 0 Mbps - full-duplex
+      Port 1 Link Up - speed 0 Mbps - full-duplex
diff --git a/doc/guides/nics/features/enetc.ini b/doc/guides/nics/features/enetc.ini
new file mode 100644
index 000000000..fb1bf5989
--- /dev/null
+++ b/doc/guides/nics/features/enetc.ini
@@ -0,0 +1,8 @@
+;
+; Supported features of the 'enetc' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+ARMv8                = Y
+Usage doc            = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 59f6063dc..0323035d3 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -21,6 +21,7 @@ Network Interface Controller Drivers
     dpaa2
     e1000em
     ena
+    enetc
     enic
     fm10k
     i40e
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v2 2/3] net/enetc: add ENETC PMD with basic operations
  2018-09-13  9:41 ` [dpdk-dev] [PATCH v2 0/3] introduces the enetc PMD driver Gagandeep Singh
  2018-09-13  9:41   ` [dpdk-dev] [PATCH v2 1/3] doc: add usage doc for ENETC PMD Gagandeep Singh
@ 2018-09-13  9:42   ` Gagandeep Singh
  2018-09-21 13:27     ` Ferruh Yigit
  2018-09-13  9:42   ` [dpdk-dev] [PATCH v2 3/3] net/enetc: enable Rx and Tx Gagandeep Singh
  2018-09-28  5:16   ` [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
  3 siblings, 1 reply; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-13  9:42 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

This patch introduces the enetc PMD with basic
initialisation functions includes probe, teardown,
hardware initialisation

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 MAINTAINERS                                 |   1 +
 config/common_base                          |   5 +
 config/common_linuxapp                      |   5 +
 doc/guides/nics/enetc.rst                   |   1 +
 doc/guides/nics/features/enetc.ini          |   2 +
 drivers/net/Makefile                        |   1 +
 drivers/net/enetc/Makefile                  |  24 ++
 drivers/net/enetc/base/enetc_hw.h           | 220 ++++++++++++++++
 drivers/net/enetc/enetc.h                   | 111 ++++++++
 drivers/net/enetc/enetc_ethdev.c            | 269 ++++++++++++++++++++
 drivers/net/enetc/enetc_logs.h              |  40 +++
 drivers/net/enetc/meson.build               |  10 +
 drivers/net/enetc/rte_pmd_enetc_version.map |   4 +
 drivers/net/meson.build                     |   1 +
 mk/rte.app.mk                               |   1 +
 15 files changed, 695 insertions(+)
 create mode 100644 drivers/net/enetc/Makefile
 create mode 100644 drivers/net/enetc/base/enetc_hw.h
 create mode 100644 drivers/net/enetc/enetc.h
 create mode 100644 drivers/net/enetc/enetc_ethdev.c
 create mode 100644 drivers/net/enetc/enetc_logs.h
 create mode 100644 drivers/net/enetc/meson.build
 create mode 100644 drivers/net/enetc/rte_pmd_enetc_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index b999230cc..fc70ac049 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -645,6 +645,7 @@ F: doc/guides/nics/features/dpaa2.ini
 
 NXP enetc
 M: Gagandeep Singh <g.singh@nxp.com>
+F: drivers/net/enetc/
 F: doc/guides/nics/enetc.rst
 F: doc/guides/nics/features/enetc.ini
 
diff --git a/config/common_base b/config/common_base
index 4bcbaf923..a7fc48667 100644
--- a/config/common_base
+++ b/config/common_base
@@ -217,6 +217,11 @@ CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
 CONFIG_RTE_LIBRTE_DPAA2_PMD=n
 CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
 
+#
+# Compile NXP ENETC PMD Driver
+#
+CONFIG_RTE_LIBRTE_ENETC_PMD=n
+
 #
 # Compile burst-oriented Amazon ENA PMD driver
 #
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 9c5ea9d89..485e1467d 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -44,3 +44,8 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y
+
+#
+# NXP ENETC PMD Driver
+#
+CONFIG_RTE_LIBRTE_ENETC_PMD=y
diff --git a/doc/guides/nics/enetc.rst b/doc/guides/nics/enetc.rst
index da775ebeb..9d30e8373 100644
--- a/doc/guides/nics/enetc.rst
+++ b/doc/guides/nics/enetc.rst
@@ -44,6 +44,7 @@ This infrastructure simplifies adding support for IEP and facilitates in followi
 ENETC Features
 ~~~~~~~~~~~~~~
 
+- Link Status
 
 NIC Driver (PMD)
 ~~~~~~~~~~~~~~~~
diff --git a/doc/guides/nics/features/enetc.ini b/doc/guides/nics/features/enetc.ini
index fb1bf5989..83b20845a 100644
--- a/doc/guides/nics/features/enetc.ini
+++ b/doc/guides/nics/features/enetc.ini
@@ -4,5 +4,7 @@
 ; Refer to default.ini for the full list of available PMD features.
 ;
 [Features]
+Link status          = Y
+Linux VFIO           = Y
 ARMv8                = Y
 Usage doc            = Y
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 664398de9..3ad436045 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -24,6 +24,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
 endif
 DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += e1000
 DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
+DIRS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc
 DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe
 DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k
diff --git a/drivers/net/enetc/Makefile b/drivers/net/enetc/Makefile
new file mode 100644
index 000000000..3f4ba97da
--- /dev/null
+++ b/drivers/net/enetc/Makefile
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_enetc.a
+
+CFLAGS += -O3
+EXPORT_MAP := rte_pmd_enetc_version.map
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_ethdev.c
+
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_ethdev
+LDLIBS += -lrte_bus_pci
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h
new file mode 100644
index 000000000..1ec16fec9
--- /dev/null
+++ b/drivers/net/enetc/base/enetc_hw.h
@@ -0,0 +1,220 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _ENETC_HW_H_
+#define _ENETC_HW_H_
+#include <rte_io.h>
+
+#define BIT(x)		((uint64_t)1 << ((x)))
+
+/* ENETC device IDs */
+#define ENETC_DEV_ID_VF		0xef00
+#define ENETC_DEV_ID		0xe100
+
+/* ENETC register block BAR */
+#define ENETC_BAR_REGS			0x0
+
+/* SI regs, offset: 0h */
+#define ENETC_SIMR			0x0
+#define ENETC_SIMR_EN			BIT(31)
+
+#define ENETC_SIPMAR0			0x80
+#define ENETC_SIPMAR1			0x84
+
+#define ENETC_SICAPR0			0x900
+#define ENETC_SICAPR1			0x904
+
+#define ENETC_SIMSITRV(n)		(0xB00 + (n) * 0x4)
+#define ENETC_SIMSIRRV(n)		(0xB80 + (n) * 0x4)
+
+#define ENETC_SICCAPR			0x1200
+
+/* enum for BD type */
+enum enetc_bdr_type {TX, RX};
+
+#define ENETC_BDR(type, n, off)		(0x8000 + (type) * 0x100 + (n) * 0x200 \
+							+ (off))
+/* RX BDR reg offsets */
+#define ENETC_RBMR		0x0 /* RX BDR mode register*/
+#define ENETC_RBMR_EN		BIT(31)
+
+#define ENETC_RBSR		0x4  /* Rx BDR status register*/
+#define ENETC_RBBSR		0x8  /* Rx BDR buffer size register*/
+#define ENETC_RBCIR		0xc  /* Rx BDR consumer index register*/
+#define ENETC_RBBAR0		0x10 /* Rx BDR base address register 0 */
+#define ENETC_RBBAR1		0x14 /* Rx BDR base address register 1*/
+#define ENETC_RBPIR		0x18 /* Rx BDR producer index register*/
+#define ENETC_RBLENR		0x20 /* Rx BDR length register*/
+#define ENETC_RBIER		0xa0 /* Rx BDR interrupt enable register*/
+#define ENETC_RBIER_RXTIE	BIT(0)
+#define ENETC_RBIDR		0xa4 /* Rx BDR interrupt detect register*/
+#define ENETC_RBICIR0		0xa8 /* Rx BDR inetrrupt coalescing register 0*/
+#define ENETC_RBICIR0_ICEN	BIT(31)
+
+
+#define ENETC_TBMR	0x0  /* Tx BDR mode register (TBMR) 32 RW */
+#define ENETC_TBSR	0x4  /* x BDR status register (TBSR) 32 RO */
+#define ENETC_TBBAR0	0x10 /* Tx BDR base address register 0 (TBBAR0) 32 RW */
+#define ENETC_TBBAR1	0x14 /* Tx BDR base address register 1 (TBBAR1) 32 RW */
+#define ENETC_TBCIR	0x18 /* Tx BDR consumer index register (TBCIR) 32 RW */
+#define ENETC_TBCISR	0x1C /* Tx BDR consumer index shadow register 32 RW */
+#define ENETC_TBIER	0xA0 /* Tx BDR interrupt enable register 32 RW */
+#define ENETC_TBIDR	0xA4 /* Tx BDR interrupt detect register 32 RO */
+#define ENETC_TBICR0	0xA8 /* Tx BDR interrupt coalescing register 0 32 RW */
+#define ENETC_TBICR1	0xAC /* Tx BDR interrupt coalescing register 1 32 RW */
+#define ENETC_TBLENR	0x20
+
+#define ENETC_TBCISR_IDX_MASK		0xffff
+#define ENETC_TBIER_TXFIE		BIT(1)
+
+#define ENETC_RTBLENR_LEN(n)		((n) & ~0x7)
+#define ENETC_TBMR_EN			BIT(31)
+
+/* Port regs, offset: 1_0000h */
+#define ENETC_PORT_BASE			0x10000
+#define ENETC_PMR			0x00000
+#define ENETC_PMR_EN			(BIT(16) | BIT(17) | BIT(18))
+#define ENETC_PSR			0x00004 /* RO */
+#define ENETC_PSIPMR			0x00018
+#define ENETC_PSIPMR_SET_UP(n)		(0x1 << (n)) /* n = SI index */
+#define ENETC_PSIPMR_SET_MP(n)		(0x1 << ((n) + 8))
+#define ENETC_PSIPMR_SET_VLAN_MP(n)	(0x1 << ((n) + 16))
+#define ENETC_PSIPMAR0(n)		(0x00100 + (n) * 0x20)
+#define ENETC_PSIPMAR1(n)		(0x00104 + (n) * 0x20)
+#define ENETC_PCAPR0			0x00900
+#define ENETC_PCAPR1			0x00904
+
+#define ENETC_PV0CFGR(n)		(0x00920 + (n) * 0x10)
+#define ENETC_PVCFGR_SET_TXBDR(val)	((val) & 0xff)
+#define ENETC_PVCFGR_SET_RXBDR(val)	(((val) & 0xff) << 16)
+
+#define ENETC_PM0_CMD_CFG		0x08008
+#define ENETC_PM0_TX_EN			BIT(0)
+#define ENETC_PM0_RX_EN			BIT(1)
+
+#define ENETC_PM0_MAXFRM		0x08014
+#define ENETC_SET_MAXFRM(val)		((val) << 16)
+
+/* Global regs, offset: 2_0000h */
+#define ENETC_GLOBAL_BASE		0x20000
+#define ENETC_G_EIPBRR0			0x00bf8
+#define ENETC_G_EIPBRR1			0x00bfc
+
+#define ETH_ADDR_LEN			6
+
+/* general register accessors */
+#define enetc_rd_reg(reg)	rte_read32((reg))
+#define enetc_wr_reg(reg, val)	rte_write32((val), (reg))
+#define enetc_rd(hw, off)	enetc_rd_reg((hw)->reg + (off))
+#define enetc_wr(hw, off, val)	enetc_wr_reg((hw)->reg + (off), val)
+/* port register accessors - PF only */
+#define enetc_port_rd(hw, off)		enetc_rd_reg((hw)->port + (off))
+#define enetc_port_wr(hw, off, val)	enetc_wr_reg((hw)->port + (off), val)
+/* global register accessors - PF only */
+#define enetc_global_rd(hw, off)	enetc_rd_reg((hw)->global + (off))
+#define enetc_global_wr(hw, off, val)	enetc_wr_reg((hw)->global + (off), val)
+/* BDR register accessors, see ENETC_BDR() */
+#define enetc_bdr_rd(hw, t, n, off) \
+				enetc_rd(hw, ENETC_BDR(t, n, off))
+#define enetc_bdr_wr(hw, t, n, off, val) \
+				enetc_wr(hw, ENETC_BDR(t, n, off), val)
+
+#define enetc_txbdr_rd(hw, n, off) enetc_bdr_rd(hw, TX, n, off)
+#define enetc_rxbdr_rd(hw, n, off) enetc_bdr_rd(hw, RX, n, off)
+#define enetc_txbdr_wr(hw, n, off, val) \
+				enetc_bdr_wr(hw, TX, n, off, val)
+#define enetc_rxbdr_wr(hw, n, off, val) \
+				enetc_bdr_wr(hw, RX, n, off, val)
+
+#define ENETC_TX_ADDR(txq, addr) ((void *)((txq)->enetc_txbdr + (addr)))
+
+#define ENETC_TXBD_FLAGS_IE		BIT(13)
+#define ENETC_TXBD_FLAGS_F		BIT(15)
+
+/* ENETC Parsed values (Little Endian) */
+#define ENETC_PKT_TYPE_ETHER            0x0060
+#define ENETC_PKT_TYPE_IPV4             0x0000
+#define ENETC_PKT_TYPE_IPV6             0x0020
+#define ENETC_PKT_TYPE_IPV4_TCP \
+			(0x0010 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_TCP \
+			(0x0010 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_PKT_TYPE_IPV4_UDP \
+			(0x0011 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_UDP \
+			(0x0011 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_PKT_TYPE_IPV4_SCTP \
+			(0x0013 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_SCTP \
+			(0x0013 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_PKT_TYPE_IPV4_ICMP \
+			(0x0003 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_ICMP \
+			(0x0003 | ENETC_PKT_TYPE_IPV6)
+
+/* PCI device info */
+struct enetc_hw {
+	/* SI registers, used by all PCI functions */
+	void *reg;
+	/* Port registers, PF only */
+	void *port;
+	/* IP global registers, PF only */
+	void *global;
+};
+
+struct enetc_eth_mac_info {
+	uint8_t addr[ETH_ADDR_LEN];
+	uint8_t perm_addr[ETH_ADDR_LEN];
+	bool get_link_status;
+};
+
+struct enetc_eth_hw {
+	struct net_device *ndev;
+	struct enetc_hw hw;
+	uint16_t device_id;
+	uint16_t vendor_id;
+	uint8_t revision_id;
+	struct enetc_eth_mac_info mac;
+};
+
+/* Transmit Descriptor */
+struct enetc_tx_desc {
+	uint64_t addr;
+	uint16_t frm_len;
+	uint16_t buf_len;
+	uint32_t flags_errors;
+};
+
+/* TX Buffer Descriptors (BD) */
+struct enetc_tx_bd {
+	uint64_t addr;
+	uint16_t buf_len;
+	uint16_t frm_len;
+	uint16_t err_csum;
+	uint16_t flags;
+};
+
+/* RX buffer descriptor */
+union enetc_rx_bd {
+	struct {
+		uint64_t addr;
+		uint8_t reserved[8];
+	} w;
+	struct {
+		uint16_t inet_csum;
+		uint16_t parse_summary;
+		uint32_t rss_hash;
+		uint16_t buf_len;
+		uint16_t vlan_opt;
+		union {
+			struct {
+				uint16_t flags;
+				uint16_t error;
+			};
+			uint32_t lstatus;
+		};
+	} r;
+};
+
+#endif
diff --git a/drivers/net/enetc/enetc.h b/drivers/net/enetc/enetc.h
new file mode 100644
index 000000000..9ed003fc8
--- /dev/null
+++ b/drivers/net/enetc/enetc.h
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _ENETC_H_
+#define _ENETC_H_
+
+#include <rte_time.h>
+
+#include "base/enetc_hw.h"
+
+#define PCI_VENDOR_ID_FREESCALE 0x1957
+
+/* Max TX rings per ENETC. */
+#define MAX_TX_RINGS	2
+
+/* Max RX rings per ENTEC. */
+#define MAX_RX_RINGS	1
+
+/* Max BD counts per Ring. */
+#define MAX_BD_COUNT	256
+
+/*
+ * upper_32_bits - return bits 32-63 of a number
+ * @n: the number we're accessing
+ *
+ * A basic shift-right of a 64- or 32-bit quantity.  Use this to suppress
+ * the "right shift count >= width of type" warning when that quantity is
+ * 32-bits.
+ */
+#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
+
+/*
+ * lower_32_bits - return bits 0-31 of a number
+ * @n: the number we're accessing
+ */
+#define lower_32_bits(n) ((uint32_t)(n))
+
+#define ENETC_TXBD(BDR, i) (&(((struct enetc_tx_bd *)((BDR).bd_base))[i]))
+#define ENETC_RXBD(BDR, i) (&(((union enetc_rx_bd *)((BDR).bd_base))[i]))
+
+struct enetc_swbd {
+	struct rte_mbuf *buffer_addr;
+};
+
+struct enetc_bdr {
+	struct net_device *ndev;
+	struct rte_mempool *mb_pool;   /* mbuf pool to populate RX ring. */
+	void *bd_base;			/* points to Rx or Tx BD ring */
+	union {
+		void *tcir;
+		void *rcir;
+	};
+	uint16_t index;
+	int bd_count; /* # of BDs */
+	int next_to_use;
+	int next_to_clean;
+	struct enetc_swbd *q_swbd;
+	union {
+		void *tcisr; /* Tx */
+		int next_to_alloc; /* Rx */
+	};
+};
+
+/*
+ * Structure to store private data for each driver instance (for each port).
+ */
+struct enetc_eth_adapter {
+	struct net_device *ndev;
+	struct enetc_eth_hw hw;
+	uint16_t num_rx_rings, num_tx_rings;
+	uint16_t rx_bd_count, tx_bd_count;
+	struct enetc_bdr *tx_ring[MAX_TX_RINGS];
+	struct enetc_bdr *rx_ring[MAX_RX_RINGS];
+};
+
+#define ENETC_DEV_PRIVATE(adapter) \
+	((struct enetc_eth_adapter *)adapter)
+
+#define ENETC_DEV_PRIVATE_TO_HW(adapter) \
+	(&((struct enetc_eth_adapter *)adapter)->hw)
+
+#define ENETC_DEV_PRIVATE_TO_STATS(adapter) \
+	(&((struct enetc_eth_adapter *)adapter)->stats)
+
+#define ENETC_DEV_PRIVATE_TO_INTR(adapter) \
+	(&((struct enetc_eth_adapter *)adapter)->intr)
+
+#define ENETC_GET_HW_ADDR(reg, addr) ((void *)((reg) + (addr)))
+#define ENETC_REG_READ(addr) (*(uint32_t *)addr)
+#define ENETC_REG_WRITE(addr, val) (*(uint32_t *)addr = val)
+#define ENETC_REG_WRITE_RELAXED(addr, val) (*(uint32_t *)addr = val)
+
+/*
+ * RX/TX ENETC function prototypes
+ */
+int enetc_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 enetc_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 enetc_xmit_pkts(void *txq, struct rte_mbuf **tx_pkts,
+		uint16_t nb_pkts);
+uint16_t enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts);
+
+#endif /* _ENETC_H_ */
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
new file mode 100644
index 000000000..06438835d
--- /dev/null
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -0,0 +1,269 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <stdbool.h>
+#include <rte_ethdev_pci.h>
+
+#include "enetc_logs.h"
+#include "enetc.h"
+
+int enetc_logtype_pmd;
+
+/* Functions Prototypes */
+static int enetc_dev_configure(struct rte_eth_dev *dev);
+static int enetc_dev_start(struct rte_eth_dev *dev);
+static void enetc_dev_stop(struct rte_eth_dev *dev);
+static void enetc_dev_close(struct rte_eth_dev *dev);
+static void enetc_dev_infos_get(struct rte_eth_dev *dev,
+			struct rte_eth_dev_info *dev_info);
+static int enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete);
+static int enetc_hardware_init(struct enetc_eth_hw *hw);
+
+/*
+ * The set of PCI devices this driver supports
+ */
+static const struct rte_pci_id pci_id_enetc_map[] = {
+	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID) },
+	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_VF) },
+	{ .vendor_id = 0, /* sentinel */ },
+};
+
+/* Features supported by this driver */
+static const struct eth_dev_ops enetc_ops = {
+	.dev_configure        = enetc_dev_configure,
+	.dev_start            = enetc_dev_start,
+	.dev_stop             = enetc_dev_stop,
+	.dev_close            = enetc_dev_close,
+	.link_update          = enetc_link_update,
+	.dev_infos_get        = enetc_dev_infos_get,
+};
+
+/**
+ * Initialisation of the enetc device
+ *
+ * @param eth_dev
+ *   - Pointer to the structure rte_eth_dev
+ *
+ * @return
+ *   - On success, zero.
+ *   - On failure, negative value.
+ */
+static int
+enetc_dev_init(struct rte_eth_dev *eth_dev)
+{
+	int error = 0, i;
+	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	struct enetc_eth_hw *hw =
+		ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+	struct enetc_eth_adapter *adapter =
+		ENETC_DEV_PRIVATE(eth_dev->data->dev_private);
+
+	PMD_INIT_FUNC_TRACE();
+	eth_dev->dev_ops = &enetc_ops;
+	eth_dev->rx_pkt_burst = NULL;
+	eth_dev->tx_pkt_burst = NULL;
+
+	rte_eth_copy_pci_info(eth_dev, pci_dev);
+
+	/* Retrieving and storing the HW base address of device */
+	hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
+
+	adapter->tx_bd_count = MAX_BD_COUNT;
+	adapter->rx_bd_count = MAX_BD_COUNT;
+
+	adapter->num_rx_rings = MAX_RX_RINGS;
+	adapter->num_tx_rings = MAX_TX_RINGS;
+
+	for (i = 0; i < adapter->num_rx_rings; i++) {
+		adapter->rx_ring[i] = rte_zmalloc(NULL,
+						sizeof(struct enetc_bdr), 0);
+		if (!adapter->rx_ring[i]) {
+			ENETC_PMD_ERR("Failed to allocate RX ring memory");
+			while (--i >= 0)
+				rte_free(adapter->rx_ring[i]);
+			error = -ENOMEM;
+			goto err_late;
+		}
+		adapter->rx_ring[i]->bd_count = adapter->rx_bd_count;
+	}
+
+	for (i = 0; i < adapter->num_tx_rings; i++) {
+		adapter->tx_ring[i] = rte_zmalloc(NULL,
+						sizeof(struct enetc_bdr), 0);
+		if (!adapter->tx_ring[i]) {
+			ENETC_PMD_ERR("Failed to allocate TX ring memory");
+			while (--i >= 0)
+				rte_free(adapter->tx_ring[i]);
+			error = -ENOMEM;
+			goto err_second;
+		}
+		adapter->tx_ring[i]->bd_count = adapter->tx_bd_count;
+	}
+
+	error = enetc_hardware_init(hw);
+	if (error != 0) {
+		ENETC_PMD_ERR("Hardware initialization failed");
+		goto err_first;
+	}
+
+	/* Allocate memory for storing MAC addresses */
+	eth_dev->data->mac_addrs = rte_zmalloc("enetc_eth",
+		ETHER_ADDR_LEN, 0);
+	if (!eth_dev->data->mac_addrs) {
+		ENETC_PMD_ERR("Failed to allocate %d bytes needed to "
+						"store MAC addresses",
+				ETHER_ADDR_LEN * 1);
+		error = -ENOMEM;
+		goto err_first;
+	}
+
+	/* Copy the permanent MAC address */
+	ether_addr_copy((struct ether_addr *)hw->mac.addr,
+						&eth_dev->data->mac_addrs[0]);
+
+	ENETC_PMD_DEBUG("port_id %d vendorID=0x%x deviceID=0x%x",
+			eth_dev->data->port_id, pci_dev->id.vendor_id,
+			pci_dev->id.device_id);
+	return 0;
+
+err_first:
+	for (i = 0; i < adapter->num_tx_rings; i++)
+		rte_free(adapter->tx_ring[i]);
+err_second:
+	for (i = 0; i < adapter->num_rx_rings; i++)
+		rte_free(adapter->rx_ring[i]);
+err_late:
+	return error;
+}
+
+static int
+enetc_dev_uninit(struct rte_eth_dev *eth_dev)
+{
+	return 0;
+}
+
+static int
+enetc_dev_configure(struct rte_eth_dev *dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	return 0;
+}
+
+static int
+enetc_dev_start(struct rte_eth_dev *dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	return 0;
+}
+
+static void
+enetc_dev_stop(struct rte_eth_dev *dev)
+{
+}
+
+static void
+enetc_dev_close(struct rte_eth_dev *dev)
+{
+}
+
+/* return 0 means link status changed, -1 means not changed */
+static int
+enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+	struct enetc_eth_hw *hw =
+		ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_eth_link link;
+
+	hw->mac.get_link_status = 1;
+
+	memset(&link, 0, sizeof(link));
+	rte_eth_linkstatus_get(dev, &link);
+
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
+	link.link_status = ETH_LINK_UP;
+	rte_eth_linkstatus_set(dev, &link);
+
+	return 0;
+}
+
+static int
+enetc_hardware_init(struct enetc_eth_hw *hw)
+{
+	uint32_t psipmr = 0;
+
+	/* Calculating and storing the base HW addresses */
+	hw->hw.port = hw->hw.reg + ENETC_PORT_BASE;
+	hw->hw.global = hw->hw.reg + ENETC_GLOBAL_BASE;
+
+	/* Enabling Station Interface */
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.reg, ENETC_SIMR),
+								ENETC_SIMR_EN);
+
+	/* Setting to accept broadcast packets for each inetrface */
+	psipmr |= ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0) |
+						ENETC_PSIPMR_SET_VLAN_MP(0);
+	psipmr |= ENETC_PSIPMR_SET_UP(1) | ENETC_PSIPMR_SET_MP(1) |
+						ENETC_PSIPMR_SET_VLAN_MP(1);
+	psipmr |= ENETC_PSIPMR_SET_UP(2) | ENETC_PSIPMR_SET_MP(2) |
+						ENETC_PSIPMR_SET_VLAN_MP(2);
+
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMR),
+			psipmr);
+
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PM0_CMD_CFG),
+			ENETC_PM0_TX_EN | ENETC_PM0_RX_EN);
+
+	/* Enable port */
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR),
+							ENETC_PMR_EN);
+
+	/* Enabling broadcast address */
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMAR0(0)),
+								0xFFFFFFFF);
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMAR1(0)),
+								0xFFFF << 16);
+
+	return 0;
+}
+
+static void
+enetc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
+{
+	struct enetc_eth_adapter *adapter =
+		ENETC_DEV_PRIVATE(dev->data->dev_private);
+
+	dev_info->max_rx_queues = adapter->num_rx_rings;
+	dev_info->max_tx_queues = adapter->num_tx_rings;
+	dev_info->max_rx_pktlen = 1500;
+}
+
+static int enetc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+	struct rte_pci_device *pci_dev)
+{
+	return rte_eth_dev_pci_generic_probe(pci_dev,
+		sizeof(struct enetc_eth_adapter), enetc_dev_init);
+}
+
+static int enetc_pci_remove(struct rte_pci_device *pci_dev)
+{
+	return rte_eth_dev_pci_generic_remove(pci_dev, enetc_dev_uninit);
+}
+
+static struct rte_pci_driver rte_enetc_pmd = {
+	.id_table = pci_id_enetc_map,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
+	.probe = enetc_pci_probe,
+	.remove = enetc_pci_remove,
+};
+
+RTE_PMD_REGISTER_PCI(net_enetc, rte_enetc_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(net_enetc, pci_id_enetc_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_enetc, "* vfio-pci");
+
+RTE_INIT(enetc_pmd_init_log)
+{
+	enetc_logtype_pmd = rte_log_register("pmd.net.enetc");
+	if (enetc_logtype_pmd >= 0)
+		rte_log_set_level(enetc_logtype_pmd, RTE_LOG_NOTICE);
+}
diff --git a/drivers/net/enetc/enetc_logs.h b/drivers/net/enetc/enetc_logs.h
new file mode 100644
index 000000000..c8a6c0cf3
--- /dev/null
+++ b/drivers/net/enetc/enetc_logs.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _ENETC_LOGS_H_
+#define _ENETC_LOGS_H_
+
+extern int enetc_logtype_pmd;
+
+#define ENETC_PMD_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, enetc_logtype_pmd, "enetc_net: " \
+		fmt "\n", ##args)
+
+#define ENETC_PMD_DEBUG(fmt, args...) \
+	rte_log(RTE_LOG_DEBUG, enetc_logtype_pmd, "enetc_net: %s(): "\
+		fmt "\n", __func__, ##args)
+
+#define PMD_INIT_FUNC_TRACE() ENETC_PMD_DEBUG(">>")
+
+#define ENETC_PMD_CRIT(fmt, args...) \
+	ENETC_PMD_LOG(CRIT, fmt, ## args)
+#define ENETC_PMD_INFO(fmt, args...) \
+	ENETC_PMD_LOG(INFO, fmt, ## args)
+#define ENETC_PMD_ERR(fmt, args...) \
+	ENETC_PMD_LOG(ERR, fmt, ## args)
+#define ENETC_PMD_WARN(fmt, args...) \
+	ENETC_PMD_LOG(WARNING, fmt, ## args)
+
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define ENETC_PMD_DP_LOG(level, fmt, args...) \
+	RTE_LOG_DP(level, PMD, fmt, ## args)
+
+#define ENETC_PMD_DP_DEBUG(fmt, args...) \
+	ENETC_PMD_DP_LOG(DEBUG, fmt, ## args)
+#define ENETC_PMD_DP_INFO(fmt, args...) \
+	ENETC_PMD_DP_LOG(INFO, fmt, ## args)
+#define ENETC_PMD_DP_WARN(fmt, args...) \
+	ENETC_PMD_DP_LOG(WARNING, fmt, ## args)
+
+#endif /* _ENETC_LOGS_H_*/
diff --git a/drivers/net/enetc/meson.build b/drivers/net/enetc/meson.build
new file mode 100644
index 000000000..506b174ed
--- /dev/null
+++ b/drivers/net/enetc/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+if host_machine.system() != 'linux'
+	build = false
+endif
+
+sources = files('enetc_ethdev.c')
+
+includes += include_directories('base')
diff --git a/drivers/net/enetc/rte_pmd_enetc_version.map b/drivers/net/enetc/rte_pmd_enetc_version.map
new file mode 100644
index 000000000..521e51f41
--- /dev/null
+++ b/drivers/net/enetc/rte_pmd_enetc_version.map
@@ -0,0 +1,4 @@
+DPDK_18.11 {
+
+	local: *;
+};
diff --git a/drivers/net/meson.build b/drivers/net/meson.build
index 9c28ed4da..65aa6f60c 100644
--- a/drivers/net/meson.build
+++ b/drivers/net/meson.build
@@ -11,6 +11,7 @@ drivers = ['af_packet',
 	'dpaa', 'dpaa2',
 	'e1000',
 	'ena',
+	'enetc',
 	'enic',
 	'failsafe',
 	'fm10k', 'i40e',
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index de33883be..154ae3b2c 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -135,6 +135,7 @@ endif
 _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD)        += -lrte_pmd_ena
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD)       += -lrte_pmd_enic
+_LDLIBS-$(CONFIG_RTE_LIBRTE_ENETC_PMD)      += -lrte_pmd_enetc
 _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD)      += -lrte_pmd_fm10k
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE)   += -lrte_pmd_failsafe
 _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD)       += -lrte_pmd_i40e
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v2 3/3] net/enetc: enable Rx and Tx
  2018-09-13  9:41 ` [dpdk-dev] [PATCH v2 0/3] introduces the enetc PMD driver Gagandeep Singh
  2018-09-13  9:41   ` [dpdk-dev] [PATCH v2 1/3] doc: add usage doc for ENETC PMD Gagandeep Singh
  2018-09-13  9:42   ` [dpdk-dev] [PATCH v2 2/3] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
@ 2018-09-13  9:42   ` Gagandeep Singh
  2018-09-19 12:26     ` Shreyansh Jain
  2018-09-21 13:28     ` Ferruh Yigit
  2018-09-28  5:16   ` [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
  3 siblings, 2 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-13  9:42 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

Add RX and TX queue setup, datapath functions
and enable the packet parsing

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 MAINTAINERS                      |   1 +
 drivers/net/enetc/Makefile       |   3 +-
 drivers/net/enetc/enetc_ethdev.c |   6 +-
 drivers/net/enetc/enetc_rxtx.c   | 447 +++++++++++++++++++++++++++++++
 drivers/net/enetc/meson.build    |   3 +-
 5 files changed, 456 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/enetc/enetc_rxtx.c

diff --git a/MAINTAINERS b/MAINTAINERS
index fc70ac049..b67f2afa4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -645,6 +645,7 @@ F: doc/guides/nics/features/dpaa2.ini
 
 NXP enetc
 M: Gagandeep Singh <g.singh@nxp.com>
+M: Pankaj Chauhan <pankaj.chauhan@nxp.com>
 F: drivers/net/enetc/
 F: doc/guides/nics/enetc.rst
 F: doc/guides/nics/features/enetc.ini
diff --git a/drivers/net/enetc/Makefile b/drivers/net/enetc/Makefile
index 3f4ba97da..1f886831a 100644
--- a/drivers/net/enetc/Makefile
+++ b/drivers/net/enetc/Makefile
@@ -16,8 +16,9 @@ LIBABIVER := 1
 # all source are stored in SRCS-y
 #
 SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_rxtx.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_eal -lrte_mempool
 LDLIBS += -lrte_ethdev
 LDLIBS += -lrte_bus_pci
 
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index 06438835d..67106593f 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -37,6 +37,8 @@ static const struct eth_dev_ops enetc_ops = {
 	.dev_close            = enetc_dev_close,
 	.link_update          = enetc_link_update,
 	.dev_infos_get        = enetc_dev_infos_get,
+	.rx_queue_setup       = enetc_rx_queue_setup,
+	.tx_queue_setup       = enetc_tx_queue_setup,
 };
 
 /**
@@ -61,8 +63,8 @@ enetc_dev_init(struct rte_eth_dev *eth_dev)
 
 	PMD_INIT_FUNC_TRACE();
 	eth_dev->dev_ops = &enetc_ops;
-	eth_dev->rx_pkt_burst = NULL;
-	eth_dev->tx_pkt_burst = NULL;
+	eth_dev->rx_pkt_burst = &enetc_recv_pkts;
+	eth_dev->tx_pkt_burst = &enetc_xmit_pkts;
 
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 
diff --git a/drivers/net/enetc/enetc_rxtx.c b/drivers/net/enetc/enetc_rxtx.c
new file mode 100644
index 000000000..b01f64b0c
--- /dev/null
+++ b/drivers/net/enetc/enetc_rxtx.c
@@ -0,0 +1,447 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "rte_ethdev.h"
+#include "rte_malloc.h"
+#include "rte_memzone.h"
+
+#include "base/enetc_hw.h"
+#include "enetc.h"
+#include "enetc_logs.h"
+
+#define ENETC_RXBD_BUNDLE 8 /* Number of BDs to update at once */
+
+static inline int enetc_bd_unused(struct enetc_bdr *bdr)
+{
+	if (bdr->next_to_clean > bdr->next_to_use)
+		return bdr->next_to_clean - bdr->next_to_use - 1;
+
+	return bdr->bd_count + bdr->next_to_clean - bdr->next_to_use - 1;
+}
+
+static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring)
+{
+	int tx_frm_cnt = 0;
+	struct enetc_swbd *tx_swbd;
+	int i;
+
+	i = tx_ring->next_to_clean;
+	tx_swbd = &tx_ring->q_swbd[i];
+	while ((int)(enetc_rd_reg(tx_ring->tcisr) & ENETC_TBCISR_IDX_MASK) != i) {
+		rte_pktmbuf_free(tx_swbd->buffer_addr);
+		tx_swbd->buffer_addr = NULL;
+		tx_swbd++;
+		i++;
+		if (unlikely(i == tx_ring->bd_count)) {
+			i = 0;
+			tx_swbd = &tx_ring->q_swbd[0];
+		}
+
+		tx_frm_cnt++;
+	}
+	tx_ring->next_to_clean = i;
+	return tx_frm_cnt++;
+}
+
+uint16_t enetc_xmit_pkts(void *tx_queue,
+			struct rte_mbuf **tx_pkts,
+				uint16_t nb_pkts)
+{
+	struct enetc_swbd *tx_swbd;
+	int i, start;
+	struct enetc_tx_bd *txbd;
+	struct enetc_bdr *tx_ring = (struct enetc_bdr *)tx_queue;
+
+	i = tx_ring->next_to_use;
+	start = 0;
+	while (nb_pkts--) {
+		enetc_clean_tx_ring(tx_ring);
+
+		tx_ring->q_swbd[i].buffer_addr = tx_pkts[start];
+
+		txbd = ENETC_TXBD(*tx_ring, i);
+		tx_swbd = &tx_ring->q_swbd[i];
+		txbd->frm_len = tx_pkts[start]->pkt_len;
+		txbd->buf_len = txbd->frm_len;
+		txbd->flags = rte_cpu_to_le_16(ENETC_TXBD_FLAGS_F);
+		txbd->addr =
+		(uint64_t)rte_cpu_to_le_64(tx_swbd->buffer_addr->buf_addr +
+				tx_swbd->buffer_addr->data_off);
+		i++;
+		start++;
+		if (unlikely(i == tx_ring->bd_count))
+			i = 0;
+	}
+	tx_ring->next_to_use = i;
+	enetc_wr_reg(tx_ring->tcir, i);
+	return start;
+}
+
+static int enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt)
+{
+	struct enetc_swbd *rx_swbd;
+	union enetc_rx_bd *rxbd;
+	int i, j;
+
+	i = rx_ring->next_to_use;
+	rx_swbd = &rx_ring->q_swbd[i];
+	rxbd = ENETC_RXBD(*rx_ring, i);
+
+	for (j = 0; j < buff_cnt; j++) {
+		rx_swbd->buffer_addr =
+			rte_cpu_to_le_64(rte_mbuf_raw_alloc(rx_ring->mb_pool));
+		rxbd->w.addr = (uint64_t)rx_swbd->buffer_addr->buf_addr +
+						rx_swbd->buffer_addr->data_off;
+		/* clear 'R" as well */
+		rxbd->r.lstatus = 0;
+		rx_swbd++;
+		rxbd++;
+		i++;
+
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			rxbd = ENETC_RXBD(*rx_ring, 0);
+			rx_swbd = &rx_ring->q_swbd[i];
+		}
+	}
+	if (likely(j)) {
+		rx_ring->next_to_alloc = i;
+		rx_ring->next_to_use = i;
+		enetc_wr_reg(rx_ring->rcir, i);
+	}
+	return j;
+}
+
+
+static inline void __attribute__((hot))
+enetc_dev_rx_parse(struct rte_mbuf *m, uint16_t parse_results)
+{
+	ENETC_PMD_DP_DEBUG("parse summary = 0x%x   ", parse_results);
+
+	m->packet_type = RTE_PTYPE_UNKNOWN;
+	switch (parse_results) {
+	case ENETC_PKT_TYPE_ETHER:
+		m->packet_type = RTE_PTYPE_L2_ETHER;
+		break;
+	case ENETC_PKT_TYPE_IPV4:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+					RTE_PTYPE_L3_IPV4;
+		break;
+	case ENETC_PKT_TYPE_IPV6:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+					RTE_PTYPE_L3_IPV6;
+		break;
+	case ENETC_PKT_TYPE_IPV4_TCP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_TCP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_UDP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_UDP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_SCTP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_SCTP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_SCTP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_SCTP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_ICMP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_ICMP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_ICMP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_ICMP;
+		break;
+	/* More switch cases can be added */
+	default:
+		m->packet_type = RTE_PTYPE_UNKNOWN;
+	}
+}
+
+static int
+enetc_clean_rx_ring(struct enetc_bdr *rx_ring, struct rte_mbuf **rx_pkts,
+								int work_limit)
+{
+	int rx_frm_cnt = 0;
+	int cleaned_cnt, i;
+	struct enetc_swbd *rx_swbd;
+
+	cleaned_cnt = enetc_bd_unused(rx_ring);
+
+	/* next descriptor to process */
+	i = rx_ring->next_to_clean;
+	rx_swbd = &rx_ring->q_swbd[i];
+
+	while (likely(rx_frm_cnt < work_limit)) {
+		union enetc_rx_bd *rxbd;
+		uint32_t bd_status;
+
+		if (cleaned_cnt >= ENETC_RXBD_BUNDLE) {
+			int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt);
+
+			cleaned_cnt -= count;
+		}
+		rxbd = ENETC_RXBD(*rx_ring, i);
+		bd_status = rte_le_to_cpu_32(rxbd->r.lstatus);
+		if (!bd_status)
+			break;
+
+		rx_swbd->buffer_addr->pkt_len = rxbd->r.buf_len;
+		rx_swbd->buffer_addr->data_len = rxbd->r.buf_len;
+		rx_swbd->buffer_addr->hash.rss = rxbd->r.rss_hash;
+		rx_swbd->buffer_addr->ol_flags = 0;
+		enetc_dev_rx_parse(rx_swbd->buffer_addr, rxbd->r.parse_summary);
+
+		rx_pkts[rx_frm_cnt] = rx_swbd->buffer_addr;
+
+		cleaned_cnt++;
+		rx_swbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			rx_swbd = &rx_ring->q_swbd[i];
+		}
+		rx_ring->next_to_clean = i;
+		rx_frm_cnt++;
+	}
+
+	return rx_frm_cnt;
+}
+
+uint16_t enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
+			uint16_t nb_pkts)
+{
+	struct enetc_bdr *rx_ring = (struct enetc_bdr *)rxq;
+
+	return enetc_clean_rx_ring(rx_ring, rx_pkts, nb_pkts);
+}
+
+static int enetc_alloc_txbdr(struct enetc_bdr *txr)
+{
+	int size;
+
+	size = txr->bd_count * sizeof(struct enetc_swbd);
+	txr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (txr->q_swbd == NULL)
+		return -ENOMEM;
+
+	size = txr->bd_count * sizeof(struct enetc_tx_bd);
+	txr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+
+	if (txr->bd_base == NULL) {
+		rte_free(txr->q_swbd);
+		txr->q_swbd = NULL;
+		return -ENOMEM;
+	}
+	txr->next_to_clean = 0;
+	txr->next_to_use = 0;
+
+	return 0;
+}
+
+static void enetc_free_bdr(struct enetc_bdr *rxr)
+{
+	rte_free(rxr->q_swbd);
+	rte_free(rxr->bd_base);
+	rxr->q_swbd = NULL;
+	rxr->bd_base = NULL;
+}
+
+static int enetc_alloc_tx_resources(struct enetc_eth_adapter *priv)
+{
+	int i, err;
+
+	for (i = 0; i < priv->num_tx_rings; i++) {
+		err = enetc_alloc_txbdr(priv->tx_ring[i]);
+
+		if (err)
+			goto fail;
+		priv->tx_ring[i]->index = i;
+	}
+
+	return 0;
+
+fail:
+	while (i-- > 0)
+		enetc_free_bdr(priv->tx_ring[i]);
+
+	return err;
+}
+
+static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+{
+	int idx = tx_ring->index;
+	uint32_t tbmr;
+
+	enetc_txbdr_wr(hw, idx, ENETC_TBBAR0,
+			lower_32_bits((uint64_t)tx_ring->bd_base));
+
+	enetc_txbdr_wr(hw, idx, ENETC_TBBAR1,
+			upper_32_bits((uint64_t)tx_ring->bd_base));
+	enetc_txbdr_wr(hw, idx, ENETC_TBLENR,
+			ENETC_RTBLENR_LEN(tx_ring->bd_count));
+
+	tbmr = ENETC_TBMR_EN;
+	/* enable ring */
+	enetc_txbdr_wr(hw, idx, ENETC_TBMR, tbmr);
+
+	enetc_txbdr_wr(hw, idx, ENETC_TBCIR, 0);
+	enetc_txbdr_wr(hw, idx, ENETC_TBCISR, 0);
+	tx_ring->tcir = hw->reg + ENETC_BDR(TX, idx, ENETC_TBCIR);
+	tx_ring->tcisr = hw->reg + ENETC_BDR(TX, idx, ENETC_TBCISR);
+}
+
+static void enetc_setup_tx_bdrs(struct rte_eth_dev *dev)
+{
+	int i;
+	struct enetc_eth_adapter *priv =
+			ENETC_DEV_PRIVATE(dev->data->dev_private);
+
+	for (i = 0; i < priv->num_tx_rings; i++) {
+		enetc_setup_txbdr(&priv->hw.hw, priv->tx_ring[i]);
+		dev->data->tx_queues[i] = priv->tx_ring[i];
+	}
+}
+
+int enetc_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)
+{
+	struct enetc_eth_adapter *adapter =
+			ENETC_DEV_PRIVATE(dev->data->dev_private);
+	int err = 0;
+
+	err = enetc_alloc_tx_resources(adapter);
+	if (err)
+		goto err_alloc_tx;
+
+	enetc_setup_tx_bdrs(dev);
+
+err_alloc_tx:
+	return err;
+}
+
+static int enetc_alloc_rxbdr(struct enetc_bdr *rxr)
+{
+	int size;
+
+	size = rxr->bd_count * sizeof(struct enetc_swbd);
+	rxr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (rxr->q_swbd == NULL)
+		return -ENOMEM;
+
+	size = rxr->bd_count * sizeof(union enetc_rx_bd);
+	rxr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+
+	if (rxr->bd_base == NULL) {
+		rte_free(rxr->q_swbd);
+		rxr->q_swbd = NULL;
+		return -ENOMEM;
+	}
+
+	rxr->next_to_clean = 0;
+	rxr->next_to_use = 0;
+	rxr->next_to_alloc = 0;
+
+	return 0;
+}
+
+static int enetc_alloc_rx_resources(struct enetc_eth_adapter  *priv)
+{
+	int i, err;
+
+	for (i = 0; i < priv->num_rx_rings; i++) {
+		err = enetc_alloc_rxbdr(priv->rx_ring[i]);
+
+		if (err)
+			goto fail;
+
+		priv->rx_ring[i]->index = i;
+	}
+	return 0;
+fail:
+	while (i-- > 0)
+		enetc_free_bdr(priv->rx_ring[i]);
+
+	return err;
+}
+
+static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring,
+						struct rte_mempool *mb_pool)
+{
+	int idx = rx_ring->index;
+	uint16_t buf_size;
+
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBAR0,
+			lower_32_bits((uint64_t)rx_ring->bd_base));
+
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBAR1,
+			upper_32_bits((uint64_t)rx_ring->bd_base));
+
+	enetc_rxbdr_wr(hw, idx, ENETC_RBLENR,
+			ENETC_RTBLENR_LEN(rx_ring->bd_count));
+
+	rx_ring->mb_pool = mb_pool;
+
+	/* enable ring */
+	enetc_rxbdr_wr(hw, idx, ENETC_RBMR, ENETC_RBMR_EN);
+	enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
+	rx_ring->rcir = hw->reg + ENETC_BDR(RX, idx, ENETC_RBCIR);
+
+	enetc_refill_rx_ring(rx_ring, (enetc_bd_unused(rx_ring)));
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rx_ring->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
+
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBSR, buf_size);
+}
+
+static void enetc_setup_bdrs(struct rte_eth_dev *dev,
+					struct rte_mempool *mb_pool)
+{
+	int i;
+	struct enetc_eth_adapter *priv =
+			ENETC_DEV_PRIVATE(dev->data->dev_private);
+
+	for (i = 0; i < priv->num_rx_rings; i++) {
+		enetc_setup_rxbdr(&priv->hw.hw, priv->rx_ring[i], mb_pool);
+		dev->data->rx_queues[i] = priv->rx_ring[i];
+	}
+}
+
+
+int enetc_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)
+{
+	struct enetc_eth_adapter *adapter =
+			ENETC_DEV_PRIVATE(dev->data->dev_private);
+	int err = 0;
+
+	err = enetc_alloc_rx_resources(adapter);
+	if (err)
+		goto err_alloc_rx;
+
+	enetc_setup_bdrs(dev, mb_pool);
+
+err_alloc_rx:
+	return err;
+}
diff --git a/drivers/net/enetc/meson.build b/drivers/net/enetc/meson.build
index 506b174ed..733156bbf 100644
--- a/drivers/net/enetc/meson.build
+++ b/drivers/net/enetc/meson.build
@@ -5,6 +5,7 @@ if host_machine.system() != 'linux'
 	build = false
 endif
 
-sources = files('enetc_ethdev.c')
+sources = files('enetc_ethdev.c',
+		'enetc_rxtx.c')
 
 includes += include_directories('base')
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH 2/3] net/enetc: add ENETC PMD with basic operations
  2018-09-06  5:54 ` [dpdk-dev] [PATCH 2/3] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
@ 2018-09-19 12:15   ` Shreyansh Jain
  0 siblings, 0 replies; 40+ messages in thread
From: Shreyansh Jain @ 2018-09-19 12:15 UTC (permalink / raw)
  To: Gagandeep Singh; +Cc: dev, ferruh.yigit, pankaj.chauhan

On Thursday 06 September 2018 11:24 AM, Gagandeep Singh wrote:
> This patch introduces the enetc PMD with basic
> initialisation functions includes probe, teardown,
> hardware intialisation
> 
> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
> ---
>   MAINTAINERS                                 |   1 +
>   config/common_base                          |   5 +
>   config/common_linuxapp                      |   5 +
>   doc/guides/nics/enetc.rst                   |   1 +
>   doc/guides/nics/features/enetc.ini          |   2 +
>   drivers/net/Makefile                        |   1 +
>   drivers/net/enetc/Makefile                  |  24 ++
>   drivers/net/enetc/base/enetc_hw.h           | 220 ++++++++++++++++
>   drivers/net/enetc/enetc.h                   | 111 ++++++++
>   drivers/net/enetc/enetc_ethdev.c            | 269 ++++++++++++++++++++
>   drivers/net/enetc/enetc_logs.h              |  40 +++
>   drivers/net/enetc/meson.build               |  10 +
>   drivers/net/enetc/rte_pmd_enetc_version.map |   4 +
>   drivers/net/meson.build                     |   1 +
>   mk/rte.app.mk                               |   1 +
>   15 files changed, 695 insertions(+)
>   create mode 100644 drivers/net/enetc/Makefile
>   create mode 100644 drivers/net/enetc/base/enetc_hw.h
>   create mode 100644 drivers/net/enetc/enetc.h
>   create mode 100644 drivers/net/enetc/enetc_ethdev.c
>   create mode 100644 drivers/net/enetc/enetc_logs.h
>   create mode 100644 drivers/net/enetc/meson.build
>   create mode 100644 drivers/net/enetc/rte_pmd_enetc_version.map
> 

[...]

> diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h
> new file mode 100644
> index 000000000..806b26a2c
> --- /dev/null
> +++ b/drivers/net/enetc/base/enetc_hw.h
> @@ -0,0 +1,220 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2018 NXP
> + */
> +

[...]

> +
> +/* PCI device info */
> +struct enetc_hw {
> +	/* SI registers, used by all PCI functions */
> +	void *reg;
> +	/* Port registers, PF only */
> +	void *port;
> +	/* IP global registers, PF only */
> +	void *global;
> +};

A trivial one: Some structures have comments, but some don't.
Even the one above has comments *before* the variable. There is a no 
fixed standard, but it is expected that comments would be uniform across 
the file. If you see in file enetc/enetc.h, you would observe some 
comments *after* the variable.

Can you make them uniform?

> +
> +struct enetc_eth_mac_info {
> +	uint8_t addr[ETH_ADDR_LEN];
> +	uint8_t perm_addr[ETH_ADDR_LEN];
> +	bool get_link_status;
> +};
> +
> +struct enetc_eth_hw {
> +	struct net_device *ndev;
> +	struct enetc_hw hw;
> +	uint16_t device_id;
> +	uint16_t vendor_id;
> +	uint8_t revision_id;
> +	struct enetc_eth_mac_info mac;
> +};
> +
> +/* Transmit Descriptor */
> +struct enetc_tx_desc {
> +	uint64_t addr;
> +	uint16_t frm_len;
> +	uint16_t buf_len;
> +	uint32_t flags_errors;
> +};
> +
> +/* TX Buffer Descriptors (BD) */
> +struct enetc_tx_bd {
> +	uint64_t addr;
> +	uint16_t buf_len;
> +	uint16_t frm_len;
> +	uint16_t err_csum;
> +	uint16_t flags;
> +};
> +
> +/* RX buffer descriptor */
> +union enetc_rx_bd {
> +	struct {
> +		uint64_t addr;
> +		uint8_t reserved[8];
> +	} w;
> +	struct {
> +		uint16_t inet_csum;
> +		uint16_t parse_summary;
> +		uint32_t rss_hash;
> +		uint16_t buf_len;
> +		uint16_t vlan_opt;
> +		union {
> +			struct {
> +				uint16_t flags;
> +				uint16_t error;
> +			};
> +			uint32_t lstatus;
> +		};
> +	} r;
> +};

[...]

> +#endif /* _ENETC_H_ */
> diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
> new file mode 100644
> index 000000000..06438835d
> --- /dev/null
> +++ b/drivers/net/enetc/enetc_ethdev.c
> @@ -0,0 +1,269 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2018 NXP
> + */
> +
> +#include <stdbool.h>
> +#include <rte_ethdev_pci.h>
> +
> +#include "enetc_logs.h"
> +#include "enetc.h"
> +
> +int enetc_logtype_pmd;
> +
> +/* Functions Prototypes */
> +static int enetc_dev_configure(struct rte_eth_dev *dev);
> +static int enetc_dev_start(struct rte_eth_dev *dev);
> +static void enetc_dev_stop(struct rte_eth_dev *dev);
> +static void enetc_dev_close(struct rte_eth_dev *dev);
> +static void enetc_dev_infos_get(struct rte_eth_dev *dev,
> +			struct rte_eth_dev_info *dev_info);
> +static int enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete);
> +static int enetc_hardware_init(struct enetc_eth_hw *hw);
> +
> +/*
> + * The set of PCI devices this driver supports
> + */
> +static const struct rte_pci_id pci_id_enetc_map[] = {
> +	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID) },
> +	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_VF) },
> +	{ .vendor_id = 0, /* sentinel */ },
> +};
> +
> +/* Features supported by this driver */
> +static const struct eth_dev_ops enetc_ops = {
> +	.dev_configure        = enetc_dev_configure,
> +	.dev_start            = enetc_dev_start,
> +	.dev_stop             = enetc_dev_stop,
> +	.dev_close            = enetc_dev_close,
> +	.link_update          = enetc_link_update,
> +	.dev_infos_get        = enetc_dev_infos_get,
> +};
> +
> +/**
> + * Initialisation of the enetc device
> + *
> + * @param eth_dev
> + *   - Pointer to the structure rte_eth_dev
> + *
> + * @return
> + *   - On success, zero.
> + *   - On failure, negative value.
> + */
> +static int
> +enetc_dev_init(struct rte_eth_dev *eth_dev)
> +{
> +	int error = 0, i;
> +	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
> +	struct enetc_eth_hw *hw =
> +		ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
> +	struct enetc_eth_adapter *adapter =
> +		ENETC_DEV_PRIVATE(eth_dev->data->dev_private);
> +
> +	PMD_INIT_FUNC_TRACE();
> +	eth_dev->dev_ops = &enetc_ops;
> +	eth_dev->rx_pkt_burst = NULL;
> +	eth_dev->tx_pkt_burst = NULL;
> +
> +	rte_eth_copy_pci_info(eth_dev, pci_dev);
> +
> +	/* Retrieving and storing the HW base address of device */
> +	hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
> +
> +	adapter->tx_bd_count = MAX_BD_COUNT;
> +	adapter->rx_bd_count = MAX_BD_COUNT;
> +
> +	adapter->num_rx_rings = MAX_RX_RINGS;
> +	adapter->num_tx_rings = MAX_TX_RINGS;
> +
> +	for (i = 0; i < adapter->num_rx_rings; i++) {
> +		adapter->rx_ring[i] = rte_zmalloc(NULL,
> +						sizeof(struct enetc_bdr), 0);
> +		if (!adapter->rx_ring[i]) {
> +			ENETC_PMD_ERR("Failed to allocate RX ring memory");
> +			while (--i >= 0)
> +				rte_free(adapter->rx_ring[i]);
> +			error = -ENOMEM;
> +			goto err_late;
> +		}
> +		adapter->rx_ring[i]->bd_count = adapter->rx_bd_count;
> +	}
> +
> +	for (i = 0; i < adapter->num_tx_rings; i++) {
> +		adapter->tx_ring[i] = rte_zmalloc(NULL,
> +						sizeof(struct enetc_bdr), 0);
> +		if (!adapter->tx_ring[i]) {
> +			ENETC_PMD_ERR("Failed to allocate TX ring memory");
> +			while (--i >= 0)
> +				rte_free(adapter->tx_ring[i]);
> +			error = -ENOMEM;
> +			goto err_second;
> +		}
> +		adapter->tx_ring[i]->bd_count = adapter->tx_bd_count;
> +	}
> +
> +	error = enetc_hardware_init(hw);
> +	if (error != 0) {
> +		ENETC_PMD_ERR("Hardware initialization failed");
> +		goto err_first;
> +	}
> +
> +	/* Allocate memory for storing MAC addresses */
> +	eth_dev->data->mac_addrs = rte_zmalloc("enetc_eth",
> +		ETHER_ADDR_LEN, 0);
> +	if (!eth_dev->data->mac_addrs) {
> +		ENETC_PMD_ERR("Failed to allocate %d bytes needed to "
> +						"store MAC addresses",
> +				ETHER_ADDR_LEN * 1);

Formatting of the above log is not correct. It should be in format:

FUNCTION_NAME(Some argument,
               argument on new line after just below the first,
               ...);

> +		error = -ENOMEM;
> +		goto err_first;
> +	}
> +
> +	/* Copy the permanent MAC address */
> +	ether_addr_copy((struct ether_addr *)hw->mac.addr,
> +						&eth_dev->data->mac_addrs[0]);

Alignment of the second argument should be below the first one.

> +
> +	ENETC_PMD_DEBUG("port_id %d vendorID=0x%x deviceID=0x%x",
> +			eth_dev->data->port_id, pci_dev->id.vendor_id,
> +			pci_dev->id.device_id);
> +	return 0;
> +
> +err_first:
> +	for (i = 0; i < adapter->num_tx_rings; i++)
> +		rte_free(adapter->tx_ring[i]);
> +err_second:
> +	for (i = 0; i < adapter->num_rx_rings; i++)
> +		rte_free(adapter->rx_ring[i]);
> +err_late:
> +	return error;
> +}
> +
> +static int
> +enetc_dev_uninit(struct rte_eth_dev *eth_dev)
> +{

Some functions have FUNC_TRACE, some don't. Maybe you should make it 
uniform.

> +	return 0;
> +}
> +
> +static int
> +enetc_dev_configure(struct rte_eth_dev *dev)
> +{
> +	PMD_INIT_FUNC_TRACE();
> +	return 0;
> +}
> +
> +static int
> +enetc_dev_start(struct rte_eth_dev *dev)
> +{
> +	PMD_INIT_FUNC_TRACE();
> +	return 0;
> +}
> +
> +static void
> +enetc_dev_stop(struct rte_eth_dev *dev)
> +{
> +}
> +
> +static void
> +enetc_dev_close(struct rte_eth_dev *dev)
> +{
> +}
> +
> +/* return 0 means link status changed, -1 means not changed */
> +static int
> +enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete)
> +{
> +	struct enetc_eth_hw *hw =
> +		ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +	struct rte_eth_link link;
> +
> +	hw->mac.get_link_status = 1;
> +
> +	memset(&link, 0, sizeof(link));
> +	rte_eth_linkstatus_get(dev, &link);
> +
> +	link.link_duplex = ETH_LINK_FULL_DUPLEX;
> +	link.link_status = ETH_LINK_UP;
> +	rte_eth_linkstatus_set(dev, &link);
> +
> +	return 0;
> +}
> +
> +static int
> +enetc_hardware_init(struct enetc_eth_hw *hw)
> +{
> +	uint32_t psipmr = 0;
> +
> +	/* Calculating and storing the base HW addresses */
> +	hw->hw.port = hw->hw.reg + ENETC_PORT_BASE;
> +	hw->hw.global = hw->hw.reg + ENETC_GLOBAL_BASE;
> +
> +	/* Enabling Station Interface */
> +	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.reg, ENETC_SIMR),
> +								ENETC_SIMR_EN);

Second argument on new line should start below first.

> +
> +	/* Setting to accept broadcast packets for each inetrface */
> +	psipmr |= ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0) |
> +						ENETC_PSIPMR_SET_VLAN_MP(0);
> +	psipmr |= ENETC_PSIPMR_SET_UP(1) | ENETC_PSIPMR_SET_MP(1) |
> +						ENETC_PSIPMR_SET_VLAN_MP(1);
> +	psipmr |= ENETC_PSIPMR_SET_UP(2) | ENETC_PSIPMR_SET_MP(2) |
> +						ENETC_PSIPMR_SET_VLAN_MP(2);
> +
> +	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMR),
> +			psipmr);
> +
> +	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PM0_CMD_CFG),
> +			ENETC_PM0_TX_EN | ENETC_PM0_RX_EN);
> +
> +	/* Enable port */
> +	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR),
> +							ENETC_PMR_EN);
> +
> +	/* Enabling broadcast address */
> +	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMAR0(0)),
> +								0xFFFFFFFF);
> +	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMAR1(0)),
> +								0xFFFF << 16);
> +
> +	return 0;
> +}

[...]

> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index de33883be..154ae3b2c 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -135,6 +135,7 @@ endif
>   _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
>   _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD)        += -lrte_pmd_ena
>   _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD)       += -lrte_pmd_enic
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_ENETC_PMD)      += -lrte_pmd_enetc
>   _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD)      += -lrte_pmd_fm10k
>   _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE)   += -lrte_pmd_failsafe
>   _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD)       += -lrte_pmd_i40e
> 

32 bit compilation for this is failing with errors like this:

/home/shreyansh/build/DPDK/05_dpdk/drivers/net/enetc/enetc_rxtx.c: In 
function ‘enetc_xmit_pkts’:
/home/shreyansh/build/DPDK/05_dpdk/drivers/net/enetc/enetc_rxtx.c:73:3: 
warning: cast from pointer to integer of different size 
[-Wpointer-to-int-cast]
    (uint64_t)rte_cpu_to_le_64(tx_swbd->buffer_addr->buf_addr +
    ^
/home/shreyansh/build/DPDK/05_dpdk/drivers/net/enetc/enetc_rxtx.c: In 
function ‘enetc_refill_rx_ring’:
/home/shreyansh/build/DPDK/05_dpdk/drivers/net/enetc/enetc_rxtx.c:98:18: 
warning: cast from pointer to integer of different size 
[-Wpointer-to-int-cast]
    rxbd->w.addr = (uint64_t)rx_swbd->buffer_addr->buf_addr +
                   ^
In file included from 
/home/shreyansh/build/DPDK/05_dpdk/drivers/net/enetc/enetc_rxtx.c:13:0:
/home/shreyansh/build/DPDK/05_dpdk/drivers/net/enetc/enetc_rxtx.c: In 
function ‘enetc_setup_txbdr’:
/home/shreyansh/build/DPDK/05_dpdk/drivers/net/enetc/enetc_rxtx.c:293:18: 
warning: cast from pointer to integer of different size 
[-Wpointer-to-int-cast]
     lower_32_bits((uint64_t)tx_ring->bd_base));
                   ^
/home/shreyansh/build/DPDK/05_dpdk/drivers/net/enetc/base/enetc_hw.h:108:45: 
note: in definition of macro ‘enetc_wr_reg’
  #define enetc_wr_reg(reg, val) rte_write32((val), (reg))
                                              ^~~
/home/shreyansh/build/DPDK/05_dpdk/drivers/net/enetc/base/enetc_hw.h:121:5: 
note: in expansion of macro ‘enetc_wr’
      enetc_wr(hw, ENETC_BDR(t, n, off), val)
      ^~~~~~~~
/home/shreyansh/build/DPDK/05_dpdk/drivers/net/enetc/base/enetc_hw.h:126:5: 
note: in expansion of macro ‘enetc_bdr_wr’
      enetc_bdr_wr(hw, TX, n, off, val)
      ^~~~~~~~~~~~
/home/shreyansh/build/DPDK/05_dpdk/drivers/net/enetc/enetc_rxtx.c:292:2: 
note: in expansion of macro ‘enetc_txbdr_wr’

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v2 3/3] net/enetc: enable Rx and Tx
  2018-09-13  9:42   ` [dpdk-dev] [PATCH v2 3/3] net/enetc: enable Rx and Tx Gagandeep Singh
@ 2018-09-19 12:26     ` Shreyansh Jain
  2018-09-21 13:28     ` Ferruh Yigit
  1 sibling, 0 replies; 40+ messages in thread
From: Shreyansh Jain @ 2018-09-19 12:26 UTC (permalink / raw)
  To: Gagandeep Singh; +Cc: dev, ferruh.yigit, pankaj.chauhan

On Thursday 13 September 2018 03:12 PM, Gagandeep Singh wrote:
> Add RX and TX queue setup, datapath functions
> and enable the packet parsing
> 
> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
> ---
>   MAINTAINERS                      |   1 +
>   drivers/net/enetc/Makefile       |   3 +-
>   drivers/net/enetc/enetc_ethdev.c |   6 +-
>   drivers/net/enetc/enetc_rxtx.c   | 447 +++++++++++++++++++++++++++++++
>   drivers/net/enetc/meson.build    |   3 +-
>   5 files changed, 456 insertions(+), 4 deletions(-)
>   create mode 100644 drivers/net/enetc/enetc_rxtx.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fc70ac049..b67f2afa4 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -645,6 +645,7 @@ F: doc/guides/nics/features/dpaa2.ini
>   
>   NXP enetc
>   M: Gagandeep Singh <g.singh@nxp.com>
> +M: Pankaj Chauhan <pankaj.chauhan@nxp.com>
>   F: drivers/net/enetc/
>   F: doc/guides/nics/enetc.rst
>   F: doc/guides/nics/features/enetc.ini
> diff --git a/drivers/net/enetc/Makefile b/drivers/net/enetc/Makefile
> index 3f4ba97da..1f886831a 100644
> --- a/drivers/net/enetc/Makefile
> +++ b/drivers/net/enetc/Makefile
> @@ -16,8 +16,9 @@ LIBABIVER := 1
>   # all source are stored in SRCS-y
>   #
>   SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_ethdev.c
> +SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_rxtx.c
>   
> -LDLIBS += -lrte_eal
> +LDLIBS += -lrte_eal -lrte_mempool
>   LDLIBS += -lrte_ethdev
>   LDLIBS += -lrte_bus_pci
>   
> diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
> index 06438835d..67106593f 100644
> --- a/drivers/net/enetc/enetc_ethdev.c
> +++ b/drivers/net/enetc/enetc_ethdev.c
> @@ -37,6 +37,8 @@ static const struct eth_dev_ops enetc_ops = {
>   	.dev_close            = enetc_dev_close,
>   	.link_update          = enetc_link_update,
>   	.dev_infos_get        = enetc_dev_infos_get,
> +	.rx_queue_setup       = enetc_rx_queue_setup,
> +	.tx_queue_setup       = enetc_tx_queue_setup,
>   };
>   
>   /**
> @@ -61,8 +63,8 @@ enetc_dev_init(struct rte_eth_dev *eth_dev)
>   
>   	PMD_INIT_FUNC_TRACE();
>   	eth_dev->dev_ops = &enetc_ops;
> -	eth_dev->rx_pkt_burst = NULL;
> -	eth_dev->tx_pkt_burst = NULL;
> +	eth_dev->rx_pkt_burst = &enetc_recv_pkts;
> +	eth_dev->tx_pkt_burst = &enetc_xmit_pkts;
>   
>   	rte_eth_copy_pci_info(eth_dev, pci_dev);
>   
> diff --git a/drivers/net/enetc/enetc_rxtx.c b/drivers/net/enetc/enetc_rxtx.c
> new file mode 100644
> index 000000000..b01f64b0c
> --- /dev/null
> +++ b/drivers/net/enetc/enetc_rxtx.c
> @@ -0,0 +1,447 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2018 NXP
> + */
> +
> +#include <stdbool.h>
> +#include <stdint.h>
> +#include <unistd.h>
> +
> +#include "rte_ethdev.h"
> +#include "rte_malloc.h"
> +#include "rte_memzone.h"
> +
> +#include "base/enetc_hw.h"
> +#include "enetc.h"
> +#include "enetc_logs.h"
> +
> +#define ENETC_RXBD_BUNDLE 8 /* Number of BDs to update at once */
> +
> +static inline int enetc_bd_unused(struct enetc_bdr *bdr)

Ideally, the function definition should be like:
<static/inline etc> <return type>
<Function name>(<Arguments>,
                 <Arguments on new line>,
                 <More arguments>);

This helps in searching for the tags against function names.
Declarations are on a single line.
This is valid across other patches as well in this series.

> +{
> +	if (bdr->next_to_clean > bdr->next_to_use)
> +		return bdr->next_to_clean - bdr->next_to_use - 1;
> +
> +	return bdr->bd_count + bdr->next_to_clean - bdr->next_to_use - 1;
> +}
> +
> +static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring)
> +{
> +	int tx_frm_cnt = 0;
> +	struct enetc_swbd *tx_swbd;
> +	int i;
> +
> +	i = tx_ring->next_to_clean;
> +	tx_swbd = &tx_ring->q_swbd[i];
> +	while ((int)(enetc_rd_reg(tx_ring->tcisr) & ENETC_TBCISR_IDX_MASK) != i) {
> +		rte_pktmbuf_free(tx_swbd->buffer_addr);
> +		tx_swbd->buffer_addr = NULL;
> +		tx_swbd++;
> +		i++;
> +		if (unlikely(i == tx_ring->bd_count)) {
> +			i = 0;
> +			tx_swbd = &tx_ring->q_swbd[0];
> +		}
> +
> +		tx_frm_cnt++;
> +	}
> +	tx_ring->next_to_clean = i;
> +	return tx_frm_cnt++;
> +}
> +
> +uint16_t enetc_xmit_pkts(void *tx_queue,
> +			struct rte_mbuf **tx_pkts,
> +				uint16_t nb_pkts)

Formatting of second line arguments is wrong.
Also, maintain uniformity of the declaration syntax. Either all on 
single line with their returns or all with returns on one line and names 
on another.

> +{
> +	struct enetc_swbd *tx_swbd;
> +	int i, start;
> +	struct enetc_tx_bd *txbd;
> +	struct enetc_bdr *tx_ring = (struct enetc_bdr *)tx_queue;
> +
> +	i = tx_ring->next_to_use;
> +	start = 0;
> +	while (nb_pkts--) {
> +		enetc_clean_tx_ring(tx_ring);
> +
> +		tx_ring->q_swbd[i].buffer_addr = tx_pkts[start];
> +
> +		txbd = ENETC_TXBD(*tx_ring, i);
> +		tx_swbd = &tx_ring->q_swbd[i];
> +		txbd->frm_len = tx_pkts[start]->pkt_len;
> +		txbd->buf_len = txbd->frm_len;
> +		txbd->flags = rte_cpu_to_le_16(ENETC_TXBD_FLAGS_F);
> +		txbd->addr =
> +		(uint64_t)rte_cpu_to_le_64(tx_swbd->buffer_addr->buf_addr +
> +				tx_swbd->buffer_addr->data_off);
> +		i++;
> +		start++;
> +		if (unlikely(i == tx_ring->bd_count))
> +			i = 0;
> +	}
> +	tx_ring->next_to_use = i;
> +	enetc_wr_reg(tx_ring->tcir, i);
> +	return start;
> +}
> +
> +static int enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt)
> +{
> +	struct enetc_swbd *rx_swbd;
> +	union enetc_rx_bd *rxbd;
> +	int i, j;
> +
> +	i = rx_ring->next_to_use;
> +	rx_swbd = &rx_ring->q_swbd[i];
> +	rxbd = ENETC_RXBD(*rx_ring, i);
> +
> +	for (j = 0; j < buff_cnt; j++) {
> +		rx_swbd->buffer_addr =
> +			rte_cpu_to_le_64(rte_mbuf_raw_alloc(rx_ring->mb_pool));
> +		rxbd->w.addr = (uint64_t)rx_swbd->buffer_addr->buf_addr +
> +						rx_swbd->buffer_addr->data_off;
> +		/* clear 'R" as well */
> +		rxbd->r.lstatus = 0;
> +		rx_swbd++;
> +		rxbd++;
> +		i++;
> +
> +		if (unlikely(i == rx_ring->bd_count)) {
> +			i = 0;
> +			rxbd = ENETC_RXBD(*rx_ring, 0);
> +			rx_swbd = &rx_ring->q_swbd[i];
> +		}
> +	}
> +	if (likely(j)) {
> +		rx_ring->next_to_alloc = i;
> +		rx_ring->next_to_use = i;
> +		enetc_wr_reg(rx_ring->rcir, i);
> +	}

It is nice to have a new line after a logical block (like the for and if 
above). It helps in reading.
But, no formal rule exists to enforce this.

> +	return j;
> +}
> +
> +
> +static inline void __attribute__((hot))
> +enetc_dev_rx_parse(struct rte_mbuf *m, uint16_t parse_results)
> +{
> +	ENETC_PMD_DP_DEBUG("parse summary = 0x%x   ", parse_results);
> +
> +	m->packet_type = RTE_PTYPE_UNKNOWN;
> +	switch (parse_results) {
> +	case ENETC_PKT_TYPE_ETHER:
> +		m->packet_type = RTE_PTYPE_L2_ETHER;
> +		break;
> +	case ENETC_PKT_TYPE_IPV4:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +					RTE_PTYPE_L3_IPV4;
> +		break;
> +	case ENETC_PKT_TYPE_IPV6:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +					RTE_PTYPE_L3_IPV6;
> +		break;
> +	case ENETC_PKT_TYPE_IPV4_TCP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV6_TCP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV4_UDP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV6_UDP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV4_SCTP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_SCTP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV6_SCTP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_SCTP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV4_ICMP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_ICMP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV6_ICMP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_ICMP;

If you order your packet_type values, they would be easier to read:

		m->packet_type = RTE_PTYPE_L2_ETHER |
				 RTE_PTYPE_L3_IPV6 |
				 RTE_PTYPE_L4_ICMP;

Again, just like above, no strict formatting rule exists.
You can choose to ignore.

> +		break;
> +	/* More switch cases can be added */
> +	default:
> +		m->packet_type = RTE_PTYPE_UNKNOWN;
> +	}
> +}
> +
> +static int
> +enetc_clean_rx_ring(struct enetc_bdr *rx_ring, struct rte_mbuf **rx_pkts,
> +								int work_limit)

I think the above line would exceed 79 char - even if not, formatting is 
incorrect.

> +{
> +	int rx_frm_cnt = 0;
> +	int cleaned_cnt, i;
> +	struct enetc_swbd *rx_swbd;
> +
> +	cleaned_cnt = enetc_bd_unused(rx_ring);
> +
> +	/* next descriptor to process */
> +	i = rx_ring->next_to_clean;
> +	rx_swbd = &rx_ring->q_swbd[i];
> +
> +	while (likely(rx_frm_cnt < work_limit)) {
> +		union enetc_rx_bd *rxbd;
> +		uint32_t bd_status;
> +
> +		if (cleaned_cnt >= ENETC_RXBD_BUNDLE) {
> +			int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt);
> +
> +			cleaned_cnt -= count;
> +		}
> +		rxbd = ENETC_RXBD(*rx_ring, i);
> +		bd_status = rte_le_to_cpu_32(rxbd->r.lstatus);
> +		if (!bd_status)
> +			break;
> +
> +		rx_swbd->buffer_addr->pkt_len = rxbd->r.buf_len;
> +		rx_swbd->buffer_addr->data_len = rxbd->r.buf_len;
> +		rx_swbd->buffer_addr->hash.rss = rxbd->r.rss_hash;
> +		rx_swbd->buffer_addr->ol_flags = 0;
> +		enetc_dev_rx_parse(rx_swbd->buffer_addr, rxbd->r.parse_summary);
> +
> +		rx_pkts[rx_frm_cnt] = rx_swbd->buffer_addr;
> +
> +		cleaned_cnt++;
> +		rx_swbd++;
> +		i++;
> +		if (unlikely(i == rx_ring->bd_count)) {
> +			i = 0;
> +			rx_swbd = &rx_ring->q_swbd[i];
> +		}
> +		rx_ring->next_to_clean = i;
> +		rx_frm_cnt++;
> +	}
> +
> +	return rx_frm_cnt;
> +}
> +

[...]

> +static void enetc_setup_tx_bdrs(struct rte_eth_dev *dev)
> +{
> +	int i;
> +	struct enetc_eth_adapter *priv =
> +			ENETC_DEV_PRIVATE(dev->data->dev_private);
> +
> +	for (i = 0; i < priv->num_tx_rings; i++) {
> +		enetc_setup_txbdr(&priv->hw.hw, priv->tx_ring[i]);
> +		dev->data->tx_queues[i] = priv->tx_ring[i];
> +	}
> +}
> +
> +int enetc_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)

Can you please fix the format of the arguments on new line.

> +{
> +	struct enetc_eth_adapter *adapter =
> +			ENETC_DEV_PRIVATE(dev->data->dev_private);
> +	int err = 0;
> +
> +	err = enetc_alloc_tx_resources(adapter);
> +	if (err)
> +		goto err_alloc_tx;
> +
> +	enetc_setup_tx_bdrs(dev);
> +
> +err_alloc_tx:
> +	return err;
> +}
> +
> +static int enetc_alloc_rxbdr(struct enetc_bdr *rxr)
> +{
> +	int size;
> +
> +	size = rxr->bd_count * sizeof(struct enetc_swbd);
> +	rxr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
> +	if (rxr->q_swbd == NULL)
> +		return -ENOMEM;
> +
> +	size = rxr->bd_count * sizeof(union enetc_rx_bd);
> +	rxr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
> +

New line is not required here - rxr->bd_base allocation is being 
checked, so essentially a single logical block.

> +	if (rxr->bd_base == NULL) {
> +		rte_free(rxr->q_swbd);
> +		rxr->q_swbd = NULL;
> +		return -ENOMEM;
> +	}
> +
> +	rxr->next_to_clean = 0;
> +	rxr->next_to_use = 0;
> +	rxr->next_to_alloc = 0;
> +
> +	return 0;
> +}
> +

[...]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/3] doc: add usage doc for ENETC PMD
  2018-09-13  9:41   ` [dpdk-dev] [PATCH v2 1/3] doc: add usage doc for ENETC PMD Gagandeep Singh
@ 2018-09-21 13:22     ` Ferruh Yigit
  0 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2018-09-21 13:22 UTC (permalink / raw)
  To: Gagandeep Singh, dev; +Cc: pankaj.chauhan

On 9/13/2018 10:41 AM, Gagandeep Singh wrote:
> Add enetc usage document to compile and run the
> DPDK application on enetc supported platform.
> This document introduces the enetc driver, supported
> platforms and supported features.
> 
> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
> ---
>  MAINTAINERS                        |   5 +
>  doc/guides/nics/enetc.rst          | 153 +++++++++++++++++++++++++++++
>  doc/guides/nics/features/enetc.ini |   8 ++
>  doc/guides/nics/index.rst          |   1 +

Please also add a release note update.
And a web page patch to supported device list: https://core.dpdk.org/supported/

<...>

> +Driver compilation and testing
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +#. Please refer the document :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
> +   to compile the driver. Use target "arm64-armv8a-linuxapp-gcc" in make command
> +
> +#. Refer to the document :ref:`cross build dpdk for arm64 <configure_and_cross_compile_dpdk_build>` to
> +   disable flags and for cross compilation
> +
> +#. To compile in performance mode, please set ``CONFIG_RTE_CACHE_LINE_SIZE=64``
> +
> +#. Running l2fwd:
> +
> +   Follow instructions available in the document
> +   :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
> +   to run l2fwd.
> +
> +   - First unbind the ports from kernel
> +
> +     - echo vfio-pci > /sys/bus/pci/devices/0000\:00\:00.1/driver_override
> +     - echo 0000:00:00.1 > /sys/bus/pci/drivers/fsl_enetc/unbind
> +     - echo vfio-pci > /sys/bus/pci/devices/0000\:00\:00.0/driver_override
> +     - echo 0000:00:00.0 > /sys/bus/pci/drivers/fsl_enetc/unbind
> +   - Then bind them to VFIO, so that DPDK application can use them
> +
> +     - echo 0000:00:00.1 > /sys/bus/pci/drivers/vfio-pci/bind
> +     - echo 0000:00:00.0 > /sys/bus/pci/drivers/vfio-pci/bind
> +   - Mount Hugepages
> +
> +     - mkdir /mnt/hugepages
> +     - mount -t hugetlbfs none /mnt/hugepages
> +   - Run l2fwd application

We moved common part of documentation into " compiling and testing a PMD for a
NIC" section, check other PMD docs for usage, for example ena PMD, "Usage
example" section.

It is good to keep example output if it has PMD specific logs, but not required
to have generic output.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/3] net/enetc: add ENETC PMD with basic operations
  2018-09-13  9:42   ` [dpdk-dev] [PATCH v2 2/3] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
@ 2018-09-21 13:27     ` Ferruh Yigit
  0 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2018-09-21 13:27 UTC (permalink / raw)
  To: Gagandeep Singh, dev; +Cc: pankaj.chauhan

On 9/13/2018 10:42 AM, Gagandeep Singh wrote:
> This patch introduces the enetc PMD with basic
> initialisation functions includes probe, teardown,
> hardware initialisation
> 
> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
<...>

> @@ -0,0 +1,24 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright 2018 NXP
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +#
> +# library name
> +#
> +LIB = librte_pmd_enetc.a
> +
> +CFLAGS += -O3

Can you please add following to catch errors.
 +CFLAGS += $(WERROR_FLAGS)

<...>

> +struct enetc_eth_mac_info {
> +	uint8_t addr[ETH_ADDR_LEN];
> +	uint8_t perm_addr[ETH_ADDR_LEN];
> +	bool get_link_status;

Don't use bool in structures, this is slightly new, please check:
https://patches.dpdk.org/patch/44817/

<...>

> +/*
> + * RX/TX ENETC function prototypes
> + */
> +int enetc_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 enetc_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 enetc_xmit_pkts(void *txq, struct rte_mbuf **tx_pkts,
> +		uint16_t nb_pkts);
> +uint16_t enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
> +		uint16_t nb_pkts);

Should these function declerations be in next patch?

<...>

> +static int
> +enetc_dev_init(struct rte_eth_dev *eth_dev)
> +{
> +	int error = 0, i;
> +	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
> +	struct enetc_eth_hw *hw =
> +		ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
> +	struct enetc_eth_adapter *adapter =
> +		ENETC_DEV_PRIVATE(eth_dev->data->dev_private);
> +
> +	PMD_INIT_FUNC_TRACE();
> +	eth_dev->dev_ops = &enetc_ops;
> +	eth_dev->rx_pkt_burst = NULL;
> +	eth_dev->tx_pkt_burst = NULL;
> +
> +	rte_eth_copy_pci_info(eth_dev, pci_dev);

Isn't this alredy done by rte_eth_dev_pci_generic_probe() ?

> +
> +	/* Retrieving and storing the HW base address of device */
> +	hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
> +
> +	adapter->tx_bd_count = MAX_BD_COUNT;
> +	adapter->rx_bd_count = MAX_BD_COUNT;
> +
> +	adapter->num_rx_rings = MAX_RX_RINGS;
> +	adapter->num_tx_rings = MAX_TX_RINGS;
> +
> +	for (i = 0; i < adapter->num_rx_rings; i++) {
> +		adapter->rx_ring[i] = rte_zmalloc(NULL,
> +						sizeof(struct enetc_bdr), 0);
> +		if (!adapter->rx_ring[i]) {
> +			ENETC_PMD_ERR("Failed to allocate RX ring memory");
> +			while (--i >= 0)
> +				rte_free(adapter->rx_ring[i]);
> +			error = -ENOMEM;
> +			goto err_late;
> +		}
> +		adapter->rx_ring[i]->bd_count = adapter->rx_bd_count;
> +	}

There are dev->data->nb_rx_queues & dev->data->nb_tx_queues variables set with
user provided values,
Also there are dev->data->rx_queues & dev->data->tx_queues already allocated by
ethdev according queue numbers.

Why you are not using them but having a private version of them and use them?
<...>

> +static int
> +enetc_dev_uninit(struct rte_eth_dev *eth_dev)

error: unused parameter ‘eth_dev’ [-Werror=unused-parameter]
same is valid for below a few more functions.

<...>

> +static int
> +enetc_hardware_init(struct enetc_eth_hw *hw)
> +{
> +	uint32_t psipmr = 0;
> +
> +	/* Calculating and storing the base HW addresses */
> +	hw->hw.port = hw->hw.reg + ENETC_PORT_BASE;
> +	hw->hw.global = hw->hw.reg + ENETC_GLOBAL_BASE;

error: pointer of type ‘void *’ used in arithmetic [-Werror=pointer-arith]

You will get more of this when warnings enabled (please check above suggested
change on Makefile)

<...>

> +static void
> +enetc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
> +{
> +	struct enetc_eth_adapter *adapter =
> +		ENETC_DEV_PRIVATE(dev->data->dev_private);
> +
> +	dev_info->max_rx_queues = adapter->num_rx_rings;
> +	dev_info->max_tx_queues = adapter->num_tx_rings;
> +	dev_info->max_rx_pktlen = 1500
rte_eth_dev_info_get() also returns dev_info->nb_rx_queues &
dev_info->nb_tx_queues based on dev->data->nb_[r/t]x_queues but that is wrong
for this driver becase it uses different values as number of [r/t]x queues.

This is related to the above comment. Using dev->data->nb_[r/t]x_queues instead
of adapter->num_[r/t]x_rings will fix this.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v2 3/3] net/enetc: enable Rx and Tx
  2018-09-13  9:42   ` [dpdk-dev] [PATCH v2 3/3] net/enetc: enable Rx and Tx Gagandeep Singh
  2018-09-19 12:26     ` Shreyansh Jain
@ 2018-09-21 13:28     ` Ferruh Yigit
  1 sibling, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2018-09-21 13:28 UTC (permalink / raw)
  To: Gagandeep Singh, dev; +Cc: pankaj.chauhan

On 9/13/2018 10:42 AM, Gagandeep Singh wrote:
> Add RX and TX queue setup, datapath functions
> and enable the packet parsing
> 
> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
<...>

> -LDLIBS += -lrte_eal
> +LDLIBS += -lrte_eal -lrte_mempool
>  LDLIBS += -lrte_ethdev
>  LDLIBS += -lrte_bus_pci

Isn't mbuf and ring are dependency?

<...>

> +static inline void __attribute__((hot))
> +enetc_dev_rx_parse(struct rte_mbuf *m, uint16_t parse_results)
> +{
> +	ENETC_PMD_DP_DEBUG("parse summary = 0x%x   ", parse_results);
> +
> +	m->packet_type = RTE_PTYPE_UNKNOWN;
> +	switch (parse_results) {
> +	case ENETC_PKT_TYPE_ETHER:
> +		m->packet_type = RTE_PTYPE_L2_ETHER;
> +		break;
> +	case ENETC_PKT_TYPE_IPV4:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +					RTE_PTYPE_L3_IPV4;
> +		break;
> +	case ENETC_PKT_TYPE_IPV6:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +					RTE_PTYPE_L3_IPV6;
> +		break;
> +	case ENETC_PKT_TYPE_IPV4_TCP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV6_TCP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV4_UDP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV6_UDP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV4_SCTP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_SCTP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV6_SCTP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_SCTP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV4_ICMP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_ICMP;
> +		break;
> +	case ENETC_PKT_TYPE_IPV6_ICMP:
> +		m->packet_type = RTE_PTYPE_L2_ETHER |
> +			RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_ICMP;
> +		break;
> +	/* More switch cases can be added */
> +	default:
> +		m->packet_type = RTE_PTYPE_UNKNOWN;
> +	}
> +}

You are already getting packet type info from device and set mbuf, by
implementing (relatively easy) rte_eth_dev_get_supported_ptypes() API you can
make applications use these values better,
And enable "Packet type parsing" feature in .ini file

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver
  2018-09-13  9:41 ` [dpdk-dev] [PATCH v2 0/3] introduces the enetc PMD driver Gagandeep Singh
                     ` (2 preceding siblings ...)
  2018-09-13  9:42   ` [dpdk-dev] [PATCH v2 3/3] net/enetc: enable Rx and Tx Gagandeep Singh
@ 2018-09-28  5:16   ` Gagandeep Singh
  2018-09-28  5:16     ` [dpdk-dev] [PATCH v3 1/3] net/enetc: enable Rx and Tx Gagandeep Singh
                       ` (4 more replies)
  3 siblings, 5 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-28  5:16 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

*ENETC* PMD driver which integrates with the existing PCI bus.
Document is also part of the set

v2->v3 Change-log:
* Added a release note
* commom part of documentation is removed
* cflag Werror added in Makefile
* private list of RX/TX queues removed
* added the dev_start and dev_stop APIs
* added rx/tx queue release APIs
* packet parse type feature enabled

v1->v2 Change-log:
* document improvement
* checkpatch warnings removed


Gagandeep Singh (3):
  net/enetc: enable Rx and Tx
  net/enetc: support packet parse type
  doc: add usage doc for ENETC PMD

 MAINTAINERS                            |   7 +
 doc/guides/nics/enetc.rst              | 110 ++++++++
 doc/guides/nics/features/enetc.ini     |  11 +
 doc/guides/nics/index.rst              |   1 +
 doc/guides/rel_notes/release_18_11.rst |   6 +
 drivers/net/enetc/Makefile             |   3 +-
 drivers/net/enetc/base/enetc_hw.h      |  19 +-
 drivers/net/enetc/enetc.h              |  25 +-
 drivers/net/enetc/enetc_ethdev.c       | 345 ++++++++++++++++++++++++-
 drivers/net/enetc/enetc_rxtx.c         | 239 +++++++++++++++++
 drivers/net/enetc/meson.build          |   3 +-
 11 files changed, 756 insertions(+), 13 deletions(-)
 create mode 100644 doc/guides/nics/enetc.rst
 create mode 100644 doc/guides/nics/features/enetc.ini
 create mode 100644 drivers/net/enetc/enetc_rxtx.c

-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v3 1/3] net/enetc: enable Rx and Tx
  2018-09-28  5:16   ` [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
@ 2018-09-28  5:16     ` Gagandeep Singh
  2018-09-28  5:16     ` [dpdk-dev] [PATCH v3 2/3] net/enetc: support packet parse type Gagandeep Singh
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-28  5:16 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

Add RX and TX queue setup, datapath functions

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 drivers/net/enetc/Makefile        |   3 +-
 drivers/net/enetc/base/enetc_hw.h |  19 +-
 drivers/net/enetc/enetc.h         |  25 ++-
 drivers/net/enetc/enetc_ethdev.c  | 326 +++++++++++++++++++++++++++++-
 drivers/net/enetc/enetc_rxtx.c    | 239 ++++++++++++++++++++++
 drivers/net/enetc/meson.build     |   3 +-
 6 files changed, 602 insertions(+), 13 deletions(-)
 create mode 100644 drivers/net/enetc/enetc_rxtx.c

diff --git a/drivers/net/enetc/Makefile b/drivers/net/enetc/Makefile
index 519153868..9895501db 100644
--- a/drivers/net/enetc/Makefile
+++ b/drivers/net/enetc/Makefile
@@ -14,8 +14,9 @@ EXPORT_MAP := rte_pmd_enetc_version.map
 LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_rxtx.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
 LDLIBS += -lrte_ethdev
 LDLIBS += -lrte_bus_pci
 
diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h
index c962b9ca1..c74c94875 100644
--- a/drivers/net/enetc/base/enetc_hw.h
+++ b/drivers/net/enetc/base/enetc_hw.h
@@ -104,16 +104,19 @@ enum enetc_bdr_type {TX, RX};
 #define ETH_ADDR_LEN			6
 
 /* general register accessors */
-#define enetc_rd_reg(reg)	rte_read32((reg))
-#define enetc_wr_reg(reg, val)	rte_write32((val), (reg))
-#define enetc_rd(hw, off)	enetc_rd_reg((hw)->reg + (off))
-#define enetc_wr(hw, off, val)	enetc_wr_reg((hw)->reg + (off), val)
+#define enetc_rd_reg(reg)	rte_read32((void *)(reg))
+#define enetc_wr_reg(reg, val)	rte_write32((val), (void *)(reg))
+#define enetc_rd(hw, off)	enetc_rd_reg((size_t)(hw)->reg + (off))
+#define enetc_wr(hw, off, val)	enetc_wr_reg((size_t)(hw)->reg + (off), val)
 /* port register accessors - PF only */
-#define enetc_port_rd(hw, off)		enetc_rd_reg((hw)->port + (off))
-#define enetc_port_wr(hw, off, val)	enetc_wr_reg((hw)->port + (off), val)
+#define enetc_port_rd(hw, off)	enetc_rd_reg((size_t)(hw)->port + (off))
+#define enetc_port_wr(hw, off, val) \
+				enetc_wr_reg((size_t)(hw)->port + (off), val)
 /* global register accessors - PF only */
-#define enetc_global_rd(hw, off)	enetc_rd_reg((hw)->global + (off))
-#define enetc_global_wr(hw, off, val)	enetc_wr_reg((hw)->global + (off), val)
+#define enetc_global_rd(hw, off) \
+				enetc_rd_reg((size_t)(hw)->global + (off))
+#define enetc_global_wr(hw, off, val) \
+				enetc_wr_reg((size_t)(hw)->global + (off), val)
 /* BDR register accessors, see ENETC_BDR() */
 #define enetc_bdr_rd(hw, t, n, off) \
 				enetc_rd(hw, ENETC_BDR(t, n, off))
diff --git a/drivers/net/enetc/enetc.h b/drivers/net/enetc/enetc.h
index 9fa7c726c..140daf0dd 100644
--- a/drivers/net/enetc/enetc.h
+++ b/drivers/net/enetc/enetc.h
@@ -18,7 +18,11 @@
 #define MAX_RX_RINGS	1
 
 /* Max BD counts per Ring. */
-#define MAX_BD_COUNT	256
+#define MAX_BD_COUNT	64000
+/* Min BD counts per Ring. */
+#define MIN_BD_COUNT	32
+/* BD ALIGN */
+#define BD_ALIGN	8
 
 /*
  * upper_32_bits - return bits 32-63 of a number
@@ -87,4 +91,23 @@ struct enetc_eth_adapter {
 #define ENETC_REG_WRITE(addr, val) (*(uint32_t *)addr = val)
 #define ENETC_REG_WRITE_RELAXED(addr, val) (*(uint32_t *)addr = val)
 
+/*
+ * RX/TX ENETC function prototypes
+ */
+uint16_t enetc_xmit_pkts(void *txq, struct rte_mbuf **tx_pkts,
+		uint16_t nb_pkts);
+uint16_t enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts);
+
+
+int enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt);
+
+static inline int
+enetc_bd_unused(struct enetc_bdr *bdr)
+{
+	if (bdr->next_to_clean > bdr->next_to_use)
+		return bdr->next_to_clean - bdr->next_to_use - 1;
+
+	return bdr->bd_count + bdr->next_to_clean - bdr->next_to_use - 1;
+}
 #endif /* _ENETC_H_ */
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index 47e2a8ebf..2d90d8fd5 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -19,6 +19,15 @@ static void enetc_dev_infos_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete);
 static int enetc_hardware_init(struct enetc_eth_hw *hw);
+static int enetc_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);
+static void enetc_rx_queue_release(void *rxq);
+static int enetc_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);
+static void enetc_tx_queue_release(void *txq);
 
 /*
  * The set of PCI devices this driver supports
@@ -37,6 +46,10 @@ static const struct eth_dev_ops enetc_ops = {
 	.dev_close            = enetc_dev_close,
 	.link_update          = enetc_link_update,
 	.dev_infos_get        = enetc_dev_infos_get,
+	.rx_queue_setup       = enetc_rx_queue_setup,
+	.rx_queue_release     = enetc_rx_queue_release,
+	.tx_queue_setup       = enetc_tx_queue_setup,
+	.tx_queue_release     = enetc_tx_queue_release,
 };
 
 /**
@@ -59,8 +72,8 @@ enetc_dev_init(struct rte_eth_dev *eth_dev)
 
 	PMD_INIT_FUNC_TRACE();
 	eth_dev->dev_ops = &enetc_ops;
-	eth_dev->rx_pkt_burst = NULL;
-	eth_dev->tx_pkt_burst = NULL;
+	eth_dev->rx_pkt_burst = &enetc_recv_pkts;
+	eth_dev->tx_pkt_burst = &enetc_xmit_pkts;
 
 	/* Retrieving and storing the HW base address of device */
 	hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
@@ -212,11 +225,320 @@ enetc_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
 		    struct rte_eth_dev_info *dev_info)
 {
 	PMD_INIT_FUNC_TRACE();
+	dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
+		.nb_max = MAX_BD_COUNT,
+		.nb_min = MIN_BD_COUNT,
+		.nb_align = BD_ALIGN,
+	};
+	dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
+		.nb_max = MAX_BD_COUNT,
+		.nb_min = MIN_BD_COUNT,
+		.nb_align = BD_ALIGN,
+	};
 	dev_info->max_rx_queues = MAX_RX_RINGS;
 	dev_info->max_tx_queues = MAX_TX_RINGS;
 	dev_info->max_rx_pktlen = 1500;
 }
 
+static int
+enetc_alloc_txbdr(struct enetc_bdr *txr, uint16_t nb_desc)
+{
+	int size;
+
+	size = nb_desc * sizeof(struct enetc_swbd);
+	txr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (txr->q_swbd == NULL)
+		return -ENOMEM;
+
+	size = nb_desc * sizeof(struct enetc_tx_bd);
+	txr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (txr->bd_base == NULL) {
+		rte_free(txr->q_swbd);
+		txr->q_swbd = NULL;
+		return -ENOMEM;
+	}
+
+	txr->bd_count = nb_desc;
+	txr->next_to_clean = 0;
+	txr->next_to_use = 0;
+
+	return 0;
+}
+
+static void
+enetc_free_bdr(struct enetc_bdr *rxr)
+{
+	rte_free(rxr->q_swbd);
+	rte_free(rxr->bd_base);
+	rxr->q_swbd = NULL;
+	rxr->bd_base = NULL;
+}
+
+static void
+enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+{
+	int idx = tx_ring->index;
+	uintptr_t base_addr;
+	uint32_t tbmr;
+
+	base_addr = (uintptr_t)tx_ring->bd_base;
+	enetc_txbdr_wr(hw, idx, ENETC_TBBAR0,
+		       lower_32_bits((uint64_t)base_addr));
+	enetc_txbdr_wr(hw, idx, ENETC_TBBAR1,
+		       upper_32_bits((uint64_t)base_addr));
+	enetc_txbdr_wr(hw, idx, ENETC_TBLENR,
+		       ENETC_RTBLENR_LEN(tx_ring->bd_count));
+
+	tbmr = ENETC_TBMR_EN;
+	/* enable ring */
+	enetc_txbdr_wr(hw, idx, ENETC_TBMR, tbmr);
+	enetc_txbdr_wr(hw, idx, ENETC_TBCIR, 0);
+	enetc_txbdr_wr(hw, idx, ENETC_TBCISR, 0);
+	tx_ring->tcir = (void *)((size_t)hw->reg +
+			ENETC_BDR(TX, idx, ENETC_TBCIR));
+	tx_ring->tcisr = (void *)((size_t)hw->reg +
+			 ENETC_BDR(TX, idx, ENETC_TBCISR));
+}
+
+static int
+enetc_alloc_tx_resources(struct rte_eth_dev *dev,
+			 uint16_t queue_idx,
+			 uint16_t nb_desc)
+{
+	int err;
+	struct enetc_bdr *tx_ring;
+	struct rte_eth_dev_data *data = dev->data;
+	struct enetc_eth_adapter *priv =
+			ENETC_DEV_PRIVATE(data->dev_private);
+
+	tx_ring = rte_zmalloc(NULL, sizeof(struct enetc_bdr), 0);
+	if (tx_ring == NULL) {
+		ENETC_PMD_ERR("Failed to allocate TX ring memory");
+		err = -ENOMEM;
+		return -1;
+	}
+
+	err = enetc_alloc_txbdr(tx_ring, nb_desc);
+	if (err)
+		goto fail;
+
+	tx_ring->index = queue_idx;
+	tx_ring->ndev = dev;
+	enetc_setup_txbdr(&priv->hw.hw, tx_ring);
+	data->tx_queues[queue_idx] = tx_ring;
+
+	return 0;
+fail:
+	rte_free(tx_ring);
+
+	return err;
+}
+
+static int
+enetc_tx_queue_setup(struct rte_eth_dev *dev,
+		     uint16_t queue_idx,
+		     uint16_t nb_desc,
+		     unsigned int socket_id __rte_unused,
+		     const struct rte_eth_txconf *tx_conf __rte_unused)
+{
+	int err = 0;
+
+	PMD_INIT_FUNC_TRACE();
+	if (nb_desc > MAX_BD_COUNT)
+		return -1;
+
+	err = enetc_alloc_tx_resources(dev, queue_idx, nb_desc);
+
+	return err;
+}
+
+static void
+enetc_tx_queue_release(void *txq)
+{
+	if (txq == NULL)
+		return;
+
+	struct enetc_bdr *tx_ring = (struct enetc_bdr *)txq;
+	struct enetc_eth_hw *eth_hw =
+		ENETC_DEV_PRIVATE_TO_HW(tx_ring->ndev->data->dev_private);
+	struct enetc_hw *hw;
+	struct enetc_swbd *tx_swbd;
+	int i;
+	uint32_t val;
+
+	/* Disable the ring */
+	hw = &eth_hw->hw;
+	val = enetc_txbdr_rd(hw, tx_ring->index, ENETC_TBMR);
+	val &= (~ENETC_TBMR_EN);
+	enetc_txbdr_wr(hw, tx_ring->index, ENETC_TBMR, val);
+
+	/* clean the ring*/
+	i = tx_ring->next_to_clean;
+	tx_swbd = &tx_ring->q_swbd[i];
+	while (tx_swbd->buffer_addr != NULL) {
+		rte_pktmbuf_free(tx_swbd->buffer_addr);
+		tx_swbd->buffer_addr = NULL;
+		tx_swbd++;
+		i++;
+		if (unlikely(i == tx_ring->bd_count)) {
+			i = 0;
+			tx_swbd = &tx_ring->q_swbd[i];
+		}
+	}
+
+	enetc_free_bdr(tx_ring);
+	rte_free(tx_ring);
+}
+
+static int
+enetc_alloc_rxbdr(struct enetc_bdr *rxr,
+		  uint16_t nb_rx_desc)
+{
+	int size;
+
+	size = nb_rx_desc * sizeof(struct enetc_swbd);
+	rxr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (rxr->q_swbd == NULL)
+		return -ENOMEM;
+
+	size = nb_rx_desc * sizeof(union enetc_rx_bd);
+	rxr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (rxr->bd_base == NULL) {
+		rte_free(rxr->q_swbd);
+		rxr->q_swbd = NULL;
+		return -ENOMEM;
+	}
+
+	rxr->bd_count = nb_rx_desc;
+	rxr->next_to_clean = 0;
+	rxr->next_to_use = 0;
+	rxr->next_to_alloc = 0;
+
+	return 0;
+}
+
+static void
+enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring,
+		  struct rte_mempool *mb_pool)
+{
+	int idx = rx_ring->index;
+	uintptr_t base_addr;
+	uint16_t buf_size;
+
+	base_addr = (uintptr_t)rx_ring->bd_base;
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBAR0,
+		       lower_32_bits((uint64_t)base_addr));
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBAR1,
+		       upper_32_bits((uint64_t)base_addr));
+	enetc_rxbdr_wr(hw, idx, ENETC_RBLENR,
+		       ENETC_RTBLENR_LEN(rx_ring->bd_count));
+
+	rx_ring->mb_pool = mb_pool;
+	/* enable ring */
+	enetc_rxbdr_wr(hw, idx, ENETC_RBMR, ENETC_RBMR_EN);
+	enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
+	rx_ring->rcir = (void *)((size_t)hw->reg +
+			ENETC_BDR(RX, idx, ENETC_RBCIR));
+	enetc_refill_rx_ring(rx_ring, (enetc_bd_unused(rx_ring)));
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rx_ring->mb_pool) -
+		   RTE_PKTMBUF_HEADROOM);
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBSR, buf_size);
+}
+
+static int
+enetc_alloc_rx_resources(struct rte_eth_dev *dev,
+			 uint16_t rx_queue_id,
+			 uint16_t nb_rx_desc,
+			 struct rte_mempool *mb_pool)
+{
+	int err;
+	struct enetc_bdr *rx_ring;
+	struct rte_eth_dev_data *data =  dev->data;
+	struct enetc_eth_adapter *adapter =
+			ENETC_DEV_PRIVATE(data->dev_private);
+
+	rx_ring = rte_zmalloc(NULL, sizeof(struct enetc_bdr), 0);
+	if (rx_ring == NULL) {
+		ENETC_PMD_ERR("Failed to allocate RX ring memory");
+		err = -ENOMEM;
+		return err;
+	}
+
+	err = enetc_alloc_rxbdr(rx_ring, nb_rx_desc);
+	if (err)
+		goto fail;
+
+	rx_ring->index = rx_queue_id;
+	rx_ring->ndev = dev;
+	enetc_setup_rxbdr(&adapter->hw.hw, rx_ring, mb_pool);
+	data->rx_queues[rx_queue_id] = rx_ring;
+
+	return 0;
+fail:
+	rte_free(rx_ring);
+
+	return err;
+}
+
+static int
+enetc_rx_queue_setup(struct rte_eth_dev *dev,
+		     uint16_t rx_queue_id,
+		     uint16_t nb_rx_desc,
+		     unsigned int socket_id __rte_unused,
+		     const struct rte_eth_rxconf *rx_conf __rte_unused,
+		     struct rte_mempool *mb_pool)
+{
+	int err = 0;
+
+	PMD_INIT_FUNC_TRACE();
+	if (nb_rx_desc > MAX_BD_COUNT)
+		return -1;
+
+	err = enetc_alloc_rx_resources(dev, rx_queue_id,
+				       nb_rx_desc,
+				       mb_pool);
+
+	return err;
+}
+
+static void
+enetc_rx_queue_release(void *rxq)
+{
+	if (rxq == NULL)
+		return;
+
+	struct enetc_bdr *rx_ring = (struct enetc_bdr *)rxq;
+	struct enetc_eth_hw *eth_hw =
+		ENETC_DEV_PRIVATE_TO_HW(rx_ring->ndev->data->dev_private);
+	struct enetc_swbd *q_swbd;
+	struct enetc_hw *hw;
+	uint32_t val;
+	int i;
+
+	/* Disable the ring */
+	hw = &eth_hw->hw;
+	val = enetc_rxbdr_rd(hw, rx_ring->index, ENETC_RBMR);
+	val &= (~ENETC_RBMR_EN);
+	enetc_rxbdr_wr(hw, rx_ring->index, ENETC_RBMR, val);
+
+	/* Clean the ring */
+	i = rx_ring->next_to_clean;
+	q_swbd = &rx_ring->q_swbd[i];
+	while (i != rx_ring->next_to_use) {
+		rte_pktmbuf_free(q_swbd->buffer_addr);
+		q_swbd->buffer_addr = NULL;
+		q_swbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			q_swbd = &rx_ring->q_swbd[i];
+		}
+	}
+
+	enetc_free_bdr(rx_ring);
+	rte_free(rx_ring);
+}
+
 static int
 enetc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 			   struct rte_pci_device *pci_dev)
diff --git a/drivers/net/enetc/enetc_rxtx.c b/drivers/net/enetc/enetc_rxtx.c
new file mode 100644
index 000000000..631e2430d
--- /dev/null
+++ b/drivers/net/enetc/enetc_rxtx.c
@@ -0,0 +1,239 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "rte_ethdev.h"
+#include "rte_malloc.h"
+#include "rte_memzone.h"
+
+#include "base/enetc_hw.h"
+#include "enetc.h"
+#include "enetc_logs.h"
+
+#define ENETC_RXBD_BUNDLE 8 /* Number of BDs to update at once */
+
+static int
+enetc_clean_tx_ring(struct enetc_bdr *tx_ring)
+{
+	int tx_frm_cnt = 0;
+	struct enetc_swbd *tx_swbd;
+	int i;
+
+	i = tx_ring->next_to_clean;
+	tx_swbd = &tx_ring->q_swbd[i];
+	while ((int)(enetc_rd_reg(tx_ring->tcisr) &
+	       ENETC_TBCISR_IDX_MASK) != i) {
+		rte_pktmbuf_free(tx_swbd->buffer_addr);
+		tx_swbd->buffer_addr = NULL;
+		tx_swbd++;
+		i++;
+		if (unlikely(i == tx_ring->bd_count)) {
+			i = 0;
+			tx_swbd = &tx_ring->q_swbd[0];
+		}
+
+		tx_frm_cnt++;
+	}
+
+	tx_ring->next_to_clean = i;
+	return tx_frm_cnt++;
+}
+
+uint16_t
+enetc_xmit_pkts(void *tx_queue,
+		struct rte_mbuf **tx_pkts,
+		uint16_t nb_pkts)
+{
+	struct enetc_swbd *tx_swbd;
+	int i, start;
+	struct enetc_tx_bd *txbd;
+	struct enetc_bdr *tx_ring = (struct enetc_bdr *)tx_queue;
+
+	i = tx_ring->next_to_use;
+	start = 0;
+	while (nb_pkts--) {
+		enetc_clean_tx_ring(tx_ring);
+		tx_ring->q_swbd[i].buffer_addr = tx_pkts[start];
+		txbd = ENETC_TXBD(*tx_ring, i);
+		tx_swbd = &tx_ring->q_swbd[i];
+		txbd->frm_len = tx_pkts[start]->pkt_len;
+		txbd->buf_len = txbd->frm_len;
+		txbd->flags = rte_cpu_to_le_16(ENETC_TXBD_FLAGS_F);
+		txbd->addr = (uint64_t)(uintptr_t)
+		rte_cpu_to_le_64((size_t)tx_swbd->buffer_addr->buf_addr +
+				 tx_swbd->buffer_addr->data_off);
+		i++;
+		start++;
+		if (unlikely(i == tx_ring->bd_count))
+			i = 0;
+	}
+
+	tx_ring->next_to_use = i;
+	enetc_wr_reg(tx_ring->tcir, i);
+	return start;
+}
+
+int
+enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt)
+{
+	struct enetc_swbd *rx_swbd;
+	union enetc_rx_bd *rxbd;
+	int i, j;
+
+	i = rx_ring->next_to_use;
+	rx_swbd = &rx_ring->q_swbd[i];
+	rxbd = ENETC_RXBD(*rx_ring, i);
+	for (j = 0; j < buff_cnt; j++) {
+		rx_swbd->buffer_addr =
+			rte_cpu_to_le_64(rte_mbuf_raw_alloc(rx_ring->mb_pool));
+		rxbd->w.addr = (uint64_t)(uintptr_t)
+			       rx_swbd->buffer_addr->buf_addr +
+			       rx_swbd->buffer_addr->data_off;
+		/* clear 'R" as well */
+		rxbd->r.lstatus = 0;
+		rx_swbd++;
+		rxbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			rxbd = ENETC_RXBD(*rx_ring, 0);
+			rx_swbd = &rx_ring->q_swbd[i];
+		}
+	}
+
+	if (likely(j)) {
+		rx_ring->next_to_alloc = i;
+		rx_ring->next_to_use = i;
+		enetc_wr_reg(rx_ring->rcir, i);
+	}
+
+	return j;
+}
+
+
+static inline void __attribute__((hot))
+enetc_dev_rx_parse(struct rte_mbuf *m, uint16_t parse_results)
+{
+	ENETC_PMD_DP_DEBUG("parse summary = 0x%x   ", parse_results);
+
+	m->packet_type = RTE_PTYPE_UNKNOWN;
+	switch (parse_results) {
+	case ENETC_PKT_TYPE_ETHER:
+		m->packet_type = RTE_PTYPE_L2_ETHER;
+		break;
+	case ENETC_PKT_TYPE_IPV4:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4;
+		break;
+	case ENETC_PKT_TYPE_IPV6:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6;
+		break;
+	case ENETC_PKT_TYPE_IPV4_TCP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_TCP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_TCP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_TCP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_UDP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_UDP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_UDP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_UDP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_SCTP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_SCTP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_SCTP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_SCTP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_ICMP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_ICMP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_ICMP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_ICMP;
+		break;
+	/* More switch cases can be added */
+	default:
+		m->packet_type = RTE_PTYPE_UNKNOWN;
+	}
+}
+
+static int
+enetc_clean_rx_ring(struct enetc_bdr *rx_ring,
+		    struct rte_mbuf **rx_pkts,
+		    int work_limit)
+{
+	int rx_frm_cnt = 0;
+	int cleaned_cnt, i;
+	struct enetc_swbd *rx_swbd;
+
+	cleaned_cnt = enetc_bd_unused(rx_ring);
+	/* next descriptor to process */
+	i = rx_ring->next_to_clean;
+	rx_swbd = &rx_ring->q_swbd[i];
+	while (likely(rx_frm_cnt < work_limit)) {
+		union enetc_rx_bd *rxbd;
+		uint32_t bd_status;
+
+		if (cleaned_cnt >= ENETC_RXBD_BUNDLE) {
+			int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt);
+
+			cleaned_cnt -= count;
+		}
+
+		rxbd = ENETC_RXBD(*rx_ring, i);
+		bd_status = rte_le_to_cpu_32(rxbd->r.lstatus);
+		if (!bd_status)
+			break;
+
+		rx_swbd->buffer_addr->pkt_len = rxbd->r.buf_len;
+		rx_swbd->buffer_addr->data_len = rxbd->r.buf_len;
+		rx_swbd->buffer_addr->hash.rss = rxbd->r.rss_hash;
+		rx_swbd->buffer_addr->ol_flags = 0;
+		enetc_dev_rx_parse(rx_swbd->buffer_addr,
+				   rxbd->r.parse_summary);
+		rx_pkts[rx_frm_cnt] = rx_swbd->buffer_addr;
+		cleaned_cnt++;
+		rx_swbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			rx_swbd = &rx_ring->q_swbd[i];
+		}
+
+		rx_ring->next_to_clean = i;
+		rx_frm_cnt++;
+	}
+
+	return rx_frm_cnt;
+}
+
+uint16_t
+enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts)
+{
+	struct enetc_bdr *rx_ring = (struct enetc_bdr *)rxq;
+
+	return enetc_clean_rx_ring(rx_ring, rx_pkts, nb_pkts);
+}
diff --git a/drivers/net/enetc/meson.build b/drivers/net/enetc/meson.build
index 506b174ed..733156bbf 100644
--- a/drivers/net/enetc/meson.build
+++ b/drivers/net/enetc/meson.build
@@ -5,6 +5,7 @@ if host_machine.system() != 'linux'
 	build = false
 endif
 
-sources = files('enetc_ethdev.c')
+sources = files('enetc_ethdev.c',
+		'enetc_rxtx.c')
 
 includes += include_directories('base')
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v3 2/3] net/enetc: support packet parse type
  2018-09-28  5:16   ` [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
  2018-09-28  5:16     ` [dpdk-dev] [PATCH v3 1/3] net/enetc: enable Rx and Tx Gagandeep Singh
@ 2018-09-28  5:16     ` Gagandeep Singh
  2018-09-28  5:16     ` [dpdk-dev] [PATCH v3 3/3] doc: add usage doc for ENETC PMD Gagandeep Singh
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-28  5:16 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 drivers/net/enetc/enetc_ethdev.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index 2d90d8fd5..3e1c934cb 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -28,6 +28,7 @@ static int enetc_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);
 static void enetc_tx_queue_release(void *txq);
+static const uint32_t *enetc_supported_ptypes_get(struct rte_eth_dev *dev);
 
 /*
  * The set of PCI devices this driver supports
@@ -50,6 +51,7 @@ static const struct eth_dev_ops enetc_ops = {
 	.rx_queue_release     = enetc_rx_queue_release,
 	.tx_queue_setup       = enetc_tx_queue_setup,
 	.tx_queue_release     = enetc_tx_queue_release,
+	.dev_supported_ptypes_get = enetc_supported_ptypes_get,
 };
 
 /**
@@ -165,6 +167,23 @@ enetc_dev_close(struct rte_eth_dev *dev __rte_unused)
 	PMD_INIT_FUNC_TRACE();
 }
 
+static const uint32_t *
+enetc_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused)
+{
+        static const uint32_t ptypes[] = {
+                RTE_PTYPE_L2_ETHER,
+                RTE_PTYPE_L3_IPV4,
+                RTE_PTYPE_L3_IPV6,
+                RTE_PTYPE_L4_TCP,
+                RTE_PTYPE_L4_UDP,
+                RTE_PTYPE_L4_SCTP,
+                RTE_PTYPE_L4_ICMP,
+                RTE_PTYPE_UNKNOWN
+        };
+
+        return ptypes;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v3 3/3] doc: add usage doc for ENETC PMD
  2018-09-28  5:16   ` [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
  2018-09-28  5:16     ` [dpdk-dev] [PATCH v3 1/3] net/enetc: enable Rx and Tx Gagandeep Singh
  2018-09-28  5:16     ` [dpdk-dev] [PATCH v3 2/3] net/enetc: support packet parse type Gagandeep Singh
@ 2018-09-28  5:16     ` Gagandeep Singh
  2018-09-28  5:26     ` [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
  2018-09-28  7:45     ` [dpdk-dev] [PATCH v4 0/4] " Gagandeep Singh
  4 siblings, 0 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-28  5:16 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

Add enetc usage document to compile and run the
DPDK application on enetc supported platform.
This document introduces the enetc driver, supported
platforms and supported features.

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 MAINTAINERS                            |   7 ++
 doc/guides/nics/enetc.rst              | 110 +++++++++++++++++++++++++
 doc/guides/nics/features/enetc.ini     |  11 +++
 doc/guides/nics/index.rst              |   1 +
 doc/guides/rel_notes/release_18_11.rst |   6 ++
 5 files changed, 135 insertions(+)
 create mode 100644 doc/guides/nics/enetc.rst
 create mode 100644 doc/guides/nics/features/enetc.ini

diff --git a/MAINTAINERS b/MAINTAINERS
index 9fd258fad..b67f2afa4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -643,6 +643,13 @@ F: drivers/net/dpaa2/
 F: doc/guides/nics/dpaa2.rst
 F: doc/guides/nics/features/dpaa2.ini
 
+NXP enetc
+M: Gagandeep Singh <g.singh@nxp.com>
+M: Pankaj Chauhan <pankaj.chauhan@nxp.com>
+F: drivers/net/enetc/
+F: doc/guides/nics/enetc.rst
+F: doc/guides/nics/features/enetc.ini
+
 QLogic bnx2x
 M: Harish Patil <harish.patil@cavium.com>
 M: Rasesh Mody <rasesh.mody@cavium.com>
diff --git a/doc/guides/nics/enetc.rst b/doc/guides/nics/enetc.rst
new file mode 100644
index 000000000..8038bf205
--- /dev/null
+++ b/doc/guides/nics/enetc.rst
@@ -0,0 +1,110 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+   Copyright 2018 NXP
+
+ENETC Poll Mode Driver
+======================
+
+The ENETC NIC PMD (**librte_pmd_enetc**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP LS1028** SoC.
+
+More information can be found at `NXP Official Website
+<https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/qoriq-layerscape-arm-processors/qoriq-layerscape-1028a-industrial-applications-processor:LS1028A>`_.
+
+ENETC
+-----
+
+This section provides an overview of the NXP ENETC
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- ENETC overview
+- ENETC features
+- PCI bus driver
+- NIC driver
+- Supported ENETC SoCs
+- Prerequisites
+- Driver compilation and testing
+
+ENETC Overview
+~~~~~~~~~~~~~~
+
+ENETC is a PCI Integrated End Point(IEP). IEP implements
+peripheral devices in an SoC such that software sees them as PCIe device.
+ENETC is an evolution of BDR(Buffer Descriptor Ring) based networking
+IPs.
+
+This infrastructure simplifies adding support for IEP and facilitates in following:
+
+- Device discovery and location
+- Resource requirement discovery and allocation (e.g. interrupt assignment,
+  device register address)
+- Event reporting
+
+ENETC Features
+~~~~~~~~~~~~~~
+
+- Link Status
+- Packet type information
+
+NIC Driver (PMD)
+~~~~~~~~~~~~~~~~
+
+ENETC PMD is traditional DPDK PMD which provides necessary interface between
+RTE framework and ENETC internal drivers.
+
+- Driver registers the device vendor table in PCI subsystem.
+- RTE framework scans the PCI bus for connected devices.
+- This scanning will invoke the probe function of ENETC driver.
+- The probe function will set the basic device registers and also setups BD rings.
+- On packet Rx the respective BD Ring status bit is set which is then used for
+  packet processing.
+- Then Tx is done first followed by Rx.
+
+Supported ENETC SoCs
+~~~~~~~~~~~~~~~~~~~~
+
+- LS1028
+
+Prerequisites
+~~~~~~~~~~~~~
+
+There are three main pre-requisities for executing ENETC PMD on a ENETC
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-i686_aarch64-linux-gnu.tar.xz>`_.
+
+2. **Linux Kernel**
+
+   It can be obtained from `NXP's Github hosting <https://source.codeaurora.org/external/qoriq/qoriq-components/linux>`_.
+
+3. **Rootfile system**
+
+   Any *aarch64* supporting filesystem can be used. For example,
+   Ubuntu 16.04 LTS (Xenial) or 18.04 (Bionic) userland which can be obtained
+   from `here <http://cdimage.ubuntu.com/ubuntu-base/releases/18.04/release/ubuntu-base-18.04.1-base-arm64.tar.gz>`_.
+
+The following dependencies are not part of DPDK and must be installed
+separately:
+
+- **NXP Linux LSDK**
+
+  NXP Layerscape software development kit (LSDK) includes support for family
+  of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+  and corresponding boards.
+
+  It includes the Linux board support packages (BSPs) for NXP SoCs,
+  a fully operational tool chain, kernel and board specific modules.
+
+  LSDK and related information can be obtained from:  `LSDK <https://www.nxp.com/support/developer-resources/run-time-software/linux-software-and-development-tools/layerscape-software-development-kit:LAYERSCAPE-SDK>`_
+
+Driver compilation and testing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Follow instructions available in the document
+:ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
+to launch **testpmd**
+
+To compile in performance mode, please set ``CONFIG_RTE_CACHE_LINE_SIZE=64``
diff --git a/doc/guides/nics/features/enetc.ini b/doc/guides/nics/features/enetc.ini
new file mode 100644
index 000000000..69476a2a1
--- /dev/null
+++ b/doc/guides/nics/features/enetc.ini
@@ -0,0 +1,11 @@
+;
+; Supported features of the 'enetc' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+Packet type parsing  = Y
+Link status          = Y
+Linux VFIO           = Y
+ARMv8                = Y
+Usage doc            = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 59f6063dc..0323035d3 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -21,6 +21,7 @@ Network Interface Controller Drivers
     dpaa2
     e1000em
     ena
+    enetc
     enic
     fm10k
     i40e
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 3ae6b3f58..f4a2535f4 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -50,6 +50,11 @@ New Features
      * Other libs
      * Apps, Examples, Tools (if significative)
 
+   * **Added NXP ENETC PMD.**
+
+     Added the new enetc driver for NXP enetc platform. See the
+     "ENETC Poll Mode Driver" document for more details on this new driver.
+
      This section is a comment. Do not overwrite or remove it.
      Also, make sure to start the actual text at the margin.
      =========================================================
@@ -156,6 +161,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_pmd_ixgbe.so.2
      librte_pmd_dpaa2_cmdif.so.1
      librte_pmd_dpaa2_qdma.so.1
+   + librte_pmd_enetc.so.1
      librte_pmd_ring.so.2
      librte_pmd_softnic.so.1
      librte_pmd_vhost.so.2
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver
  2018-09-28  5:16   ` [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
                       ` (2 preceding siblings ...)
  2018-09-28  5:16     ` [dpdk-dev] [PATCH v3 3/3] doc: add usage doc for ENETC PMD Gagandeep Singh
@ 2018-09-28  5:26     ` Gagandeep Singh
  2018-09-28  7:45     ` [dpdk-dev] [PATCH v4 0/4] " Gagandeep Singh
  4 siblings, 0 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-28  5:26 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: Pankaj Chauhan



> -----Original Message-----
> From: Gagandeep Singh
> Sent: Friday, September 28, 2018 10:47 AM
> To: dev@dpdk.org; ferruh.yigit@intel.com
> Cc: Pankaj Chauhan <pankaj.chauhan@nxp.com>; Gagandeep Singh
> <G.Singh@nxp.com>
> Subject: [PATCH v3 0/3] introduces the enetc PMD driver
> 
> *ENETC* PMD driver which integrates with the existing PCI bus.
> Document is also part of the set
> 
> v2->v3 Change-log:
> * Added a release note
> * commom part of documentation is removed
> * cflag Werror added in Makefile
> * private list of RX/TX queues removed
> * added the dev_start and dev_stop APIs
> * added rx/tx queue release APIs
> * packet parse type feature enabled
> 
> v1->v2 Change-log:
> * document improvement
> * checkpatch warnings removed
> 
> 
> Gagandeep Singh (3):
>   net/enetc: enable Rx and Tx
>   net/enetc: support packet parse type
>   doc: add usage doc for ENETC PMD
> 

Self NACK
One patch is missing. I will send a V4

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v4 0/4] introduces the enetc PMD driver
  2018-09-28  5:16   ` [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
                       ` (3 preceding siblings ...)
  2018-09-28  5:26     ` [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
@ 2018-09-28  7:45     ` Gagandeep Singh
  2018-09-28  7:45       ` [dpdk-dev] [PATCH v4 1/4] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
                         ` (5 more replies)
  4 siblings, 6 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-28  7:45 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

*ENETC* PMD driver which integrates with the existing PCI bus.
Document is also part of the set

v3->v4 Change-log:
* fixed patch set

v2->v3 Change-log:
* Added a release note
* commom part of documentation is removed
* cflag Werror added in Makefile
* private list of RX/TX queues removed
* added the dev_start and dev_stop APIs
* added rx/tx queue release APIs
* packet parse type feature enabled

v1->v2 Change-log:
* document improvement
* checkpatch warnings removed

Gagandeep Singh (4):
  net/enetc: add ENETC PMD with basic operations
  net/enetc: enable Rx and Tx
  net/enetc: support packet parse type
  doc: add usage doc for ENETC PMD

 MAINTAINERS                                 |   7 +
 config/common_base                          |   5 +
 config/common_linuxapp                      |   5 +
 doc/guides/nics/enetc.rst                   | 110 ++++
 doc/guides/nics/features/enetc.ini          |  11 +
 doc/guides/nics/index.rst                   |   1 +
 doc/guides/rel_notes/release_18_11.rst      |   6 +
 drivers/net/Makefile                        |   1 +
 drivers/net/enetc/Makefile                  |  23 +
 drivers/net/enetc/base/enetc_hw.h           | 220 ++++++++
 drivers/net/enetc/enetc.h                   | 113 ++++
 drivers/net/enetc/enetc_ethdev.c            | 592 ++++++++++++++++++++
 drivers/net/enetc/enetc_logs.h              |  40 ++
 drivers/net/enetc/enetc_rxtx.c              | 239 ++++++++
 drivers/net/enetc/meson.build               |  11 +
 drivers/net/enetc/rte_pmd_enetc_version.map |   4 +
 drivers/net/meson.build                     |   1 +
 mk/rte.app.mk                               |   1 +
 18 files changed, 1390 insertions(+)
 create mode 100644 doc/guides/nics/enetc.rst
 create mode 100644 doc/guides/nics/features/enetc.ini
 create mode 100644 drivers/net/enetc/Makefile
 create mode 100644 drivers/net/enetc/base/enetc_hw.h
 create mode 100644 drivers/net/enetc/enetc.h
 create mode 100644 drivers/net/enetc/enetc_ethdev.c
 create mode 100644 drivers/net/enetc/enetc_logs.h
 create mode 100644 drivers/net/enetc/enetc_rxtx.c
 create mode 100644 drivers/net/enetc/meson.build
 create mode 100644 drivers/net/enetc/rte_pmd_enetc_version.map

-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v4 1/4] net/enetc: add ENETC PMD with basic operations
  2018-09-28  7:45     ` [dpdk-dev] [PATCH v4 0/4] " Gagandeep Singh
@ 2018-09-28  7:45       ` Gagandeep Singh
  2018-10-01 15:58         ` Ferruh Yigit
  2018-09-28  7:45       ` [dpdk-dev] [PATCH v4 2/4] net/enetc: enable Rx and Tx Gagandeep Singh
                         ` (4 subsequent siblings)
  5 siblings, 1 reply; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-28  7:45 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

This patch introduces the enetc PMD with basic
initialisation functions includes probe, teardown,
hardware initialisation

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 config/common_base                          |   5 +
 config/common_linuxapp                      |   5 +
 drivers/net/Makefile                        |   1 +
 drivers/net/enetc/Makefile                  |  22 ++
 drivers/net/enetc/base/enetc_hw.h           | 217 +++++++++++++++++
 drivers/net/enetc/enetc.h                   |  90 +++++++
 drivers/net/enetc/enetc_ethdev.c            | 251 ++++++++++++++++++++
 drivers/net/enetc/enetc_logs.h              |  40 ++++
 drivers/net/enetc/meson.build               |  10 +
 drivers/net/enetc/rte_pmd_enetc_version.map |   4 +
 drivers/net/meson.build                     |   1 +
 mk/rte.app.mk                               |   1 +
 12 files changed, 647 insertions(+)
 create mode 100644 drivers/net/enetc/Makefile
 create mode 100644 drivers/net/enetc/base/enetc_hw.h
 create mode 100644 drivers/net/enetc/enetc.h
 create mode 100644 drivers/net/enetc/enetc_ethdev.c
 create mode 100644 drivers/net/enetc/enetc_logs.h
 create mode 100644 drivers/net/enetc/meson.build
 create mode 100644 drivers/net/enetc/rte_pmd_enetc_version.map

diff --git a/config/common_base b/config/common_base
index 4bcbaf923..a7fc48667 100644
--- a/config/common_base
+++ b/config/common_base
@@ -217,6 +217,11 @@ CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
 CONFIG_RTE_LIBRTE_DPAA2_PMD=n
 CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
 
+#
+# Compile NXP ENETC PMD Driver
+#
+CONFIG_RTE_LIBRTE_ENETC_PMD=n
+
 #
 # Compile burst-oriented Amazon ENA PMD driver
 #
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 9c5ea9d89..485e1467d 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -44,3 +44,8 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y
+
+#
+# NXP ENETC PMD Driver
+#
+CONFIG_RTE_LIBRTE_ENETC_PMD=y
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 664398de9..3ad436045 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -24,6 +24,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
 endif
 DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += e1000
 DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
+DIRS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc
 DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe
 DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k
diff --git a/drivers/net/enetc/Makefile b/drivers/net/enetc/Makefile
new file mode 100644
index 000000000..519153868
--- /dev/null
+++ b/drivers/net/enetc/Makefile
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_enetc.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+EXPORT_MAP := rte_pmd_enetc_version.map
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_ethdev.c
+
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_ethdev
+LDLIBS += -lrte_bus_pci
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h
new file mode 100644
index 000000000..c962b9ca1
--- /dev/null
+++ b/drivers/net/enetc/base/enetc_hw.h
@@ -0,0 +1,217 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _ENETC_HW_H_
+#define _ENETC_HW_H_
+#include <rte_io.h>
+
+#define BIT(x)		((uint64_t)1 << ((x)))
+
+/* ENETC device IDs */
+#define ENETC_DEV_ID_VF		0xef00
+#define ENETC_DEV_ID		0xe100
+
+/* ENETC register block BAR */
+#define ENETC_BAR_REGS			0x0
+
+/* SI regs, offset: 0h */
+#define ENETC_SIMR			0x0
+#define ENETC_SIMR_EN			BIT(31)
+
+#define ENETC_SIPMAR0			0x80
+#define ENETC_SIPMAR1			0x84
+
+#define ENETC_SICAPR0			0x900
+#define ENETC_SICAPR1			0x904
+
+#define ENETC_SIMSITRV(n)		(0xB00 + (n) * 0x4)
+#define ENETC_SIMSIRRV(n)		(0xB80 + (n) * 0x4)
+
+#define ENETC_SICCAPR			0x1200
+
+/* enum for BD type */
+enum enetc_bdr_type {TX, RX};
+
+#define ENETC_BDR(type, n, off)		(0x8000 + (type) * 0x100 + (n) * 0x200 \
+							+ (off))
+/* RX BDR reg offsets */
+#define ENETC_RBMR		0x0 /* RX BDR mode register*/
+#define ENETC_RBMR_EN		BIT(31)
+
+#define ENETC_RBSR		0x4  /* Rx BDR status register*/
+#define ENETC_RBBSR		0x8  /* Rx BDR buffer size register*/
+#define ENETC_RBCIR		0xc  /* Rx BDR consumer index register*/
+#define ENETC_RBBAR0		0x10 /* Rx BDR base address register 0 */
+#define ENETC_RBBAR1		0x14 /* Rx BDR base address register 1*/
+#define ENETC_RBPIR		0x18 /* Rx BDR producer index register*/
+#define ENETC_RBLENR		0x20 /* Rx BDR length register*/
+#define ENETC_RBIER		0xa0 /* Rx BDR interrupt enable register*/
+#define ENETC_RBIER_RXTIE	BIT(0)
+#define ENETC_RBIDR		0xa4 /* Rx BDR interrupt detect register*/
+#define ENETC_RBICIR0		0xa8 /* Rx BDR inetrrupt coalescing register 0*/
+#define ENETC_RBICIR0_ICEN	BIT(31)
+
+
+#define ENETC_TBMR	0x0  /* Tx BDR mode register (TBMR) 32 RW */
+#define ENETC_TBSR	0x4  /* x BDR status register (TBSR) 32 RO */
+#define ENETC_TBBAR0	0x10 /* Tx BDR base address register 0 (TBBAR0) 32 RW */
+#define ENETC_TBBAR1	0x14 /* Tx BDR base address register 1 (TBBAR1) 32 RW */
+#define ENETC_TBCIR	0x18 /* Tx BDR consumer index register (TBCIR) 32 RW */
+#define ENETC_TBCISR	0x1C /* Tx BDR consumer index shadow register 32 RW */
+#define ENETC_TBIER	0xA0 /* Tx BDR interrupt enable register 32 RW */
+#define ENETC_TBIDR	0xA4 /* Tx BDR interrupt detect register 32 RO */
+#define ENETC_TBICR0	0xA8 /* Tx BDR interrupt coalescing register 0 32 RW */
+#define ENETC_TBICR1	0xAC /* Tx BDR interrupt coalescing register 1 32 RW */
+#define ENETC_TBLENR	0x20
+
+#define ENETC_TBCISR_IDX_MASK		0xffff
+#define ENETC_TBIER_TXFIE		BIT(1)
+
+#define ENETC_RTBLENR_LEN(n)		((n) & ~0x7)
+#define ENETC_TBMR_EN			BIT(31)
+
+/* Port regs, offset: 1_0000h */
+#define ENETC_PORT_BASE			0x10000
+#define ENETC_PMR			0x00000
+#define ENETC_PMR_EN			(BIT(16) | BIT(17) | BIT(18))
+#define ENETC_PSR			0x00004 /* RO */
+#define ENETC_PSIPMR			0x00018
+#define ENETC_PSIPMR_SET_UP(n)		(0x1 << (n)) /* n = SI index */
+#define ENETC_PSIPMR_SET_MP(n)		(0x1 << ((n) + 8))
+#define ENETC_PSIPMR_SET_VLAN_MP(n)	(0x1 << ((n) + 16))
+#define ENETC_PSIPMAR0(n)		(0x00100 + (n) * 0x20)
+#define ENETC_PSIPMAR1(n)		(0x00104 + (n) * 0x20)
+#define ENETC_PCAPR0			0x00900
+#define ENETC_PCAPR1			0x00904
+
+#define ENETC_PV0CFGR(n)		(0x00920 + (n) * 0x10)
+#define ENETC_PVCFGR_SET_TXBDR(val)	((val) & 0xff)
+#define ENETC_PVCFGR_SET_RXBDR(val)	(((val) & 0xff) << 16)
+
+#define ENETC_PM0_CMD_CFG		0x08008
+#define ENETC_PM0_TX_EN			BIT(0)
+#define ENETC_PM0_RX_EN			BIT(1)
+
+#define ENETC_PM0_MAXFRM		0x08014
+#define ENETC_SET_MAXFRM(val)		((val) << 16)
+
+/* Global regs, offset: 2_0000h */
+#define ENETC_GLOBAL_BASE		0x20000
+#define ENETC_G_EIPBRR0			0x00bf8
+#define ENETC_G_EIPBRR1			0x00bfc
+
+#define ETH_ADDR_LEN			6
+
+/* general register accessors */
+#define enetc_rd_reg(reg)	rte_read32((reg))
+#define enetc_wr_reg(reg, val)	rte_write32((val), (reg))
+#define enetc_rd(hw, off)	enetc_rd_reg((hw)->reg + (off))
+#define enetc_wr(hw, off, val)	enetc_wr_reg((hw)->reg + (off), val)
+/* port register accessors - PF only */
+#define enetc_port_rd(hw, off)		enetc_rd_reg((hw)->port + (off))
+#define enetc_port_wr(hw, off, val)	enetc_wr_reg((hw)->port + (off), val)
+/* global register accessors - PF only */
+#define enetc_global_rd(hw, off)	enetc_rd_reg((hw)->global + (off))
+#define enetc_global_wr(hw, off, val)	enetc_wr_reg((hw)->global + (off), val)
+/* BDR register accessors, see ENETC_BDR() */
+#define enetc_bdr_rd(hw, t, n, off) \
+				enetc_rd(hw, ENETC_BDR(t, n, off))
+#define enetc_bdr_wr(hw, t, n, off, val) \
+				enetc_wr(hw, ENETC_BDR(t, n, off), val)
+
+#define enetc_txbdr_rd(hw, n, off) enetc_bdr_rd(hw, TX, n, off)
+#define enetc_rxbdr_rd(hw, n, off) enetc_bdr_rd(hw, RX, n, off)
+#define enetc_txbdr_wr(hw, n, off, val) \
+				enetc_bdr_wr(hw, TX, n, off, val)
+#define enetc_rxbdr_wr(hw, n, off, val) \
+				enetc_bdr_wr(hw, RX, n, off, val)
+
+#define ENETC_TX_ADDR(txq, addr) ((void *)((txq)->enetc_txbdr + (addr)))
+
+#define ENETC_TXBD_FLAGS_IE		BIT(13)
+#define ENETC_TXBD_FLAGS_F		BIT(15)
+
+/* ENETC Parsed values (Little Endian) */
+#define ENETC_PKT_TYPE_ETHER            0x0060
+#define ENETC_PKT_TYPE_IPV4             0x0000
+#define ENETC_PKT_TYPE_IPV6             0x0020
+#define ENETC_PKT_TYPE_IPV4_TCP \
+			(0x0010 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_TCP \
+			(0x0010 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_PKT_TYPE_IPV4_UDP \
+			(0x0011 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_UDP \
+			(0x0011 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_PKT_TYPE_IPV4_SCTP \
+			(0x0013 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_SCTP \
+			(0x0013 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_PKT_TYPE_IPV4_ICMP \
+			(0x0003 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_ICMP \
+			(0x0003 | ENETC_PKT_TYPE_IPV6)
+
+/* PCI device info */
+struct enetc_hw {
+	void *reg;	/* SI registers, used by all PCI functions */
+	void *port;	/* Port registers, PF only */
+	void *global;	/* IP global registers, PF only */
+};
+
+struct enetc_eth_mac_info {
+	uint8_t addr[ETH_ADDR_LEN];
+	uint8_t perm_addr[ETH_ADDR_LEN];
+	uint8_t get_link_status;
+};
+
+struct enetc_eth_hw {
+	struct rte_eth_dev *ndev;
+	struct enetc_hw hw;
+	uint16_t device_id;
+	uint16_t vendor_id;
+	uint8_t revision_id;
+	struct enetc_eth_mac_info mac;
+};
+
+/* Transmit Descriptor */
+struct enetc_tx_desc {
+	uint64_t addr;
+	uint16_t frm_len;
+	uint16_t buf_len;
+	uint32_t flags_errors;
+};
+
+/* TX Buffer Descriptors (BD) */
+struct enetc_tx_bd {
+	uint64_t addr;
+	uint16_t buf_len;
+	uint16_t frm_len;
+	uint16_t err_csum;
+	uint16_t flags;
+};
+
+/* RX buffer descriptor */
+union enetc_rx_bd {
+	struct {
+		uint64_t addr;
+		uint8_t reserved[8];
+	} w;
+	struct {
+		uint16_t inet_csum;
+		uint16_t parse_summary;
+		uint32_t rss_hash;
+		uint16_t buf_len;
+		uint16_t vlan_opt;
+		union {
+			struct {
+				uint16_t flags;
+				uint16_t error;
+			};
+			uint32_t lstatus;
+		};
+	} r;
+};
+
+#endif
diff --git a/drivers/net/enetc/enetc.h b/drivers/net/enetc/enetc.h
new file mode 100644
index 000000000..9fa7c726c
--- /dev/null
+++ b/drivers/net/enetc/enetc.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _ENETC_H_
+#define _ENETC_H_
+
+#include <rte_time.h>
+
+#include "base/enetc_hw.h"
+
+#define PCI_VENDOR_ID_FREESCALE 0x1957
+
+/* Max TX rings per ENETC. */
+#define MAX_TX_RINGS	2
+
+/* Max RX rings per ENTEC. */
+#define MAX_RX_RINGS	1
+
+/* Max BD counts per Ring. */
+#define MAX_BD_COUNT	256
+
+/*
+ * upper_32_bits - return bits 32-63 of a number
+ * @n: the number we're accessing
+ *
+ * A basic shift-right of a 64- or 32-bit quantity.  Use this to suppress
+ * the "right shift count >= width of type" warning when that quantity is
+ * 32-bits.
+ */
+#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
+
+/*
+ * lower_32_bits - return bits 0-31 of a number
+ * @n: the number we're accessing
+ */
+#define lower_32_bits(n) ((uint32_t)(n))
+
+#define ENETC_TXBD(BDR, i) (&(((struct enetc_tx_bd *)((BDR).bd_base))[i]))
+#define ENETC_RXBD(BDR, i) (&(((union enetc_rx_bd *)((BDR).bd_base))[i]))
+
+struct enetc_swbd {
+	struct rte_mbuf *buffer_addr;
+};
+
+struct enetc_bdr {
+	struct rte_eth_dev *ndev;
+	struct rte_mempool *mb_pool;   /* mbuf pool to populate RX ring. */
+	void *bd_base;			/* points to Rx or Tx BD ring */
+	union {
+		void *tcir;
+		void *rcir;
+	};
+	uint16_t index;
+	int bd_count; /* # of BDs */
+	int next_to_use;
+	int next_to_clean;
+	struct enetc_swbd *q_swbd;
+	union {
+		void *tcisr; /* Tx */
+		int next_to_alloc; /* Rx */
+	};
+};
+
+/*
+ * Structure to store private data for each driver instance (for each port).
+ */
+struct enetc_eth_adapter {
+	struct rte_eth_dev *ndev;
+	struct enetc_eth_hw hw;
+};
+
+#define ENETC_DEV_PRIVATE(adapter) \
+	((struct enetc_eth_adapter *)adapter)
+
+#define ENETC_DEV_PRIVATE_TO_HW(adapter) \
+	(&((struct enetc_eth_adapter *)adapter)->hw)
+
+#define ENETC_DEV_PRIVATE_TO_STATS(adapter) \
+	(&((struct enetc_eth_adapter *)adapter)->stats)
+
+#define ENETC_DEV_PRIVATE_TO_INTR(adapter) \
+	(&((struct enetc_eth_adapter *)adapter)->intr)
+
+#define ENETC_GET_HW_ADDR(reg, addr) ((void *)(((size_t)reg) + (addr)))
+#define ENETC_REG_READ(addr) (*(uint32_t *)addr)
+#define ENETC_REG_WRITE(addr, val) (*(uint32_t *)addr = val)
+#define ENETC_REG_WRITE_RELAXED(addr, val) (*(uint32_t *)addr = val)
+
+#endif /* _ENETC_H_ */
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
new file mode 100644
index 000000000..47e2a8ebf
--- /dev/null
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -0,0 +1,251 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <stdbool.h>
+#include <rte_ethdev_pci.h>
+
+#include "enetc_logs.h"
+#include "enetc.h"
+
+int enetc_logtype_pmd;
+
+/* Functions Prototypes */
+static int enetc_dev_configure(struct rte_eth_dev *dev);
+static int enetc_dev_start(struct rte_eth_dev *dev);
+static void enetc_dev_stop(struct rte_eth_dev *dev);
+static void enetc_dev_close(struct rte_eth_dev *dev);
+static void enetc_dev_infos_get(struct rte_eth_dev *dev,
+				struct rte_eth_dev_info *dev_info);
+static int enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete);
+static int enetc_hardware_init(struct enetc_eth_hw *hw);
+
+/*
+ * The set of PCI devices this driver supports
+ */
+static const struct rte_pci_id pci_id_enetc_map[] = {
+	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID) },
+	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_VF) },
+	{ .vendor_id = 0, /* sentinel */ },
+};
+
+/* Features supported by this driver */
+static const struct eth_dev_ops enetc_ops = {
+	.dev_configure        = enetc_dev_configure,
+	.dev_start            = enetc_dev_start,
+	.dev_stop             = enetc_dev_stop,
+	.dev_close            = enetc_dev_close,
+	.link_update          = enetc_link_update,
+	.dev_infos_get        = enetc_dev_infos_get,
+};
+
+/**
+ * Initialisation of the enetc device
+ *
+ * @param eth_dev
+ *   - Pointer to the structure rte_eth_dev
+ *
+ * @return
+ *   - On success, zero.
+ *   - On failure, negative value.
+ */
+static int
+enetc_dev_init(struct rte_eth_dev *eth_dev)
+{
+	int error = 0;
+	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	struct enetc_eth_hw *hw =
+		ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+
+	PMD_INIT_FUNC_TRACE();
+	eth_dev->dev_ops = &enetc_ops;
+	eth_dev->rx_pkt_burst = NULL;
+	eth_dev->tx_pkt_burst = NULL;
+
+	/* Retrieving and storing the HW base address of device */
+	hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
+	hw->device_id = pci_dev->id.device_id;
+
+	error = enetc_hardware_init(hw);
+	if (error != 0) {
+		ENETC_PMD_ERR("Hardware initialization failed");
+		return -1;
+	}
+
+	/* Allocate memory for storing MAC addresses */
+	eth_dev->data->mac_addrs = rte_zmalloc("enetc_eth", ETHER_ADDR_LEN, 0);
+	if (!eth_dev->data->mac_addrs) {
+		ENETC_PMD_ERR("Failed to allocate %d bytes needed to "
+			      "store MAC addresses",
+			      ETHER_ADDR_LEN * 1);
+		error = -ENOMEM;
+		return -1;
+	}
+
+	/* Copy the permanent MAC address */
+	ether_addr_copy((struct ether_addr *)hw->mac.addr,
+			&eth_dev->data->mac_addrs[0]);
+
+	ENETC_PMD_DEBUG("port_id %d vendorID=0x%x deviceID=0x%x",
+			eth_dev->data->port_id, pci_dev->id.vendor_id,
+			pci_dev->id.device_id);
+	return 0;
+}
+
+static int
+enetc_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused)
+{
+	PMD_INIT_FUNC_TRACE();
+	return 0;
+}
+
+static int
+enetc_dev_configure(struct rte_eth_dev *dev __rte_unused)
+{
+	PMD_INIT_FUNC_TRACE();
+	return 0;
+}
+
+static int
+enetc_dev_start(struct rte_eth_dev *dev)
+{
+	struct enetc_eth_hw *hw =
+		ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t val;
+
+	PMD_INIT_FUNC_TRACE();
+	val = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port,
+			     ENETC_PM0_CMD_CFG));
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PM0_CMD_CFG),
+			val | ENETC_PM0_TX_EN | ENETC_PM0_RX_EN);
+
+	/* Enable port */
+	val = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR));
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR),
+			val | ENETC_PMR_EN);
+
+	return 0;
+}
+
+static void
+enetc_dev_stop(struct rte_eth_dev *dev)
+{
+	struct enetc_eth_hw *hw =
+		ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t val;
+
+	PMD_INIT_FUNC_TRACE();
+	/* Disable port */
+	val = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR));
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR),
+			val & (~ENETC_PMR_EN));
+
+	val = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port,
+			     ENETC_PM0_CMD_CFG));
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PM0_CMD_CFG),
+			val & (~(ENETC_PM0_TX_EN | ENETC_PM0_RX_EN)));
+}
+
+static void
+enetc_dev_close(struct rte_eth_dev *dev __rte_unused)
+{
+	PMD_INIT_FUNC_TRACE();
+}
+
+/* return 0 means link status changed, -1 means not changed */
+static int
+enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
+{
+	struct enetc_eth_hw *hw =
+		ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_eth_link link;
+
+	PMD_INIT_FUNC_TRACE();
+	hw->mac.get_link_status = 1;
+
+	memset(&link, 0, sizeof(link));
+	rte_eth_linkstatus_get(dev, &link);
+
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
+	link.link_status = ETH_LINK_UP;
+	rte_eth_linkstatus_set(dev, &link);
+
+	return 0;
+}
+
+static int
+enetc_hardware_init(struct enetc_eth_hw *hw)
+{
+	uint32_t psipmr = 0;
+
+	PMD_INIT_FUNC_TRACE();
+	/* Calculating and storing the base HW addresses */
+	hw->hw.port = (void *)((size_t)hw->hw.reg + ENETC_PORT_BASE);
+	hw->hw.global = (void *)((size_t)hw->hw.reg + ENETC_GLOBAL_BASE);
+
+	/* Enabling Station Interface */
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.reg, ENETC_SIMR),
+					  ENETC_SIMR_EN);
+
+	/* Setting to accept broadcast packets for each inetrface */
+	psipmr |= ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0) |
+		  ENETC_PSIPMR_SET_VLAN_MP(0);
+	psipmr |= ENETC_PSIPMR_SET_UP(1) | ENETC_PSIPMR_SET_MP(1) |
+		  ENETC_PSIPMR_SET_VLAN_MP(1);
+	psipmr |= ENETC_PSIPMR_SET_UP(2) | ENETC_PSIPMR_SET_MP(2) |
+		  ENETC_PSIPMR_SET_VLAN_MP(2);
+
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMR),
+			psipmr);
+
+	/* Enabling broadcast address */
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMAR0(0)),
+			0xFFFFFFFF);
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMAR1(0)),
+			0xFFFF << 16);
+
+	return 0;
+}
+
+static void
+enetc_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
+		    struct rte_eth_dev_info *dev_info)
+{
+	PMD_INIT_FUNC_TRACE();
+	dev_info->max_rx_queues = MAX_RX_RINGS;
+	dev_info->max_tx_queues = MAX_TX_RINGS;
+	dev_info->max_rx_pktlen = 1500;
+}
+
+static int
+enetc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+			   struct rte_pci_device *pci_dev)
+{
+	return rte_eth_dev_pci_generic_probe(pci_dev,
+					     sizeof(struct enetc_eth_adapter),
+					     enetc_dev_init);
+}
+
+static int
+enetc_pci_remove(struct rte_pci_device *pci_dev)
+{
+	return rte_eth_dev_pci_generic_remove(pci_dev, enetc_dev_uninit);
+}
+
+static struct rte_pci_driver rte_enetc_pmd = {
+	.id_table = pci_id_enetc_map,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
+	.probe = enetc_pci_probe,
+	.remove = enetc_pci_remove,
+};
+
+RTE_PMD_REGISTER_PCI(net_enetc, rte_enetc_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(net_enetc, pci_id_enetc_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_enetc, "* vfio-pci");
+
+RTE_INIT(enetc_pmd_init_log)
+{
+	enetc_logtype_pmd = rte_log_register("pmd.net.enetc");
+	if (enetc_logtype_pmd >= 0)
+		rte_log_set_level(enetc_logtype_pmd, RTE_LOG_NOTICE);
+}
diff --git a/drivers/net/enetc/enetc_logs.h b/drivers/net/enetc/enetc_logs.h
new file mode 100644
index 000000000..c8a6c0cf3
--- /dev/null
+++ b/drivers/net/enetc/enetc_logs.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _ENETC_LOGS_H_
+#define _ENETC_LOGS_H_
+
+extern int enetc_logtype_pmd;
+
+#define ENETC_PMD_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, enetc_logtype_pmd, "enetc_net: " \
+		fmt "\n", ##args)
+
+#define ENETC_PMD_DEBUG(fmt, args...) \
+	rte_log(RTE_LOG_DEBUG, enetc_logtype_pmd, "enetc_net: %s(): "\
+		fmt "\n", __func__, ##args)
+
+#define PMD_INIT_FUNC_TRACE() ENETC_PMD_DEBUG(">>")
+
+#define ENETC_PMD_CRIT(fmt, args...) \
+	ENETC_PMD_LOG(CRIT, fmt, ## args)
+#define ENETC_PMD_INFO(fmt, args...) \
+	ENETC_PMD_LOG(INFO, fmt, ## args)
+#define ENETC_PMD_ERR(fmt, args...) \
+	ENETC_PMD_LOG(ERR, fmt, ## args)
+#define ENETC_PMD_WARN(fmt, args...) \
+	ENETC_PMD_LOG(WARNING, fmt, ## args)
+
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define ENETC_PMD_DP_LOG(level, fmt, args...) \
+	RTE_LOG_DP(level, PMD, fmt, ## args)
+
+#define ENETC_PMD_DP_DEBUG(fmt, args...) \
+	ENETC_PMD_DP_LOG(DEBUG, fmt, ## args)
+#define ENETC_PMD_DP_INFO(fmt, args...) \
+	ENETC_PMD_DP_LOG(INFO, fmt, ## args)
+#define ENETC_PMD_DP_WARN(fmt, args...) \
+	ENETC_PMD_DP_LOG(WARNING, fmt, ## args)
+
+#endif /* _ENETC_LOGS_H_*/
diff --git a/drivers/net/enetc/meson.build b/drivers/net/enetc/meson.build
new file mode 100644
index 000000000..506b174ed
--- /dev/null
+++ b/drivers/net/enetc/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+if host_machine.system() != 'linux'
+	build = false
+endif
+
+sources = files('enetc_ethdev.c')
+
+includes += include_directories('base')
diff --git a/drivers/net/enetc/rte_pmd_enetc_version.map b/drivers/net/enetc/rte_pmd_enetc_version.map
new file mode 100644
index 000000000..521e51f41
--- /dev/null
+++ b/drivers/net/enetc/rte_pmd_enetc_version.map
@@ -0,0 +1,4 @@
+DPDK_18.11 {
+
+	local: *;
+};
diff --git a/drivers/net/meson.build b/drivers/net/meson.build
index 9c28ed4da..65aa6f60c 100644
--- a/drivers/net/meson.build
+++ b/drivers/net/meson.build
@@ -11,6 +11,7 @@ drivers = ['af_packet',
 	'dpaa', 'dpaa2',
 	'e1000',
 	'ena',
+	'enetc',
 	'enic',
 	'failsafe',
 	'fm10k', 'i40e',
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index de33883be..154ae3b2c 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -135,6 +135,7 @@ endif
 _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD)        += -lrte_pmd_ena
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD)       += -lrte_pmd_enic
+_LDLIBS-$(CONFIG_RTE_LIBRTE_ENETC_PMD)      += -lrte_pmd_enetc
 _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD)      += -lrte_pmd_fm10k
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE)   += -lrte_pmd_failsafe
 _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD)       += -lrte_pmd_i40e
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v4 2/4] net/enetc: enable Rx and Tx
  2018-09-28  7:45     ` [dpdk-dev] [PATCH v4 0/4] " Gagandeep Singh
  2018-09-28  7:45       ` [dpdk-dev] [PATCH v4 1/4] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
@ 2018-09-28  7:45       ` Gagandeep Singh
  2018-10-01 15:59         ` Ferruh Yigit
  2018-09-28  7:46       ` [dpdk-dev] [PATCH v4 3/4] net/enetc: support packet parse type Gagandeep Singh
                         ` (3 subsequent siblings)
  5 siblings, 1 reply; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-28  7:45 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

Add RX and TX queue setup, datapath functions

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 drivers/net/enetc/Makefile        |   3 +-
 drivers/net/enetc/base/enetc_hw.h |  19 +-
 drivers/net/enetc/enetc.h         |  25 ++-
 drivers/net/enetc/enetc_ethdev.c  | 326 +++++++++++++++++++++++++++++-
 drivers/net/enetc/enetc_rxtx.c    | 239 ++++++++++++++++++++++
 drivers/net/enetc/meson.build     |   3 +-
 6 files changed, 602 insertions(+), 13 deletions(-)
 create mode 100644 drivers/net/enetc/enetc_rxtx.c

diff --git a/drivers/net/enetc/Makefile b/drivers/net/enetc/Makefile
index 519153868..9895501db 100644
--- a/drivers/net/enetc/Makefile
+++ b/drivers/net/enetc/Makefile
@@ -14,8 +14,9 @@ EXPORT_MAP := rte_pmd_enetc_version.map
 LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_rxtx.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
 LDLIBS += -lrte_ethdev
 LDLIBS += -lrte_bus_pci
 
diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h
index c962b9ca1..c74c94875 100644
--- a/drivers/net/enetc/base/enetc_hw.h
+++ b/drivers/net/enetc/base/enetc_hw.h
@@ -104,16 +104,19 @@ enum enetc_bdr_type {TX, RX};
 #define ETH_ADDR_LEN			6
 
 /* general register accessors */
-#define enetc_rd_reg(reg)	rte_read32((reg))
-#define enetc_wr_reg(reg, val)	rte_write32((val), (reg))
-#define enetc_rd(hw, off)	enetc_rd_reg((hw)->reg + (off))
-#define enetc_wr(hw, off, val)	enetc_wr_reg((hw)->reg + (off), val)
+#define enetc_rd_reg(reg)	rte_read32((void *)(reg))
+#define enetc_wr_reg(reg, val)	rte_write32((val), (void *)(reg))
+#define enetc_rd(hw, off)	enetc_rd_reg((size_t)(hw)->reg + (off))
+#define enetc_wr(hw, off, val)	enetc_wr_reg((size_t)(hw)->reg + (off), val)
 /* port register accessors - PF only */
-#define enetc_port_rd(hw, off)		enetc_rd_reg((hw)->port + (off))
-#define enetc_port_wr(hw, off, val)	enetc_wr_reg((hw)->port + (off), val)
+#define enetc_port_rd(hw, off)	enetc_rd_reg((size_t)(hw)->port + (off))
+#define enetc_port_wr(hw, off, val) \
+				enetc_wr_reg((size_t)(hw)->port + (off), val)
 /* global register accessors - PF only */
-#define enetc_global_rd(hw, off)	enetc_rd_reg((hw)->global + (off))
-#define enetc_global_wr(hw, off, val)	enetc_wr_reg((hw)->global + (off), val)
+#define enetc_global_rd(hw, off) \
+				enetc_rd_reg((size_t)(hw)->global + (off))
+#define enetc_global_wr(hw, off, val) \
+				enetc_wr_reg((size_t)(hw)->global + (off), val)
 /* BDR register accessors, see ENETC_BDR() */
 #define enetc_bdr_rd(hw, t, n, off) \
 				enetc_rd(hw, ENETC_BDR(t, n, off))
diff --git a/drivers/net/enetc/enetc.h b/drivers/net/enetc/enetc.h
index 9fa7c726c..140daf0dd 100644
--- a/drivers/net/enetc/enetc.h
+++ b/drivers/net/enetc/enetc.h
@@ -18,7 +18,11 @@
 #define MAX_RX_RINGS	1
 
 /* Max BD counts per Ring. */
-#define MAX_BD_COUNT	256
+#define MAX_BD_COUNT	64000
+/* Min BD counts per Ring. */
+#define MIN_BD_COUNT	32
+/* BD ALIGN */
+#define BD_ALIGN	8
 
 /*
  * upper_32_bits - return bits 32-63 of a number
@@ -87,4 +91,23 @@ struct enetc_eth_adapter {
 #define ENETC_REG_WRITE(addr, val) (*(uint32_t *)addr = val)
 #define ENETC_REG_WRITE_RELAXED(addr, val) (*(uint32_t *)addr = val)
 
+/*
+ * RX/TX ENETC function prototypes
+ */
+uint16_t enetc_xmit_pkts(void *txq, struct rte_mbuf **tx_pkts,
+		uint16_t nb_pkts);
+uint16_t enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts);
+
+
+int enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt);
+
+static inline int
+enetc_bd_unused(struct enetc_bdr *bdr)
+{
+	if (bdr->next_to_clean > bdr->next_to_use)
+		return bdr->next_to_clean - bdr->next_to_use - 1;
+
+	return bdr->bd_count + bdr->next_to_clean - bdr->next_to_use - 1;
+}
 #endif /* _ENETC_H_ */
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index 47e2a8ebf..2d90d8fd5 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -19,6 +19,15 @@ static void enetc_dev_infos_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete);
 static int enetc_hardware_init(struct enetc_eth_hw *hw);
+static int enetc_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);
+static void enetc_rx_queue_release(void *rxq);
+static int enetc_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);
+static void enetc_tx_queue_release(void *txq);
 
 /*
  * The set of PCI devices this driver supports
@@ -37,6 +46,10 @@ static const struct eth_dev_ops enetc_ops = {
 	.dev_close            = enetc_dev_close,
 	.link_update          = enetc_link_update,
 	.dev_infos_get        = enetc_dev_infos_get,
+	.rx_queue_setup       = enetc_rx_queue_setup,
+	.rx_queue_release     = enetc_rx_queue_release,
+	.tx_queue_setup       = enetc_tx_queue_setup,
+	.tx_queue_release     = enetc_tx_queue_release,
 };
 
 /**
@@ -59,8 +72,8 @@ enetc_dev_init(struct rte_eth_dev *eth_dev)
 
 	PMD_INIT_FUNC_TRACE();
 	eth_dev->dev_ops = &enetc_ops;
-	eth_dev->rx_pkt_burst = NULL;
-	eth_dev->tx_pkt_burst = NULL;
+	eth_dev->rx_pkt_burst = &enetc_recv_pkts;
+	eth_dev->tx_pkt_burst = &enetc_xmit_pkts;
 
 	/* Retrieving and storing the HW base address of device */
 	hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
@@ -212,11 +225,320 @@ enetc_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
 		    struct rte_eth_dev_info *dev_info)
 {
 	PMD_INIT_FUNC_TRACE();
+	dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
+		.nb_max = MAX_BD_COUNT,
+		.nb_min = MIN_BD_COUNT,
+		.nb_align = BD_ALIGN,
+	};
+	dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
+		.nb_max = MAX_BD_COUNT,
+		.nb_min = MIN_BD_COUNT,
+		.nb_align = BD_ALIGN,
+	};
 	dev_info->max_rx_queues = MAX_RX_RINGS;
 	dev_info->max_tx_queues = MAX_TX_RINGS;
 	dev_info->max_rx_pktlen = 1500;
 }
 
+static int
+enetc_alloc_txbdr(struct enetc_bdr *txr, uint16_t nb_desc)
+{
+	int size;
+
+	size = nb_desc * sizeof(struct enetc_swbd);
+	txr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (txr->q_swbd == NULL)
+		return -ENOMEM;
+
+	size = nb_desc * sizeof(struct enetc_tx_bd);
+	txr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (txr->bd_base == NULL) {
+		rte_free(txr->q_swbd);
+		txr->q_swbd = NULL;
+		return -ENOMEM;
+	}
+
+	txr->bd_count = nb_desc;
+	txr->next_to_clean = 0;
+	txr->next_to_use = 0;
+
+	return 0;
+}
+
+static void
+enetc_free_bdr(struct enetc_bdr *rxr)
+{
+	rte_free(rxr->q_swbd);
+	rte_free(rxr->bd_base);
+	rxr->q_swbd = NULL;
+	rxr->bd_base = NULL;
+}
+
+static void
+enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+{
+	int idx = tx_ring->index;
+	uintptr_t base_addr;
+	uint32_t tbmr;
+
+	base_addr = (uintptr_t)tx_ring->bd_base;
+	enetc_txbdr_wr(hw, idx, ENETC_TBBAR0,
+		       lower_32_bits((uint64_t)base_addr));
+	enetc_txbdr_wr(hw, idx, ENETC_TBBAR1,
+		       upper_32_bits((uint64_t)base_addr));
+	enetc_txbdr_wr(hw, idx, ENETC_TBLENR,
+		       ENETC_RTBLENR_LEN(tx_ring->bd_count));
+
+	tbmr = ENETC_TBMR_EN;
+	/* enable ring */
+	enetc_txbdr_wr(hw, idx, ENETC_TBMR, tbmr);
+	enetc_txbdr_wr(hw, idx, ENETC_TBCIR, 0);
+	enetc_txbdr_wr(hw, idx, ENETC_TBCISR, 0);
+	tx_ring->tcir = (void *)((size_t)hw->reg +
+			ENETC_BDR(TX, idx, ENETC_TBCIR));
+	tx_ring->tcisr = (void *)((size_t)hw->reg +
+			 ENETC_BDR(TX, idx, ENETC_TBCISR));
+}
+
+static int
+enetc_alloc_tx_resources(struct rte_eth_dev *dev,
+			 uint16_t queue_idx,
+			 uint16_t nb_desc)
+{
+	int err;
+	struct enetc_bdr *tx_ring;
+	struct rte_eth_dev_data *data = dev->data;
+	struct enetc_eth_adapter *priv =
+			ENETC_DEV_PRIVATE(data->dev_private);
+
+	tx_ring = rte_zmalloc(NULL, sizeof(struct enetc_bdr), 0);
+	if (tx_ring == NULL) {
+		ENETC_PMD_ERR("Failed to allocate TX ring memory");
+		err = -ENOMEM;
+		return -1;
+	}
+
+	err = enetc_alloc_txbdr(tx_ring, nb_desc);
+	if (err)
+		goto fail;
+
+	tx_ring->index = queue_idx;
+	tx_ring->ndev = dev;
+	enetc_setup_txbdr(&priv->hw.hw, tx_ring);
+	data->tx_queues[queue_idx] = tx_ring;
+
+	return 0;
+fail:
+	rte_free(tx_ring);
+
+	return err;
+}
+
+static int
+enetc_tx_queue_setup(struct rte_eth_dev *dev,
+		     uint16_t queue_idx,
+		     uint16_t nb_desc,
+		     unsigned int socket_id __rte_unused,
+		     const struct rte_eth_txconf *tx_conf __rte_unused)
+{
+	int err = 0;
+
+	PMD_INIT_FUNC_TRACE();
+	if (nb_desc > MAX_BD_COUNT)
+		return -1;
+
+	err = enetc_alloc_tx_resources(dev, queue_idx, nb_desc);
+
+	return err;
+}
+
+static void
+enetc_tx_queue_release(void *txq)
+{
+	if (txq == NULL)
+		return;
+
+	struct enetc_bdr *tx_ring = (struct enetc_bdr *)txq;
+	struct enetc_eth_hw *eth_hw =
+		ENETC_DEV_PRIVATE_TO_HW(tx_ring->ndev->data->dev_private);
+	struct enetc_hw *hw;
+	struct enetc_swbd *tx_swbd;
+	int i;
+	uint32_t val;
+
+	/* Disable the ring */
+	hw = &eth_hw->hw;
+	val = enetc_txbdr_rd(hw, tx_ring->index, ENETC_TBMR);
+	val &= (~ENETC_TBMR_EN);
+	enetc_txbdr_wr(hw, tx_ring->index, ENETC_TBMR, val);
+
+	/* clean the ring*/
+	i = tx_ring->next_to_clean;
+	tx_swbd = &tx_ring->q_swbd[i];
+	while (tx_swbd->buffer_addr != NULL) {
+		rte_pktmbuf_free(tx_swbd->buffer_addr);
+		tx_swbd->buffer_addr = NULL;
+		tx_swbd++;
+		i++;
+		if (unlikely(i == tx_ring->bd_count)) {
+			i = 0;
+			tx_swbd = &tx_ring->q_swbd[i];
+		}
+	}
+
+	enetc_free_bdr(tx_ring);
+	rte_free(tx_ring);
+}
+
+static int
+enetc_alloc_rxbdr(struct enetc_bdr *rxr,
+		  uint16_t nb_rx_desc)
+{
+	int size;
+
+	size = nb_rx_desc * sizeof(struct enetc_swbd);
+	rxr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (rxr->q_swbd == NULL)
+		return -ENOMEM;
+
+	size = nb_rx_desc * sizeof(union enetc_rx_bd);
+	rxr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (rxr->bd_base == NULL) {
+		rte_free(rxr->q_swbd);
+		rxr->q_swbd = NULL;
+		return -ENOMEM;
+	}
+
+	rxr->bd_count = nb_rx_desc;
+	rxr->next_to_clean = 0;
+	rxr->next_to_use = 0;
+	rxr->next_to_alloc = 0;
+
+	return 0;
+}
+
+static void
+enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring,
+		  struct rte_mempool *mb_pool)
+{
+	int idx = rx_ring->index;
+	uintptr_t base_addr;
+	uint16_t buf_size;
+
+	base_addr = (uintptr_t)rx_ring->bd_base;
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBAR0,
+		       lower_32_bits((uint64_t)base_addr));
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBAR1,
+		       upper_32_bits((uint64_t)base_addr));
+	enetc_rxbdr_wr(hw, idx, ENETC_RBLENR,
+		       ENETC_RTBLENR_LEN(rx_ring->bd_count));
+
+	rx_ring->mb_pool = mb_pool;
+	/* enable ring */
+	enetc_rxbdr_wr(hw, idx, ENETC_RBMR, ENETC_RBMR_EN);
+	enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
+	rx_ring->rcir = (void *)((size_t)hw->reg +
+			ENETC_BDR(RX, idx, ENETC_RBCIR));
+	enetc_refill_rx_ring(rx_ring, (enetc_bd_unused(rx_ring)));
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rx_ring->mb_pool) -
+		   RTE_PKTMBUF_HEADROOM);
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBSR, buf_size);
+}
+
+static int
+enetc_alloc_rx_resources(struct rte_eth_dev *dev,
+			 uint16_t rx_queue_id,
+			 uint16_t nb_rx_desc,
+			 struct rte_mempool *mb_pool)
+{
+	int err;
+	struct enetc_bdr *rx_ring;
+	struct rte_eth_dev_data *data =  dev->data;
+	struct enetc_eth_adapter *adapter =
+			ENETC_DEV_PRIVATE(data->dev_private);
+
+	rx_ring = rte_zmalloc(NULL, sizeof(struct enetc_bdr), 0);
+	if (rx_ring == NULL) {
+		ENETC_PMD_ERR("Failed to allocate RX ring memory");
+		err = -ENOMEM;
+		return err;
+	}
+
+	err = enetc_alloc_rxbdr(rx_ring, nb_rx_desc);
+	if (err)
+		goto fail;
+
+	rx_ring->index = rx_queue_id;
+	rx_ring->ndev = dev;
+	enetc_setup_rxbdr(&adapter->hw.hw, rx_ring, mb_pool);
+	data->rx_queues[rx_queue_id] = rx_ring;
+
+	return 0;
+fail:
+	rte_free(rx_ring);
+
+	return err;
+}
+
+static int
+enetc_rx_queue_setup(struct rte_eth_dev *dev,
+		     uint16_t rx_queue_id,
+		     uint16_t nb_rx_desc,
+		     unsigned int socket_id __rte_unused,
+		     const struct rte_eth_rxconf *rx_conf __rte_unused,
+		     struct rte_mempool *mb_pool)
+{
+	int err = 0;
+
+	PMD_INIT_FUNC_TRACE();
+	if (nb_rx_desc > MAX_BD_COUNT)
+		return -1;
+
+	err = enetc_alloc_rx_resources(dev, rx_queue_id,
+				       nb_rx_desc,
+				       mb_pool);
+
+	return err;
+}
+
+static void
+enetc_rx_queue_release(void *rxq)
+{
+	if (rxq == NULL)
+		return;
+
+	struct enetc_bdr *rx_ring = (struct enetc_bdr *)rxq;
+	struct enetc_eth_hw *eth_hw =
+		ENETC_DEV_PRIVATE_TO_HW(rx_ring->ndev->data->dev_private);
+	struct enetc_swbd *q_swbd;
+	struct enetc_hw *hw;
+	uint32_t val;
+	int i;
+
+	/* Disable the ring */
+	hw = &eth_hw->hw;
+	val = enetc_rxbdr_rd(hw, rx_ring->index, ENETC_RBMR);
+	val &= (~ENETC_RBMR_EN);
+	enetc_rxbdr_wr(hw, rx_ring->index, ENETC_RBMR, val);
+
+	/* Clean the ring */
+	i = rx_ring->next_to_clean;
+	q_swbd = &rx_ring->q_swbd[i];
+	while (i != rx_ring->next_to_use) {
+		rte_pktmbuf_free(q_swbd->buffer_addr);
+		q_swbd->buffer_addr = NULL;
+		q_swbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			q_swbd = &rx_ring->q_swbd[i];
+		}
+	}
+
+	enetc_free_bdr(rx_ring);
+	rte_free(rx_ring);
+}
+
 static int
 enetc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 			   struct rte_pci_device *pci_dev)
diff --git a/drivers/net/enetc/enetc_rxtx.c b/drivers/net/enetc/enetc_rxtx.c
new file mode 100644
index 000000000..631e2430d
--- /dev/null
+++ b/drivers/net/enetc/enetc_rxtx.c
@@ -0,0 +1,239 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "rte_ethdev.h"
+#include "rte_malloc.h"
+#include "rte_memzone.h"
+
+#include "base/enetc_hw.h"
+#include "enetc.h"
+#include "enetc_logs.h"
+
+#define ENETC_RXBD_BUNDLE 8 /* Number of BDs to update at once */
+
+static int
+enetc_clean_tx_ring(struct enetc_bdr *tx_ring)
+{
+	int tx_frm_cnt = 0;
+	struct enetc_swbd *tx_swbd;
+	int i;
+
+	i = tx_ring->next_to_clean;
+	tx_swbd = &tx_ring->q_swbd[i];
+	while ((int)(enetc_rd_reg(tx_ring->tcisr) &
+	       ENETC_TBCISR_IDX_MASK) != i) {
+		rte_pktmbuf_free(tx_swbd->buffer_addr);
+		tx_swbd->buffer_addr = NULL;
+		tx_swbd++;
+		i++;
+		if (unlikely(i == tx_ring->bd_count)) {
+			i = 0;
+			tx_swbd = &tx_ring->q_swbd[0];
+		}
+
+		tx_frm_cnt++;
+	}
+
+	tx_ring->next_to_clean = i;
+	return tx_frm_cnt++;
+}
+
+uint16_t
+enetc_xmit_pkts(void *tx_queue,
+		struct rte_mbuf **tx_pkts,
+		uint16_t nb_pkts)
+{
+	struct enetc_swbd *tx_swbd;
+	int i, start;
+	struct enetc_tx_bd *txbd;
+	struct enetc_bdr *tx_ring = (struct enetc_bdr *)tx_queue;
+
+	i = tx_ring->next_to_use;
+	start = 0;
+	while (nb_pkts--) {
+		enetc_clean_tx_ring(tx_ring);
+		tx_ring->q_swbd[i].buffer_addr = tx_pkts[start];
+		txbd = ENETC_TXBD(*tx_ring, i);
+		tx_swbd = &tx_ring->q_swbd[i];
+		txbd->frm_len = tx_pkts[start]->pkt_len;
+		txbd->buf_len = txbd->frm_len;
+		txbd->flags = rte_cpu_to_le_16(ENETC_TXBD_FLAGS_F);
+		txbd->addr = (uint64_t)(uintptr_t)
+		rte_cpu_to_le_64((size_t)tx_swbd->buffer_addr->buf_addr +
+				 tx_swbd->buffer_addr->data_off);
+		i++;
+		start++;
+		if (unlikely(i == tx_ring->bd_count))
+			i = 0;
+	}
+
+	tx_ring->next_to_use = i;
+	enetc_wr_reg(tx_ring->tcir, i);
+	return start;
+}
+
+int
+enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt)
+{
+	struct enetc_swbd *rx_swbd;
+	union enetc_rx_bd *rxbd;
+	int i, j;
+
+	i = rx_ring->next_to_use;
+	rx_swbd = &rx_ring->q_swbd[i];
+	rxbd = ENETC_RXBD(*rx_ring, i);
+	for (j = 0; j < buff_cnt; j++) {
+		rx_swbd->buffer_addr =
+			rte_cpu_to_le_64(rte_mbuf_raw_alloc(rx_ring->mb_pool));
+		rxbd->w.addr = (uint64_t)(uintptr_t)
+			       rx_swbd->buffer_addr->buf_addr +
+			       rx_swbd->buffer_addr->data_off;
+		/* clear 'R" as well */
+		rxbd->r.lstatus = 0;
+		rx_swbd++;
+		rxbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			rxbd = ENETC_RXBD(*rx_ring, 0);
+			rx_swbd = &rx_ring->q_swbd[i];
+		}
+	}
+
+	if (likely(j)) {
+		rx_ring->next_to_alloc = i;
+		rx_ring->next_to_use = i;
+		enetc_wr_reg(rx_ring->rcir, i);
+	}
+
+	return j;
+}
+
+
+static inline void __attribute__((hot))
+enetc_dev_rx_parse(struct rte_mbuf *m, uint16_t parse_results)
+{
+	ENETC_PMD_DP_DEBUG("parse summary = 0x%x   ", parse_results);
+
+	m->packet_type = RTE_PTYPE_UNKNOWN;
+	switch (parse_results) {
+	case ENETC_PKT_TYPE_ETHER:
+		m->packet_type = RTE_PTYPE_L2_ETHER;
+		break;
+	case ENETC_PKT_TYPE_IPV4:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4;
+		break;
+	case ENETC_PKT_TYPE_IPV6:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6;
+		break;
+	case ENETC_PKT_TYPE_IPV4_TCP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_TCP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_TCP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_TCP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_UDP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_UDP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_UDP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_UDP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_SCTP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_SCTP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_SCTP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_SCTP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_ICMP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_ICMP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_ICMP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_ICMP;
+		break;
+	/* More switch cases can be added */
+	default:
+		m->packet_type = RTE_PTYPE_UNKNOWN;
+	}
+}
+
+static int
+enetc_clean_rx_ring(struct enetc_bdr *rx_ring,
+		    struct rte_mbuf **rx_pkts,
+		    int work_limit)
+{
+	int rx_frm_cnt = 0;
+	int cleaned_cnt, i;
+	struct enetc_swbd *rx_swbd;
+
+	cleaned_cnt = enetc_bd_unused(rx_ring);
+	/* next descriptor to process */
+	i = rx_ring->next_to_clean;
+	rx_swbd = &rx_ring->q_swbd[i];
+	while (likely(rx_frm_cnt < work_limit)) {
+		union enetc_rx_bd *rxbd;
+		uint32_t bd_status;
+
+		if (cleaned_cnt >= ENETC_RXBD_BUNDLE) {
+			int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt);
+
+			cleaned_cnt -= count;
+		}
+
+		rxbd = ENETC_RXBD(*rx_ring, i);
+		bd_status = rte_le_to_cpu_32(rxbd->r.lstatus);
+		if (!bd_status)
+			break;
+
+		rx_swbd->buffer_addr->pkt_len = rxbd->r.buf_len;
+		rx_swbd->buffer_addr->data_len = rxbd->r.buf_len;
+		rx_swbd->buffer_addr->hash.rss = rxbd->r.rss_hash;
+		rx_swbd->buffer_addr->ol_flags = 0;
+		enetc_dev_rx_parse(rx_swbd->buffer_addr,
+				   rxbd->r.parse_summary);
+		rx_pkts[rx_frm_cnt] = rx_swbd->buffer_addr;
+		cleaned_cnt++;
+		rx_swbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			rx_swbd = &rx_ring->q_swbd[i];
+		}
+
+		rx_ring->next_to_clean = i;
+		rx_frm_cnt++;
+	}
+
+	return rx_frm_cnt;
+}
+
+uint16_t
+enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts)
+{
+	struct enetc_bdr *rx_ring = (struct enetc_bdr *)rxq;
+
+	return enetc_clean_rx_ring(rx_ring, rx_pkts, nb_pkts);
+}
diff --git a/drivers/net/enetc/meson.build b/drivers/net/enetc/meson.build
index 506b174ed..733156bbf 100644
--- a/drivers/net/enetc/meson.build
+++ b/drivers/net/enetc/meson.build
@@ -5,6 +5,7 @@ if host_machine.system() != 'linux'
 	build = false
 endif
 
-sources = files('enetc_ethdev.c')
+sources = files('enetc_ethdev.c',
+		'enetc_rxtx.c')
 
 includes += include_directories('base')
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v4 3/4] net/enetc: support packet parse type
  2018-09-28  7:45     ` [dpdk-dev] [PATCH v4 0/4] " Gagandeep Singh
  2018-09-28  7:45       ` [dpdk-dev] [PATCH v4 1/4] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
  2018-09-28  7:45       ` [dpdk-dev] [PATCH v4 2/4] net/enetc: enable Rx and Tx Gagandeep Singh
@ 2018-09-28  7:46       ` Gagandeep Singh
  2018-09-28 10:17         ` Shreyansh Jain
  2018-09-28  7:46       ` [dpdk-dev] [PATCH v4 4/4] doc: add usage doc for ENETC PMD Gagandeep Singh
                         ` (2 subsequent siblings)
  5 siblings, 1 reply; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-28  7:46 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 drivers/net/enetc/enetc_ethdev.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index 2d90d8fd5..8f4da8533 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -28,6 +28,7 @@ static int enetc_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);
 static void enetc_tx_queue_release(void *txq);
+static const uint32_t *enetc_supported_ptypes_get(struct rte_eth_dev *dev);
 
 /*
  * The set of PCI devices this driver supports
@@ -50,6 +51,7 @@ static const struct eth_dev_ops enetc_ops = {
 	.rx_queue_release     = enetc_rx_queue_release,
 	.tx_queue_setup       = enetc_tx_queue_setup,
 	.tx_queue_release     = enetc_tx_queue_release,
+	.dev_supported_ptypes_get = enetc_supported_ptypes_get,
 };
 
 /**
@@ -165,6 +167,23 @@ enetc_dev_close(struct rte_eth_dev *dev __rte_unused)
 	PMD_INIT_FUNC_TRACE();
 }
 
+static const uint32_t *
+enetc_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_ICMP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	return ptypes;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v4 4/4] doc: add usage doc for ENETC PMD
  2018-09-28  7:45     ` [dpdk-dev] [PATCH v4 0/4] " Gagandeep Singh
                         ` (2 preceding siblings ...)
  2018-09-28  7:46       ` [dpdk-dev] [PATCH v4 3/4] net/enetc: support packet parse type Gagandeep Singh
@ 2018-09-28  7:46       ` Gagandeep Singh
  2018-10-01 16:00         ` Ferruh Yigit
  2018-09-28 10:36       ` [dpdk-dev] [PATCH v4 0/4] introduces the enetc PMD driver Shreyansh Jain
  2018-10-03 13:36       ` [dpdk-dev] [PATCH v5 " Gagandeep Singh
  5 siblings, 1 reply; 40+ messages in thread
From: Gagandeep Singh @ 2018-09-28  7:46 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

Add enetc usage document to compile and run the
DPDK application on enetc supported platform.
This document introduces the enetc driver, supported
platforms and supported features.

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 MAINTAINERS                            |   7 ++
 doc/guides/nics/enetc.rst              | 110 +++++++++++++++++++++++++
 doc/guides/nics/features/enetc.ini     |  11 +++
 doc/guides/nics/index.rst              |   1 +
 doc/guides/rel_notes/release_18_11.rst |   6 ++
 5 files changed, 135 insertions(+)
 create mode 100644 doc/guides/nics/enetc.rst
 create mode 100644 doc/guides/nics/features/enetc.ini

diff --git a/MAINTAINERS b/MAINTAINERS
index 9fd258fad..b67f2afa4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -643,6 +643,13 @@ F: drivers/net/dpaa2/
 F: doc/guides/nics/dpaa2.rst
 F: doc/guides/nics/features/dpaa2.ini
 
+NXP enetc
+M: Gagandeep Singh <g.singh@nxp.com>
+M: Pankaj Chauhan <pankaj.chauhan@nxp.com>
+F: drivers/net/enetc/
+F: doc/guides/nics/enetc.rst
+F: doc/guides/nics/features/enetc.ini
+
 QLogic bnx2x
 M: Harish Patil <harish.patil@cavium.com>
 M: Rasesh Mody <rasesh.mody@cavium.com>
diff --git a/doc/guides/nics/enetc.rst b/doc/guides/nics/enetc.rst
new file mode 100644
index 000000000..8038bf205
--- /dev/null
+++ b/doc/guides/nics/enetc.rst
@@ -0,0 +1,110 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+   Copyright 2018 NXP
+
+ENETC Poll Mode Driver
+======================
+
+The ENETC NIC PMD (**librte_pmd_enetc**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP LS1028** SoC.
+
+More information can be found at `NXP Official Website
+<https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/qoriq-layerscape-arm-processors/qoriq-layerscape-1028a-industrial-applications-processor:LS1028A>`_.
+
+ENETC
+-----
+
+This section provides an overview of the NXP ENETC
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- ENETC overview
+- ENETC features
+- PCI bus driver
+- NIC driver
+- Supported ENETC SoCs
+- Prerequisites
+- Driver compilation and testing
+
+ENETC Overview
+~~~~~~~~~~~~~~
+
+ENETC is a PCI Integrated End Point(IEP). IEP implements
+peripheral devices in an SoC such that software sees them as PCIe device.
+ENETC is an evolution of BDR(Buffer Descriptor Ring) based networking
+IPs.
+
+This infrastructure simplifies adding support for IEP and facilitates in following:
+
+- Device discovery and location
+- Resource requirement discovery and allocation (e.g. interrupt assignment,
+  device register address)
+- Event reporting
+
+ENETC Features
+~~~~~~~~~~~~~~
+
+- Link Status
+- Packet type information
+
+NIC Driver (PMD)
+~~~~~~~~~~~~~~~~
+
+ENETC PMD is traditional DPDK PMD which provides necessary interface between
+RTE framework and ENETC internal drivers.
+
+- Driver registers the device vendor table in PCI subsystem.
+- RTE framework scans the PCI bus for connected devices.
+- This scanning will invoke the probe function of ENETC driver.
+- The probe function will set the basic device registers and also setups BD rings.
+- On packet Rx the respective BD Ring status bit is set which is then used for
+  packet processing.
+- Then Tx is done first followed by Rx.
+
+Supported ENETC SoCs
+~~~~~~~~~~~~~~~~~~~~
+
+- LS1028
+
+Prerequisites
+~~~~~~~~~~~~~
+
+There are three main pre-requisities for executing ENETC PMD on a ENETC
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-i686_aarch64-linux-gnu.tar.xz>`_.
+
+2. **Linux Kernel**
+
+   It can be obtained from `NXP's Github hosting <https://source.codeaurora.org/external/qoriq/qoriq-components/linux>`_.
+
+3. **Rootfile system**
+
+   Any *aarch64* supporting filesystem can be used. For example,
+   Ubuntu 16.04 LTS (Xenial) or 18.04 (Bionic) userland which can be obtained
+   from `here <http://cdimage.ubuntu.com/ubuntu-base/releases/18.04/release/ubuntu-base-18.04.1-base-arm64.tar.gz>`_.
+
+The following dependencies are not part of DPDK and must be installed
+separately:
+
+- **NXP Linux LSDK**
+
+  NXP Layerscape software development kit (LSDK) includes support for family
+  of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+  and corresponding boards.
+
+  It includes the Linux board support packages (BSPs) for NXP SoCs,
+  a fully operational tool chain, kernel and board specific modules.
+
+  LSDK and related information can be obtained from:  `LSDK <https://www.nxp.com/support/developer-resources/run-time-software/linux-software-and-development-tools/layerscape-software-development-kit:LAYERSCAPE-SDK>`_
+
+Driver compilation and testing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Follow instructions available in the document
+:ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
+to launch **testpmd**
+
+To compile in performance mode, please set ``CONFIG_RTE_CACHE_LINE_SIZE=64``
diff --git a/doc/guides/nics/features/enetc.ini b/doc/guides/nics/features/enetc.ini
new file mode 100644
index 000000000..69476a2a1
--- /dev/null
+++ b/doc/guides/nics/features/enetc.ini
@@ -0,0 +1,11 @@
+;
+; Supported features of the 'enetc' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+Packet type parsing  = Y
+Link status          = Y
+Linux VFIO           = Y
+ARMv8                = Y
+Usage doc            = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 59f6063dc..0323035d3 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -21,6 +21,7 @@ Network Interface Controller Drivers
     dpaa2
     e1000em
     ena
+    enetc
     enic
     fm10k
     i40e
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 3ae6b3f58..f4a2535f4 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -50,6 +50,11 @@ New Features
      * Other libs
      * Apps, Examples, Tools (if significative)
 
+   * **Added NXP ENETC PMD.**
+
+     Added the new enetc driver for NXP enetc platform. See the
+     "ENETC Poll Mode Driver" document for more details on this new driver.
+
      This section is a comment. Do not overwrite or remove it.
      Also, make sure to start the actual text at the margin.
      =========================================================
@@ -156,6 +161,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_pmd_ixgbe.so.2
      librte_pmd_dpaa2_cmdif.so.1
      librte_pmd_dpaa2_qdma.so.1
+   + librte_pmd_enetc.so.1
      librte_pmd_ring.so.2
      librte_pmd_softnic.so.1
      librte_pmd_vhost.so.2
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v4 3/4] net/enetc: support packet parse type
  2018-09-28  7:46       ` [dpdk-dev] [PATCH v4 3/4] net/enetc: support packet parse type Gagandeep Singh
@ 2018-09-28 10:17         ` Shreyansh Jain
  2018-10-01 15:59           ` Ferruh Yigit
  0 siblings, 1 reply; 40+ messages in thread
From: Shreyansh Jain @ 2018-09-28 10:17 UTC (permalink / raw)
  To: Gagandeep Singh, dev, ferruh.yigit; +Cc: pankaj.chauhan

On Friday 28 September 2018 01:16 PM, Gagandeep Singh wrote:
> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
> ---
>   drivers/net/enetc/enetc_ethdev.c | 19 +++++++++++++++++++
>   1 file changed, 19 insertions(+)
> 

Commit message is missing in this patch.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v4 0/4] introduces the enetc PMD driver
  2018-09-28  7:45     ` [dpdk-dev] [PATCH v4 0/4] " Gagandeep Singh
                         ` (3 preceding siblings ...)
  2018-09-28  7:46       ` [dpdk-dev] [PATCH v4 4/4] doc: add usage doc for ENETC PMD Gagandeep Singh
@ 2018-09-28 10:36       ` Shreyansh Jain
  2018-10-03 13:36       ` [dpdk-dev] [PATCH v5 " Gagandeep Singh
  5 siblings, 0 replies; 40+ messages in thread
From: Shreyansh Jain @ 2018-09-28 10:36 UTC (permalink / raw)
  To: Gagandeep Singh; +Cc: dev, ferruh.yigit, pankaj.chauhan

On Friday 28 September 2018 01:15 PM, Gagandeep Singh wrote:
> *ENETC* PMD driver which integrates with the existing PCI bus.
> Document is also part of the set
> 
> v3->v4 Change-log:
> * fixed patch set
> 
> v2->v3 Change-log:
> * Added a release note
> * commom part of documentation is removed
> * cflag Werror added in Makefile
> * private list of RX/TX queues removed
> * added the dev_start and dev_stop APIs
> * added rx/tx queue release APIs
> * packet parse type feature enabled
> 
> v1->v2 Change-log:
> * document improvement
> * checkpatch warnings removed
> 
> Gagandeep Singh (4):
>    net/enetc: add ENETC PMD with basic operations
>    net/enetc: enable Rx and Tx
>    net/enetc: support packet parse type
>    doc: add usage doc for ENETC PMD
> 

Please feel free to use my ACK in the next version of this series (which 
you would have to send for 3rd/4 patch which doesn't have a commit message).

Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v4 1/4] net/enetc: add ENETC PMD with basic operations
  2018-09-28  7:45       ` [dpdk-dev] [PATCH v4 1/4] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
@ 2018-10-01 15:58         ` Ferruh Yigit
  0 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2018-10-01 15:58 UTC (permalink / raw)
  To: Gagandeep Singh, dev; +Cc: pankaj.chauhan

On 9/28/2018 8:45 AM, Gagandeep Singh wrote:
> This patch introduces the enetc PMD with basic
> initialisation functions includes probe, teardown,
> hardware initialisation
> 
> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>

<...>

> +struct enetc_eth_mac_info {
> +	uint8_t addr[ETH_ADDR_LEN];
> +	uint8_t perm_addr[ETH_ADDR_LEN];

Can reuse DPDK ETHER_ADDR_LEN for this instead of re-defining? (You can skip if
this is coming from a common code and you need to maintain the difference
yourself for this change.)

<...>

> +static int
> +enetc_dev_init(struct rte_eth_dev *eth_dev)
> +{
> +	int error = 0;
> +	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
> +	struct enetc_eth_hw *hw =
> +		ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
> +
> +	PMD_INIT_FUNC_TRACE();
> +	eth_dev->dev_ops = &enetc_ops;
> +	eth_dev->rx_pkt_burst = NULL;
> +	eth_dev->tx_pkt_burst = NULL;
> +
> +	/* Retrieving and storing the HW base address of device */
> +	hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
> +	hw->device_id = pci_dev->id.device_id;
> +
> +	error = enetc_hardware_init(hw);
> +	if (error != 0) {
> +		ENETC_PMD_ERR("Hardware initialization failed");
> +		return -1;
> +	}
> +
> +	/* Allocate memory for storing MAC addresses */
> +	eth_dev->data->mac_addrs = rte_zmalloc("enetc_eth", ETHER_ADDR_LEN, 0);
> +	if (!eth_dev->data->mac_addrs) {
> +		ENETC_PMD_ERR("Failed to allocate %d bytes needed to "
> +			      "store MAC addresses",
> +			      ETHER_ADDR_LEN * 1);
> +		error = -ENOMEM;
> +		return -1;
> +	}

Need to free eth_dev->data->mac_addrs on uninit()

<...>

> +static int
> +enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
> +{
> +	struct enetc_eth_hw *hw =
> +		ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +	struct rte_eth_link link;
> +
> +	PMD_INIT_FUNC_TRACE();
> +	hw->mac.get_link_status = 1;
> +
> +	memset(&link, 0, sizeof(link));
> +	rte_eth_linkstatus_get(dev, &link);
> +
> +	link.link_duplex = ETH_LINK_FULL_DUPLEX;
> +	link.link_status = ETH_LINK_UP;
> +	rte_eth_linkstatus_set(dev, &link);

rte_eth_linkstatus_get() / rte_eth_linkstatus_set() updates variables that holds
the status of the link, but this PMD function should update the HW link status
not just the state.

<...>

> +/* DP Logs, toggled out at compile time if level lower than current level */
> +#define ENETC_PMD_DP_LOG(level, fmt, args...) \
> +	RTE_LOG_DP(level, PMD, fmt, ## args)
> +
> +#define ENETC_PMD_DP_DEBUG(fmt, args...) \
> +	ENETC_PMD_DP_LOG(DEBUG, fmt, ## args)
> +#define ENETC_PMD_DP_INFO(fmt, args...) \
> +	ENETC_PMD_DP_LOG(INFO, fmt, ## args)
> +#define ENETC_PMD_DP_WARN(fmt, args...) \
> +	ENETC_PMD_DP_LOG(WARNING, fmt, ## args)

What about adding DP logs when you need them?

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v4 2/4] net/enetc: enable Rx and Tx
  2018-09-28  7:45       ` [dpdk-dev] [PATCH v4 2/4] net/enetc: enable Rx and Tx Gagandeep Singh
@ 2018-10-01 15:59         ` Ferruh Yigit
  0 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2018-10-01 15:59 UTC (permalink / raw)
  To: Gagandeep Singh, dev; +Cc: pankaj.chauhan

On 9/28/2018 8:45 AM, Gagandeep Singh wrote:
> Add RX and TX queue setup, datapath functions
> 
> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>

<...>

> @@ -104,16 +104,19 @@ enum enetc_bdr_type {TX, RX};
>  #define ETH_ADDR_LEN			6
>  
>  /* general register accessors */
> -#define enetc_rd_reg(reg)	rte_read32((reg))
> -#define enetc_wr_reg(reg, val)	rte_write32((val), (reg))
> -#define enetc_rd(hw, off)	enetc_rd_reg((hw)->reg + (off))
> -#define enetc_wr(hw, off, val)	enetc_wr_reg((hw)->reg + (off), val)
> +#define enetc_rd_reg(reg)	rte_read32((void *)(reg))
> +#define enetc_wr_reg(reg, val)	rte_write32((val), (void *)(reg))
> +#define enetc_rd(hw, off)	enetc_rd_reg((size_t)(hw)->reg + (off))
> +#define enetc_wr(hw, off, val)	enetc_wr_reg((size_t)(hw)->reg + (off), val)
>  /* port register accessors - PF only */
> -#define enetc_port_rd(hw, off)		enetc_rd_reg((hw)->port + (off))
> -#define enetc_port_wr(hw, off, val)	enetc_wr_reg((hw)->port + (off), val)
> +#define enetc_port_rd(hw, off)	enetc_rd_reg((size_t)(hw)->port + (off))
> +#define enetc_port_wr(hw, off, val) \
> +				enetc_wr_reg((size_t)(hw)->port + (off), val)
>  /* global register accessors - PF only */
> -#define enetc_global_rd(hw, off)	enetc_rd_reg((hw)->global + (off))
> -#define enetc_global_wr(hw, off, val)	enetc_wr_reg((hw)->global + (off), val)
> +#define enetc_global_rd(hw, off) \
> +				enetc_rd_reg((size_t)(hw)->global + (off))
> +#define enetc_global_wr(hw, off, val) \
> +				enetc_wr_reg((size_t)(hw)->global + (off), val)

Is there any reason to not add these functions as updated version at first plane
at previous patch?

>  /* BDR register accessors, see ENETC_BDR() */
>  #define enetc_bdr_rd(hw, t, n, off) \
>  				enetc_rd(hw, ENETC_BDR(t, n, off))
> diff --git a/drivers/net/enetc/enetc.h b/drivers/net/enetc/enetc.h
> index 9fa7c726c..140daf0dd 100644
> --- a/drivers/net/enetc/enetc.h
> +++ b/drivers/net/enetc/enetc.h
> @@ -18,7 +18,11 @@
>  #define MAX_RX_RINGS	1
>  
>  /* Max BD counts per Ring. */
> -#define MAX_BD_COUNT	256
> +#define MAX_BD_COUNT	64000

Same here, is there a reason this has not been defined as 64000 in prev patch at
first place.
Or if this variable not used in prev patch at all, why not introduce here.

<...>

> @@ -37,6 +46,10 @@ static const struct eth_dev_ops enetc_ops = {
>  	.dev_close            = enetc_dev_close,
>  	.link_update          = enetc_link_update,
>  	.dev_infos_get        = enetc_dev_infos_get,
> +	.rx_queue_setup       = enetc_rx_queue_setup,
> +	.rx_queue_release     = enetc_rx_queue_release,
> +	.tx_queue_setup       = enetc_tx_queue_setup,
> +	.tx_queue_release     = enetc_tx_queue_release,

It is not very explicit in API doc but generally PMDs clean all queue related
resources in dev_close() too, can you please implement it.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v4 3/4] net/enetc: support packet parse type
  2018-09-28 10:17         ` Shreyansh Jain
@ 2018-10-01 15:59           ` Ferruh Yigit
  0 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2018-10-01 15:59 UTC (permalink / raw)
  To: Shreyansh Jain, Gagandeep Singh, dev; +Cc: pankaj.chauhan

On 9/28/2018 11:17 AM, Shreyansh Jain wrote:
> On Friday 28 September 2018 01:16 PM, Gagandeep Singh wrote:
>> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
>> ---
>>   drivers/net/enetc/enetc_ethdev.c | 19 +++++++++++++++++++
>>   1 file changed, 19 insertions(+)
>>
> 
> Commit message is missing in this patch.

+1 to provide some details.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v4 4/4] doc: add usage doc for ENETC PMD
  2018-09-28  7:46       ` [dpdk-dev] [PATCH v4 4/4] doc: add usage doc for ENETC PMD Gagandeep Singh
@ 2018-10-01 16:00         ` Ferruh Yigit
  0 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2018-10-01 16:00 UTC (permalink / raw)
  To: Gagandeep Singh, dev; +Cc: pankaj.chauhan

On 9/28/2018 8:46 AM, Gagandeep Singh wrote:
> Add enetc usage document to compile and run the
> DPDK application on enetc supported platform.
> This document introduces the enetc driver, supported
> platforms and supported features.
> 
> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>

<...>

> @@ -643,6 +643,13 @@ F: drivers/net/dpaa2/
>  F: doc/guides/nics/dpaa2.rst
>  F: doc/guides/nics/features/dpaa2.ini
>  
> +NXP enetc
> +M: Gagandeep Singh <g.singh@nxp.com>
> +M: Pankaj Chauhan <pankaj.chauhan@nxp.com>
> +F: drivers/net/enetc/

Can you please add above part with patch 1/4, and append rest with this patch.

<...>

> @@ -0,0 +1,11 @@
> +;
> +; Supported features of the 'enetc' network poll mode driver.
> +;
> +; Refer to default.ini for the full list of available PMD features.
> +;
> +[Features]
> +Packet type parsing  = Y
> +Link status          = Y
> +Linux VFIO           = Y
> +ARMv8                = Y
> +Usage doc            = Y

Can you please add .ini file with patch 1/4, so you will need to above
MAINTAINERS part to add .ini file too

And add "Packet type parsing  = Y" part with patch 3/4

<...>

> @@ -156,6 +161,7 @@ The libraries prepended with a plus sign were incremented in this version.
>       librte_pmd_ixgbe.so.2
>       librte_pmd_dpaa2_cmdif.so.1
>       librte_pmd_dpaa2_qdma.so.1
> +   + librte_pmd_enetc.so.1

No need to add this one, there is no API that this PMD provides.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v5 0/4] introduces the enetc PMD driver
  2018-09-28  7:45     ` [dpdk-dev] [PATCH v4 0/4] " Gagandeep Singh
                         ` (4 preceding siblings ...)
  2018-09-28 10:36       ` [dpdk-dev] [PATCH v4 0/4] introduces the enetc PMD driver Shreyansh Jain
@ 2018-10-03 13:36       ` Gagandeep Singh
  2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 1/4] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
                           ` (4 more replies)
  5 siblings, 5 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-10-03 13:36 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

*ENETC* PMD driver which integrates with the existing PCI bus.
Document is also part of the set

v4->v5 Change-log:
* missing commit info added in patch [3/4]
* dev_close API implemented
* link_update API updated
* all comments handled

v3->v4 Change-log:
* fixed patch set

v2->v3 Change-log:
* Added a release note
* commom part of documentation is removed
* cflag Werror added in Makefile
* private list of RX/TX queues removed
* added the dev_start and dev_stop APIs
* added rx/tx queue release APIs
* packet parse type feature enabled

v1->v2 Change-log:
* document improvement
* checkpatch warnings removed

Gagandeep Singh (4):
  net/enetc: add ENETC PMD with basic operations
  net/enetc: enable Rx and Tx
  net/enetc: support packet parse type
  doc: add usage doc for ENETC PMD

 MAINTAINERS                                 |   7 +
 config/common_base                          |   5 +
 config/common_linuxapp                      |   5 +
 doc/guides/nics/enetc.rst                   | 110 ++++
 doc/guides/nics/features/enetc.ini          |  11 +
 doc/guides/nics/index.rst                   |   1 +
 doc/guides/rel_notes/release_18_11.rst      |   5 +
 drivers/net/Makefile                        |   1 +
 drivers/net/enetc/Makefile                  |  23 +
 drivers/net/enetc/base/enetc_hw.h           | 226 +++++++
 drivers/net/enetc/enetc.h                   | 113 ++++
 drivers/net/enetc/enetc_ethdev.c            | 631 ++++++++++++++++++++
 drivers/net/enetc/enetc_logs.h              |  40 ++
 drivers/net/enetc/enetc_rxtx.c              | 239 ++++++++
 drivers/net/enetc/meson.build               |  11 +
 drivers/net/enetc/rte_pmd_enetc_version.map |   4 +
 drivers/net/meson.build                     |   1 +
 mk/rte.app.mk                               |   1 +
 18 files changed, 1434 insertions(+)
 create mode 100644 doc/guides/nics/enetc.rst
 create mode 100644 doc/guides/nics/features/enetc.ini
 create mode 100644 drivers/net/enetc/Makefile
 create mode 100644 drivers/net/enetc/base/enetc_hw.h
 create mode 100644 drivers/net/enetc/enetc.h
 create mode 100644 drivers/net/enetc/enetc_ethdev.c
 create mode 100644 drivers/net/enetc/enetc_logs.h
 create mode 100644 drivers/net/enetc/enetc_rxtx.c
 create mode 100644 drivers/net/enetc/meson.build
 create mode 100644 drivers/net/enetc/rte_pmd_enetc_version.map

-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v5 1/4] net/enetc: add ENETC PMD with basic operations
  2018-10-03 13:36       ` [dpdk-dev] [PATCH v5 " Gagandeep Singh
@ 2018-10-03 13:36         ` Gagandeep Singh
  2018-10-03 19:47           ` Ferruh Yigit
  2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 2/4] net/enetc: enable Rx and Tx Gagandeep Singh
                           ` (3 subsequent siblings)
  4 siblings, 1 reply; 40+ messages in thread
From: Gagandeep Singh @ 2018-10-03 13:36 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

This patch introduces the enetc PMD with basic
initialisation functions includes probe, teardown,
hardware initialisation

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 MAINTAINERS                                 |   6 +
 config/common_base                          |   5 +
 config/common_linuxapp                      |   5 +
 doc/guides/nics/features/enetc.ini          |   9 +
 drivers/net/Makefile                        |   1 +
 drivers/net/enetc/Makefile                  |  22 ++
 drivers/net/enetc/base/enetc_hw.h           | 226 ++++++++++++++++
 drivers/net/enetc/enetc.h                   |  87 +++++++
 drivers/net/enetc/enetc_ethdev.c            | 275 ++++++++++++++++++++
 drivers/net/enetc/enetc_logs.h              |  29 +++
 drivers/net/enetc/meson.build               |  10 +
 drivers/net/enetc/rte_pmd_enetc_version.map |   4 +
 drivers/net/meson.build                     |   1 +
 mk/rte.app.mk                               |   1 +
 14 files changed, 681 insertions(+)
 create mode 100644 doc/guides/nics/features/enetc.ini
 create mode 100644 drivers/net/enetc/Makefile
 create mode 100644 drivers/net/enetc/base/enetc_hw.h
 create mode 100644 drivers/net/enetc/enetc.h
 create mode 100644 drivers/net/enetc/enetc_ethdev.c
 create mode 100644 drivers/net/enetc/enetc_logs.h
 create mode 100644 drivers/net/enetc/meson.build
 create mode 100644 drivers/net/enetc/rte_pmd_enetc_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index 9fd258fad..0443addc0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -643,6 +643,12 @@ F: drivers/net/dpaa2/
 F: doc/guides/nics/dpaa2.rst
 F: doc/guides/nics/features/dpaa2.ini
 
+NXP enetc
+M: Gagandeep Singh <g.singh@nxp.com>
+M: Pankaj Chauhan <pankaj.chauhan@nxp.com>
+F: drivers/net/enetc/
+F: doc/guides/nics/features/enetc.ini
+
 QLogic bnx2x
 M: Harish Patil <harish.patil@cavium.com>
 M: Rasesh Mody <rasesh.mody@cavium.com>
diff --git a/config/common_base b/config/common_base
index 4bcbaf923..a7fc48667 100644
--- a/config/common_base
+++ b/config/common_base
@@ -217,6 +217,11 @@ CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
 CONFIG_RTE_LIBRTE_DPAA2_PMD=n
 CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
 
+#
+# Compile NXP ENETC PMD Driver
+#
+CONFIG_RTE_LIBRTE_ENETC_PMD=n
+
 #
 # Compile burst-oriented Amazon ENA PMD driver
 #
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 9c5ea9d89..485e1467d 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -44,3 +44,8 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y
+
+#
+# NXP ENETC PMD Driver
+#
+CONFIG_RTE_LIBRTE_ENETC_PMD=y
diff --git a/doc/guides/nics/features/enetc.ini b/doc/guides/nics/features/enetc.ini
new file mode 100644
index 000000000..f780404b8
--- /dev/null
+++ b/doc/guides/nics/features/enetc.ini
@@ -0,0 +1,9 @@
+;
+; Supported features of the 'enetc' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+Link status          = Y
+Linux VFIO           = Y
+ARMv8                = Y
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 664398de9..3ad436045 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -24,6 +24,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
 endif
 DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += e1000
 DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
+DIRS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc
 DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe
 DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k
diff --git a/drivers/net/enetc/Makefile b/drivers/net/enetc/Makefile
new file mode 100644
index 000000000..519153868
--- /dev/null
+++ b/drivers/net/enetc/Makefile
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_enetc.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+EXPORT_MAP := rte_pmd_enetc_version.map
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_ethdev.c
+
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_ethdev
+LDLIBS += -lrte_bus_pci
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h
new file mode 100644
index 000000000..f36fa11e0
--- /dev/null
+++ b/drivers/net/enetc/base/enetc_hw.h
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _ENETC_HW_H_
+#define _ENETC_HW_H_
+#include <rte_io.h>
+
+#define BIT(x)		((uint64_t)1 << ((x)))
+
+/* ENETC device IDs */
+#define ENETC_DEV_ID_VF		0xef00
+#define ENETC_DEV_ID		0xe100
+
+/* ENETC register block BAR */
+#define ENETC_BAR_REGS			0x0
+
+/* SI regs, offset: 0h */
+#define ENETC_SIMR			0x0
+#define ENETC_SIMR_EN			BIT(31)
+
+#define ENETC_SIPMAR0			0x80
+#define ENETC_SIPMAR1			0x84
+
+#define ENETC_SICAPR0			0x900
+#define ENETC_SICAPR1			0x904
+
+#define ENETC_SIMSITRV(n)		(0xB00 + (n) * 0x4)
+#define ENETC_SIMSIRRV(n)		(0xB80 + (n) * 0x4)
+
+#define ENETC_SICCAPR			0x1200
+
+/* enum for BD type */
+enum enetc_bdr_type {TX, RX};
+
+#define ENETC_BDR(type, n, off)		(0x8000 + (type) * 0x100 + (n) * 0x200 \
+							+ (off))
+/* RX BDR reg offsets */
+#define ENETC_RBMR		0x0 /* RX BDR mode register*/
+#define ENETC_RBMR_EN		BIT(31)
+
+#define ENETC_RBSR		0x4  /* Rx BDR status register*/
+#define ENETC_RBBSR		0x8  /* Rx BDR buffer size register*/
+#define ENETC_RBCIR		0xc  /* Rx BDR consumer index register*/
+#define ENETC_RBBAR0		0x10 /* Rx BDR base address register 0 */
+#define ENETC_RBBAR1		0x14 /* Rx BDR base address register 1*/
+#define ENETC_RBPIR		0x18 /* Rx BDR producer index register*/
+#define ENETC_RBLENR		0x20 /* Rx BDR length register*/
+#define ENETC_RBIER		0xa0 /* Rx BDR interrupt enable register*/
+#define ENETC_RBIER_RXTIE	BIT(0)
+#define ENETC_RBIDR		0xa4 /* Rx BDR interrupt detect register*/
+#define ENETC_RBICIR0		0xa8 /* Rx BDR inetrrupt coalescing register 0*/
+#define ENETC_RBICIR0_ICEN	BIT(31)
+
+
+#define ENETC_TBMR	0x0  /* Tx BDR mode register (TBMR) 32 RW */
+#define ENETC_TBSR	0x4  /* x BDR status register (TBSR) 32 RO */
+#define ENETC_TBBAR0	0x10 /* Tx BDR base address register 0 (TBBAR0) 32 RW */
+#define ENETC_TBBAR1	0x14 /* Tx BDR base address register 1 (TBBAR1) 32 RW */
+#define ENETC_TBCIR	0x18 /* Tx BDR consumer index register (TBCIR) 32 RW */
+#define ENETC_TBCISR	0x1C /* Tx BDR consumer index shadow register 32 RW */
+#define ENETC_TBIER	0xA0 /* Tx BDR interrupt enable register 32 RW */
+#define ENETC_TBIDR	0xA4 /* Tx BDR interrupt detect register 32 RO */
+#define ENETC_TBICR0	0xA8 /* Tx BDR interrupt coalescing register 0 32 RW */
+#define ENETC_TBICR1	0xAC /* Tx BDR interrupt coalescing register 1 32 RW */
+#define ENETC_TBLENR	0x20
+
+#define ENETC_TBCISR_IDX_MASK		0xffff
+#define ENETC_TBIER_TXFIE		BIT(1)
+
+#define ENETC_RTBLENR_LEN(n)		((n) & ~0x7)
+#define ENETC_TBMR_EN			BIT(31)
+
+/* Port regs, offset: 1_0000h */
+#define ENETC_PORT_BASE			0x10000
+#define ENETC_PMR			0x00000
+#define ENETC_PMR_EN			(BIT(16) | BIT(17) | BIT(18))
+#define ENETC_PSR			0x00004 /* RO */
+#define ENETC_PSIPMR			0x00018
+#define ENETC_PSIPMR_SET_UP(n)		(0x1 << (n)) /* n = SI index */
+#define ENETC_PSIPMR_SET_MP(n)		(0x1 << ((n) + 8))
+#define ENETC_PSIPMR_SET_VLAN_MP(n)	(0x1 << ((n) + 16))
+#define ENETC_PSIPMAR0(n)		(0x00100 + (n) * 0x20)
+#define ENETC_PSIPMAR1(n)		(0x00104 + (n) * 0x20)
+#define ENETC_PCAPR0			0x00900
+#define ENETC_PCAPR1			0x00904
+
+#define ENETC_PV0CFGR(n)		(0x00920 + (n) * 0x10)
+#define ENETC_PVCFGR_SET_TXBDR(val)	((val) & 0xff)
+#define ENETC_PVCFGR_SET_RXBDR(val)	(((val) & 0xff) << 16)
+
+#define ENETC_PM0_CMD_CFG		0x08008
+#define ENETC_PM0_TX_EN			BIT(0)
+#define ENETC_PM0_RX_EN			BIT(1)
+
+#define ENETC_PM0_MAXFRM		0x08014
+#define ENETC_SET_MAXFRM(val)		((val) << 16)
+
+#define ENETC_PM0_STATUS		0x08304
+#define ENETC_LINK_MODE			0x0000000000080000ULL
+#define ENETC_LINK_STATUS		0x0000000000010000ULL
+#define ENETC_LINK_SPEED_MASK		0x0000000000060000ULL
+#define ENETC_LINK_SPEED_10M		0x0ULL
+#define ENETC_LINK_SPEED_100M		0x0000000000020000ULL
+#define ENETC_LINK_SPEED_1G		0x0000000000040000ULL
+
+/* Global regs, offset: 2_0000h */
+#define ENETC_GLOBAL_BASE		0x20000
+#define ENETC_G_EIPBRR0			0x00bf8
+#define ENETC_G_EIPBRR1			0x00bfc
+
+/* general register accessors */
+#define enetc_rd_reg(reg)	rte_read32((void *)(reg))
+#define enetc_wr_reg(reg, val)	rte_write32((val), (void *)(reg))
+#define enetc_rd(hw, off)	enetc_rd_reg((size_t)(hw)->reg + (off))
+#define enetc_wr(hw, off, val)	enetc_wr_reg((size_t)(hw)->reg + (off), val)
+/* port register accessors - PF only */
+#define enetc_port_rd(hw, off)	enetc_rd_reg((size_t)(hw)->port + (off))
+#define enetc_port_wr(hw, off, val) \
+				enetc_wr_reg((size_t)(hw)->port + (off), val)
+/* global register accessors - PF only */
+#define enetc_global_rd(hw, off) \
+				enetc_rd_reg((size_t)(hw)->global + (off))
+#define enetc_global_wr(hw, off, val) \
+				enetc_wr_reg((size_t)(hw)->global + (off), val)
+/* BDR register accessors, see ENETC_BDR() */
+#define enetc_bdr_rd(hw, t, n, off) \
+				enetc_rd(hw, ENETC_BDR(t, n, off))
+#define enetc_bdr_wr(hw, t, n, off, val) \
+				enetc_wr(hw, ENETC_BDR(t, n, off), val)
+
+#define enetc_txbdr_rd(hw, n, off) enetc_bdr_rd(hw, TX, n, off)
+#define enetc_rxbdr_rd(hw, n, off) enetc_bdr_rd(hw, RX, n, off)
+#define enetc_txbdr_wr(hw, n, off, val) \
+				enetc_bdr_wr(hw, TX, n, off, val)
+#define enetc_rxbdr_wr(hw, n, off, val) \
+				enetc_bdr_wr(hw, RX, n, off, val)
+
+#define ENETC_TX_ADDR(txq, addr) ((void *)((txq)->enetc_txbdr + (addr)))
+
+#define ENETC_TXBD_FLAGS_IE		BIT(13)
+#define ENETC_TXBD_FLAGS_F		BIT(15)
+
+/* ENETC Parsed values (Little Endian) */
+#define ENETC_PKT_TYPE_ETHER            0x0060
+#define ENETC_PKT_TYPE_IPV4             0x0000
+#define ENETC_PKT_TYPE_IPV6             0x0020
+#define ENETC_PKT_TYPE_IPV4_TCP \
+			(0x0010 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_TCP \
+			(0x0010 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_PKT_TYPE_IPV4_UDP \
+			(0x0011 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_UDP \
+			(0x0011 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_PKT_TYPE_IPV4_SCTP \
+			(0x0013 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_SCTP \
+			(0x0013 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_PKT_TYPE_IPV4_ICMP \
+			(0x0003 | ENETC_PKT_TYPE_IPV4)
+#define ENETC_PKT_TYPE_IPV6_ICMP \
+			(0x0003 | ENETC_PKT_TYPE_IPV6)
+
+/* PCI device info */
+struct enetc_hw {
+	void *reg;	/* SI registers, used by all PCI functions */
+	void *port;	/* Port registers, PF only */
+	void *global;	/* IP global registers, PF only */
+};
+
+struct enetc_eth_mac_info {
+	uint8_t addr[ETHER_ADDR_LEN];
+	uint8_t perm_addr[ETHER_ADDR_LEN];
+	uint8_t get_link_status;
+};
+
+struct enetc_eth_hw {
+	struct rte_eth_dev *ndev;
+	struct enetc_hw hw;
+	uint16_t device_id;
+	uint16_t vendor_id;
+	uint8_t revision_id;
+	struct enetc_eth_mac_info mac;
+};
+
+/* Transmit Descriptor */
+struct enetc_tx_desc {
+	uint64_t addr;
+	uint16_t frm_len;
+	uint16_t buf_len;
+	uint32_t flags_errors;
+};
+
+/* TX Buffer Descriptors (BD) */
+struct enetc_tx_bd {
+	uint64_t addr;
+	uint16_t buf_len;
+	uint16_t frm_len;
+	uint16_t err_csum;
+	uint16_t flags;
+};
+
+/* RX buffer descriptor */
+union enetc_rx_bd {
+	struct {
+		uint64_t addr;
+		uint8_t reserved[8];
+	} w;
+	struct {
+		uint16_t inet_csum;
+		uint16_t parse_summary;
+		uint32_t rss_hash;
+		uint16_t buf_len;
+		uint16_t vlan_opt;
+		union {
+			struct {
+				uint16_t flags;
+				uint16_t error;
+			};
+			uint32_t lstatus;
+		};
+	} r;
+};
+
+#endif
diff --git a/drivers/net/enetc/enetc.h b/drivers/net/enetc/enetc.h
new file mode 100644
index 000000000..817e4b434
--- /dev/null
+++ b/drivers/net/enetc/enetc.h
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _ENETC_H_
+#define _ENETC_H_
+
+#include <rte_time.h>
+
+#include "base/enetc_hw.h"
+
+#define PCI_VENDOR_ID_FREESCALE 0x1957
+
+/* Max TX rings per ENETC. */
+#define MAX_TX_RINGS	2
+
+/* Max RX rings per ENTEC. */
+#define MAX_RX_RINGS	1
+
+/*
+ * upper_32_bits - return bits 32-63 of a number
+ * @n: the number we're accessing
+ *
+ * A basic shift-right of a 64- or 32-bit quantity.  Use this to suppress
+ * the "right shift count >= width of type" warning when that quantity is
+ * 32-bits.
+ */
+#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
+
+/*
+ * lower_32_bits - return bits 0-31 of a number
+ * @n: the number we're accessing
+ */
+#define lower_32_bits(n) ((uint32_t)(n))
+
+#define ENETC_TXBD(BDR, i) (&(((struct enetc_tx_bd *)((BDR).bd_base))[i]))
+#define ENETC_RXBD(BDR, i) (&(((union enetc_rx_bd *)((BDR).bd_base))[i]))
+
+struct enetc_swbd {
+	struct rte_mbuf *buffer_addr;
+};
+
+struct enetc_bdr {
+	struct rte_eth_dev *ndev;
+	struct rte_mempool *mb_pool;   /* mbuf pool to populate RX ring. */
+	void *bd_base;			/* points to Rx or Tx BD ring */
+	union {
+		void *tcir;
+		void *rcir;
+	};
+	uint16_t index;
+	int bd_count; /* # of BDs */
+	int next_to_use;
+	int next_to_clean;
+	struct enetc_swbd *q_swbd;
+	union {
+		void *tcisr; /* Tx */
+		int next_to_alloc; /* Rx */
+	};
+};
+
+/*
+ * Structure to store private data for each driver instance (for each port).
+ */
+struct enetc_eth_adapter {
+	struct rte_eth_dev *ndev;
+	struct enetc_eth_hw hw;
+};
+
+#define ENETC_DEV_PRIVATE(adapter) \
+	((struct enetc_eth_adapter *)adapter)
+
+#define ENETC_DEV_PRIVATE_TO_HW(adapter) \
+	(&((struct enetc_eth_adapter *)adapter)->hw)
+
+#define ENETC_DEV_PRIVATE_TO_STATS(adapter) \
+	(&((struct enetc_eth_adapter *)adapter)->stats)
+
+#define ENETC_DEV_PRIVATE_TO_INTR(adapter) \
+	(&((struct enetc_eth_adapter *)adapter)->intr)
+
+#define ENETC_GET_HW_ADDR(reg, addr) ((void *)(((size_t)reg) + (addr)))
+#define ENETC_REG_READ(addr) (*(uint32_t *)addr)
+#define ENETC_REG_WRITE(addr, val) (*(uint32_t *)addr = val)
+#define ENETC_REG_WRITE_RELAXED(addr, val) (*(uint32_t *)addr = val)
+
+#endif /* _ENETC_H_ */
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
new file mode 100644
index 000000000..f465f286f
--- /dev/null
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -0,0 +1,275 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <stdbool.h>
+#include <rte_ethdev_pci.h>
+
+#include "enetc_logs.h"
+#include "enetc.h"
+
+int enetc_logtype_pmd;
+
+/* Functions Prototypes */
+static int enetc_dev_configure(struct rte_eth_dev *dev);
+static int enetc_dev_start(struct rte_eth_dev *dev);
+static void enetc_dev_stop(struct rte_eth_dev *dev);
+static void enetc_dev_close(struct rte_eth_dev *dev);
+static void enetc_dev_infos_get(struct rte_eth_dev *dev,
+				struct rte_eth_dev_info *dev_info);
+static int enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete);
+static int enetc_hardware_init(struct enetc_eth_hw *hw);
+
+/*
+ * The set of PCI devices this driver supports
+ */
+static const struct rte_pci_id pci_id_enetc_map[] = {
+	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID) },
+	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_VF) },
+	{ .vendor_id = 0, /* sentinel */ },
+};
+
+/* Features supported by this driver */
+static const struct eth_dev_ops enetc_ops = {
+	.dev_configure        = enetc_dev_configure,
+	.dev_start            = enetc_dev_start,
+	.dev_stop             = enetc_dev_stop,
+	.dev_close            = enetc_dev_close,
+	.link_update          = enetc_link_update,
+	.dev_infos_get        = enetc_dev_infos_get,
+};
+
+/**
+ * Initialisation of the enetc device
+ *
+ * @param eth_dev
+ *   - Pointer to the structure rte_eth_dev
+ *
+ * @return
+ *   - On success, zero.
+ *   - On failure, negative value.
+ */
+static int
+enetc_dev_init(struct rte_eth_dev *eth_dev)
+{
+	int error = 0;
+	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	struct enetc_eth_hw *hw =
+		ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+
+	PMD_INIT_FUNC_TRACE();
+	eth_dev->dev_ops = &enetc_ops;
+	eth_dev->rx_pkt_burst = NULL;
+	eth_dev->tx_pkt_burst = NULL;
+
+	/* Retrieving and storing the HW base address of device */
+	hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
+	hw->device_id = pci_dev->id.device_id;
+
+	error = enetc_hardware_init(hw);
+	if (error != 0) {
+		ENETC_PMD_ERR("Hardware initialization failed");
+		return -1;
+	}
+
+	/* Allocate memory for storing MAC addresses */
+	eth_dev->data->mac_addrs = rte_zmalloc("enetc_eth", ETHER_ADDR_LEN, 0);
+	if (!eth_dev->data->mac_addrs) {
+		ENETC_PMD_ERR("Failed to allocate %d bytes needed to "
+			      "store MAC addresses",
+			      ETHER_ADDR_LEN * 1);
+		error = -ENOMEM;
+		return -1;
+	}
+
+	/* Copy the permanent MAC address */
+	ether_addr_copy((struct ether_addr *)hw->mac.addr,
+			&eth_dev->data->mac_addrs[0]);
+
+	ENETC_PMD_DEBUG("port_id %d vendorID=0x%x deviceID=0x%x",
+			eth_dev->data->port_id, pci_dev->id.vendor_id,
+			pci_dev->id.device_id);
+	return 0;
+}
+
+static int
+enetc_dev_uninit(struct rte_eth_dev *eth_dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	rte_free(eth_dev->data->mac_addrs);
+
+	return 0;
+}
+
+static int
+enetc_dev_configure(struct rte_eth_dev *dev __rte_unused)
+{
+	PMD_INIT_FUNC_TRACE();
+	return 0;
+}
+
+static int
+enetc_dev_start(struct rte_eth_dev *dev)
+{
+	struct enetc_eth_hw *hw =
+		ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t val;
+
+	PMD_INIT_FUNC_TRACE();
+	val = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port,
+			     ENETC_PM0_CMD_CFG));
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PM0_CMD_CFG),
+			val | ENETC_PM0_TX_EN | ENETC_PM0_RX_EN);
+
+	/* Enable port */
+	val = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR));
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR),
+			val | ENETC_PMR_EN);
+
+	return 0;
+}
+
+static void
+enetc_dev_stop(struct rte_eth_dev *dev)
+{
+	struct enetc_eth_hw *hw =
+		ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t val;
+
+	PMD_INIT_FUNC_TRACE();
+	/* Disable port */
+	val = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR));
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR),
+			val & (~ENETC_PMR_EN));
+
+	val = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port,
+			     ENETC_PM0_CMD_CFG));
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PM0_CMD_CFG),
+			val & (~(ENETC_PM0_TX_EN | ENETC_PM0_RX_EN)));
+}
+
+static void
+enetc_dev_close(struct rte_eth_dev *dev __rte_unused)
+{
+	PMD_INIT_FUNC_TRACE();
+}
+
+/* return 0 means link status changed, -1 means not changed */
+static int
+enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
+{
+	struct enetc_eth_hw *hw =
+		ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_eth_link link;
+	uint32_t status;
+
+	PMD_INIT_FUNC_TRACE();
+
+	memset(&link, 0, sizeof(link));
+
+	status = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port,
+				ENETC_PM0_STATUS));
+
+	if (status & ENETC_LINK_MODE)
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
+	else
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+
+	if (status & ENETC_LINK_STATUS)
+		link.link_status = ETH_LINK_UP;
+	else
+		link.link_status = ETH_LINK_DOWN;
+
+	switch (status & ENETC_LINK_SPEED_MASK) {
+	case ENETC_LINK_SPEED_1G:
+		link.link_speed = ETH_SPEED_NUM_1G;
+		break;
+
+	case ENETC_LINK_SPEED_100M:
+		link.link_speed = ETH_SPEED_NUM_100M;
+		break;
+
+	default:
+	case ENETC_LINK_SPEED_10M:
+		link.link_speed = ETH_SPEED_NUM_10M;
+	}
+
+	return rte_eth_linkstatus_set(dev, &link);
+}
+
+static int
+enetc_hardware_init(struct enetc_eth_hw *hw)
+{
+	uint32_t psipmr = 0;
+
+	PMD_INIT_FUNC_TRACE();
+	/* Calculating and storing the base HW addresses */
+	hw->hw.port = (void *)((size_t)hw->hw.reg + ENETC_PORT_BASE);
+	hw->hw.global = (void *)((size_t)hw->hw.reg + ENETC_GLOBAL_BASE);
+
+	/* Enabling Station Interface */
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.reg, ENETC_SIMR),
+					  ENETC_SIMR_EN);
+
+	/* Setting to accept broadcast packets for each inetrface */
+	psipmr |= ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0) |
+		  ENETC_PSIPMR_SET_VLAN_MP(0);
+	psipmr |= ENETC_PSIPMR_SET_UP(1) | ENETC_PSIPMR_SET_MP(1) |
+		  ENETC_PSIPMR_SET_VLAN_MP(1);
+	psipmr |= ENETC_PSIPMR_SET_UP(2) | ENETC_PSIPMR_SET_MP(2) |
+		  ENETC_PSIPMR_SET_VLAN_MP(2);
+
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMR),
+			psipmr);
+
+	/* Enabling broadcast address */
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMAR0(0)),
+			0xFFFFFFFF);
+	ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMAR1(0)),
+			0xFFFF << 16);
+
+	return 0;
+}
+
+static void
+enetc_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
+		    struct rte_eth_dev_info *dev_info)
+{
+	PMD_INIT_FUNC_TRACE();
+	dev_info->max_rx_queues = MAX_RX_RINGS;
+	dev_info->max_tx_queues = MAX_TX_RINGS;
+	dev_info->max_rx_pktlen = 1500;
+}
+
+static int
+enetc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+			   struct rte_pci_device *pci_dev)
+{
+	return rte_eth_dev_pci_generic_probe(pci_dev,
+					     sizeof(struct enetc_eth_adapter),
+					     enetc_dev_init);
+}
+
+static int
+enetc_pci_remove(struct rte_pci_device *pci_dev)
+{
+	return rte_eth_dev_pci_generic_remove(pci_dev, enetc_dev_uninit);
+}
+
+static struct rte_pci_driver rte_enetc_pmd = {
+	.id_table = pci_id_enetc_map,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
+	.probe = enetc_pci_probe,
+	.remove = enetc_pci_remove,
+};
+
+RTE_PMD_REGISTER_PCI(net_enetc, rte_enetc_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(net_enetc, pci_id_enetc_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_enetc, "* vfio-pci");
+
+RTE_INIT(enetc_pmd_init_log)
+{
+	enetc_logtype_pmd = rte_log_register("pmd.net.enetc");
+	if (enetc_logtype_pmd >= 0)
+		rte_log_set_level(enetc_logtype_pmd, RTE_LOG_NOTICE);
+}
diff --git a/drivers/net/enetc/enetc_logs.h b/drivers/net/enetc/enetc_logs.h
new file mode 100644
index 000000000..f5d37c005
--- /dev/null
+++ b/drivers/net/enetc/enetc_logs.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _ENETC_LOGS_H_
+#define _ENETC_LOGS_H_
+
+extern int enetc_logtype_pmd;
+
+#define ENETC_PMD_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, enetc_logtype_pmd, "enetc_net: " \
+		fmt "\n", ##args)
+
+#define ENETC_PMD_DEBUG(fmt, args...) \
+	rte_log(RTE_LOG_DEBUG, enetc_logtype_pmd, "enetc_net: %s(): "\
+		fmt "\n", __func__, ##args)
+
+#define PMD_INIT_FUNC_TRACE() ENETC_PMD_DEBUG(">>")
+
+#define ENETC_PMD_CRIT(fmt, args...) \
+	ENETC_PMD_LOG(CRIT, fmt, ## args)
+#define ENETC_PMD_INFO(fmt, args...) \
+	ENETC_PMD_LOG(INFO, fmt, ## args)
+#define ENETC_PMD_ERR(fmt, args...) \
+	ENETC_PMD_LOG(ERR, fmt, ## args)
+#define ENETC_PMD_WARN(fmt, args...) \
+	ENETC_PMD_LOG(WARNING, fmt, ## args)
+
+#endif /* _ENETC_LOGS_H_*/
diff --git a/drivers/net/enetc/meson.build b/drivers/net/enetc/meson.build
new file mode 100644
index 000000000..506b174ed
--- /dev/null
+++ b/drivers/net/enetc/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+if host_machine.system() != 'linux'
+	build = false
+endif
+
+sources = files('enetc_ethdev.c')
+
+includes += include_directories('base')
diff --git a/drivers/net/enetc/rte_pmd_enetc_version.map b/drivers/net/enetc/rte_pmd_enetc_version.map
new file mode 100644
index 000000000..521e51f41
--- /dev/null
+++ b/drivers/net/enetc/rte_pmd_enetc_version.map
@@ -0,0 +1,4 @@
+DPDK_18.11 {
+
+	local: *;
+};
diff --git a/drivers/net/meson.build b/drivers/net/meson.build
index 9c28ed4da..65aa6f60c 100644
--- a/drivers/net/meson.build
+++ b/drivers/net/meson.build
@@ -11,6 +11,7 @@ drivers = ['af_packet',
 	'dpaa', 'dpaa2',
 	'e1000',
 	'ena',
+	'enetc',
 	'enic',
 	'failsafe',
 	'fm10k', 'i40e',
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index de33883be..154ae3b2c 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -135,6 +135,7 @@ endif
 _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD)        += -lrte_pmd_ena
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD)       += -lrte_pmd_enic
+_LDLIBS-$(CONFIG_RTE_LIBRTE_ENETC_PMD)      += -lrte_pmd_enetc
 _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD)      += -lrte_pmd_fm10k
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE)   += -lrte_pmd_failsafe
 _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD)       += -lrte_pmd_i40e
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v5 2/4] net/enetc: enable Rx and Tx
  2018-10-03 13:36       ` [dpdk-dev] [PATCH v5 " Gagandeep Singh
  2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 1/4] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
@ 2018-10-03 13:36         ` Gagandeep Singh
  2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 3/4] net/enetc: support packet parse type Gagandeep Singh
                           ` (2 subsequent siblings)
  4 siblings, 0 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-10-03 13:36 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

Add RX and TX queue setup, datapath functions

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 drivers/net/enetc/Makefile       |   3 +-
 drivers/net/enetc/enetc.h        |  26 +++
 drivers/net/enetc/enetc_ethdev.c | 343 ++++++++++++++++++++++++++++++-
 drivers/net/enetc/enetc_logs.h   |  11 +
 drivers/net/enetc/enetc_rxtx.c   | 239 +++++++++++++++++++++
 drivers/net/enetc/meson.build    |   3 +-
 6 files changed, 620 insertions(+), 5 deletions(-)
 create mode 100644 drivers/net/enetc/enetc_rxtx.c

diff --git a/drivers/net/enetc/Makefile b/drivers/net/enetc/Makefile
index 519153868..9895501db 100644
--- a/drivers/net/enetc/Makefile
+++ b/drivers/net/enetc/Makefile
@@ -14,8 +14,9 @@ EXPORT_MAP := rte_pmd_enetc_version.map
 LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_rxtx.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
 LDLIBS += -lrte_ethdev
 LDLIBS += -lrte_bus_pci
 
diff --git a/drivers/net/enetc/enetc.h b/drivers/net/enetc/enetc.h
index 817e4b434..0e80d1c5b 100644
--- a/drivers/net/enetc/enetc.h
+++ b/drivers/net/enetc/enetc.h
@@ -17,6 +17,13 @@
 /* Max RX rings per ENTEC. */
 #define MAX_RX_RINGS	1
 
+/* Max BD counts per Ring. */
+#define MAX_BD_COUNT   64000
+/* Min BD counts per Ring. */
+#define MIN_BD_COUNT   32
+/* BD ALIGN */
+#define BD_ALIGN       8
+
 /*
  * upper_32_bits - return bits 32-63 of a number
  * @n: the number we're accessing
@@ -84,4 +91,23 @@ struct enetc_eth_adapter {
 #define ENETC_REG_WRITE(addr, val) (*(uint32_t *)addr = val)
 #define ENETC_REG_WRITE_RELAXED(addr, val) (*(uint32_t *)addr = val)
 
+/*
+ * RX/TX ENETC function prototypes
+ */
+uint16_t enetc_xmit_pkts(void *txq, struct rte_mbuf **tx_pkts,
+		uint16_t nb_pkts);
+uint16_t enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts);
+
+
+int enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt);
+
+static inline int
+enetc_bd_unused(struct enetc_bdr *bdr)
+{
+	if (bdr->next_to_clean > bdr->next_to_use)
+		return bdr->next_to_clean - bdr->next_to_use - 1;
+
+	return bdr->bd_count + bdr->next_to_clean - bdr->next_to_use - 1;
+}
 #endif /* _ENETC_H_ */
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index f465f286f..dfe7ddaa1 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -19,6 +19,15 @@ static void enetc_dev_infos_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete);
 static int enetc_hardware_init(struct enetc_eth_hw *hw);
+static int enetc_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);
+static void enetc_rx_queue_release(void *rxq);
+static int enetc_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);
+static void enetc_tx_queue_release(void *txq);
 
 /*
  * The set of PCI devices this driver supports
@@ -37,6 +46,10 @@ static const struct eth_dev_ops enetc_ops = {
 	.dev_close            = enetc_dev_close,
 	.link_update          = enetc_link_update,
 	.dev_infos_get        = enetc_dev_infos_get,
+	.rx_queue_setup       = enetc_rx_queue_setup,
+	.rx_queue_release     = enetc_rx_queue_release,
+	.tx_queue_setup       = enetc_tx_queue_setup,
+	.tx_queue_release     = enetc_tx_queue_release,
 };
 
 /**
@@ -59,8 +72,8 @@ enetc_dev_init(struct rte_eth_dev *eth_dev)
 
 	PMD_INIT_FUNC_TRACE();
 	eth_dev->dev_ops = &enetc_ops;
-	eth_dev->rx_pkt_burst = NULL;
-	eth_dev->tx_pkt_burst = NULL;
+	eth_dev->rx_pkt_burst = &enetc_recv_pkts;
+	eth_dev->tx_pkt_burst = &enetc_xmit_pkts;
 
 	/* Retrieving and storing the HW base address of device */
 	hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
@@ -149,9 +162,24 @@ enetc_dev_stop(struct rte_eth_dev *dev)
 }
 
 static void
-enetc_dev_close(struct rte_eth_dev *dev __rte_unused)
+enetc_dev_close(struct rte_eth_dev *dev)
 {
+	uint16_t i;
+
 	PMD_INIT_FUNC_TRACE();
+	enetc_dev_stop(dev);
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		enetc_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++) {
+		enetc_tx_queue_release(dev->data->tx_queues[i]);
+		dev->data->tx_queues[i] = NULL;
+	}
+	dev->data->nb_tx_queues = 0;
 }
 
 /* return 0 means link status changed, -1 means not changed */
@@ -236,11 +264,320 @@ enetc_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
 		    struct rte_eth_dev_info *dev_info)
 {
 	PMD_INIT_FUNC_TRACE();
+	dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
+		.nb_max = MAX_BD_COUNT,
+		.nb_min = MIN_BD_COUNT,
+		.nb_align = BD_ALIGN,
+	};
+	dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
+		.nb_max = MAX_BD_COUNT,
+		.nb_min = MIN_BD_COUNT,
+		.nb_align = BD_ALIGN,
+	};
 	dev_info->max_rx_queues = MAX_RX_RINGS;
 	dev_info->max_tx_queues = MAX_TX_RINGS;
 	dev_info->max_rx_pktlen = 1500;
 }
 
+static int
+enetc_alloc_txbdr(struct enetc_bdr *txr, uint16_t nb_desc)
+{
+	int size;
+
+	size = nb_desc * sizeof(struct enetc_swbd);
+	txr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (txr->q_swbd == NULL)
+		return -ENOMEM;
+
+	size = nb_desc * sizeof(struct enetc_tx_bd);
+	txr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (txr->bd_base == NULL) {
+		rte_free(txr->q_swbd);
+		txr->q_swbd = NULL;
+		return -ENOMEM;
+	}
+
+	txr->bd_count = nb_desc;
+	txr->next_to_clean = 0;
+	txr->next_to_use = 0;
+
+	return 0;
+}
+
+static void
+enetc_free_bdr(struct enetc_bdr *rxr)
+{
+	rte_free(rxr->q_swbd);
+	rte_free(rxr->bd_base);
+	rxr->q_swbd = NULL;
+	rxr->bd_base = NULL;
+}
+
+static void
+enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+{
+	int idx = tx_ring->index;
+	uintptr_t base_addr;
+	uint32_t tbmr;
+
+	base_addr = (uintptr_t)tx_ring->bd_base;
+	enetc_txbdr_wr(hw, idx, ENETC_TBBAR0,
+		       lower_32_bits((uint64_t)base_addr));
+	enetc_txbdr_wr(hw, idx, ENETC_TBBAR1,
+		       upper_32_bits((uint64_t)base_addr));
+	enetc_txbdr_wr(hw, idx, ENETC_TBLENR,
+		       ENETC_RTBLENR_LEN(tx_ring->bd_count));
+
+	tbmr = ENETC_TBMR_EN;
+	/* enable ring */
+	enetc_txbdr_wr(hw, idx, ENETC_TBMR, tbmr);
+	enetc_txbdr_wr(hw, idx, ENETC_TBCIR, 0);
+	enetc_txbdr_wr(hw, idx, ENETC_TBCISR, 0);
+	tx_ring->tcir = (void *)((size_t)hw->reg +
+			ENETC_BDR(TX, idx, ENETC_TBCIR));
+	tx_ring->tcisr = (void *)((size_t)hw->reg +
+			 ENETC_BDR(TX, idx, ENETC_TBCISR));
+}
+
+static int
+enetc_alloc_tx_resources(struct rte_eth_dev *dev,
+			 uint16_t queue_idx,
+			 uint16_t nb_desc)
+{
+	int err;
+	struct enetc_bdr *tx_ring;
+	struct rte_eth_dev_data *data = dev->data;
+	struct enetc_eth_adapter *priv =
+			ENETC_DEV_PRIVATE(data->dev_private);
+
+	tx_ring = rte_zmalloc(NULL, sizeof(struct enetc_bdr), 0);
+	if (tx_ring == NULL) {
+		ENETC_PMD_ERR("Failed to allocate TX ring memory");
+		err = -ENOMEM;
+		return -1;
+	}
+
+	err = enetc_alloc_txbdr(tx_ring, nb_desc);
+	if (err)
+		goto fail;
+
+	tx_ring->index = queue_idx;
+	tx_ring->ndev = dev;
+	enetc_setup_txbdr(&priv->hw.hw, tx_ring);
+	data->tx_queues[queue_idx] = tx_ring;
+
+	return 0;
+fail:
+	rte_free(tx_ring);
+
+	return err;
+}
+
+static int
+enetc_tx_queue_setup(struct rte_eth_dev *dev,
+		     uint16_t queue_idx,
+		     uint16_t nb_desc,
+		     unsigned int socket_id __rte_unused,
+		     const struct rte_eth_txconf *tx_conf __rte_unused)
+{
+	int err = 0;
+
+	PMD_INIT_FUNC_TRACE();
+	if (nb_desc > MAX_BD_COUNT)
+		return -1;
+
+	err = enetc_alloc_tx_resources(dev, queue_idx, nb_desc);
+
+	return err;
+}
+
+static void
+enetc_tx_queue_release(void *txq)
+{
+	if (txq == NULL)
+		return;
+
+	struct enetc_bdr *tx_ring = (struct enetc_bdr *)txq;
+	struct enetc_eth_hw *eth_hw =
+		ENETC_DEV_PRIVATE_TO_HW(tx_ring->ndev->data->dev_private);
+	struct enetc_hw *hw;
+	struct enetc_swbd *tx_swbd;
+	int i;
+	uint32_t val;
+
+	/* Disable the ring */
+	hw = &eth_hw->hw;
+	val = enetc_txbdr_rd(hw, tx_ring->index, ENETC_TBMR);
+	val &= (~ENETC_TBMR_EN);
+	enetc_txbdr_wr(hw, tx_ring->index, ENETC_TBMR, val);
+
+	/* clean the ring*/
+	i = tx_ring->next_to_clean;
+	tx_swbd = &tx_ring->q_swbd[i];
+	while (tx_swbd->buffer_addr != NULL) {
+		rte_pktmbuf_free(tx_swbd->buffer_addr);
+		tx_swbd->buffer_addr = NULL;
+		tx_swbd++;
+		i++;
+		if (unlikely(i == tx_ring->bd_count)) {
+			i = 0;
+			tx_swbd = &tx_ring->q_swbd[i];
+		}
+	}
+
+	enetc_free_bdr(tx_ring);
+	rte_free(tx_ring);
+}
+
+static int
+enetc_alloc_rxbdr(struct enetc_bdr *rxr,
+		  uint16_t nb_rx_desc)
+{
+	int size;
+
+	size = nb_rx_desc * sizeof(struct enetc_swbd);
+	rxr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (rxr->q_swbd == NULL)
+		return -ENOMEM;
+
+	size = nb_rx_desc * sizeof(union enetc_rx_bd);
+	rxr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (rxr->bd_base == NULL) {
+		rte_free(rxr->q_swbd);
+		rxr->q_swbd = NULL;
+		return -ENOMEM;
+	}
+
+	rxr->bd_count = nb_rx_desc;
+	rxr->next_to_clean = 0;
+	rxr->next_to_use = 0;
+	rxr->next_to_alloc = 0;
+
+	return 0;
+}
+
+static void
+enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring,
+		  struct rte_mempool *mb_pool)
+{
+	int idx = rx_ring->index;
+	uintptr_t base_addr;
+	uint16_t buf_size;
+
+	base_addr = (uintptr_t)rx_ring->bd_base;
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBAR0,
+		       lower_32_bits((uint64_t)base_addr));
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBAR1,
+		       upper_32_bits((uint64_t)base_addr));
+	enetc_rxbdr_wr(hw, idx, ENETC_RBLENR,
+		       ENETC_RTBLENR_LEN(rx_ring->bd_count));
+
+	rx_ring->mb_pool = mb_pool;
+	/* enable ring */
+	enetc_rxbdr_wr(hw, idx, ENETC_RBMR, ENETC_RBMR_EN);
+	enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
+	rx_ring->rcir = (void *)((size_t)hw->reg +
+			ENETC_BDR(RX, idx, ENETC_RBCIR));
+	enetc_refill_rx_ring(rx_ring, (enetc_bd_unused(rx_ring)));
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rx_ring->mb_pool) -
+		   RTE_PKTMBUF_HEADROOM);
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBSR, buf_size);
+}
+
+static int
+enetc_alloc_rx_resources(struct rte_eth_dev *dev,
+			 uint16_t rx_queue_id,
+			 uint16_t nb_rx_desc,
+			 struct rte_mempool *mb_pool)
+{
+	int err;
+	struct enetc_bdr *rx_ring;
+	struct rte_eth_dev_data *data =  dev->data;
+	struct enetc_eth_adapter *adapter =
+			ENETC_DEV_PRIVATE(data->dev_private);
+
+	rx_ring = rte_zmalloc(NULL, sizeof(struct enetc_bdr), 0);
+	if (rx_ring == NULL) {
+		ENETC_PMD_ERR("Failed to allocate RX ring memory");
+		err = -ENOMEM;
+		return err;
+	}
+
+	err = enetc_alloc_rxbdr(rx_ring, nb_rx_desc);
+	if (err)
+		goto fail;
+
+	rx_ring->index = rx_queue_id;
+	rx_ring->ndev = dev;
+	enetc_setup_rxbdr(&adapter->hw.hw, rx_ring, mb_pool);
+	data->rx_queues[rx_queue_id] = rx_ring;
+
+	return 0;
+fail:
+	rte_free(rx_ring);
+
+	return err;
+}
+
+static int
+enetc_rx_queue_setup(struct rte_eth_dev *dev,
+		     uint16_t rx_queue_id,
+		     uint16_t nb_rx_desc,
+		     unsigned int socket_id __rte_unused,
+		     const struct rte_eth_rxconf *rx_conf __rte_unused,
+		     struct rte_mempool *mb_pool)
+{
+	int err = 0;
+
+	PMD_INIT_FUNC_TRACE();
+	if (nb_rx_desc > MAX_BD_COUNT)
+		return -1;
+
+	err = enetc_alloc_rx_resources(dev, rx_queue_id,
+				       nb_rx_desc,
+				       mb_pool);
+
+	return err;
+}
+
+static void
+enetc_rx_queue_release(void *rxq)
+{
+	if (rxq == NULL)
+		return;
+
+	struct enetc_bdr *rx_ring = (struct enetc_bdr *)rxq;
+	struct enetc_eth_hw *eth_hw =
+		ENETC_DEV_PRIVATE_TO_HW(rx_ring->ndev->data->dev_private);
+	struct enetc_swbd *q_swbd;
+	struct enetc_hw *hw;
+	uint32_t val;
+	int i;
+
+	/* Disable the ring */
+	hw = &eth_hw->hw;
+	val = enetc_rxbdr_rd(hw, rx_ring->index, ENETC_RBMR);
+	val &= (~ENETC_RBMR_EN);
+	enetc_rxbdr_wr(hw, rx_ring->index, ENETC_RBMR, val);
+
+	/* Clean the ring */
+	i = rx_ring->next_to_clean;
+	q_swbd = &rx_ring->q_swbd[i];
+	while (i != rx_ring->next_to_use) {
+		rte_pktmbuf_free(q_swbd->buffer_addr);
+		q_swbd->buffer_addr = NULL;
+		q_swbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			q_swbd = &rx_ring->q_swbd[i];
+		}
+	}
+
+	enetc_free_bdr(rx_ring);
+	rte_free(rx_ring);
+}
+
 static int
 enetc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 			   struct rte_pci_device *pci_dev)
diff --git a/drivers/net/enetc/enetc_logs.h b/drivers/net/enetc/enetc_logs.h
index f5d37c005..c8a6c0cf3 100644
--- a/drivers/net/enetc/enetc_logs.h
+++ b/drivers/net/enetc/enetc_logs.h
@@ -26,4 +26,15 @@ extern int enetc_logtype_pmd;
 #define ENETC_PMD_WARN(fmt, args...) \
 	ENETC_PMD_LOG(WARNING, fmt, ## args)
 
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define ENETC_PMD_DP_LOG(level, fmt, args...) \
+	RTE_LOG_DP(level, PMD, fmt, ## args)
+
+#define ENETC_PMD_DP_DEBUG(fmt, args...) \
+	ENETC_PMD_DP_LOG(DEBUG, fmt, ## args)
+#define ENETC_PMD_DP_INFO(fmt, args...) \
+	ENETC_PMD_DP_LOG(INFO, fmt, ## args)
+#define ENETC_PMD_DP_WARN(fmt, args...) \
+	ENETC_PMD_DP_LOG(WARNING, fmt, ## args)
+
 #endif /* _ENETC_LOGS_H_*/
diff --git a/drivers/net/enetc/enetc_rxtx.c b/drivers/net/enetc/enetc_rxtx.c
new file mode 100644
index 000000000..631e2430d
--- /dev/null
+++ b/drivers/net/enetc/enetc_rxtx.c
@@ -0,0 +1,239 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "rte_ethdev.h"
+#include "rte_malloc.h"
+#include "rte_memzone.h"
+
+#include "base/enetc_hw.h"
+#include "enetc.h"
+#include "enetc_logs.h"
+
+#define ENETC_RXBD_BUNDLE 8 /* Number of BDs to update at once */
+
+static int
+enetc_clean_tx_ring(struct enetc_bdr *tx_ring)
+{
+	int tx_frm_cnt = 0;
+	struct enetc_swbd *tx_swbd;
+	int i;
+
+	i = tx_ring->next_to_clean;
+	tx_swbd = &tx_ring->q_swbd[i];
+	while ((int)(enetc_rd_reg(tx_ring->tcisr) &
+	       ENETC_TBCISR_IDX_MASK) != i) {
+		rte_pktmbuf_free(tx_swbd->buffer_addr);
+		tx_swbd->buffer_addr = NULL;
+		tx_swbd++;
+		i++;
+		if (unlikely(i == tx_ring->bd_count)) {
+			i = 0;
+			tx_swbd = &tx_ring->q_swbd[0];
+		}
+
+		tx_frm_cnt++;
+	}
+
+	tx_ring->next_to_clean = i;
+	return tx_frm_cnt++;
+}
+
+uint16_t
+enetc_xmit_pkts(void *tx_queue,
+		struct rte_mbuf **tx_pkts,
+		uint16_t nb_pkts)
+{
+	struct enetc_swbd *tx_swbd;
+	int i, start;
+	struct enetc_tx_bd *txbd;
+	struct enetc_bdr *tx_ring = (struct enetc_bdr *)tx_queue;
+
+	i = tx_ring->next_to_use;
+	start = 0;
+	while (nb_pkts--) {
+		enetc_clean_tx_ring(tx_ring);
+		tx_ring->q_swbd[i].buffer_addr = tx_pkts[start];
+		txbd = ENETC_TXBD(*tx_ring, i);
+		tx_swbd = &tx_ring->q_swbd[i];
+		txbd->frm_len = tx_pkts[start]->pkt_len;
+		txbd->buf_len = txbd->frm_len;
+		txbd->flags = rte_cpu_to_le_16(ENETC_TXBD_FLAGS_F);
+		txbd->addr = (uint64_t)(uintptr_t)
+		rte_cpu_to_le_64((size_t)tx_swbd->buffer_addr->buf_addr +
+				 tx_swbd->buffer_addr->data_off);
+		i++;
+		start++;
+		if (unlikely(i == tx_ring->bd_count))
+			i = 0;
+	}
+
+	tx_ring->next_to_use = i;
+	enetc_wr_reg(tx_ring->tcir, i);
+	return start;
+}
+
+int
+enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt)
+{
+	struct enetc_swbd *rx_swbd;
+	union enetc_rx_bd *rxbd;
+	int i, j;
+
+	i = rx_ring->next_to_use;
+	rx_swbd = &rx_ring->q_swbd[i];
+	rxbd = ENETC_RXBD(*rx_ring, i);
+	for (j = 0; j < buff_cnt; j++) {
+		rx_swbd->buffer_addr =
+			rte_cpu_to_le_64(rte_mbuf_raw_alloc(rx_ring->mb_pool));
+		rxbd->w.addr = (uint64_t)(uintptr_t)
+			       rx_swbd->buffer_addr->buf_addr +
+			       rx_swbd->buffer_addr->data_off;
+		/* clear 'R" as well */
+		rxbd->r.lstatus = 0;
+		rx_swbd++;
+		rxbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			rxbd = ENETC_RXBD(*rx_ring, 0);
+			rx_swbd = &rx_ring->q_swbd[i];
+		}
+	}
+
+	if (likely(j)) {
+		rx_ring->next_to_alloc = i;
+		rx_ring->next_to_use = i;
+		enetc_wr_reg(rx_ring->rcir, i);
+	}
+
+	return j;
+}
+
+
+static inline void __attribute__((hot))
+enetc_dev_rx_parse(struct rte_mbuf *m, uint16_t parse_results)
+{
+	ENETC_PMD_DP_DEBUG("parse summary = 0x%x   ", parse_results);
+
+	m->packet_type = RTE_PTYPE_UNKNOWN;
+	switch (parse_results) {
+	case ENETC_PKT_TYPE_ETHER:
+		m->packet_type = RTE_PTYPE_L2_ETHER;
+		break;
+	case ENETC_PKT_TYPE_IPV4:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4;
+		break;
+	case ENETC_PKT_TYPE_IPV6:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6;
+		break;
+	case ENETC_PKT_TYPE_IPV4_TCP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_TCP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_TCP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_TCP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_UDP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_UDP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_UDP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_UDP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_SCTP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_SCTP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_SCTP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_SCTP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_ICMP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_ICMP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_ICMP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_ICMP;
+		break;
+	/* More switch cases can be added */
+	default:
+		m->packet_type = RTE_PTYPE_UNKNOWN;
+	}
+}
+
+static int
+enetc_clean_rx_ring(struct enetc_bdr *rx_ring,
+		    struct rte_mbuf **rx_pkts,
+		    int work_limit)
+{
+	int rx_frm_cnt = 0;
+	int cleaned_cnt, i;
+	struct enetc_swbd *rx_swbd;
+
+	cleaned_cnt = enetc_bd_unused(rx_ring);
+	/* next descriptor to process */
+	i = rx_ring->next_to_clean;
+	rx_swbd = &rx_ring->q_swbd[i];
+	while (likely(rx_frm_cnt < work_limit)) {
+		union enetc_rx_bd *rxbd;
+		uint32_t bd_status;
+
+		if (cleaned_cnt >= ENETC_RXBD_BUNDLE) {
+			int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt);
+
+			cleaned_cnt -= count;
+		}
+
+		rxbd = ENETC_RXBD(*rx_ring, i);
+		bd_status = rte_le_to_cpu_32(rxbd->r.lstatus);
+		if (!bd_status)
+			break;
+
+		rx_swbd->buffer_addr->pkt_len = rxbd->r.buf_len;
+		rx_swbd->buffer_addr->data_len = rxbd->r.buf_len;
+		rx_swbd->buffer_addr->hash.rss = rxbd->r.rss_hash;
+		rx_swbd->buffer_addr->ol_flags = 0;
+		enetc_dev_rx_parse(rx_swbd->buffer_addr,
+				   rxbd->r.parse_summary);
+		rx_pkts[rx_frm_cnt] = rx_swbd->buffer_addr;
+		cleaned_cnt++;
+		rx_swbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			rx_swbd = &rx_ring->q_swbd[i];
+		}
+
+		rx_ring->next_to_clean = i;
+		rx_frm_cnt++;
+	}
+
+	return rx_frm_cnt;
+}
+
+uint16_t
+enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts)
+{
+	struct enetc_bdr *rx_ring = (struct enetc_bdr *)rxq;
+
+	return enetc_clean_rx_ring(rx_ring, rx_pkts, nb_pkts);
+}
diff --git a/drivers/net/enetc/meson.build b/drivers/net/enetc/meson.build
index 506b174ed..733156bbf 100644
--- a/drivers/net/enetc/meson.build
+++ b/drivers/net/enetc/meson.build
@@ -5,6 +5,7 @@ if host_machine.system() != 'linux'
 	build = false
 endif
 
-sources = files('enetc_ethdev.c')
+sources = files('enetc_ethdev.c',
+		'enetc_rxtx.c')
 
 includes += include_directories('base')
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v5 3/4] net/enetc: support packet parse type
  2018-10-03 13:36       ` [dpdk-dev] [PATCH v5 " Gagandeep Singh
  2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 1/4] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
  2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 2/4] net/enetc: enable Rx and Tx Gagandeep Singh
@ 2018-10-03 13:36         ` Gagandeep Singh
  2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 4/4] doc: add usage doc for ENETC PMD Gagandeep Singh
  2018-10-03 19:48         ` [dpdk-dev] [PATCH v5 0/4] introduces the enetc PMD driver Ferruh Yigit
  4 siblings, 0 replies; 40+ messages in thread
From: Gagandeep Singh @ 2018-10-03 13:36 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

enable supported packet parse types feature

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 doc/guides/nics/features/enetc.ini |  1 +
 drivers/net/enetc/enetc_ethdev.c   | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/doc/guides/nics/features/enetc.ini b/doc/guides/nics/features/enetc.ini
index f780404b8..bd9cb0bc0 100644
--- a/doc/guides/nics/features/enetc.ini
+++ b/doc/guides/nics/features/enetc.ini
@@ -4,6 +4,7 @@
 ; Refer to default.ini for the full list of available PMD features.
 ;
 [Features]
+Packet type parsing  = Y
 Link status          = Y
 Linux VFIO           = Y
 ARMv8                = Y
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index dfe7ddaa1..3ee7bb446 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -28,6 +28,7 @@ static int enetc_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);
 static void enetc_tx_queue_release(void *txq);
+static const uint32_t *enetc_supported_ptypes_get(struct rte_eth_dev *dev);
 
 /*
  * The set of PCI devices this driver supports
@@ -50,6 +51,7 @@ static const struct eth_dev_ops enetc_ops = {
 	.rx_queue_release     = enetc_rx_queue_release,
 	.tx_queue_setup       = enetc_tx_queue_setup,
 	.tx_queue_release     = enetc_tx_queue_release,
+	.dev_supported_ptypes_get = enetc_supported_ptypes_get,
 };
 
 /**
@@ -182,6 +184,23 @@ enetc_dev_close(struct rte_eth_dev *dev)
 	dev->data->nb_tx_queues = 0;
 }
 
+static const uint32_t *
+enetc_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_ICMP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	return ptypes;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [dpdk-dev] [PATCH v5 4/4] doc: add usage doc for ENETC PMD
  2018-10-03 13:36       ` [dpdk-dev] [PATCH v5 " Gagandeep Singh
                           ` (2 preceding siblings ...)
  2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 3/4] net/enetc: support packet parse type Gagandeep Singh
@ 2018-10-03 13:36         ` Gagandeep Singh
  2018-10-03 19:47           ` Ferruh Yigit
  2018-10-03 19:48         ` [dpdk-dev] [PATCH v5 0/4] introduces the enetc PMD driver Ferruh Yigit
  4 siblings, 1 reply; 40+ messages in thread
From: Gagandeep Singh @ 2018-10-03 13:36 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: pankaj.chauhan, Gagandeep Singh

Add enetc usage document to compile and run the
DPDK application on enetc supported platform.
This document introduces the enetc driver, supported
platforms and supported features.

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 MAINTAINERS                            |   1 +
 doc/guides/nics/enetc.rst              | 110 +++++++++++++++++++++++++
 doc/guides/nics/features/enetc.ini     |   1 +
 doc/guides/nics/index.rst              |   1 +
 doc/guides/rel_notes/release_18_11.rst |   5 ++
 5 files changed, 118 insertions(+)
 create mode 100644 doc/guides/nics/enetc.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 0443addc0..b67f2afa4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -647,6 +647,7 @@ NXP enetc
 M: Gagandeep Singh <g.singh@nxp.com>
 M: Pankaj Chauhan <pankaj.chauhan@nxp.com>
 F: drivers/net/enetc/
+F: doc/guides/nics/enetc.rst
 F: doc/guides/nics/features/enetc.ini
 
 QLogic bnx2x
diff --git a/doc/guides/nics/enetc.rst b/doc/guides/nics/enetc.rst
new file mode 100644
index 000000000..8038bf205
--- /dev/null
+++ b/doc/guides/nics/enetc.rst
@@ -0,0 +1,110 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+   Copyright 2018 NXP
+
+ENETC Poll Mode Driver
+======================
+
+The ENETC NIC PMD (**librte_pmd_enetc**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP LS1028** SoC.
+
+More information can be found at `NXP Official Website
+<https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/qoriq-layerscape-arm-processors/qoriq-layerscape-1028a-industrial-applications-processor:LS1028A>`_.
+
+ENETC
+-----
+
+This section provides an overview of the NXP ENETC
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- ENETC overview
+- ENETC features
+- PCI bus driver
+- NIC driver
+- Supported ENETC SoCs
+- Prerequisites
+- Driver compilation and testing
+
+ENETC Overview
+~~~~~~~~~~~~~~
+
+ENETC is a PCI Integrated End Point(IEP). IEP implements
+peripheral devices in an SoC such that software sees them as PCIe device.
+ENETC is an evolution of BDR(Buffer Descriptor Ring) based networking
+IPs.
+
+This infrastructure simplifies adding support for IEP and facilitates in following:
+
+- Device discovery and location
+- Resource requirement discovery and allocation (e.g. interrupt assignment,
+  device register address)
+- Event reporting
+
+ENETC Features
+~~~~~~~~~~~~~~
+
+- Link Status
+- Packet type information
+
+NIC Driver (PMD)
+~~~~~~~~~~~~~~~~
+
+ENETC PMD is traditional DPDK PMD which provides necessary interface between
+RTE framework and ENETC internal drivers.
+
+- Driver registers the device vendor table in PCI subsystem.
+- RTE framework scans the PCI bus for connected devices.
+- This scanning will invoke the probe function of ENETC driver.
+- The probe function will set the basic device registers and also setups BD rings.
+- On packet Rx the respective BD Ring status bit is set which is then used for
+  packet processing.
+- Then Tx is done first followed by Rx.
+
+Supported ENETC SoCs
+~~~~~~~~~~~~~~~~~~~~
+
+- LS1028
+
+Prerequisites
+~~~~~~~~~~~~~
+
+There are three main pre-requisities for executing ENETC PMD on a ENETC
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-i686_aarch64-linux-gnu.tar.xz>`_.
+
+2. **Linux Kernel**
+
+   It can be obtained from `NXP's Github hosting <https://source.codeaurora.org/external/qoriq/qoriq-components/linux>`_.
+
+3. **Rootfile system**
+
+   Any *aarch64* supporting filesystem can be used. For example,
+   Ubuntu 16.04 LTS (Xenial) or 18.04 (Bionic) userland which can be obtained
+   from `here <http://cdimage.ubuntu.com/ubuntu-base/releases/18.04/release/ubuntu-base-18.04.1-base-arm64.tar.gz>`_.
+
+The following dependencies are not part of DPDK and must be installed
+separately:
+
+- **NXP Linux LSDK**
+
+  NXP Layerscape software development kit (LSDK) includes support for family
+  of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+  and corresponding boards.
+
+  It includes the Linux board support packages (BSPs) for NXP SoCs,
+  a fully operational tool chain, kernel and board specific modules.
+
+  LSDK and related information can be obtained from:  `LSDK <https://www.nxp.com/support/developer-resources/run-time-software/linux-software-and-development-tools/layerscape-software-development-kit:LAYERSCAPE-SDK>`_
+
+Driver compilation and testing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Follow instructions available in the document
+:ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
+to launch **testpmd**
+
+To compile in performance mode, please set ``CONFIG_RTE_CACHE_LINE_SIZE=64``
diff --git a/doc/guides/nics/features/enetc.ini b/doc/guides/nics/features/enetc.ini
index bd9cb0bc0..69476a2a1 100644
--- a/doc/guides/nics/features/enetc.ini
+++ b/doc/guides/nics/features/enetc.ini
@@ -8,3 +8,4 @@ Packet type parsing  = Y
 Link status          = Y
 Linux VFIO           = Y
 ARMv8                = Y
+Usage doc            = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 59f6063dc..0323035d3 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -21,6 +21,7 @@ Network Interface Controller Drivers
     dpaa2
     e1000em
     ena
+    enetc
     enic
     fm10k
     i40e
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 3ae6b3f58..1fa7152d2 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -50,6 +50,11 @@ New Features
      * Other libs
      * Apps, Examples, Tools (if significative)
 
+   * **Added NXP ENETC PMD.**
+
+     Added the new enetc driver for NXP enetc platform. See the
+     "ENETC Poll Mode Driver" document for more details on this new driver.
+
      This section is a comment. Do not overwrite or remove it.
      Also, make sure to start the actual text at the margin.
      =========================================================
-- 
2.17.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v5 1/4] net/enetc: add ENETC PMD with basic operations
  2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 1/4] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
@ 2018-10-03 19:47           ` Ferruh Yigit
  0 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2018-10-03 19:47 UTC (permalink / raw)
  To: Gagandeep Singh, dev; +Cc: pankaj.chauhan

On 10/3/2018 2:36 PM, Gagandeep Singh wrote:
> This patch introduces the enetc PMD with basic
> initialisation functions includes probe, teardown,
> hardware initialisation
> 
> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>

<...>

> @@ -135,6 +135,7 @@ endif
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD)        += -lrte_pmd_ena
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD)       += -lrte_pmd_enic
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_ENETC_PMD)      += -lrte_pmd_enetc
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD)      += -lrte_pmd_fm10k
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE)   += -lrte_pmd_failsafe
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD)       += -lrte_pmd_i40e

Alphabetical order please, I can fix while merging.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v5 4/4] doc: add usage doc for ENETC PMD
  2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 4/4] doc: add usage doc for ENETC PMD Gagandeep Singh
@ 2018-10-03 19:47           ` Ferruh Yigit
  0 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2018-10-03 19:47 UTC (permalink / raw)
  To: Gagandeep Singh, dev; +Cc: pankaj.chauhan

On 10/3/2018 2:36 PM, Gagandeep Singh wrote:
> Add enetc usage document to compile and run the
> DPDK application on enetc supported platform.
> This document introduces the enetc driver, supported
> platforms and supported features.
> 
> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>

<...>

> @@ -50,6 +50,11 @@ New Features
>       * Other libs
>       * Apps, Examples, Tools (if significative)
>  
> +   * **Added NXP ENETC PMD.**
> +
> +     Added the new enetc driver for NXP enetc platform. See the
> +     "ENETC Poll Mode Driver" document for more details on this new driver.
> +
>       This section is a comment. Do not overwrite or remove it.
>       Also, make sure to start the actual text at the margin.
>       =========================================================

This seems put into comment part of the section, I can fix while merging.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v5 0/4] introduces the enetc PMD driver
  2018-10-03 13:36       ` [dpdk-dev] [PATCH v5 " Gagandeep Singh
                           ` (3 preceding siblings ...)
  2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 4/4] doc: add usage doc for ENETC PMD Gagandeep Singh
@ 2018-10-03 19:48         ` Ferruh Yigit
  2018-11-21 17:36           ` Ferruh Yigit
  4 siblings, 1 reply; 40+ messages in thread
From: Ferruh Yigit @ 2018-10-03 19:48 UTC (permalink / raw)
  To: Gagandeep Singh, dev; +Cc: pankaj.chauhan

On 10/3/2018 2:36 PM, Gagandeep Singh wrote:
> *ENETC* PMD driver which integrates with the existing PCI bus.
> Document is also part of the set
> 
> v4->v5 Change-log:
> * missing commit info added in patch [3/4]
> * dev_close API implemented
> * link_update API updated
> * all comments handled
> 
> v3->v4 Change-log:
> * fixed patch set
> 
> v2->v3 Change-log:
> * Added a release note
> * commom part of documentation is removed
> * cflag Werror added in Makefile
> * private list of RX/TX queues removed
> * added the dev_start and dev_stop APIs
> * added rx/tx queue release APIs
> * packet parse type feature enabled
> 
> v1->v2 Change-log:
> * document improvement
> * checkpatch warnings removed
> 
> Gagandeep Singh (4):
>   net/enetc: add ENETC PMD with basic operations
>   net/enetc: enable Rx and Tx
>   net/enetc: support packet parse type
>   doc: add usage doc for ENETC PMD

For series,
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>

Series applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v5 0/4] introduces the enetc PMD driver
  2018-10-03 19:48         ` [dpdk-dev] [PATCH v5 0/4] introduces the enetc PMD driver Ferruh Yigit
@ 2018-11-21 17:36           ` Ferruh Yigit
  2018-11-22 10:34             ` Shreyansh Jain
  0 siblings, 1 reply; 40+ messages in thread
From: Ferruh Yigit @ 2018-11-21 17:36 UTC (permalink / raw)
  To: Gagandeep Singh, dev; +Cc: pankaj.chauhan

On 10/3/2018 8:48 PM, Ferruh Yigit wrote:
> On 10/3/2018 2:36 PM, Gagandeep Singh wrote:
>> *ENETC* PMD driver which integrates with the existing PCI bus.
>> Document is also part of the set
>>
>> v4->v5 Change-log:
>> * missing commit info added in patch [3/4]
>> * dev_close API implemented
>> * link_update API updated
>> * all comments handled
>>
>> v3->v4 Change-log:
>> * fixed patch set
>>
>> v2->v3 Change-log:
>> * Added a release note
>> * commom part of documentation is removed
>> * cflag Werror added in Makefile
>> * private list of RX/TX queues removed
>> * added the dev_start and dev_stop APIs
>> * added rx/tx queue release APIs
>> * packet parse type feature enabled
>>
>> v1->v2 Change-log:
>> * document improvement
>> * checkpatch warnings removed
>>
>> Gagandeep Singh (4):
>>   net/enetc: add ENETC PMD with basic operations
>>   net/enetc: enable Rx and Tx
>>   net/enetc: support packet parse type
>>   doc: add usage doc for ENETC PMD
> 
> For series,
> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
> 
> Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> 
> Series applied to dpdk-next-net/master, thanks.
> 

Can you please send a web page patch [1], to announce NIC support [2]?

You can benefit from recent samples like 'Marvell NETA' [3] or 'Aquantia
Atlantic' [4].

Thanks,
ferruh


[1]
https://git.dpdk.org/tools/dpdk-web/

[2]
https://core.dpdk.org/supported/

[3]
https://mails.dpdk.org/archives/web/2018-October/000908.html

[4]
https://mails.dpdk.org/archives/web/2018-November/000922.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v5 0/4] introduces the enetc PMD driver
  2018-11-21 17:36           ` Ferruh Yigit
@ 2018-11-22 10:34             ` Shreyansh Jain
  2018-11-22 12:08               ` Ferruh Yigit
  0 siblings, 1 reply; 40+ messages in thread
From: Shreyansh Jain @ 2018-11-22 10:34 UTC (permalink / raw)
  To: Ferruh Yigit, Gagandeep Singh, dev; +Cc: Pankaj Chauhan

Hello Ferruh,

On Wednesday 21 November 2018 11:06 PM, Ferruh Yigit wrote:
> On 10/3/2018 8:48 PM, Ferruh Yigit wrote:
>> On 10/3/2018 2:36 PM, Gagandeep Singh wrote:
>>> *ENETC* PMD driver which integrates with the existing PCI bus.
>>> Document is also part of the set
>>>
...
...
>>> Gagandeep Singh (4):
>>>    net/enetc: add ENETC PMD with basic operations
>>>    net/enetc: enable Rx and Tx
>>>    net/enetc: support packet parse type
>>>    doc: add usage doc for ENETC PMD
>>
>> For series,
>> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
>>
>> Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>>
>> Series applied to dpdk-next-net/master, thanks.
>>
> 
> Can you please send a web page patch [1], to announce NIC support [2]?
> 
> You can benefit from recent samples like 'Marvell NETA' [3] or 'Aquantia
> Atlantic' [4].

I have sent a patch for this here [5] - which also fixes/elaborates 
existing device names.

[5] https://mails.dpdk.org/archives/web/2018-November/000948.html

> 
> Thanks,
> ferruh
> 
> 
> [1]
> https://git.dpdk.org/tools/dpdk-web/
> 
> [2]
> https://core.dpdk.org/supported/
> 
> [3]
> https://mails.dpdk.org/archives/web/2018-October/000908.html
> 
> [4]
> https://mails.dpdk.org/archives/web/2018-November/000922.html
> 


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [dpdk-dev] [PATCH v5 0/4] introduces the enetc PMD driver
  2018-11-22 10:34             ` Shreyansh Jain
@ 2018-11-22 12:08               ` Ferruh Yigit
  0 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2018-11-22 12:08 UTC (permalink / raw)
  To: Shreyansh Jain, Gagandeep Singh, dev; +Cc: Pankaj Chauhan

On 11/22/2018 10:34 AM, Shreyansh Jain wrote:
> Hello Ferruh,
> 
> On Wednesday 21 November 2018 11:06 PM, Ferruh Yigit wrote:
>> On 10/3/2018 8:48 PM, Ferruh Yigit wrote:
>>> On 10/3/2018 2:36 PM, Gagandeep Singh wrote:
>>>> *ENETC* PMD driver which integrates with the existing PCI bus.
>>>> Document is also part of the set
>>>>
> ...
> ...
>>>> Gagandeep Singh (4):
>>>>    net/enetc: add ENETC PMD with basic operations
>>>>    net/enetc: enable Rx and Tx
>>>>    net/enetc: support packet parse type
>>>>    doc: add usage doc for ENETC PMD
>>>
>>> For series,
>>> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
>>>
>>> Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>>>
>>> Series applied to dpdk-next-net/master, thanks.
>>>
>>
>> Can you please send a web page patch [1], to announce NIC support [2]?
>>
>> You can benefit from recent samples like 'Marvell NETA' [3] or 'Aquantia
>> Atlantic' [4].
> 
> I have sent a patch for this here [5] - which also fixes/elaborates 
> existing device names.

Great, thanks.

> 
> [5] https://mails.dpdk.org/archives/web/2018-November/000948.html
> 
>>
>> Thanks,
>> ferruh
>>
>>
>> [1]
>> https://git.dpdk.org/tools/dpdk-web/
>>
>> [2]
>> https://core.dpdk.org/supported/
>>
>> [3]
>> https://mails.dpdk.org/archives/web/2018-October/000908.html
>>
>> [4]
>> https://mails.dpdk.org/archives/web/2018-November/000922.html
>>
> 

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2018-11-22 12:08 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-06  5:54 [dpdk-dev] [PATCH 0/3] introduces the ENETC PMD Gagandeep Singh
2018-09-06  5:54 ` [dpdk-dev] [PATCH 1/3] doc: add usage doc for " Gagandeep Singh
2018-09-06  5:54 ` [dpdk-dev] [PATCH 2/3] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
2018-09-19 12:15   ` Shreyansh Jain
2018-09-06  5:54 ` [dpdk-dev] [PATCH 3/3] net/enetc: enable Rx and Tx Gagandeep Singh
2018-09-13  9:41 ` [dpdk-dev] [PATCH v2 0/3] introduces the enetc PMD driver Gagandeep Singh
2018-09-13  9:41   ` [dpdk-dev] [PATCH v2 1/3] doc: add usage doc for ENETC PMD Gagandeep Singh
2018-09-21 13:22     ` Ferruh Yigit
2018-09-13  9:42   ` [dpdk-dev] [PATCH v2 2/3] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
2018-09-21 13:27     ` Ferruh Yigit
2018-09-13  9:42   ` [dpdk-dev] [PATCH v2 3/3] net/enetc: enable Rx and Tx Gagandeep Singh
2018-09-19 12:26     ` Shreyansh Jain
2018-09-21 13:28     ` Ferruh Yigit
2018-09-28  5:16   ` [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
2018-09-28  5:16     ` [dpdk-dev] [PATCH v3 1/3] net/enetc: enable Rx and Tx Gagandeep Singh
2018-09-28  5:16     ` [dpdk-dev] [PATCH v3 2/3] net/enetc: support packet parse type Gagandeep Singh
2018-09-28  5:16     ` [dpdk-dev] [PATCH v3 3/3] doc: add usage doc for ENETC PMD Gagandeep Singh
2018-09-28  5:26     ` [dpdk-dev] [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
2018-09-28  7:45     ` [dpdk-dev] [PATCH v4 0/4] " Gagandeep Singh
2018-09-28  7:45       ` [dpdk-dev] [PATCH v4 1/4] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
2018-10-01 15:58         ` Ferruh Yigit
2018-09-28  7:45       ` [dpdk-dev] [PATCH v4 2/4] net/enetc: enable Rx and Tx Gagandeep Singh
2018-10-01 15:59         ` Ferruh Yigit
2018-09-28  7:46       ` [dpdk-dev] [PATCH v4 3/4] net/enetc: support packet parse type Gagandeep Singh
2018-09-28 10:17         ` Shreyansh Jain
2018-10-01 15:59           ` Ferruh Yigit
2018-09-28  7:46       ` [dpdk-dev] [PATCH v4 4/4] doc: add usage doc for ENETC PMD Gagandeep Singh
2018-10-01 16:00         ` Ferruh Yigit
2018-09-28 10:36       ` [dpdk-dev] [PATCH v4 0/4] introduces the enetc PMD driver Shreyansh Jain
2018-10-03 13:36       ` [dpdk-dev] [PATCH v5 " Gagandeep Singh
2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 1/4] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
2018-10-03 19:47           ` Ferruh Yigit
2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 2/4] net/enetc: enable Rx and Tx Gagandeep Singh
2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 3/4] net/enetc: support packet parse type Gagandeep Singh
2018-10-03 13:36         ` [dpdk-dev] [PATCH v5 4/4] doc: add usage doc for ENETC PMD Gagandeep Singh
2018-10-03 19:47           ` Ferruh Yigit
2018-10-03 19:48         ` [dpdk-dev] [PATCH v5 0/4] introduces the enetc PMD driver Ferruh Yigit
2018-11-21 17:36           ` Ferruh Yigit
2018-11-22 10:34             ` Shreyansh Jain
2018-11-22 12:08               ` Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).