[dpdk-dev,PATCHv5,13/33] net/dpaa2: introducing NXP dpaa2 pmd driver

Message ID 1484832240-2048-16-git-send-email-hemant.agrawal@nxp.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel compilation success Compilation OK

Commit Message

Hemant Agrawal Jan. 19, 2017, 1:23 p.m. UTC
  add support for fsl-mc bus based dpaa2 pmd driver.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 config/common_base                          |   4 +
 config/defconfig_arm64-dpaa2-linuxapp-gcc   |   5 +
 drivers/bus/Makefile                        |   2 +
 drivers/common/Makefile                     |   2 +
 drivers/net/Makefile                        |   2 +-
 drivers/net/dpaa2/Makefile                  |  59 +++++++++++
 drivers/net/dpaa2/dpaa2_ethdev.c            | 153 ++++++++++++++++++++++++++++
 drivers/net/dpaa2/dpaa2_ethdev.h            |  44 ++++++++
 drivers/net/dpaa2/rte_pmd_dpaa2_version.map |   4 +
 mk/rte.app.mk                               |   5 +
 10 files changed, 279 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/dpaa2/Makefile
 create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.c
 create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.h
 create mode 100644 drivers/net/dpaa2/rte_pmd_dpaa2_version.map
  

Comments

Ferruh Yigit Jan. 19, 2017, 7:15 p.m. UTC | #1
On 1/19/2017 1:23 PM, Hemant Agrawal wrote:
> add support for fsl-mc bus based dpaa2 pmd driver.
> 
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>

<...>

> diff --git a/drivers/common/Makefile b/drivers/common/Makefile
> index e5bfecb..76ec2d1 100644
> --- a/drivers/common/Makefile
> +++ b/drivers/common/Makefile
> @@ -31,6 +31,8 @@
>  
>  include $(RTE_SDK)/mk/rte.vars.mk
>  
> +CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)

This logic make sense, is there any reason DPAA2_COMMON to be a config
option, it doesn't look like something a user would like to change on
its own.

Instead, as done here, if there is a user of common folder it is enabled
in Makefile. For this DPAA2_COMMON doesn't need to be a config option
itself I think.

> +
>  DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += dpaa2
>  
>  include $(RTE_SDK)/mk/rte.subdir.mk
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 40fc333..f716ca0 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -57,7 +57,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
>  DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
>  DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
>  DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
> -
> +DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2

Add alphabetically please.

>  ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
>  DIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += vhost
>  endif # $(CONFIG_RTE_LIBRTE_VHOST)

<...>

> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
> new file mode 100644
> index 0000000..2295f82
> --- /dev/null
> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
<...>
> +/* Name of the DPAA2 Net PMD */
> +static const char *drivername = "DPAA2 PMD";

Custom names not preferred, please check any other PMD to be consistent.

<...>

> +static int
> +rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv,
> +		struct rte_dpaa2_device *dpaa2_dev)
> +{
> +	struct eth_driver    *eth_drv;

whitespace error.

> +	struct rte_eth_dev *eth_dev;
> +	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
> +
> +	int diag;
> +
> +	eth_drv = (struct eth_driver *)dpaa2_drv;

How this suppose to work?

struct eth_driver {

	struct rte_pci_driver pci_drv;
	eth_dev_init_t eth_dev_init;
	eth_dev_uninit_t eth_dev_uninit;
	unsigned int dev_private_size;
};

struct rte_dpaa2_driver {
	TAILQ_ENTRY(rte_dpaa2_driver) next;
	struct rte_driver driver;
	struct rte_fslmc_bus *fslmc_bus;
	uint32_t drv_flags;
	uint16_t drv_type;
	rte_dpaa2_probe_t probe
	rte_dpaa2_remove_t remove;
};

> +
> +	sprintf(ethdev_name, "dpni-%d", dpaa2_dev->object_id);
> +
> +	eth_dev = rte_eth_dev_allocate(ethdev_name);
> +	if (eth_dev == NULL)
> +		return -ENOMEM;
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +		eth_dev->data->dev_private = rte_zmalloc(
> +						"ethdev private structure",
> +						sizeof(struct dpaa2_dev_priv),
> +						RTE_CACHE_LINE_SIZE);
> +		if (eth_dev->data->dev_private == NULL) {
> +			RTE_LOG(CRIT, PMD, "Cannot allocate memzone for"
> +				" private port data\n");
> +			return -ENOMEM;

release allocated port?

> +		}
> +	}
> +	eth_dev->device = &dpaa2_dev->device;
> +	dpaa2_dev->eth_dev = eth_dev;
> +	eth_dev->driver = eth_drv;
> +	eth_dev->data->rx_mbuf_alloc_failed = 0;
> +
> +	/* init user callbacks */
> +	TAILQ_INIT(&eth_dev->link_intr_cbs);

