Show a patch.

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

{
    "id": 44100,
    "url": "http://patches.dpdk.org/api/patches/44100/",
    "web_url": "http://patches.dpdk.org/patch/44100/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk"
    },
    "msgid": "<1535718368-15803-4-git-send-email-amo@semihalf.com>",
    "date": "2018-08-31T12:25:59",
    "name": "[v2,2/8] net/mvneta: add neta PMD skeleton",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "2ab183312d45695d5815dfbe2df97906ab596041",
    "submitter": {
        "id": 1112,
        "url": "http://patches.dpdk.org/api/people/1112/",
        "name": "Andrzej Ostruszka",
        "email": "amo@semihalf.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@intel.com"
    },
    "mbox": "http://patches.dpdk.org/patch/44100/mbox/",
    "series": [
        {
            "id": 1131,
            "url": "http://patches.dpdk.org/api/series/1131/",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=1131",
            "date": "2018-08-31T12:25:56",
            "name": "Add Marvell NETA PMD",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/1131/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/44100/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/44100/checks/",
    "tags": {},
    "headers": {
        "X-Mailman-Version": "2.1.15",
        "In-Reply-To": "<1535718368-15803-1-git-send-email-amo@semihalf.com>",
        "Errors-To": "dev-bounces@dpdk.org",
        "X-Mailer": "git-send-email 2.7.4",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 20C3058FA;\n\tFri, 31 Aug 2018 14:26:19 +0200 (CEST)",
            "from mail-lf1-f45.google.com (mail-lf1-f45.google.com\n\t[209.85.167.45]) by dpdk.org (Postfix) with ESMTP id 3E34C5398\n\tfor <dev@dpdk.org>; Fri, 31 Aug 2018 14:26:14 +0200 (CEST)",
            "by mail-lf1-f45.google.com with SMTP id c29-v6so3683865lfj.1\n\tfor <dev@dpdk.org>; Fri, 31 Aug 2018 05:26:14 -0700 (PDT)",
            "from amok.semihalf.local (31-172-191-173.noc.fibertech.net.pl.\n\t[31.172.191.173]) by smtp.googlemail.com with ESMTPSA id\n\tt4-v6sm1825422lfd.13.2018.08.31.05.26.12\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tFri, 31 Aug 2018 05:26:13 -0700 (PDT)"
        ],
        "References": "<1535469030-18647-1-git-send-email-amo@semihalf.com>\n\t<1535718368-15803-1-git-send-email-amo@semihalf.com>",
        "X-Google-Smtp-Source": "ANB0VdZD338wuoIPa4JDElZJ993JF3ElgOI+KCKuNpaWGcZmPVyubk5SkCMTXvKOwpBP+eu6Tmq1uQ==",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=semihalf-com.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=ZV6RljjtEZ9i1Hk6sJsaqDg72cx6gUPDxZqjS9iecso=;\n\tb=baRWGpgdoTJRwPfm7rJijrjsfyDzkAIHYbXGqMAryzyL0grcLtVm0ShattS0WwbtAN\n\tOGy14L/jAIWtUQhu2M7UzMXIHeHBdHKpmLmbut9EVGnMbIX2laHRgqyWt2iaTnBecn80\n\tE9exUIPqbNJNSRuXcVh3nPWOoY7GV0J8Dsa0R2djXmuxP4cjH0rRRNbEZj7y0/Zntncn\n\tyd89IeMW7PluRF6gYJJAqztQwAQTnNjcGgfV3Hv1k4hJgBqMDedqI0q6ccVEligywBmS\n\th+A/yjLt2WOwO9A2QS4PiAbeOui7QeefBhiN1Y834+g1e7oqZilkk1mZ1rAtI43azi1M\n\toNzg==",
        "X-BeenThere": "dev@dpdk.org",
        "X-Received": "by 2002:ac2:4242:: with SMTP id\n\tm2-v6mr11029529lfl.40.1535718373926; \n\tFri, 31 Aug 2018 05:26:13 -0700 (PDT)",
        "Message-Id": "<1535718368-15803-4-git-send-email-amo@semihalf.com>",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=ZV6RljjtEZ9i1Hk6sJsaqDg72cx6gUPDxZqjS9iecso=;\n\tb=JGHRLJUdd4AsU1aDdzN8mwEwqdVhqHqzTI/W7FHW60IYt0q+Fzg+4G7hsFFp1hhLns\n\tK27DwdqUU8L9+2qHmaH/UkInLt9s0nl8neJmoAkbpKYS077XFTI6d3vSwpt6yLcXpTKc\n\tFEFE+UZ3vYWhIixIQJwPgLtwjutsEhiicKkG9MYDBhZC85ArER91t8idRAcYRuxSjExM\n\tLbZsNfcJYi1QgTtuiK/cF2Jk7F9evWa6TcFivKyQSuowHq48eFHG/QF0eF9Szl3xn3OE\n\toEVlEUVi4Q/ir2VvfidpYA0UWKVPLL7WDMHz3Jmwn5gKZE7HRRUJZMHPzE0nwbORqBq5\n\thong==",
        "Delivered-To": "patchwork@dpdk.org",
        "Precedence": "list",
        "From": "Andrzej Ostruszka <amo@semihalf.com>",
        "X-Original-To": "patchwork@dpdk.org",
        "List-Post": "<mailto:dev@dpdk.org>",
        "Return-Path": "<dev-bounces@dpdk.org>",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "To": "dev@dpdk.org",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "Date": "Fri, 31 Aug 2018 14:25:59 +0200",
        "X-Gm-Message-State": "APzg51BFnrvWmW2mm5snv8PI2Q+J3s5fu6mg0BLiSrLKbj8arzUV7NRu\n\tbstgJNBdwwY2GsGVwaeNZk3pDtryVho=",
        "Cc": "mw@semihalf.com, zr@semihalf.com, tdu@semihalf.com, nsamsono@marvell.com",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "Subject": "[dpdk-dev] [PATCH v2 2/8] net/mvneta: add neta PMD skeleton"
    },
    "content": "From: Zyta Szpak <zr@semihalf.com>\n\nAdd neta pmd driver skeleton providing base for the further\ndevelopment.\n\nSigned-off-by: Natalie Samsonov <nsamsono@marvell.com>\nSigned-off-by: Yelena Krivosheev <yelena@marvell.com>\nSigned-off-by: Dmitri Epshtein <dima@marvell.com>\nSigned-off-by: Zyta Szpak <zr@semihalf.com>\nSigned-off-by: Andrzej Ostruszka <amo@semihalf.com>\n---\n MAINTAINERS                                   |   8 +\n config/common_base                            |   5 +\n devtools/test-build.sh                        |   2 +\n doc/guides/nics/features/mvneta.ini           |  18 +\n doc/guides/nics/mvneta.rst                    | 154 +++++\n doc/guides/rel_notes/release_18_11.rst        |   4 +\n drivers/common/Makefile                       |   4 +-\n drivers/common/mvep/rte_mvep_common.h         |   1 +\n drivers/net/Makefile                          |   1 +\n drivers/net/meson.build                       |   1 +\n drivers/net/mvneta/Makefile                   |  42 ++\n drivers/net/mvneta/meson.build                |  27 +\n drivers/net/mvneta/mvneta_ethdev.c            | 880 ++++++++++++++++++++++++++\n drivers/net/mvneta/mvneta_ethdev.h            |  78 +++\n drivers/net/mvneta/rte_pmd_mvneta_version.map |   3 +\n mk/rte.app.mk                                 |   7 +-\n 16 files changed, 1232 insertions(+), 3 deletions(-)\n create mode 100644 doc/guides/nics/features/mvneta.ini\n create mode 100644 doc/guides/nics/mvneta.rst\n create mode 100644 drivers/net/mvneta/Makefile\n create mode 100644 drivers/net/mvneta/meson.build\n create mode 100644 drivers/net/mvneta/mvneta_ethdev.c\n create mode 100644 drivers/net/mvneta/mvneta_ethdev.h\n create mode 100644 drivers/net/mvneta/rte_pmd_mvneta_version.map",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 9fd258f..18858b9 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -585,6 +585,14 @@ F: drivers/net/mvpp2/\n F: doc/guides/nics/mvpp2.rst\n F: doc/guides/nics/features/mvpp2.ini\n \n+Marvell mvneta\n+M: Zyta Szpak <zr@semihalf.com>\n+M: Dmitri Epshtein <dima@marvell.com>\n+M: Natalie Samsonov <nsamsono@marvell.com>\n+F: drivers/net/mvneta/\n+F: doc/guides/nics/mvneta.rst\n+F: doc/guides/nics/features/mvneta.ini\n+\n Mellanox mlx4\n M: Matan Azrad <matan@mellanox.com>\n M: Shahaf Shuler <shahafs@mellanox.com>\ndiff --git a/config/common_base b/config/common_base\nindex 155c7d4..1f8410b 100644\n--- a/config/common_base\n+++ b/config/common_base\n@@ -400,6 +400,11 @@ CONFIG_RTE_LIBRTE_PMD_FAILSAFE=y\n CONFIG_RTE_LIBRTE_MVPP2_PMD=n\n \n #\n+# Compile Marvell MVNETA PMD driver\n+#\n+CONFIG_RTE_LIBRTE_MVNETA_PMD=n\n+\n+#\n # Compile support for VMBus library\n #\n CONFIG_RTE_LIBRTE_VMBUS=n\ndiff --git a/devtools/test-build.sh b/devtools/test-build.sh\nindex 1eee241..2990978 100755\n--- a/devtools/test-build.sh\n+++ b/devtools/test-build.sh\n@@ -182,6 +182,8 @@ config () # <directory> <target> <options>\n \t\tsed -ri    's,(PMD_MVSAM_CRYPTO=)n,\\1y,' $1/.config\n \t\ttest -z \"$LIBMUSDK_PATH\" || \\\n \t\tsed -ri          's,(MVPP2_PMD=)n,\\1y,' $1/.config\n+\t\ttest -z \"$LIBMUSDK_PATH\" || \\\n+\t\tsed -ri          's,(MVNETA_PMD=)n,\\1y,' $1/.config\n \t\tbuild_config_hook $1 $2 $3\n \n \t\t# Explicit enabler/disabler (uppercase)\ndiff --git a/doc/guides/nics/features/mvneta.ini b/doc/guides/nics/features/mvneta.ini\nnew file mode 100644\nindex 0000000..3f02f84\n--- /dev/null\n+++ b/doc/guides/nics/features/mvneta.ini\n@@ -0,0 +1,18 @@\n+;\n+; Supported features of the 'mvneta' network poll mode driver.\n+;\n+; Refer to default.ini for the full list of available PMD features.\n+;\n+[Features]\n+Speed capabilities   = Y\n+Link status          = Y\n+MTU update           = Y\n+Jumbo frame          = Y\n+Promiscuous mode     = Y\n+CRC offload          = Y\n+L3 checksum offload  = Y\n+L4 checksum offload  = Y\n+Packet type parsing  = Y\n+Basic stats          = Y\n+ARMv8                = Y\n+Usage doc            = Y\ndiff --git a/doc/guides/nics/mvneta.rst b/doc/guides/nics/mvneta.rst\nnew file mode 100644\nindex 0000000..8d4b9e4\n--- /dev/null\n+++ b/doc/guides/nics/mvneta.rst\n@@ -0,0 +1,154 @@\n+..  SPDX-License-Identifier: BSD-3-Clause\n+    Copyright(c) 2018 Marvell International Ltd.\n+    Copyright(c) 2018 Semihalf.\n+    All rights reserved.\n+\n+MVNETA Poll Mode Driver\n+=======================\n+\n+The MVNETA PMD (librte_pmd_mvneta) provides poll mode driver support\n+for the Marvell NETA 1/2.5 Gbps adapter.\n+\n+Detailed information about SoCs that use PPv2 can be obtained here:\n+\n+* https://www.marvell.com/embedded-processors/armada-3700/\n+\n+.. Note::\n+\n+   Due to external dependencies, this driver is disabled by default. It must\n+   be enabled manually by setting relevant configuration option manually.\n+   Please refer to `Config File Options`_ section for further details.\n+\n+\n+Features\n+--------\n+\n+Features of the MVNETA PMD are:\n+\n+- Start/stop\n+- tx/rx_queue_setup\n+- tx/rx_burst\n+- Speed capabilities\n+- Link status\n+- CRC offload\n+- Packet type parsing\n+\n+\n+Limitations\n+-----------\n+\n+- Flushing vlans added for filtering is not possible due to MUSDK missing\n+  functionality. Current workaround is to reset board so that NETA has a\n+  chance to start in a sane state.\n+\n+Prerequisites\n+-------------\n+\n+- Custom Linux Kernel sources\n+\n+  .. code-block:: console\n+\n+     git clone https://github.com/MarvellEmbeddedProcessors/linux-marvell.git -b linux-4.4.52-armada-17.10\n+\n+\n+- MUSDK (Marvell User-Space SDK) sources\n+\n+  .. code-block:: console\n+\n+      git clone git@github.com:Semihalf/marvell-dpdk.git -b musdk-armada-17.10-mvneta\n+\n+  MUSDK is a light-weight library that provides direct access to Marvell's\n+  NETA. Alternatively prebuilt MUSDK library can be\n+  requested from `Marvell Extranet <https://extranet.marvell.com>`_. Once\n+  approval has been granted, library can be found by typing ``musdk`` in\n+  the search box.\n+\n+  MUSDK must be configured with the following features:\n+\n+  .. code-block:: console\n+\n+     --enable-bpool-dma=64 --enable-pp2=no --enable-neta\n+\n+- DPDK environment\n+\n+  Follow the DPDK :ref:`Getting Started Guide for Linux <linux_gsg>` to setup\n+  DPDK environment.\n+\n+\n+Config File Options\n+-------------------\n+\n+The following options can be modified in the ``config`` file.\n+\n+- ``CONFIG_RTE_LIBRTE_MVNETA_PMD`` (default ``n``)\n+\n+    Toggle compilation of the librte_pmd_mvneta driver.\n+\n+\n+Usage example\n+^^^^^^^^^^^^^\n+\n+.. code-block:: console\n+\n+   ./testpmd --vdev=eth_mvneta,iface=eth0,iface=eth1 \\\n+    -c 3 -- -i --p 3 -a\n+\n+\n+Building DPDK\n+-------------\n+\n+Driver needs precompiled MUSDK library during compilation.\n+\n+.. code-block:: console\n+\n+   export CROSS_COMPILE=<toolchain>/bin/aarch64-linux-gnu-\n+   ./bootstrap\n+   ./configure --host=aarch64-linux-gnu --enable-bpool-dma=64\n+   make install\n+\n+MUSDK will be installed to `usr/local` under current directory.\n+For the detailed build instructions please consult ``doc/musdk_get_started.txt``.\n+\n+Before the DPDK build process the environmental variable ``LIBMUSDK_PATH`` with\n+the path to the MUSDK installation directory needs to be exported.\n+\n+.. code-block:: console\n+\n+   export LIBMUSDK_PATH=<musdk>/usr/local\n+   export CROSS=aarch64-linux-gnu-\n+   make config T=arm64-armv8a-linuxapp-gcc\n+   sed -ri 's,(MVNETA_PMD=)n,\\1y,' build/.config\n+   make\n+\n+Usage Example\n+-------------\n+\n+MVNETA PMD requires extra out of tree kernel modules to function properly.\n+`musdk_uio` and `mv_neta_uio` sources are part of the MUSDK. Please consult\n+``doc/musdk_get_started.txt`` for the detailed build instructions.\n+\n+.. code-block:: console\n+\n+   insmod musdk_uio.ko\n+   insmod mv_neta_uio.ko\n+\n+Additionally interfaces used by DPDK application need to be put up:\n+\n+.. code-block:: console\n+\n+   ip link set eth0 up\n+   ip link set eth1 up\n+\n+In order to run testpmd example application following command can be used:\n+\n+.. code-block:: console\n+\n+   ./testpmd --vdev=eth_mvneta,iface=eth0,iface=eth1 -c 3 -- \\\n+     -i --p 3 -a --txd 256 --rxd 128 --rxq=1 --txq=1  --nb-cores=1\n+\n+\n+In order to run l2fwd example application following command can be used:\n+\n+.. code-block:: console\n+\n+   ./l2fwd --vdev=eth_mvneta,iface=eth0,iface=eth1 -c 3 -- -T 1 -p 3\ndiff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst\nindex 24204e6..0586715 100644\n--- a/doc/guides/rel_notes/release_18_11.rst\n+++ b/doc/guides/rel_notes/release_18_11.rst\n@@ -54,6 +54,10 @@ New Features\n      Also, make sure to start the actual text at the margin.\n      =========================================================\n \n+* **Added a new net driver for Marvell Armada 3k device.**\n+\n+  Added the new ``mvneta`` net driver for Marvell Armada 3k device. See the\n+  :doc:`../nics/mvneta` NIC guide for more details on this new driver.\n \n API Changes\n -----------\ndiff --git a/drivers/common/Makefile b/drivers/common/Makefile\nindex 5f72da0..b498c23 100644\n--- a/drivers/common/Makefile\n+++ b/drivers/common/Makefile\n@@ -8,7 +8,9 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF)$(CONFIG_RTE_LIBRTE_OCTEONTX_MEMPOO\n DIRS-y += octeontx\n endif\n \n-ifeq ($(CONFIG_RTE_LIBRTE_MVPP2_PMD),y)\n+MVEP-y := $(CONFIG_RTE_LIBRTE_MVPP2_PMD)\n+MVEP-y += $(CONFIG_RTE_LIBRTE_MVNETA_PMD)\n+ifneq (,$(findstring y,$(MVEP-y)))\n DIRS-y += mvep\n endif\n \ndiff --git a/drivers/common/mvep/rte_mvep_common.h b/drivers/common/mvep/rte_mvep_common.h\nindex ba47e16..0593cef 100644\n--- a/drivers/common/mvep/rte_mvep_common.h\n+++ b/drivers/common/mvep/rte_mvep_common.h\n@@ -11,6 +11,7 @@ enum mvep_module_type {\n \tMVEP_MOD_T_NONE = 0,\n \tMVEP_MOD_T_PP2,\n \tMVEP_MOD_T_SAM,\n+\tMVEP_MOD_T_NETA,\n \tMVEP_MOD_T_LAST\n };\n \ndiff --git a/drivers/net/Makefile b/drivers/net/Makefile\nindex 664398d..0d2c5b8 100644\n--- a/drivers/net/Makefile\n+++ b/drivers/net/Makefile\n@@ -33,6 +33,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_LIO_PMD) += liquidio\n DIRS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4\n DIRS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5\n DIRS-$(CONFIG_RTE_LIBRTE_MVPP2_PMD) += mvpp2\n+DIRS-$(CONFIG_RTE_LIBRTE_MVNETA_PMD) += mvneta\n DIRS-$(CONFIG_RTE_LIBRTE_NETVSC_PMD) += netvsc\n DIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp\n DIRS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt\ndiff --git a/drivers/net/meson.build b/drivers/net/meson.build\nindex 9c28ed4..852a720 100644\n--- a/drivers/net/meson.build\n+++ b/drivers/net/meson.build\n@@ -19,6 +19,7 @@ drivers = ['af_packet',\n \t'kni',\n \t'liquidio',\n \t'mvpp2',\n+\t'mvneta',\n \t'netvsc',\n \t'nfp',\n \t'null', 'octeontx', 'pcap', 'ring',\ndiff --git a/drivers/net/mvneta/Makefile b/drivers/net/mvneta/Makefile\nnew file mode 100644\nindex 0000000..149992e\n--- /dev/null\n+++ b/drivers/net/mvneta/Makefile\n@@ -0,0 +1,42 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2018 Marvell International Ltd.\n+# Copyright(c) 2018 Semihalf.\n+# All rights reserved.\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+ifneq ($(MAKECMDGOALS),clean)\n+ifneq ($(MAKECMDGOALS),config)\n+ifeq ($(LIBMUSDK_PATH),)\n+$(error \"Please define LIBMUSDK_PATH environment variable\")\n+endif\n+endif\n+endif\n+\n+# library name\n+LIB = librte_pmd_mvneta.a\n+\n+# library version\n+LIBABIVER := 1\n+\n+# versioning export map\n+EXPORT_MAP := rte_pmd_mvneta_version.map\n+\n+# external library dependencies\n+CFLAGS += -I$(RTE_SDK)/drivers/common/mvep\n+CFLAGS += -I$(LIBMUSDK_PATH)/include\n+CFLAGS += -DMVCONF_TYPES_PUBLIC\n+CFLAGS += -DMVCONF_DMA_PHYS_ADDR_T_PUBLIC\n+CFLAGS += -DMVCONF_DMA_PHYS_ADDR_T_SIZE=64\n+CFLAGS += $(WERROR_FLAGS)\n+CFLAGS += -O3\n+LDLIBS += -L$(LIBMUSDK_PATH)/lib\n+LDLIBS += -lmusdk\n+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring\n+LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_cfgfile\n+LDLIBS += -lrte_bus_vdev\n+\n+# library source files\n+SRCS-$(CONFIG_RTE_LIBRTE_MVNETA_PMD) += mvneta_ethdev.c\n+\n+include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/drivers/net/mvneta/meson.build b/drivers/net/mvneta/meson.build\nnew file mode 100644\nindex 0000000..2f31954\n--- /dev/null\n+++ b/drivers/net/mvneta/meson.build\n@@ -0,0 +1,27 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2018 Marvell International Ltd.\n+# Copyright(c) 2018 Semihalf.\n+# All rights reserved.\n+\n+path = get_option('lib_musdk_dir')\n+lib_dir = path + '/lib'\n+inc_dir = path + '/include'\n+\n+lib = cc.find_library('libmusdk', dirs : [lib_dir], required: false)\n+if not lib.found()\n+\tbuild = false\n+else\n+\text_deps += lib\n+\tincludes += include_directories(inc_dir)\n+\tcflags += [\n+\t  '-DMVCONF_TYPES_PUBLIC',\n+\t  '-DMVCONF_DMA_PHYS_ADDR_T_PUBLIC',\n+\t  '-DMVCONF_DMA_PHYS_ADDR_T_SIZE=64'\n+\t]\n+endif\n+\n+sources = files(\n+\t'mvneta_ethdev.c'\n+)\n+\n+deps += ['cfgfile', 'common_mvep']\ndiff --git a/drivers/net/mvneta/mvneta_ethdev.c b/drivers/net/mvneta/mvneta_ethdev.c\nnew file mode 100644\nindex 0000000..621f38a\n--- /dev/null\n+++ b/drivers/net/mvneta/mvneta_ethdev.c\n@@ -0,0 +1,880 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018 Marvell International Ltd.\n+ * Copyright(c) 2018 Semihalf.\n+ * All rights reserved.\n+ */\n+\n+#include <rte_ethdev_driver.h>\n+#include <rte_kvargs.h>\n+#include <rte_log.h>\n+#include <rte_malloc.h>\n+#include <rte_bus_vdev.h>\n+\n+#include <stdio.h>\n+#include <fcntl.h>\n+#include <linux/ethtool.h>\n+#include <linux/sockios.h>\n+#include <net/if.h>\n+#include <net/if_arp.h>\n+#include <sys/ioctl.h>\n+#include <sys/socket.h>\n+#include <sys/stat.h>\n+#include <sys/types.h>\n+\n+#include <rte_mvep_common.h>\n+#include \"mvneta_ethdev.h\"\n+\n+\n+#define MVNETA_IFACE_NAME_ARG \"iface\"\n+\n+#define MVNETA_RX_OFFLOADS (DEV_RX_OFFLOAD_JUMBO_FRAME | \\\n+\t\t\t  DEV_RX_OFFLOAD_CRC_STRIP | \\\n+\t\t\t  DEV_RX_OFFLOAD_CHECKSUM)\n+\n+/** Port Tx offloads capabilities */\n+#define MVNETA_TX_OFFLOADS (DEV_TX_OFFLOAD_IPV4_CKSUM | \\\n+\t\t\t  DEV_TX_OFFLOAD_UDP_CKSUM | \\\n+\t\t\t  DEV_TX_OFFLOAD_TCP_CKSUM | \\\n+\t\t\t  DEV_TX_OFFLOAD_MULTI_SEGS)\n+\n+#define MVNETA_PKT_SIZE_MAX (16382 - MV_MH_SIZE) /* 9700B */\n+#define MVNETA_DEFAULT_MTU\t1500\n+\n+#define MVNETA_MAC_ADDRS_MAX 256 /*16 UC, 256 IP, 256 MC/BC */\n+/** Maximum length of a match string */\n+#define MVNETA_MATCH_LEN 16\n+\n+#define MVNETA_PKT_EFFEC_OFFS (MRVL_NETA_PKT_OFFS + MV_MH_SIZE)\n+\n+int mvneta_logtype;\n+\n+static const char * const valid_args[] = {\n+\tMVNETA_IFACE_NAME_ARG,\n+\tNULL\n+};\n+\n+struct mvneta_ifnames {\n+\tconst char *names[NETA_NUM_ETH_PPIO];\n+\tint idx;\n+};\n+\n+\n+struct mvneta_rxq {\n+\tstruct mvneta_priv *priv;\n+\tstruct rte_mempool *mp;\n+\tint queue_id;\n+\tint port_id;\n+\tint size;\n+\tint cksum_enabled;\n+\tuint64_t bytes_recv;\n+\tuint64_t drop_mac;\n+\tuint64_t pkts_processed;\n+};\n+\n+\n+struct mvneta_txq {\n+\tstruct mvneta_priv *priv;\n+\tint queue_id;\n+\tint port_id;\n+\tuint64_t bytes_sent;\n+\tint tx_deferred_start;\n+};\n+\n+static int mvneta_dev_num;\n+static int mvneta_lcore_first;\n+static int mvneta_lcore_last;\n+\n+\n+/**\n+ * Deinitialize packet processor.\n+ */\n+static void\n+mvneta_neta_deinit(void)\n+{\n+\tneta_deinit();\n+}\n+\n+/**\n+ * Initialize packet processor.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+static int\n+mvneta_neta_init(void)\n+{\n+\treturn neta_init();\n+}\n+\n+/**\n+ * Callback used by rte_kvargs_process() during argument parsing.\n+ *\n+ * @param key\n+ *   Pointer to the parsed key (unused).\n+ * @param value\n+ *   Pointer to the parsed value.\n+ * @param extra_args\n+ *   Pointer to the extra arguments which contains address of the\n+ *   table of pointers to parsed interface names.\n+ *\n+ * @return\n+ *   Always 0.\n+ */\n+static int\n+mvneta_ifnames_get(const char *key __rte_unused, const char *value,\n+\t\t void *extra_args)\n+{\n+\tstruct mvneta_ifnames *ifnames = extra_args;\n+\n+\tifnames->names[ifnames->idx++] = value;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Ethernet device configuration.\n+ *\n+ * Prepare the driver for a given number of TX and RX queues and\n+ * configure RSS if supported.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+static int\n+mvneta_dev_configure(struct rte_eth_dev *dev)\n+{\n+\tstruct mvneta_priv *priv = dev->data->dev_private;\n+\tstruct neta_ppio_params *ppio_params;\n+\n+\tif (dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_NONE) {\n+\t\tMVNETA_LOG(INFO, \"Unsupported RSS and rx multi queue mode %d\",\n+\t\t\tdev->data->dev_conf.rxmode.mq_mode);\n+\t\tif (dev->data->nb_rx_queues > 1)\n+\t\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!(dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {\n+\t\tMVNETA_LOG(INFO,\n+\t\t\t\"L2 CRC stripping is always enabled in hw\");\n+\t\tdev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;\n+\t}\n+\n+\tif (dev->data->dev_conf.rxmode.split_hdr_size) {\n+\t\tMVNETA_LOG(INFO, \"Split headers not supported\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)\n+\t\tdev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len -\n+\t\t\t\t MRVL_NETA_ETH_HDRS_LEN;\n+\n+\tif (dev->data->dev_conf.txmode.offloads & DEV_TX_OFFLOAD_MULTI_SEGS)\n+\t\tpriv->multiseg = 1;\n+\n+\tppio_params = &priv->ppio_params;\n+\tppio_params->outqs_params.num_outqs = dev->data->nb_tx_queues;\n+\tpriv->nb_rx_queues = dev->data->nb_rx_queues;\n+\t/* Default: 1 TC, no QoS supported. */\n+\tppio_params->inqs_params.num_tcs = 1;\n+\tppio_params->inqs_params.tcs_params[0].pkt_offset = MRVL_NETA_PKT_OFFS;\n+\tpriv->ppio_id = dev->data->port_id;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * DPDK callback to get information about the device.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure (unused).\n+ * @param info\n+ *   Info structure output buffer.\n+ */\n+static void\n+mvneta_dev_infos_get(struct rte_eth_dev *dev __rte_unused,\n+\t\t   struct rte_eth_dev_info *info)\n+{\n+\tinfo->speed_capa = ETH_LINK_SPEED_10M |\n+\t\t\t   ETH_LINK_SPEED_100M |\n+\t\t\t   ETH_LINK_SPEED_1G |\n+\t\t\t   ETH_LINK_SPEED_2_5G;\n+\n+\tinfo->max_rx_queues = MRVL_NETA_RXQ_MAX;\n+\tinfo->max_tx_queues = MRVL_NETA_TXQ_MAX;\n+\tinfo->max_mac_addrs = MVNETA_MAC_ADDRS_MAX;\n+\n+\tinfo->rx_desc_lim.nb_max = MRVL_NETA_RXD_MAX;\n+\tinfo->rx_desc_lim.nb_min = MRVL_NETA_RXD_MIN;\n+\tinfo->rx_desc_lim.nb_align = MRVL_NETA_RXD_ALIGN;\n+\n+\tinfo->tx_desc_lim.nb_max = MRVL_NETA_TXD_MAX;\n+\tinfo->tx_desc_lim.nb_min = MRVL_NETA_TXD_MIN;\n+\tinfo->tx_desc_lim.nb_align = MRVL_NETA_TXD_ALIGN;\n+\n+\tinfo->rx_offload_capa = MVNETA_RX_OFFLOADS;\n+\tinfo->rx_queue_offload_capa = MVNETA_RX_OFFLOADS;\n+\n+\tinfo->tx_offload_capa =  MVNETA_TX_OFFLOADS;\n+\tinfo->tx_queue_offload_capa =  MVNETA_TX_OFFLOADS;\n+\n+\t/* By default packets are dropped if no descriptors are available */\n+\tinfo->default_rxconf.rx_drop_en = 1;\n+\tinfo->default_rxconf.offloads = DEV_RX_OFFLOAD_CRC_STRIP;\n+\t/* Deferred tx queue start is not supported */\n+\tinfo->default_txconf.tx_deferred_start = 0;\n+\tinfo->default_txconf.offloads = 0;\n+\n+\tinfo->max_rx_pktlen = MVNETA_PKT_SIZE_MAX;\n+}\n+\n+/**\n+ * Return supported packet types.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure (unused).\n+ *\n+ * @return\n+ *   Const pointer to the table with supported packet types.\n+ */\n+static const uint32_t *\n+mvneta_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused)\n+{\n+\tstatic const uint32_t ptypes[] = {\n+\t\tRTE_PTYPE_L2_ETHER,\n+\t\tRTE_PTYPE_L2_ETHER_VLAN,\n+\t\tRTE_PTYPE_L3_IPV4,\n+\t\tRTE_PTYPE_L3_IPV6,\n+\t\tRTE_PTYPE_L4_TCP,\n+\t\tRTE_PTYPE_L4_UDP\n+\t};\n+\n+\treturn ptypes;\n+}\n+\n+/**\n+ * DPDK callback to get information about specific receive queue.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ * @param rx_queue_id\n+ *   Receive queue index.\n+ * @param qinfo\n+ *   Receive queue information structure.\n+ */\n+static void mvneta_rxq_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,\n+\t\t\t      struct rte_eth_rxq_info *qinfo)\n+{\n+\tstruct mvneta_rxq *q = dev->data->rx_queues[rx_queue_id];\n+\n+\tqinfo->mp = q->mp;\n+\tqinfo->nb_desc = q->size;\n+}\n+\n+/**\n+ * DPDK callback to get information about specific transmit queue.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ * @param tx_queue_id\n+ *   Transmit queue index.\n+ * @param qinfo\n+ *   Transmit queue information structure.\n+ */\n+static void mvneta_txq_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id,\n+\t\t\t      struct rte_eth_txq_info *qinfo)\n+{\n+\tstruct mvneta_priv *priv = dev->data->dev_private;\n+\n+\tqinfo->nb_desc =\n+\t\tpriv->ppio_params.outqs_params.outqs_params[tx_queue_id].size;\n+}\n+\n+/**\n+ * DPDK callback to bring the link up.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+static int\n+mvneta_dev_set_link_up(struct rte_eth_dev *dev)\n+{\n+\tstruct mvneta_priv *priv = dev->data->dev_private;\n+\n+\tif (!priv->ppio)\n+\t\treturn 0;\n+\n+\treturn neta_ppio_enable(priv->ppio);\n+}\n+\n+/**\n+ * DPDK callback to bring the link down.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+static int\n+mvneta_dev_set_link_down(struct rte_eth_dev *dev)\n+{\n+\tstruct mvneta_priv *priv = dev->data->dev_private;\n+\n+\tif (!priv->ppio)\n+\t\treturn 0;\n+\n+\treturn neta_ppio_disable(priv->ppio);\n+}\n+\n+/**\n+ * DPDK callback to configure the receive queue.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ * @param idx\n+ *   RX queue index.\n+ * @param desc\n+ *   Number of descriptors to configure in queue.\n+ * @param socket\n+ *   NUMA socket on which memory must be allocated.\n+ * @param conf\n+ *   Thresholds parameters (unused_).\n+ * @param mp\n+ *   Memory pool for buffer allocations.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+static int\n+mvneta_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,\n+\t\t    unsigned int socket,\n+\t\t    const struct rte_eth_rxconf *conf __rte_unused,\n+\t\t    struct rte_mempool *mp)\n+{\n+\tstruct mvneta_priv *priv = dev->data->dev_private;\n+\tstruct mvneta_rxq *rxq;\n+\tuint32_t frame_size, buf_size = rte_pktmbuf_data_room_size(mp);\n+\tuint32_t max_rx_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;\n+\n+\tframe_size = buf_size - RTE_PKTMBUF_HEADROOM - MVNETA_PKT_EFFEC_OFFS;\n+\n+\tif (frame_size < max_rx_pkt_len) {\n+\t\tMVNETA_LOG(ERR,\n+\t\t\t\"Mbuf size must be increased to %u bytes to hold up \"\n+\t\t\t\"to %u bytes of data.\",\n+\t\t\tbuf_size + max_rx_pkt_len - frame_size,\n+\t\t\tmax_rx_pkt_len);\n+\t\tdev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size;\n+\t\tMVNETA_LOG(INFO, \"Setting max rx pkt len to %u\",\n+\t\t\tdev->data->dev_conf.rxmode.max_rx_pkt_len);\n+\t}\n+\n+\tif (dev->data->rx_queues[idx]) {\n+\t\trte_free(dev->data->rx_queues[idx]);\n+\t\tdev->data->rx_queues[idx] = NULL;\n+\t}\n+\n+\trxq = rte_zmalloc_socket(\"rxq\", sizeof(*rxq), 0, socket);\n+\tif (!rxq)\n+\t\treturn -ENOMEM;\n+\n+\trxq->priv = priv;\n+\trxq->mp = mp;\n+\trxq->cksum_enabled = dev->data->dev_conf.rxmode.offloads &\n+\t\t\t     DEV_RX_OFFLOAD_IPV4_CKSUM;\n+\trxq->queue_id = idx;\n+\trxq->port_id = dev->data->port_id;\n+\trxq->size = desc;\n+\tpriv->ppio_params.inqs_params.tcs_params[MRVL_NETA_DEFAULT_TC].size =\n+\t\tdesc;\n+\n+\tdev->data->rx_queues[idx] = rxq;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * DPDK callback to release the receive queue.\n+ *\n+ * @param rxq\n+ *   Generic receive queue pointer.\n+ */\n+static void\n+mvneta_rx_queue_release(void *rxq)\n+{\n+\tstruct mvneta_rxq *q = rxq;\n+\n+\tif (!q)\n+\t\treturn;\n+\n+\trte_free(rxq);\n+}\n+\n+/**\n+ * DPDK callback to configure the transmit queue.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ * @param idx\n+ *   Transmit queue index.\n+ * @param desc\n+ *   Number of descriptors to configure in the queue.\n+ * @param socket\n+ *   NUMA socket on which memory must be allocated.\n+ * @param conf\n+ *   Tx queue configuration parameters.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+static int\n+mvneta_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,\n+\t\t    unsigned int socket, const struct rte_eth_txconf *conf)\n+{\n+\tstruct mvneta_priv *priv = dev->data->dev_private;\n+\tstruct mvneta_txq *txq;\n+\n+\tif (dev->data->tx_queues[idx]) {\n+\t\trte_free(dev->data->tx_queues[idx]);\n+\t\tdev->data->tx_queues[idx] = NULL;\n+\t}\n+\n+\ttxq = rte_zmalloc_socket(\"txq\", sizeof(*txq), 0, socket);\n+\tif (!txq)\n+\t\treturn -ENOMEM;\n+\n+\ttxq->priv = priv;\n+\ttxq->queue_id = idx;\n+\ttxq->port_id = dev->data->port_id;\n+\ttxq->tx_deferred_start = conf->tx_deferred_start;\n+\tdev->data->tx_queues[idx] = txq;\n+\n+\tpriv->ppio_params.outqs_params.outqs_params[idx].size = desc;\n+\tpriv->ppio_params.outqs_params.outqs_params[idx].weight = 1;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * DPDK callback to release the transmit queue.\n+ *\n+ * @param txq\n+ *   Generic transmit queue pointer.\n+ */\n+static void\n+mvneta_tx_queue_release(void *txq)\n+{\n+\tstruct mvneta_txq *q = txq;\n+\n+\tif (!q)\n+\t\treturn;\n+\n+\trte_free(q);\n+}\n+\n+\n+/**\n+ * DPDK callback to start the device.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success, negative errno value on failure.\n+ */\n+static int\n+mvneta_dev_start(struct rte_eth_dev *dev)\n+{\n+\tstruct mvneta_priv *priv = dev->data->dev_private;\n+\tchar match[MVNETA_MATCH_LEN];\n+\tint ret = 0, i;\n+\n+\tif (priv->ppio)\n+\t\treturn mvneta_dev_set_link_up(dev);\n+\n+\tsnprintf(match, sizeof(match), \"%s\", dev->data->name);\n+\tpriv->ppio_params.match = match;\n+\tpriv->ppio_params.inqs_params.mtu = dev->data->mtu;\n+\n+\tret = neta_ppio_init(&priv->ppio_params, &priv->ppio);\n+\tif (ret) {\n+\t\tMVNETA_LOG(ERR, \"Failed to init ppio\");\n+\t\treturn ret;\n+\t}\n+\tpriv->ppio_id = priv->ppio->port_id;\n+\n+\t/*\n+\t * In case there are some some stale uc/mc mac addresses flush them\n+\t * here. It cannot be done during mvneta_dev_close() as port information\n+\t * is already gone at that point (due to neta_ppio_deinit() in\n+\t * mvneta_dev_stop()).\n+\t */\n+\tif (!priv->uc_mc_flushed) {\n+\t\tret = neta_ppio_flush_mac_addrs(priv->ppio, 0, 1);\n+\t\tif (ret) {\n+\t\t\tMVNETA_LOG(ERR,\n+\t\t\t\t\"Failed to flush uc/mc filter list\");\n+\t\t\tgoto out;\n+\t\t}\n+\t\tpriv->uc_mc_flushed = 1;\n+\t}\n+\n+\tret = mvneta_dev_set_link_up(dev);\n+\tif (ret) {\n+\t\tMVNETA_LOG(ERR, \"Failed to set link up\");\n+\t\tgoto out;\n+\t}\n+\n+\t/* start tx queues */\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++)\n+\t\tdev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;\n+\n+\treturn 0;\n+\n+out:\n+\tMVNETA_LOG(ERR, \"Failed to start device\");\n+\tneta_ppio_deinit(priv->ppio);\n+\treturn ret;\n+}\n+\n+/**\n+ * DPDK callback to stop the device.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ */\n+static void\n+mvneta_dev_stop(struct rte_eth_dev *dev)\n+{\n+\tstruct mvneta_priv *priv = dev->data->dev_private;\n+\n+\tif (!priv->ppio)\n+\t\treturn;\n+\n+\tmvneta_dev_set_link_down(dev);\n+\n+\tneta_ppio_deinit(priv->ppio);\n+\n+\tpriv->ppio = NULL;\n+}\n+\n+/**\n+ * DPDK callback to close the device.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ */\n+static void\n+mvneta_dev_close(struct rte_eth_dev *dev)\n+{\n+\tstruct mvneta_priv *priv = dev->data->dev_private;\n+\tint i;\n+\n+\tif (priv->ppio)\n+\t\tmvneta_dev_stop(dev);\n+\n+\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\tmvneta_rx_queue_release(dev->data->rx_queues[i]);\n+\t\tdev->data->rx_queues[i] = NULL;\n+\t}\n+\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\tmvneta_tx_queue_release(dev->data->tx_queues[i]);\n+\t\tdev->data->tx_queues[i] = NULL;\n+\t}\n+}\n+\n+/**\n+ * DPDK callback to set the primary MAC address.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ * @param mac_addr\n+ *   MAC address to register.\n+ */\n+static int\n+mvneta_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)\n+{\n+\tstruct mvneta_priv *priv = dev->data->dev_private;\n+\tint ret;\n+\n+\tif (!priv->ppio)\n+\t\treturn -EINVAL;\n+\n+\tret = neta_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes);\n+\tif (ret) {\n+\t\tchar buf[ETHER_ADDR_FMT_SIZE];\n+\t\tether_format_addr(buf, sizeof(buf), mac_addr);\n+\t\tMVNETA_LOG(ERR, \"Failed to set mac to %s\", buf);\n+\t}\n+\treturn 0;\n+}\n+\n+static const struct eth_dev_ops mvneta_ops = {\n+\t.dev_configure = mvneta_dev_configure,\n+\t.dev_start = mvneta_dev_start,\n+\t.dev_stop = mvneta_dev_stop,\n+\t.dev_set_link_up = mvneta_dev_set_link_up,\n+\t.dev_set_link_down = mvneta_dev_set_link_down,\n+\t.dev_close = mvneta_dev_close,\n+\t.mac_addr_set = mvneta_mac_addr_set,\n+\t.dev_infos_get = mvneta_dev_infos_get,\n+\t.dev_supported_ptypes_get = mvneta_dev_supported_ptypes_get,\n+\t.rxq_info_get = mvneta_rxq_info_get,\n+\t.txq_info_get = mvneta_txq_info_get,\n+\t.rx_queue_setup = mvneta_rx_queue_setup,\n+\t.rx_queue_release = mvneta_rx_queue_release,\n+\t.tx_queue_setup = mvneta_tx_queue_setup,\n+\t.tx_queue_release = mvneta_tx_queue_release,\n+};\n+\n+/**\n+ * Create private device structure.\n+ *\n+ * @param dev_name\n+ *   Pointer to the port name passed in the initialization parameters.\n+ *\n+ * @return\n+ *   Pointer to the newly allocated private device structure.\n+ */\n+static struct mvneta_priv *\n+mvneta_priv_create(const char *dev_name)\n+{\n+\tstruct mvneta_priv *priv;\n+\n+\tpriv = rte_zmalloc_socket(dev_name, sizeof(*priv), 0, rte_socket_id());\n+\tif (!priv)\n+\t\treturn NULL;\n+\n+\treturn priv;\n+}\n+\n+/**\n+ * Create device representing Ethernet port.\n+ *\n+ * @param name\n+ *   Pointer to the port's name.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+static int\n+mvneta_eth_dev_create(struct rte_vdev_device *vdev, const char *name)\n+{\n+\tint ret, fd = socket(AF_INET, SOCK_DGRAM, 0);\n+\tstruct rte_eth_dev *eth_dev;\n+\tstruct mvneta_priv *priv;\n+\tstruct ifreq req;\n+\n+\teth_dev = rte_eth_dev_allocate(name);\n+\tif (!eth_dev)\n+\t\treturn -ENOMEM;\n+\n+\tpriv = mvneta_priv_create(name);\n+\n+\tif (!priv) {\n+\t\tret = -ENOMEM;\n+\t\tgoto out_free_dev;\n+\t}\n+\n+\teth_dev->data->mac_addrs =\n+\t\trte_zmalloc(\"mac_addrs\",\n+\t\t\t    ETHER_ADDR_LEN * MVNETA_MAC_ADDRS_MAX, 0);\n+\tif (!eth_dev->data->mac_addrs) {\n+\t\tMVNETA_LOG(ERR, \"Failed to allocate space for eth addrs\");\n+\t\tret = -ENOMEM;\n+\t\tgoto out_free_priv;\n+\t}\n+\n+\tmemset(&req, 0, sizeof(req));\n+\tstrcpy(req.ifr_name, name);\n+\tret = ioctl(fd, SIOCGIFHWADDR, &req);\n+\tif (ret)\n+\t\tgoto out_free_mac;\n+\n+\tmemcpy(eth_dev->data->mac_addrs[0].addr_bytes,\n+\t       req.ifr_addr.sa_data, ETHER_ADDR_LEN);\n+\n+\teth_dev->data->kdrv = RTE_KDRV_NONE;\n+\teth_dev->data->dev_private = priv;\n+\teth_dev->device = &vdev->device;\n+;\teth_dev->dev_ops = &mvneta_ops;\n+\n+\treturn 0;\n+out_free_mac:\n+\trte_free(eth_dev->data->mac_addrs);\n+out_free_dev:\n+\trte_eth_dev_release_port(eth_dev);\n+out_free_priv:\n+\trte_free(priv);\n+\n+\treturn ret;\n+}\n+\n+static void\n+mvneta_eth_dev_destroy(struct rte_eth_dev *eth_dev)\n+{\n+\trte_free(eth_dev->data->dev_private);\n+\trte_free(eth_dev->data->mac_addrs);\n+\trte_eth_dev_release_port(eth_dev);\n+}\n+\n+/**\n+ * Cleanup previously created device representing Ethernet port.\n+ *\n+ * @param name\n+ *   Pointer to the port name.\n+ */\n+static void\n+mvneta_eth_dev_destroy_name(const char *name)\n+{\n+\tstruct rte_eth_dev *eth_dev;\n+\n+\teth_dev = rte_eth_dev_allocated(name);\n+\tif (!eth_dev)\n+\t\treturn;\n+\n+\tmvneta_eth_dev_destroy(eth_dev);\n+}\n+\n+/**\n+ * DPDK callback to register the virtual device.\n+ *\n+ * @param vdev\n+ *   Pointer to the virtual device.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+static int\n+rte_pmd_mvneta_probe(struct rte_vdev_device *vdev)\n+{\n+\tstruct rte_kvargs *kvlist;\n+\tstruct mvneta_ifnames ifnames;\n+\tint ret = -EINVAL;\n+\tuint32_t i, ifnum;\n+\tconst char *params;\n+\n+\tparams = rte_vdev_device_args(vdev);\n+\tif (!params)\n+\t\treturn -EINVAL;\n+\n+\tkvlist = rte_kvargs_parse(params, valid_args);\n+\tif (!kvlist)\n+\t\treturn -EINVAL;\n+\n+\tifnum = rte_kvargs_count(kvlist, MVNETA_IFACE_NAME_ARG);\n+\tif (ifnum > RTE_DIM(ifnames.names))\n+\t\tgoto out_free_kvlist;\n+\n+\tifnames.idx = 0;\n+\trte_kvargs_process(kvlist, MVNETA_IFACE_NAME_ARG,\n+\t\t\t   mvneta_ifnames_get, &ifnames);\n+\n+\t/*\n+\t * The below system initialization should be done only once,\n+\t * on the first provided configuration file\n+\t */\n+\tif (mvneta_dev_num)\n+\t\tgoto init_devices;\n+\n+\tMVNETA_LOG(INFO, \"Perform MUSDK initializations\");\n+\n+\tret = rte_mvep_init(MVEP_MOD_T_NETA, kvlist);\n+\tif (ret)\n+\t\tgoto out_free_kvlist;\n+\n+\tret = mvneta_neta_init();\n+\tif (ret) {\n+\t\tMVNETA_LOG(ERR, \"Failed to init NETA!\");\n+\t\trte_mvep_deinit(MVEP_MOD_T_NETA);\n+\t\tgoto out_free_kvlist;\n+\t}\n+\n+\tmvneta_lcore_first = RTE_MAX_LCORE;\n+\tmvneta_lcore_last = 0;\n+\n+init_devices:\n+\tfor (i = 0; i < ifnum; i++) {\n+\t\tMVNETA_LOG(INFO, \"Creating %s\", ifnames.names[i]);\n+\t\tret = mvneta_eth_dev_create(vdev, ifnames.names[i]);\n+\t\tif (ret)\n+\t\t\tgoto out_cleanup;\n+\t}\n+\tmvneta_dev_num += ifnum;\n+\n+\trte_kvargs_free(kvlist);\n+\n+\treturn 0;\n+out_cleanup:\n+\tfor (; i > 0; i--)\n+\t\tmvneta_eth_dev_destroy_name(ifnames.names[i]);\n+\n+\tif (mvneta_dev_num == 0) {\n+\t\tmvneta_neta_deinit();\n+\t\trte_mvep_deinit(MVEP_MOD_T_NETA);\n+\t}\n+out_free_kvlist:\n+\trte_kvargs_free(kvlist);\n+\n+\treturn ret;\n+}\n+\n+/**\n+ * DPDK callback to remove virtual device.\n+ *\n+ * @param vdev\n+ *   Pointer to the removed virtual device.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+static int\n+rte_pmd_mvneta_remove(struct rte_vdev_device *vdev)\n+{\n+\tint i;\n+\tconst char *name;\n+\n+\tname = rte_vdev_device_name(vdev);\n+\tif (!name)\n+\t\treturn -EINVAL;\n+\n+\tMVNETA_LOG(INFO, \"Removing %s\", name);\n+\n+\tRTE_ETH_FOREACH_DEV(i) {\n+\t\tif (rte_eth_devices[i].device != &vdev->device)\n+\t\t\tcontinue;\n+\n+\t\tmvneta_eth_dev_destroy(&rte_eth_devices[i]);\n+\t\tmvneta_dev_num--;\n+\t}\n+\n+\tif (mvneta_dev_num == 0) {\n+\t\tMVNETA_LOG(INFO, \"Perform MUSDK deinit\");\n+\t\tmvneta_neta_deinit();\n+\t\trte_mvep_deinit(MVEP_MOD_T_NETA);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static struct rte_vdev_driver pmd_mvneta_drv = {\n+\t.probe = rte_pmd_mvneta_probe,\n+\t.remove = rte_pmd_mvneta_remove,\n+};\n+\n+RTE_PMD_REGISTER_VDEV(net_mvneta, pmd_mvneta_drv);\n+RTE_PMD_REGISTER_ALIAS(net_mvneta, eth_mvneta);\n+\n+RTE_INIT(mvneta_init_log)\n+{\n+\tmvneta_logtype = rte_log_register(\"pmd.net.mvneta\");\n+\tif (mvneta_logtype >= 0)\n+\t\trte_log_set_level(mvneta_logtype, RTE_LOG_NOTICE);\n+}\ndiff --git a/drivers/net/mvneta/mvneta_ethdev.h b/drivers/net/mvneta/mvneta_ethdev.h\nnew file mode 100644\nindex 0000000..8957034\n--- /dev/null\n+++ b/drivers/net/mvneta/mvneta_ethdev.h\n@@ -0,0 +1,78 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018 Marvell International Ltd.\n+ * Copyright(c) 2018 Semihalf.\n+ * All rights reserved.\n+ */\n+\n+#ifndef _MVNETA_ETHDEV_H_\n+#define _MVNETA_ETHDEV_H_\n+\n+/*\n+ * container_of is defined by both DPDK and MUSDK,\n+ * we'll declare only one version.\n+ *\n+ * Note that it is not used in this PMD anyway.\n+ */\n+#ifdef container_of\n+#undef container_of\n+#endif\n+\n+#include <drivers/mv_neta.h>\n+#include <drivers/mv_neta_ppio.h>\n+\n+/** Packet offset inside RX buffer. */\n+#define MRVL_NETA_PKT_OFFS 64\n+\n+/** Maximum number of rx/tx queues per port */\n+#define MRVL_NETA_RXQ_MAX 8\n+#define MRVL_NETA_TXQ_MAX 8\n+\n+/** Minimum/maximum number of descriptors in tx queue TODO is it? */\n+#define MRVL_NETA_TXD_MIN 16\n+#define MRVL_NETA_TXD_MAX 2048\n+\n+/** Tx queue descriptors alignment in B */\n+#define MRVL_NETA_TXD_ALIGN 32\n+\n+/** Minimum/maximum number of descriptors in rx queue TODO is it? */\n+#define MRVL_NETA_RXD_MIN 16\n+#define MRVL_NETA_RXD_MAX 2048\n+\n+/** Rx queue descriptors alignment in B */\n+#define MRVL_NETA_RXD_ALIGN 32\n+\n+#define MRVL_NETA_DEFAULT_TC 0\n+\n+\n+#define MRVL_NETA_VLAN_TAG_LEN\t\t4\n+#define MRVL_NETA_ETH_HDRS_LEN\t\t(ETHER_HDR_LEN + ETHER_CRC_LEN + \\\n+\t\t\t\t\tMRVL_NETA_VLAN_TAG_LEN)\n+\n+#define MRVL_NETA_HDRS_LEN\t\t(MV_MH_SIZE + MRVL_NETA_ETH_HDRS_LEN)\n+#define MRVL_NETA_MTU_TO_MRU(mtu)\t((mtu) + MRVL_NETA_HDRS_LEN)\n+#define MRVL_NETA_MRU_TO_MTU(mru)\t((mru) - MRVL_NETA_HDRS_LEN)\n+\n+\n+struct mvneta_priv {\n+\t/* Hot fields, used in fast path. */\n+\tstruct neta_ppio\t*ppio;    /**< Port handler pointer */\n+\n+\tuint8_t pp_id;\n+\tuint8_t ppio_id;\t/* ppio port id */\n+\tuint8_t uc_mc_flushed;\n+\tuint8_t multiseg;\n+\n+\tstruct neta_ppio_params ppio_params;\n+\tuint16_t nb_rx_queues;\n+\n+\tuint64_t rate_max;\n+};\n+\n+/** Current log type. */\n+extern int mvneta_logtype;\n+\n+#define MVNETA_LOG(level, fmt, args...) \\\n+\trte_log(RTE_LOG_ ## level, mvneta_logtype, \"%s(): \" fmt \"\\n\", \\\n+\t\t__func__, ##args)\n+\n+#endif /* _MVNETA_ETHDEV_H_ */\ndiff --git a/drivers/net/mvneta/rte_pmd_mvneta_version.map b/drivers/net/mvneta/rte_pmd_mvneta_version.map\nnew file mode 100644\nindex 0000000..24bd5cd\n--- /dev/null\n+++ b/drivers/net/mvneta/rte_pmd_mvneta_version.map\n@@ -0,0 +1,3 @@\n+DPDK_18.11 {\n+\tlocal: *;\n+};\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex 899d51a..66f9199 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -98,7 +98,9 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF)$(CONFIG_RTE_LIBRTE_OCTEONTX_MEMPOO\n _LDLIBS-y += -lrte_common_octeontx\n endif\n \n-ifeq ($(CONFIG_RTE_LIBRTE_MVPP2_PMD),y)\n+MVEP-y := $(CONFIG_RTE_LIBRTE_MVPP2_PMD)\n+MVEP-y += $(CONFIG_RTE_LIBRTE_MVNETA_PMD)\n+ifneq (,$(findstring y,$(MVEP-y)))\n _LDLIBS-y += -lrte_common_mvep -L$(LIBMUSDK_PATH)/lib -lmusdk\n endif\n \n@@ -157,7 +159,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5 -ldl -lmnl\n else\n _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5 -libverbs -lmlx5 -lmnl\n endif\n-_LDLIBS-$(CONFIG_RTE_LIBRTE_MVPP2_PMD)      += -lrte_pmd_mvpp2 -L$(LIBMUSDK_PATH)/lib -lmusdk\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_MVPP2_PMD)      += -lrte_pmd_mvpp2\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_MVNETA_PMD)     += -lrte_pmd_mvneta\n _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD)        += -lrte_pmd_nfp\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL)       += -lrte_pmd_null\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP)       += -lrte_pmd_pcap -lpcap\n",
    "prefixes": [
        "v2",
        "2/8"
    ]
}