This is no more required, since done by rte_eth_dev_allocate()

> +
> +	/*
> +	 * Set the default MTU.
> +	 */
> +	eth_dev->data->mtu = ETHER_MTU;

Same, no more required to set in pmd.

> +
> +	/* Invoke PMD device initialization function */
> +	diag = dpaa2_dev_init(eth_dev);
> +	if (diag == 0)
> +		return 0;
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> +		rte_free(eth_dev->data->dev_private);
> +	rte_eth_dev_release_port(eth_dev);
> +	return diag;
> +}

<...>

> +static struct rte_dpaa2_driver rte_dpaa2_pmd = {
> +	.drv_type = DPAA2_MC_DPNI_DEVID,
> +	.driver = {
> +		.name = "DPAA2 PMD",

This is not required, RTE_PMD_REGISTER_DPAA2 will set it.

> +	},
> +	.probe = rte_dpaa2_probe,
> +	.remove = rte_dpaa2_remove,

These are PMD specific APIs, PCI equivalent of these are eth_dev_init()
and eth_dev_uninit() functions. Instead of rte_eth_dev_pci_probe() like
function.
Here it seems used as how it is used for virtual devices. But even for
virtual devices, it is desired to have more proper virtual bus structure.

I understand this part is a little problematic now, because of the
eth_driver <-> pci_driver relation, this is not generic.
What do you think first solve eth_driver <-> pci_driver problem, out of
this patchset, and later add this PMD?

<...>

> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index a5daa84..c793dd2 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -110,6 +110,11 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET)  += -lrte_pmd_af_packet
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD)      += -lrte_pmd_bnx2x -lz
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD)       += -lrte_pmd_bnxt
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD)      += -lrte_pmd_cxgbe
> +ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_COMMON),y)

If DPAA2_COMMON removed it can work here too, because if DPAA2_PMD
enabled, DPAA2_COMMON should be already enabled.

> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_pmd_dpaa2
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_pmd_dpaa2_qbman
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_pmd_fslmcbus
> +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
>
  
Shreyansh Jain Jan. 20, 2017, 2:01 p.m. UTC | #2
Hello Ferruh,

On Friday 20 January 2017 12:45 AM, Ferruh Yigit wrote:
> On 1/19/2017 1:23 PM, Hemant Agrawal wrote:
>> add support for fsl-mc bus based dpaa2 pmd driver.
>>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>
> <...>
>
>> diff --git a/drivers/common/Makefile b/drivers/common/Makefile
>> index e5bfecb..76ec2d1 100644
>> --- a/drivers/common/Makefile
>> +++ b/drivers/common/Makefile
>> @@ -31,6 +31,8 @@
>>
>>  include $(RTE_SDK)/mk/rte.vars.mk
>>
>> +CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
>
> This logic make sense, is there any reason DPAA2_COMMON to be a config
> option, it doesn't look like something a user would like to change on
> its own.

I am assuming you wanted to say "The logic _doesn't_ make sense, ..." :)

>
> Instead, as done here, if there is a user of common folder it is enabled
> in Makefile. For this DPAA2_COMMON doesn't need to be a config option
> itself I think.

Aim of drivers/common was to introduce libraries which may be used by
more than one sub-system. These can be other than dpaa2 and may even
be external to DPDK framework itself.

But for now, we will remove it and keep it toggleable with rte.app.mk
changes. Maybe in future, if need for configurable option exist, we will
introduce.

>
>> +
>>  DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += dpaa2
>>
>>  include $(RTE_SDK)/mk/rte.subdir.mk
>> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
>> index 40fc333..f716ca0 100644
>> --- a/drivers/net/Makefile
>> +++ b/drivers/net/Makefile
>> @@ -57,7 +57,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
>>  DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
>>  DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
>>  DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
>> -
>> +DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
>
> Add alphabetically please.

Agree.

>
>>  ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
>>  DIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += vhost
>>  endif # $(CONFIG_RTE_LIBRTE_VHOST)
>
> <...>
>
>> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
>> new file mode 100644
>> index 0000000..2295f82
>> --- /dev/null
>> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
> <...>
>> +/* Name of the DPAA2 Net PMD */
>> +static const char *drivername = "DPAA2 PMD";
>
> Custom names not preferred, please check any other PMD to be consistent.

Yes, this should be changed.

>
> <...>
>
>> +static int
>> +rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv,
>> +		struct rte_dpaa2_device *dpaa2_dev)
>> +{
>> +	struct eth_driver    *eth_drv;
>
> whitespace error.

Fixed. Thanks.

>
>> +	struct rte_eth_dev *eth_dev;
>> +	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
>> +
>> +	int diag;
>> +
>> +	eth_drv = (struct eth_driver *)dpaa2_drv;
>
> How this suppose to work?

Actually, a not-so-clean-logic coupled with the above line which 
probably got added in one of our rebasing attempts. And you have pointed
out correctly - because of eth_driver<->pci_driver restriction.

(more below)

>
> struct eth_driver {
>
> 	struct rte_pci_driver pci_drv;
> 	eth_dev_init_t eth_dev_init;
> 	eth_dev_uninit_t eth_dev_uninit;
> 	unsigned int dev_private_size;
> };
>
> struct rte_dpaa2_driver {
> 	TAILQ_ENTRY(rte_dpaa2_driver) next;
> 	struct rte_driver driver;
> 	struct rte_fslmc_bus *fslmc_bus;
> 	uint32_t drv_flags;
> 	uint16_t drv_type;
> 	rte_dpaa2_probe_t probe
> 	rte_dpaa2_remove_t remove;
> };

dpaa2 driver is not using eth_drv - it is more of a dummy.

If we had used rte_eth_dev_pci_probe, we would have faced this issue of
delinking eth_driver from pci_probe. So, we have leveraged the
bus->probe and created our own probing routine (rather than use 
rte_eth_dev_pci_probe).

Then, because it is our own probe routine, we simply allocate the
eth_dev (which luckily is free from pci_dev), and call our dev_init,
which rte_eth_dev_pci_probe would have done using eth_drv->init().

(More below)


>
>> +
>> +	sprintf(ethdev_name, "dpni-%d", dpaa2_dev->object_id);
>> +
>> +	eth_dev = rte_eth_dev_allocate(ethdev_name);
>> +	if (eth_dev == NULL)
>> +		return -ENOMEM;
>> +
>> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
>> +		eth_dev->data->dev_private = rte_zmalloc(
>> +						"ethdev private structure",
>> +						sizeof(struct dpaa2_dev_priv),
>> +						RTE_CACHE_LINE_SIZE);
>> +		if (eth_dev->data->dev_private == NULL) {
>> +			RTE_LOG(CRIT, PMD, "Cannot allocate memzone for"
>> +				" private port data\n");
>> +			return -ENOMEM;
>
> release allocated port?

Yes, I will fix this.

>
>> +		}
>> +	}
>> +	eth_dev->device = &dpaa2_dev->device;
>> +	dpaa2_dev->eth_dev = eth_dev;
>> +	eth_dev->driver = eth_drv;
>> +	eth_dev->data->rx_mbuf_alloc_failed = 0;
>> +
>> +	/* init user callbacks */
>> +	TAILQ_INIT(&eth_dev->link_intr_cbs);
>
> This is no more required, since done by rte_eth_dev_allocate()

yes, through eth_dev_get. Thanks - next version will contain the fix.

>
>> +
>> +	/*
>> +	 * Set the default MTU.
>> +	 */
>> +	eth_dev->data->mtu = ETHER_MTU;
>
> Same, no more required to set in pmd.

Yes, thanks for highlighting. Implementing our own rte_eth_dev_pci_probe
meant writing all these ourselves which we couldn't match to the changes
being done upstream.

>
>> +
>> +	/* Invoke PMD device initialization function */
>> +	diag = dpaa2_dev_init(eth_dev);
>> +	if (diag == 0)
>> +		return 0;
>> +
>> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
>> +		rte_free(eth_dev->data->dev_private);
>> +	rte_eth_dev_release_port(eth_dev);
>> +	return diag;
>> +}
>
> <...>
>
>> +static struct rte_dpaa2_driver rte_dpaa2_pmd = {
>> +	.drv_type = DPAA2_MC_DPNI_DEVID,
>> +	.driver = {
>> +		.name = "DPAA2 PMD",
>
> This is not required, RTE_PMD_REGISTER_DPAA2 will set it.

Yes. Will be removed.

>
>> +	},
>> +	.probe = rte_dpaa2_probe,
>> +	.remove = rte_dpaa2_remove,
>
> These are PMD specific APIs, PCI equivalent of these are eth_dev_init()
> and eth_dev_uninit() functions. Instead of rte_eth_dev_pci_probe() like
> function.
> Here it seems used as how it is used for virtual devices. But even for
> virtual devices, it is desired to have more proper virtual bus structure.
>
> I understand this part is a little problematic now, because of the
> eth_driver <-> pci_driver relation, this is not generic.
> What do you think first solve eth_driver <-> pci_driver problem, out of
> this patchset, and later add this PMD?

This is a long pending problem. I agree that it would be cleaner to do 
this unlink. But, I think that the current way dpaa2 driver handles it
is not truly incorrect.

bus->probe() can be linked to a driver specific probe (which dpaa2 
does). A PCI PMD would have called rte_eth_dev_pci_probe() as a helper
for doing all eth_dev/eth_drv initialization. dpaa2 does it manually.

I agree we need to match up to various changes done in 
rte_eth_dev_pci_probe(), but after that our code is as legal as any 
other PMD :D.

>
> <...>
>
>> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
>> index a5daa84..c793dd2 100644
>> --- a/mk/rte.app.mk
>> +++ b/mk/rte.app.mk
>> @@ -110,6 +110,11 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET)  += -lrte_pmd_af_packet
>>  _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD)      += -lrte_pmd_bnx2x -lz
>>  _LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD)       += -lrte_pmd_bnxt
>>  _LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD)      += -lrte_pmd_cxgbe
>> +ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_COMMON),y)
>
> If DPAA2_COMMON removed it can work here too, because if DPAA2_PMD
> enabled, DPAA2_COMMON should be already enabled.

Agreed.

>
>> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_pmd_dpaa2
>> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_pmd_dpaa2_qbman
>> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_pmd_fslmcbus
>> +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
>>
>
>
  

Patch

diff --git a/config/common_base b/config/common_base
index e6b4d60..6f513fe 100644
--- a/config/common_base
+++ b/config/common_base
@@ -297,6 +297,10 @@  CONFIG_RTE_LIBRTE_DPAA2_COMMON=n
 #
 CONFIG_RTE_LIBRTE_FSLMC_BUS=n
 
+#
+# Compile burst-oriented NXP DPAA2 PMD driver
+#
+CONFIG_RTE_LIBRTE_DPAA2_PMD=n
 # Compile burst-oriented VIRTIO PMD driver
 #
 CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index 800e22b..13c16c0 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -51,3 +51,8 @@  CONFIG_RTE_LIBRTE_DPAA2_COMMON=y
 # Compile NXP DPAA2 FSL-MC Bus
 #
 CONFIG_RTE_LIBRTE_FSLMC_BUS=y
+
+#
+# Compile burst-oriented NXP DPAA2 PMD driver
+#
+CONFIG_RTE_LIBRTE_DPAA2_PMD=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 60e9764..8f7864b 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -31,6 +31,8 @@ 
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
+CONFIG_RTE_LIBRTE_FSLMC_BUS = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/common/Makefile b/drivers/common/Makefile
index e5bfecb..76ec2d1 100644
--- a/drivers/common/Makefile
+++ b/drivers/common/Makefile
@@ -31,6 +31,8 @@ 
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+
 DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += dpaa2
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 40fc333..f716ca0 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -57,7 +57,7 @@  DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
 DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
-
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
 ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += vhost
 endif # $(CONFIG_RTE_LIBRTE_VHOST)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
new file mode 100644
index 0000000..9e7f958
--- /dev/null
+++ b/drivers/net/dpaa2/Makefile
@@ -0,0 +1,59 @@ 
+#   BSD LICENSE
+#
+#   Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+#   Copyright (c) 2016 NXP. All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Freescale Semiconductor, Inc nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+
+# versioning export map
+EXPORT_MAP := rte_pmd_dpaa2_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pmd_fslmcbus
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
new file mode 100644
index 0000000..2295f82
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -0,0 +1,153 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
+ *   Copyright (c) 2016 NXP. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Freescale Semiconductor, Inc nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <time.h>
+#include <net/if.h>
+
+#include <rte_mbuf.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_string_fns.h>
+#include <rte_cycles.h>
+#include <rte_kvargs.h>
+#include <rte_dev.h>
+#include <rte_ethdev.h>
+#include <rte_fslmc.h>
+
+#include <fslmc_vfio.h>
+#include "dpaa2_ethdev.h"
+
+/* Name of the DPAA2 Net PMD */
+static const char *drivername = "DPAA2 PMD";
+
+static int
+dpaa2_dev_init(struct rte_eth_dev *eth_dev)
+{
+	/* For secondary processes, the primary has done all the work */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	eth_dev->data->drv_name = drivername;
+
+	return 0;
+}
+
+static int
+dpaa2_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused)
+{
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return -EPERM;
+
+	return 0;
+}
+
+static int
+rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv,
+		struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct eth_driver    *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+	int diag;
+
+	eth_drv = (struct eth_driver *)dpaa2_drv;
+
+	sprintf(ethdev_name, "dpni-%d", dpaa2_dev->object_id);
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		eth_dev->data->dev_private = rte_zmalloc(
+						"ethdev private structure",
+						sizeof(struct dpaa2_dev_priv),
+						RTE_CACHE_LINE_SIZE);
+		if (eth_dev->data->dev_private == NULL) {
+			RTE_LOG(CRIT, PMD, "Cannot allocate memzone for"
+				" private port data\n");
+			return -ENOMEM;
+		}
+	}
+	eth_dev->device = &dpaa2_dev->device;
+	dpaa2_dev->eth_dev = eth_dev;
+	eth_dev->driver = eth_drv;
+	eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+	/* init user callbacks */
+	TAILQ_INIT(&eth_dev->link_intr_cbs);
+
+	/*
+	 * Set the default MTU.
+	 */
+	eth_dev->data->mtu = ETHER_MTU;
+
+	/* Invoke PMD device initialization function */
+	diag = dpaa2_dev_init(eth_dev);
+	if (diag == 0)
+		return 0;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+	rte_eth_dev_release_port(eth_dev);
+	return diag;
+}
+
+static int
+rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_eth_dev *eth_dev;
+
+	eth_dev = dpaa2_dev->eth_dev;
+	dpaa2_dev_uninit(eth_dev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+	rte_eth_dev_release_port(eth_dev);
+
+	return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_pmd = {
+	.drv_type = DPAA2_MC_DPNI_DEVID,
+	.driver = {
+		.name = "DPAA2 PMD",
+	},
+	.probe = rte_dpaa2_probe,
+	.remove = rte_dpaa2_remove,
+};
+
+
+RTE_PMD_REGISTER_DPAA2(net_dpaa2, rte_dpaa2_pmd);
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h
new file mode 100644
index 0000000..5778780
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -0,0 +1,44 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
+ *   Copyright (c) 2016 NXP. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Freescale Semiconductor, Inc nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DPAA2_ETHDEV_H
+#define _DPAA2_ETHDEV_H
+
+struct dpaa2_dev_priv {
+	void *hw;
+	int32_t hw_id;
+	uint16_t token;
+
+	uint8_t flags; /*dpaa2 config flags */
+};
+#endif /* _DPAA2_ETHDEV_H */
diff --git a/drivers/net/dpaa2/rte_pmd_dpaa2_version.map b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
new file mode 100644
index 0000000..31eca32
--- /dev/null
+++ b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
@@ -0,0 +1,4 @@ 
+DPDK_17.02 {
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a5daa84..c793dd2 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -110,6 +110,11 @@  _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET)  += -lrte_pmd_af_packet
 _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD)      += -lrte_pmd_bnx2x -lz
 _LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD)       += -lrte_pmd_bnxt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD)      += -lrte_pmd_cxgbe
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_COMMON),y)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_pmd_dpaa2
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_pmd_dpaa2_qbman
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_pmd_fslmcbus
+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