DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 02/32] drivers/common: introducing dpaa2 mc driver
From: Hemant Agrawal @ 2016-12-19 15:23 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: dev, thomas.monjalon, bruce.richardson, shreyansh.jain,
	Cristian Sovaiala
In-Reply-To: <20161217095535.GA25710@localhost.localdomain>

On 12/17/2016 3:25 PM, Jerin Jacob wrote:
> On Sun, Dec 04, 2016 at 11:46:57PM +0530, Hemant Agrawal wrote:
>> This patch intoduces the DPAA2 MC(Management complex Driver)
>>
>> This driver is common to be used by various DPAA2 net, crypto
>> and other drivers
>>
>> Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
>> [Hemant:rebase and conversion to library for DPDK]
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>>
>>  include $(RTE_SDK)/mk/rte.vars.mk
>>
>> +DIRS-y += common
>>  DIRS-y += net
>>  DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
>>
>> diff --git a/drivers/common/Makefile b/drivers/common/Makefile
>> new file mode 100644
>> index 0000000..0c3f35f
>> --- /dev/null
>> +++ b/drivers/common/Makefile
>> @@ -0,0 +1,36 @@
>> +#   BSD LICENSE
>> +#
>> +#   Copyright(c) 2016 NXP. All rights reserved.
>> +#   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 NXP 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
>> +
>> +DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
>
> If you are planning to build "external pool" driver or "eventdev" driver or net
> pmd driver as stand alone build then you could try generating the config for
> common code by selection of "external pool" or "eventdev" or net-pmd driver.
> something like below
>
> CONFIG_RTE_LIBRTE_OCTEONTX_COMMON = $(CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF)
> ifneq ($(CONFIG_RTE_LIBRTE_OCTEONTX_COMMON),y)
>     CONFIG_RTE_LIBRTE_OCTEONTX_COMMON =
>                         $(CONFIG_RTE_LIBRTE_MEMPOOL_OCTEONTX_FPAVF)
> endif
> ifneq ($(CONFIG_RTE_LIBRTE_OCTEONTX_COMMON),y)
>     CONFIG_RTE_LIBRTE_OCTEONTX_COMMON = $(CONFIG_RTE_LIBRTE_PMD_OCTEONTX)
> endif
>
> DIRS-$(CONFIG_RTE_LIBRTE_OCTEONTX_COMMON) += octeontx
>
>
>
Thanks for the suggestion. I have tried it in the V2.

I am still having issue when using shared compilation, currently I am 
not able to specify another driver in the DEPDIR

^ permalink raw reply

* [PATCHv2 34/34] drivers/common/dpaa2: frame queue based dq storage alloc
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

This patch adds generic functions for allowing dq storage
for the frame queues.
As the frame queues are common resource for different drivers
this is helpful.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c | 32 +++++++++++++++++++++++++++++++
 drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h | 10 +++++++++-
 drivers/net/dpaa2/dpaa2_ethdev.c          |  8 ++++----
 3 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c b/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c
index d7de0d5..55b5ad7 100644
--- a/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c
@@ -407,3 +407,35 @@ static inline struct dpaa2_dpio_dev *dpaa2_get_qbman_swp(void)
 
 	return 0;
 }
+
+void
+dpaa2_free_dq_storage(struct queue_storage_info_t *q_storage)
+{
+	int i = 0;
+
+	for (i = 0; i < NUM_DQS_PER_QUEUE; i++) {
+		if (q_storage->dq_storage[i])
+			rte_free(q_storage->dq_storage[i]);
+	}
+}
+
+int
+dpaa2_alloc_dq_storage(struct queue_storage_info_t *q_storage)
+{
+	int i = 0;
+
+	for (i = 0; i < NUM_DQS_PER_QUEUE; i++) {
+		q_storage->dq_storage[i] = rte_malloc(NULL,
+			DPAA2_DQRR_RING_SIZE * sizeof(struct qbman_result),
+			RTE_CACHE_LINE_SIZE);
+		if (!q_storage->dq_storage[i])
+			goto fail;
+	}
+	return 0;
+fail:
+	i -= 1;
+	while (i >= 0)
+		rte_free(q_storage->dq_storage[i]);
+
+	return -1;
+}
diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h b/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h
index b160c0f..4d871c1 100644
--- a/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h
@@ -64,4 +64,12 @@ int dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
 			     struct vfio_device_info *obj_info,
 			     int object_id);
 
-#endif /* _FSLMC_DPIO_H_ */
+/* allocate memory for FQ - dq storage */
+int
+dpaa2_alloc_dq_storage(struct queue_storage_info_t *q_storage);
+
+/* free memory for FQ- dq storage */
+void
+dpaa2_free_dq_storage(struct queue_storage_info_t *q_storage);
+
+#endif /* _DPAA2_HW_DPIO_H_ */
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 3a90e7c..43ae4cb 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -49,6 +49,7 @@
 #include <fslmc_vfio.h>
 #include <dpaa2_hw_pvt.h>
 #include <dpaa2_hw_mempool.h>
+#include <dpaa2_hw_dpio.h>
 
 #include "dpaa2_ethdev.h"
 
@@ -170,9 +171,8 @@
 
 		memset(dpaa2_q->q_storage, 0,
 		       sizeof(struct queue_storage_info_t));
-		dpaa2_q->q_storage->dq_storage[0] = rte_malloc(NULL,
-			DPAA2_DQRR_RING_SIZE * sizeof(struct qbman_result),
-			RTE_CACHE_LINE_SIZE);
+		if (dpaa2_alloc_dq_storage(dpaa2_q->q_storage))
+			goto fail;
 	}
 
 	for (i = 0; i < priv->nb_tx_queues; i++) {
@@ -196,7 +196,7 @@
 	mc_q = priv->rx_vq[0];
 	while (i >= 0) {
 		dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
-		rte_free(dpaa2_q->q_storage->dq_storage[0]);
+		dpaa2_free_dq_storage(dpaa2_q->q_storage);
 		rte_free(dpaa2_q->q_storage);
 		priv->rx_vq[i--] = NULL;
 	}
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 33/34] bus/fslmc: add support for dmamap to ARM SMMU
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/bus/fslmc/fslmc_vfio.c   | 97 ++++++++++++++++++++++++++++++++++++++++
 drivers/bus/fslmc/fslmc_vfio.h   |  1 +
 drivers/net/dpaa2/dpaa2_ethdev.c |  2 +
 3 files changed, 100 insertions(+)

diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 8d6a3eb..44cf3d1 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -77,8 +77,10 @@
 static struct fslmc_vfio_group vfio_groups[VFIO_MAX_GRP];
 static struct fslmc_vfio_container vfio_containers[VFIO_MAX_CONTAINERS];
 static int container_device_fd;
+static uint32_t *msi_intr_vaddr;
 void *(*mcp_ptr_list);
 static uint32_t mcp_id;
+static int is_dma_done;
 
 static int vfio_connect_container(struct fslmc_vfio_group *vfio_group)
 {
@@ -148,6 +150,35 @@ static int vfio_connect_container(struct fslmc_vfio_group *vfio_group)
 	return 0;
 }
 
+static int vfio_map_irq_region(struct fslmc_vfio_group *group)
+{
+	int ret;
+	unsigned long *vaddr = NULL;
+	struct vfio_iommu_type1_dma_map map = {
+		.argsz = sizeof(map),
+		.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
+		.vaddr = 0x6030000,
+		.iova = 0x6030000,
+		.size = 0x1000,
+	};
+
+	vaddr = (unsigned long *)mmap(NULL, 0x1000, PROT_WRITE |
+		PROT_READ, MAP_SHARED, container_device_fd, 0x6030000);
+	if (vaddr == MAP_FAILED) {
+		FSLMC_VFIO_LOG(ERR, "Unable to map region (errno = %d)", errno);
+		return -errno;
+	}
+
+	msi_intr_vaddr = (uint32_t *)((char *)(vaddr) + 64);
+	map.vaddr = (unsigned long)vaddr;
+	ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA, &map);
+	if (ret == 0)
+		return 0;
+
+	FSLMC_VFIO_LOG(ERR, "VFIO_IOMMU_MAP_DMA fails (errno = %d)", errno);
+	return -errno;
+}
+
 int vfio_dmamap_mem_region(uint64_t vaddr,
 			   uint64_t iova,
 			   uint64_t size)
@@ -170,6 +201,72 @@ int vfio_dmamap_mem_region(uint64_t vaddr,
 	}
 	return 0;
 }
+
+int fslmc_vfio_dmamap(void)
+{
+	int ret;
+	struct fslmc_vfio_group *group;
+	struct vfio_iommu_type1_dma_map dma_map = {
+		.argsz = sizeof(struct vfio_iommu_type1_dma_map),
+		.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
+	};
+
+	int i;
+	const struct rte_memseg *memseg;
+
+	if (is_dma_done)
+		return 0;
+	is_dma_done = 1;
+
+	for (i = 0; i < RTE_MAX_MEMSEG; i++) {
+		memseg = rte_eal_get_physmem_layout();
+		if (memseg == NULL) {
+			FSLMC_VFIO_LOG(ERR, "Cannot get physical layout.");
+			return -ENODEV;
+		}
+
+		if (memseg[i].addr == NULL && memseg[i].len == 0)
+			break;
+
+		dma_map.size = memseg[i].len;
+		dma_map.vaddr = memseg[i].addr_64;
+#ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
+		dma_map.iova = memseg[i].phys_addr;
+#else
+		dma_map.iova = dma_map.vaddr;
+#endif
+
+		/* SET DMA MAP for IOMMU */
+		group = &vfio_groups[0];
+
+		if (!group->container) {
+			FSLMC_VFIO_LOG(ERR, "Container is not connected ");
+			return -1;
+		}
+
+		FSLMC_VFIO_LOG(DEBUG, "-->Initial SHM Virtual ADDR %llX",
+			     dma_map.vaddr);
+		FSLMC_VFIO_LOG(DEBUG, "-----> DMA size 0x%llX\n", dma_map.size);
+		ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA,
+			    &dma_map);
+		if (ret) {
+			FSLMC_VFIO_LOG(ERR, "VFIO_IOMMU_MAP_DMA API"
+				       "(errno = %d)", errno);
+			return ret;
+		}
+		FSLMC_VFIO_LOG(DEBUG, "-----> dma_map.vaddr = 0x%llX",
+			     dma_map.vaddr);
+	}
+
+	/* TODO - This is a W.A. as VFIO currently does not add the mapping of
+	 * the interrupt region to SMMU. This should be removed once the
+	 * support is added in the Kernel.
+	 */
+	vfio_map_irq_region(group);
+
+	return 0;
+}
+
 static int64_t vfio_map_mcp_obj(struct fslmc_vfio_group *group, char *mcp_obj)
 {
 	int64_t v_addr = (int64_t)MAP_FAILED;
diff --git a/drivers/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h
index c5a42fe..83a7c68 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -70,5 +70,6 @@ int vfio_dmamap_mem_region(
 
 int fslmc_vfio_setup_group(void);
 int fslmc_vfio_process_group(struct rte_bus *bus);
+int fslmc_vfio_dmamap(void);
 
 #endif /* _FSLMC_VFIO_H_ */
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index d1456d5..3a90e7c 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -911,6 +911,8 @@ void dpaa2_dev_stats_reset(struct rte_eth_dev *dev)
 
 	eth_dev->rx_pkt_burst = dpaa2_dev_rx;
 	eth_dev->tx_pkt_burst = dpaa2_dev_tx;
+	fslmc_vfio_dmamap();
+
 	return 0;
 }
 
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 32/34] net/dpaa2: enabling the use of physical addresses
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

DPAA2 - ARM support both physical and virtual addressing.
This patch enables the compile time usages of physical
address instead of virtual address.

The current usages are also set to default as Physical
Address.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 config/common_base                        |  1 +
 config/defconfig_arm64-dpaa2-linuxapp-gcc |  1 +
 drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h  | 65 +++++++++++++++++++++++++++++++
 drivers/net/dpaa2/base/dpaa2_hw_dpni.c    |  4 +-
 drivers/net/dpaa2/dpaa2_rxtx.c            | 16 ++++----
 drivers/pool/dpaa2/dpaa2_hw_mempool.c     | 19 +++++++--
 6 files changed, 94 insertions(+), 12 deletions(-)

diff --git a/config/common_base b/config/common_base
index 493811f..35a580e 100644
--- a/config/common_base
+++ b/config/common_base
@@ -277,6 +277,7 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
 #
 CONFIG_RTE_LIBRTE_DPAA2_COMMON=n
 CONFIG_RTE_LIBRTE_DPAA2_POOL=n
+CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
 
 #
 # Compile NXP DPAA2 FSL-MC Bus
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index 7665912..18c9589 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -50,6 +50,7 @@ CONFIG_RTE_PKTMBUF_HEADROOM=256
 CONFIG_RTE_LIBRTE_DPAA2_COMMON=y
 CONFIG_RTE_LIBRTE_DPAA2_POOL=n
 CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
+CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
 
 #
 # Compile NXP DPAA2 FSL-MC Bus
diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
index 378d591..6e28d1a 100644
--- a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
@@ -166,4 +166,69 @@ struct qbman_fle {
  */
 #define DPAA2_EQ_RESP_ALWAYS		1
 
+#ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
+static void *dpaa2_mem_ptov(phys_addr_t paddr) __attribute__((unused));
+/* todo - this is costly, need to write a fast coversion routine */
+static void *dpaa2_mem_ptov(phys_addr_t paddr)
+{
+	const struct rte_memseg *memseg = rte_eal_get_physmem_layout();
+	int i;
+
+	for (i = 0; i < RTE_MAX_MEMSEG && memseg[i].addr_64 != 0; i++) {
+		if (paddr >= memseg[i].phys_addr &&
+		   (char *)paddr < (char *)memseg[i].phys_addr + memseg[i].len)
+			return (void *)(memseg[i].addr_64
+				+ (paddr - memseg[i].phys_addr));
+	}
+	return NULL;
+}
+
+static phys_addr_t dpaa2_mem_vtop(uint64_t vaddr) __attribute__((unused));
+static phys_addr_t dpaa2_mem_vtop(uint64_t vaddr)
+{
+	const struct rte_memseg *memseg = rte_eal_get_physmem_layout();
+	int i;
+
+	for (i = 0; i < RTE_MAX_MEMSEG && memseg[i].addr_64 != 0; i++) {
+		if (vaddr >= memseg[i].addr_64 &&
+		    vaddr < memseg[i].addr_64 + memseg[i].len)
+			return memseg[i].phys_addr
+				+ (vaddr - memseg[i].addr_64);
+	}
+	return (phys_addr_t)(NULL);
+}
+
+/**
+ * When we are using Physical addresses as IO Virtual Addresses,
+ * Need to call conversion routines dpaa2_mem_vtop & dpaa2_mem_ptov
+ * whereever required.
+ * These routines are called with help of below MACRO's
+ */
+
+#define DPAA2_MBUF_VADDR_TO_IOVA(mbuf) ((mbuf)->buf_physaddr)
+
+/**
+ * macro to convert Virtual address to IOVA
+ */
+#define DPAA2_VADDR_TO_IOVA(_vaddr) dpaa2_mem_vtop((uint64_t)(_vaddr))
+
+/**
+ * macro to convert IOVA to Virtual address
+ */
+#define DPAA2_IOVA_TO_VADDR(_iova) dpaa2_mem_ptov((phys_addr_t)(_iova))
+
+/**
+ * macro to convert modify the memory containing IOVA to Virtual address
+ */
+#define DPAA2_MODIFY_IOVA_TO_VADDR(_mem, _type) \
+	{_mem = (_type)(dpaa2_mem_ptov((phys_addr_t)(_mem))); }
+
+#else	/* RTE_LIBRTE_DPAA2_USE_PHYS_IOVA */
+
+#define DPAA2_MBUF_VADDR_TO_IOVA(mbuf) ((mbuf)->buf_addr)
+#define DPAA2_VADDR_TO_IOVA(_vaddr) (_vaddr)
+#define DPAA2_IOVA_TO_VADDR(_iova) (_iova)
+#define DPAA2_MODIFY_IOVA_TO_VADDR(_mem, _type)
+
+#endif /* RTE_LIBRTE_DPAA2_USE_PHYS_IOVA */
 #endif
diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpni.c b/drivers/net/dpaa2/base/dpaa2_hw_dpni.c
index 08f53b3..3dc60cc 100644
--- a/drivers/net/dpaa2/base/dpaa2_hw_dpni.c
+++ b/drivers/net/dpaa2/base/dpaa2_hw_dpni.c
@@ -76,7 +76,7 @@
 	memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
 
 	dpaa2_distset_to_dpkg_profile_cfg(req_dist_set, &kg_cfg);
-	tc_cfg.key_cfg_iova = (uint64_t)(p_params);
+	tc_cfg.key_cfg_iova = (uint64_t)(DPAA2_VADDR_TO_IOVA(p_params));
 	tc_cfg.dist_size = eth_dev->data->nb_rx_queues;
 	tc_cfg.dist_mode = DPNI_DIST_MODE_HASH;
 
@@ -119,7 +119,7 @@ int dpaa2_remove_flow_dist(
 	memset(p_params, 0, DIST_PARAM_IOVA_SIZE);
 	memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
 
-	tc_cfg.key_cfg_iova = (uint64_t)(p_params);
+	tc_cfg.key_cfg_iova = (uint64_t)(DPAA2_VADDR_TO_IOVA(p_params));
 	tc_cfg.dist_size = 0;
 	tc_cfg.dist_mode = DPNI_DIST_MODE_NONE;
 
diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
index 55068e5..4596337 100644
--- a/drivers/net/dpaa2/dpaa2_rxtx.c
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -136,7 +136,7 @@ static inline struct rte_mbuf *__attribute__((hot))
 eth_fd_to_mbuf(const struct qbman_fd *fd)
 {
 	struct rte_mbuf *mbuf = DPAA2_INLINE_MBUF_FROM_BUF(
-			DPAA2_GET_FD_ADDR(fd),
+		DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd)),
 			bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
 
 	/* need to repopulated some of the fields,
@@ -151,10 +151,11 @@ static inline struct rte_mbuf *__attribute__((hot))
 	/* Parse the packet */
 	/* parse results are after the private - sw annotation area */
 	mbuf->packet_type = dpaa2_dev_rx_parse(
-			(uint64_t)(DPAA2_GET_FD_ADDR(fd))
+			(uint64_t)DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd))
 			 + DPAA2_FD_PTA_SIZE);
 
-	dpaa2_dev_rx_offload((uint64_t)(DPAA2_GET_FD_ADDR(fd)) +
+	dpaa2_dev_rx_offload((uint64_t)DPAA2_IOVA_TO_VADDR(
+			     DPAA2_GET_FD_ADDR(fd)) +
 			     DPAA2_FD_PTA_SIZE, mbuf);
 
 	mbuf->next = NULL;
@@ -177,7 +178,7 @@ static void __attribute__ ((noinline)) __attribute__((hot))
 	/*Resetting the buffer pool id and offset field*/
 	fd->simple.bpid_offset = 0;
 
-	DPAA2_SET_FD_ADDR(fd, (mbuf->buf_addr));
+	DPAA2_SET_FD_ADDR(fd, DPAA2_MBUF_VADDR_TO_IOVA(mbuf));
 	DPAA2_SET_FD_LEN(fd, mbuf->data_len);
 	DPAA2_SET_FD_BPID(fd, bpid);
 	DPAA2_SET_FD_OFFSET(fd, mbuf->data_off);
@@ -218,7 +219,7 @@ static inline int __attribute__((hot))
 	/*Resetting the buffer pool id and offset field*/
 	fd->simple.bpid_offset = 0;
 
-	DPAA2_SET_FD_ADDR(fd, (m->buf_addr));
+	DPAA2_SET_FD_ADDR(fd, DPAA2_MBUF_VADDR_TO_IOVA(m));
 	DPAA2_SET_FD_LEN(fd, mbuf->data_len);
 	DPAA2_SET_FD_BPID(fd, bpid);
 	DPAA2_SET_FD_OFFSET(fd, mbuf->data_off);
@@ -270,7 +271,7 @@ static inline int __attribute__((hot))
 	qbman_pull_desc_set_fq(&pulldesc, fqid);
 	/* todo optimization - we can have dq_storage_phys available*/
 	qbman_pull_desc_set_storage(&pulldesc, dq_storage,
-			(dma_addr_t)(dq_storage), 1);
+			(dma_addr_t)(DPAA2_VADDR_TO_IOVA(dq_storage)), 1);
 
 	/*Issue a volatile dequeue command. */
 	while (1) {
@@ -311,7 +312,8 @@ static inline int __attribute__((hot))
 		}
 
 		fd = qbman_result_DQ_fd(dq_storage);
-		mbuf = (struct rte_mbuf *)(DPAA2_GET_FD_ADDR(fd)
+		mbuf = (struct rte_mbuf *)DPAA2_IOVA_TO_VADDR(
+			DPAA2_GET_FD_ADDR(fd)
 			 - bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
 		/* Prefeth mbuf */
 		rte_prefetch0(mbuf);
diff --git a/drivers/pool/dpaa2/dpaa2_hw_mempool.c b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
index f609af7..fbae6cb 100644
--- a/drivers/pool/dpaa2/dpaa2_hw_mempool.c
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
@@ -226,9 +226,14 @@ void dpaa2_mbuf_release(struct rte_mempool *pool __rte_unused,
 	n = count % DPAA2_MBUF_MAX_ACQ_REL;
 
 	/* convert mbuf to buffers  for the remainder*/
-	for (i = 0; i < n ; i++)
+	for (i = 0; i < n ; i++) {
+#ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
+		bufs[i] = (uint64_t)rte_mempool_virt2phy(pool, obj_table[i])
+				+ meta_data_size;
+#else
 		bufs[i] = (uint64_t)obj_table[i] + meta_data_size;
-
+#endif
+	}
 	/* feed them to bman*/
 	do {
 		ret = qbman_swp_release(swp, &releasedesc, bufs, n);
@@ -237,8 +242,15 @@ void dpaa2_mbuf_release(struct rte_mempool *pool __rte_unused,
 	/* if there are more buffers to free */
 	while (n < count) {
 		/* convert mbuf to buffers */
-		for (i = 0; i < DPAA2_MBUF_MAX_ACQ_REL; i++)
+		for (i = 0; i < DPAA2_MBUF_MAX_ACQ_REL; i++) {
+#ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
+			bufs[i] = (uint64_t)
+				rte_mempool_virt2phy(pool, obj_table[n + i])
+					+ meta_data_size;
+#else
 			bufs[i] = (uint64_t)obj_table[n + i] + meta_data_size;
+#endif
+		}
 
 		do {
 			ret = qbman_swp_release(swp, &releasedesc, bufs,
@@ -311,6 +323,7 @@ int hw_mbuf_alloc_bulk(struct rte_mempool *pool,
 			 * i.e. first buffer is valid,
 			 * remaining 6 buffers may be null
 			 */
+			DPAA2_MODIFY_IOVA_TO_VADDR(bufs[i], uint64_t);
 			obj_table[n] = (struct rte_mbuf *)(bufs[i] - mbuf_size);
 			rte_mbuf_refcnt_set((struct rte_mbuf *)obj_table[n], 0);
 			PMD_TX_LOG(DEBUG, "Acquired %p address %p from BMAN",
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 31/34] net/dpaa2: add support for non hw buffer pool packet transmit
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/net/dpaa2/dpaa2_rxtx.c | 74 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 72 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
index 7d73bde..55068e5 100644
--- a/drivers/net/dpaa2/dpaa2_rxtx.c
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -191,6 +191,54 @@ static void __attribute__ ((noinline)) __attribute__((hot))
 		DPAA2_GET_FD_BPID(fd), DPAA2_GET_FD_LEN(fd));
 }
 
+
+static inline int __attribute__((hot))
+eth_copy_mbuf_to_fd(struct rte_mbuf *mbuf,
+		    struct qbman_fd *fd, uint16_t bpid)
+{
+	struct rte_mbuf *m;
+	void *mb = NULL;
+
+	if (hw_mbuf_alloc_bulk(bpid_info[bpid].bp_list->buf_pool.mp, &mb, 1)) {
+		PMD_TX_LOG(WARNING, "Unable to allocated DPAA2 buffer");
+		rte_pktmbuf_free(mbuf);
+		return -1;
+	}
+	m = (struct rte_mbuf *)mb;
+	memcpy((char *)m->buf_addr + mbuf->data_off,
+	       (void *)((char *)mbuf->buf_addr + mbuf->data_off),
+		mbuf->pkt_len);
+
+	/* Copy required fields */
+	m->data_off = mbuf->data_off;
+	m->ol_flags = mbuf->ol_flags;
+	m->packet_type = mbuf->packet_type;
+	m->tx_offload = mbuf->tx_offload;
+
+	/*Resetting the buffer pool id and offset field*/
+	fd->simple.bpid_offset = 0;
+
+	DPAA2_SET_FD_ADDR(fd, (m->buf_addr));
+	DPAA2_SET_FD_LEN(fd, mbuf->data_len);
+	DPAA2_SET_FD_BPID(fd, bpid);
+	DPAA2_SET_FD_OFFSET(fd, mbuf->data_off);
+	DPAA2_SET_FD_ASAL(fd, DPAA2_ASAL_VAL);
+
+	PMD_TX_LOG(DEBUG, " mbuf %p BMAN buf addr %p",
+		   (void *)mbuf, mbuf->buf_addr);
+
+	PMD_TX_LOG(DEBUG, " fdaddr =%lx bpid =%d meta =%d off =%d, len =%d",
+		   DPAA2_GET_FD_ADDR(fd),
+		DPAA2_GET_FD_BPID(fd),
+		bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size,
+		DPAA2_GET_FD_OFFSET(fd),
+		DPAA2_GET_FD_LEN(fd));
+	/*free the original packet */
+	rte_pktmbuf_free(mbuf);
+
+	return 0;
+}
+
 uint16_t
 dpaa2_dev_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 {
@@ -331,8 +379,29 @@ static void __attribute__ ((noinline)) __attribute__((hot))
 			DPAA2_RESET_FD_CTRL((&fd_arr[loop]));
 			DPAA2_SET_FD_FLC((&fd_arr[loop]), NULL);
 			mp = (*bufs)->pool;
-			bpid = mempool_to_bpid(mp);
-			eth_mbuf_to_fd(*bufs, &fd_arr[loop], bpid);
+			/* Not a hw_pkt pool allocated frame */
+			if (mp && !(mp->flags & MEMPOOL_F_HW_PKT_POOL)) {
+				PMD_TX_LOG(ERR, "non hw offload bufffer ");
+				/* alloc should be from the default buffer pool
+				 * attached to this interface
+				 */
+				if (priv->bp_list) {
+					bpid = priv->bp_list->buf_pool.bpid;
+				} else {
+					PMD_TX_LOG(ERR, "errr: why no bpool"
+						   " attached");
+					num_tx = 0;
+					goto skip_tx;
+				}
+				if (eth_copy_mbuf_to_fd(*bufs,
+							&fd_arr[loop], bpid)) {
+					bufs++;
+					continue;
+				}
+			} else {
+				bpid = mempool_to_bpid(mp);
+				eth_mbuf_to_fd(*bufs, &fd_arr[loop], bpid);
+			}
 			bufs++;
 		}
 		loop = 0;
@@ -345,5 +414,6 @@ static void __attribute__ ((noinline)) __attribute__((hot))
 		dpaa2_q->tx_pkts += frames_to_send;
 		nb_pkts -= frames_to_send;
 	}
+skip_tx:
 	return num_tx;
 }
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 30/34] net/dpaa2: enable stashing for LS2088A devices
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

As the hardware determines which core will process which packet,
performance is boosted by direct cache warming/stashing as well
as by providing biasing for core-to-flow affinity, which ensures
that flow-specific data structures can remain in the core’s cache.

This patch enables the one cache line data stashing for packet
annotation data and packet context

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/net/dpaa2/dpaa2_ethdev.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index d0cdc80..d1456d5 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -278,6 +278,17 @@
 	options = options | DPNI_QUEUE_OPT_USER_CTX;
 	cfg.user_context = (uint64_t)(dpaa2_q);
 
+	/*if ls2088 or rev2 device, enable the stashing */
+	if ((qbman_get_version() & 0xFFFF0000) > QMAN_REV_4000) {
+		options |= DPNI_QUEUE_OPT_FLC;
+		cfg.flc.stash_control = true;
+		cfg.flc.value &= 0xFFFFFFFFFFFFFFC0;
+		/* 00 00 00 - last 6 bit represent annotation, context stashing,
+		 * data stashing setting 01 01 00 (0x14) to enable
+		 * 1 line annotation, 1 line context
+		 */
+		cfg.flc.value |= 0x14;
+	}
 	ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_RX,
 			     dpaa2_q->tc_index, flow_id, options, &cfg);
 	if (ret) {
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 28/34] net/dpaa2: link status update
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/nics/features/dpaa2.ini |   1 +
 drivers/net/dpaa2/dpaa2_ethdev.c   | 107 +++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)

diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
index 0746d4b..0660cab 100644
--- a/doc/guides/nics/features/dpaa2.ini
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -4,6 +4,7 @@
 ; Refer to default.ini for the full list of available PMD features.
 ;
 [Features]
+Link status          = Y
 Queue start/stop     = Y
 MTU update           = Y
 Promiscuous mode     = Y
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index c705014..0d53003 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -55,6 +55,58 @@
 /* Name of the DPAA2 Net PMD */
 static const char *drivername = "DPAA2 PMD";
 
+/**
+ * Atomically reads the link status information from global
+ * structure rte_eth_dev.
+ *
+ * @param dev
+ *   - Pointer to the structure rte_eth_dev to read from.
+ *   - Pointer to the buffer to be saved with the link status.
+ *
+ * @return
+ *   - On success, zero.
+ *   - On failure, negative value.
+ */
+static inline int
+dpaa2_dev_atomic_read_link_status(struct rte_eth_dev *dev,
+				  struct rte_eth_link *link)
+{
+	struct rte_eth_link *dst = link;
+	struct rte_eth_link *src = &dev->data->dev_link;
+
+	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
+				*(uint64_t *)src) == 0)
+		return -1;
+
+	return 0;
+}
+
+/**
+ * Atomically writes the link status information into global
+ * structure rte_eth_dev.
+ *
+ * @param dev
+ *   - Pointer to the structure rte_eth_dev to read from.
+ *   - Pointer to the buffer to be saved with the link status.
+ *
+ * @return
+ *   - On success, zero.
+ *   - On failure, negative value.
+ */
+static inline int
+dpaa2_dev_atomic_write_link_status(struct rte_eth_dev *dev,
+				   struct rte_eth_link *link)
+{
+	struct rte_eth_link *dst = &dev->data->dev_link;
+	struct rte_eth_link *src = link;
+
+	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
+				*(uint64_t *)src) == 0)
+		return -1;
+
+	return 0;
+}
+
 static void
 dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
@@ -431,6 +483,7 @@
 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
 	int ret;
+	struct rte_eth_link link;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -440,6 +493,10 @@
 			     ret, priv->hw_id);
 		return;
 	}
+
+	/* clear the recorded link status */
+	memset(&link, 0, sizeof(link));
+	dpaa2_dev_atomic_write_link_status(dev, &link);
 }
 
 static void
@@ -532,6 +589,55 @@
 	return 0;
 }
 
+/* return 0 means link status changed, -1 means not changed */
+static int
+dpaa2_dev_link_update(struct rte_eth_dev *dev,
+			int wait_to_complete __rte_unused)
+{
+	int ret;
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+	struct rte_eth_link link, old;
+	struct dpni_link_state state = {0};
+
+	PMD_INIT_FUNC_TRACE();
+
+	if (dpni == NULL) {
+		RTE_LOG(ERR, PMD, "error : dpni is NULL");
+		return 0;
+	}
+	memset(&old, 0, sizeof(old));
+	dpaa2_dev_atomic_read_link_status(dev, &old);
+
+	ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state);
+	if (ret < 0) {
+		RTE_LOG(ERR, PMD, "error: dpni_get_link_state %d", ret);
+		return -1;
+	}
+
+	if ((old.link_status == state.up) && (old.link_speed == state.rate)) {
+		RTE_LOG(DEBUG, PMD, "No change in status\n");
+		return -1;
+	}
+
+	memset(&link, 0, sizeof(struct rte_eth_link));
+	link.link_status = state.up;
+	link.link_speed = state.rate;
+
+	if (state.options & DPNI_LINK_OPT_HALF_DUPLEX)
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+	else
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
+
+	dpaa2_dev_atomic_write_link_status(dev, &link);
+
+	if (link.link_status)
+		PMD_DRV_LOG(INFO, "Port %d Link is Up\n", dev->data->port_id);
+	else
+		PMD_DRV_LOG(INFO, "Port %d Link is Down\n", dev->data->port_id);
+	return 0;
+}
+
 static struct eth_dev_ops dpaa2_ethdev_ops = {
 	.dev_configure	  = dpaa2_eth_dev_configure,
 	.dev_start	      = dpaa2_dev_start,
@@ -539,6 +645,7 @@
 	.dev_close	      = dpaa2_dev_close,
 	.promiscuous_enable   = dpaa2_dev_promiscuous_enable,
 	.promiscuous_disable  = dpaa2_dev_promiscuous_disable,
+	.link_update	   = dpaa2_dev_link_update,
 	.dev_infos_get	   = dpaa2_dev_info_get,
 	.dev_supported_ptypes_get = dpaa2_supported_ptypes_get,
 	.mtu_set           = dpaa2_dev_mtu_set,
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 29/34] net/dpaa2: basic stats support
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/nics/features/dpaa2.ini |  1 +
 drivers/net/dpaa2/dpaa2_ethdev.c   | 86 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)

diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
index 0660cab..d43f404 100644
--- a/doc/guides/nics/features/dpaa2.ini
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -12,6 +12,7 @@ RSS hash             = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
 Packet type parsing  = Y
+Basic stats          = Y
 Linux VFIO           = Y
 ARMv8                = Y
 Usage doc            = Y
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 0d53003..d0cdc80 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -589,6 +589,90 @@
 	return 0;
 }
 
+static
+void dpaa2_dev_stats_get(struct rte_eth_dev *dev,
+			 struct rte_eth_stats *stats)
+{
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+	int32_t  retcode;
+	uint8_t page0 = 0, page1 = 1, page2 = 2;
+	union dpni_statistics value;
+
+	memset(&value, 0, sizeof(union dpni_statistics));
+
+	PMD_INIT_FUNC_TRACE();
+
+	if (!dpni) {
+		RTE_LOG(ERR, PMD, "dpni is NULL");
+		return;
+	}
+
+	if (!stats) {
+		RTE_LOG(ERR, PMD, "stats is NULL");
+		return;
+	}
+
+	/*Get Counters from page_0*/
+	retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
+				      page0, &value);
+	if (retcode)
+		goto err;
+
+	stats->ipackets = value.page_0.ingress_all_frames;
+	stats->ibytes = value.page_0.ingress_all_bytes;
+
+	/*Get Counters from page_1*/
+	retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
+				      page1, &value);
+	if (retcode)
+		goto err;
+
+	stats->opackets = value.page_1.egress_all_frames;
+	stats->obytes = value.page_1.egress_all_bytes;
+
+	/*Get Counters from page_2*/
+	retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
+				      page2, &value);
+	if (retcode)
+		goto err;
+
+	stats->ierrors = value.page_2.ingress_discarded_frames;
+	stats->oerrors = value.page_2.egress_discarded_frames;
+	stats->imissed = value.page_2.ingress_nobuffer_discards;
+
+	return;
+
+err:
+	RTE_LOG(ERR, PMD, "Operation not completed:Error Code = %d\n", retcode);
+	return;
+};
+
+static
+void dpaa2_dev_stats_reset(struct rte_eth_dev *dev)
+{
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+	int32_t  retcode;
+
+	PMD_INIT_FUNC_TRACE();
+
+	if (dpni == NULL) {
+		RTE_LOG(ERR, PMD, "dpni is NULL");
+		return;
+	}
+
+	retcode =  dpni_reset_statistics(dpni, CMD_PRI_LOW, priv->token);
+	if (retcode)
+		goto error;
+
+	return;
+
+error:
+	RTE_LOG(ERR, PMD, "Operation not completed:Error Code = %d\n", retcode);
+	return;
+};
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 dpaa2_dev_link_update(struct rte_eth_dev *dev,
@@ -646,6 +730,8 @@
 	.promiscuous_enable   = dpaa2_dev_promiscuous_enable,
 	.promiscuous_disable  = dpaa2_dev_promiscuous_disable,
 	.link_update	   = dpaa2_dev_link_update,
+	.stats_get	       = dpaa2_dev_stats_get,
+	.stats_reset	   = dpaa2_dev_stats_reset,
 	.dev_infos_get	   = dpaa2_dev_info_get,
 	.dev_supported_ptypes_get = dpaa2_supported_ptypes_get,
 	.mtu_set           = dpaa2_dev_mtu_set,
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 27/34] net/dpaa2: rx packet parsing and packet type support
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/nics/features/dpaa2.ini           |   1 +
 drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h | 257 +++++++++++++++++++++++++++
 drivers/net/dpaa2/dpaa2_ethdev.c             |  23 +++
 drivers/net/dpaa2/dpaa2_rxtx.c               |  91 +++++++++-
 4 files changed, 371 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h

diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
index a6b7964..0746d4b 100644
--- a/doc/guides/nics/features/dpaa2.ini
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -10,6 +10,7 @@ Promiscuous mode     = Y
 RSS hash             = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
+Packet type parsing  = Y
 Linux VFIO           = Y
 ARMv8                = Y
 Usage doc            = Y
diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h b/drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h
new file mode 100644
index 0000000..9324c6a
--- /dev/null
+++ b/drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h
@@ -0,0 +1,257 @@
+/*-
+ *   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.
+ */
+
+/**
+ * @file
+ *
+ * DPNI packet parse results - implementation internal
+ */
+
+#ifndef _DPAA2_HW_DPNI_ANNOT_H_
+#define _DPAA2_HW_DPNI_ANNOT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Annotation valid bits in FD FRC */
+#define DPAA2_FD_FRC_FASV	0x8000
+#define DPAA2_FD_FRC_FAEADV	0x4000
+#define DPAA2_FD_FRC_FAPRV	0x2000
+#define DPAA2_FD_FRC_FAIADV	0x1000
+#define DPAA2_FD_FRC_FASWOV	0x0800
+#define DPAA2_FD_FRC_FAICFDV	0x0400
+
+/* Annotation bits in FD CTRL */
+#define DPAA2_FD_CTRL_ASAL	0x00020000      /* ASAL = 128 */
+#define DPAA2_FD_CTRL_PTA	0x00800000
+#define DPAA2_FD_CTRL_PTV1	0x00400000
+
+/* Frame annotation status */
+struct dpaa2_fas {
+	uint8_t reserved;
+	uint8_t ppid;
+	__le16 ifpid;
+	__le32 status;
+} __packed;
+
+/**
+ * HW Packet Annotation  Register structures
+ */
+struct dpaa2_annot_hdr {
+	/**<	word1: Frame Annotation Status (8 bytes)*/
+	uint64_t word1;
+
+	/**<	word2: Time Stamp (8 bytes)*/
+	uint64_t word2;
+
+	/**<	word3: Next Hdr + FAF Extension + FAF (2 + 2 + 4 bytes)*/
+	uint64_t word3;
+
+	/**<	word4: Frame Annotation Flags-FAF (8 bytes) */
+	uint64_t word4;
+
+	/**<	word5:
+	 *	ShimOffset_1 + ShimOffset_2 + IPPIDOffset + EthOffset +
+	 *	LLC+SNAPOffset + VLANTCIOffset_1 + VLANTCIOffset_n +
+	 *	LastETypeOffset (1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 bytes)
+	 */
+	uint64_t word5;
+
+	/**<	word6:
+	 *	PPPoEOffset + MPLSOffset_1 + MPLSOffset_n + ARPorIPOffset_1
+	 *	+ IPOffset_norMInEncapO + GREOffset + L4Offset +
+	 *	GTPorESPorIPSecOffset(1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 bytes)
+	 */
+	uint64_t word6;
+
+	/**<	word7:
+	 *	RoutingHdrOfset1 + RoutingHdrOfset2 + NxtHdrOffset
+	 *	+ IPv6FragOffset + GrossRunningSum
+	 *	+ RunningSum(1 + 1 + 1 + 1 + 2 + 2 bytes)
+	 */
+	uint64_t word7;
+
+	/**<	word8:
+	 *	ParseErrorcode + Soft Parsing Context (1 + 7 bytes)
+	 */
+	uint64_t word8;
+};
+
+/**
+ * Internal Macros to get/set Packet annotation header
+ */
+
+/** General Macro to define a particular bit position*/
+#define BIT_POS(x)			((uint64_t)1 << ((x)))
+/** Set a bit in the variable */
+#define BIT_SET_AT_POS(var, pos)	((var) |= (pos))
+/** Reset the bit in the variable */
+#define BIT_RESET_AT_POS(var, pos)	((var) &= ~(pos))
+/** Check the bit is set in the variable */
+#define BIT_ISSET_AT_POS(var, pos)	(((var) & (pos)) ? 1 : 0)
+/**
+ * Macrso to define bit position in word3
+ */
+#define NEXT_HDR(var)			((uint64_t)(var) & 0xFFFF000000000000)
+#define FAF_EXTN_IPV6_ROUTE_HDR_PRESENT(var)	BIT_POS(16)
+#define FAF_EXTN_RESERVED(var)		((uint64_t)(var) & 0x00007FFF00000000)
+#define FAF_USER_DEFINED_RESERVED(var)	((uint64_t)(var) & 0x00000000FF000000)
+#define SHIM_SHELL_SOFT_PARSING_ERRROR		BIT_POS(23)
+#define PARSING_ERROR				BIT_POS(22)
+#define L2_ETH_MAC_PRESENT			BIT_POS(21)
+#define L2_ETH_MAC_UNICAST			BIT_POS(20)
+#define L2_ETH_MAC_MULTICAST			BIT_POS(19)
+#define L2_ETH_MAC_BROADCAST			BIT_POS(18)
+#define L2_ETH_FRAME_IS_BPDU			BIT_POS(17)
+#define L2_ETH_FCOE_PRESENT			BIT_POS(16)
+#define L2_ETH_FIP_PRESENT			BIT_POS(15)
+#define L2_ETH_PARSING_ERROR			BIT_POS(14)
+#define L2_LLC_SNAP_PRESENT			BIT_POS(13)
+#define L2_UNKNOWN_LLC_OUI			BIT_POS(12)
+#define L2_LLC_SNAP_ERROR			BIT_POS(11)
+#define L2_VLAN_1_PRESENT			BIT_POS(10)
+#define L2_VLAN_N_PRESENT			BIT_POS(9)
+#define L2_VLAN_CFI_BIT_PRESENT			BIT_POS(8)
+#define L2_VLAN_PARSING_ERROR			BIT_POS(7)
+#define L2_PPPOE_PPP_PRESENT			BIT_POS(6)
+#define L2_PPPOE_PPP_PARSING_ERROR		BIT_POS(5)
+#define L2_MPLS_1_PRESENT			BIT_POS(4)
+#define L2_MPLS_N_PRESENT			BIT_POS(3)
+#define L2_MPLS_PARSING_ERROR			BIT_POS(2)
+#define L2_ARP_PRESENT				BIT_POS(1)
+#define L2_ARP_PARSING_ERROR			BIT_POS(0)
+/**
+ * Macrso to define bit position in word4
+ */
+#define L2_UNKNOWN_PROTOCOL			BIT_POS(63)
+#define L2_SOFT_PARSING_ERROR			BIT_POS(62)
+#define L3_IPV4_1_PRESENT			BIT_POS(61)
+#define L3_IPV4_1_UNICAST			BIT_POS(60)
+#define L3_IPV4_1_MULTICAST			BIT_POS(59)
+#define L3_IPV4_1_BROADCAST			BIT_POS(58)
+#define L3_IPV4_N_PRESENT			BIT_POS(57)
+#define L3_IPV4_N_UNICAST			BIT_POS(56)
+#define L3_IPV4_N_MULTICAST			BIT_POS(55)
+#define L3_IPV4_N_BROADCAST			BIT_POS(54)
+#define L3_IPV6_1_PRESENT			BIT_POS(53)
+#define L3_IPV6_1_UNICAST			BIT_POS(52)
+#define L3_IPV6_1_MULTICAST			BIT_POS(51)
+#define L3_IPV6_N_PRESENT			BIT_POS(50)
+#define L3_IPV6_N_UNICAST			BIT_POS(49)
+#define L3_IPV6_N_MULTICAST			BIT_POS(48)
+#define L3_IP_1_OPT_PRESENT			BIT_POS(47)
+#define L3_IP_1_UNKNOWN_PROTOCOL		BIT_POS(46)
+#define L3_IP_1_MORE_FRAGMENT			BIT_POS(45)
+#define L3_IP_1_FIRST_FRAGMENT			BIT_POS(44)
+#define L3_IP_1_PARSING_ERROR			BIT_POS(43)
+#define L3_IP_N_OPT_PRESENT			BIT_POS(42)
+#define L3_IP_N_UNKNOWN_PROTOCOL		BIT_POS(41)
+#define L3_IP_N_MORE_FRAGMENT			BIT_POS(40)
+#define L3_IP_N_FIRST_FRAGMENT			BIT_POS(39)
+#define L3_PROTO_ICMP_PRESENT			BIT_POS(38)
+#define L3_PROTO_IGMP_PRESENT			BIT_POS(37)
+#define L3_PROTO_ICMPV6_PRESENT			BIT_POS(36)
+#define L3_PROTO_UDP_LIGHT_PRESENT		BIT_POS(35)
+#define L3_IP_N_PARSING_ERROR			BIT_POS(34)
+#define L3_MIN_ENCAP_PRESENT			BIT_POS(33)
+#define L3_MIN_ENCAP_SBIT_PRESENT		BIT_POS(32)
+#define L3_MIN_ENCAP_PARSING_ERROR		BIT_POS(31)
+#define L3_PROTO_GRE_PRESENT			BIT_POS(30)
+#define L3_PROTO_GRE_RBIT_PRESENT		BIT_POS(29)
+#define L3_PROTO_GRE_PARSING_ERROR		BIT_POS(28)
+#define L3_IP_UNKNOWN_PROTOCOL			BIT_POS(27)
+#define L3_SOFT_PARSING_ERROR			BIT_POS(26)
+#define L3_PROTO_UDP_PRESENT			BIT_POS(25)
+#define L3_PROTO_UDP_PARSING_ERROR		BIT_POS(24)
+#define L3_PROTO_TCP_PRESENT			BIT_POS(23)
+#define L3_PROTO_TCP_OPT_PRESENT		BIT_POS(22)
+#define L3_PROTO_TCP_CTRL_BIT_6_TO_11_PRESENT	BIT_POS(21)
+#define L3_PROTO_TCP_CTRL_BIT_3_TO_5_PRESENT	BIT_POS(20)
+#define L3_PROTO_TCP_PARSING_ERROR		BIT_POS(19)
+#define L3_PROTO_IPSEC_PRESENT			BIT_POS(18)
+#define L3_PROTO_IPSEC_ESP_PRESENT		BIT_POS(17)
+#define L3_PROTO_IPSEC_AH_PRESENT		BIT_POS(16)
+#define L3_PROTO_IPSEC_PARSING_ERROR		BIT_POS(15)
+#define L3_PROTO_SCTP_PRESENT			BIT_POS(14)
+#define L3_PROTO_SCTP_PARSING_ERROR		BIT_POS(13)
+#define L3_PROTO_DCCP_PRESENT			BIT_POS(12)
+#define L3_PROTO_DCCP_PARSING_ERROR		BIT_POS(11)
+#define L4_UNKNOWN_PROTOCOL			BIT_POS(10)
+#define L4_SOFT_PARSING_ERROR			BIT_POS(9)
+#define L3_PROTO_GTP_PRESENT			BIT_POS(8)
+#define L3_PROTO_GTP_PARSING_ERROR		BIT_POS(7)
+#define L3_PROTO_ESP_PRESENT			BIT_POS(6)
+#define L3_PROTO_ESP_PARSING_ERROR		BIT_POS(5)
+#define L3_PROTO_ISCSI_PRESENT			BIT_POS(4)
+#define L3_PROTO_CAPWAN__CTRL_PRESENT		BIT_POS(3)
+#define L3_PROTO_CAPWAN__DATA_PRESENT		BIT_POS(2)
+#define L5_SOFT_PARSING_ERROR			BIT_POS(1)
+#define L3_IPV6_ROUTE_HDR_PRESENT		BIT_POS(0)
+
+/* Debug frame, otherwise supposed to be discarded */
+#define DPAA2_ETH_FAS_DISC	      0x80000000
+/* MACSEC frame */
+#define DPAA2_ETH_FAS_MS		0x40000000
+#define DPAA2_ETH_FAS_PTP	       0x08000000
+/* Ethernet multicast frame */
+#define DPAA2_ETH_FAS_MC		0x04000000
+/* Ethernet broadcast frame */
+#define DPAA2_ETH_FAS_BC		0x02000000
+#define DPAA2_ETH_FAS_KSE	       0x00040000
+#define DPAA2_ETH_FAS_EOFHE	     0x00020000
+#define DPAA2_ETH_FAS_MNLE	      0x00010000
+#define DPAA2_ETH_FAS_TIDE	      0x00008000
+#define DPAA2_ETH_FAS_PIEE	      0x00004000
+/* Frame length error */
+#define DPAA2_ETH_FAS_FLE	       0x00002000
+/* Frame physical error; our favourite pastime */
+#define DPAA2_ETH_FAS_FPE	       0x00001000
+#define DPAA2_ETH_FAS_PTE	       0x00000080
+#define DPAA2_ETH_FAS_ISP	       0x00000040
+#define DPAA2_ETH_FAS_PHE	       0x00000020
+#define DPAA2_ETH_FAS_BLE	       0x00000010
+/* L3 csum validation performed */
+#define DPAA2_ETH_FAS_L3CV	      0x00000008
+/* L3 csum error */
+#define DPAA2_ETH_FAS_L3CE	      0x00000004
+/* L4 csum validation performed */
+#define DPAA2_ETH_FAS_L4CV	      0x00000002
+/* L4 csum error */
+#define DPAA2_ETH_FAS_L4CE	      0x00000001
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 3c4ca28..c705014 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -311,6 +311,28 @@
 	PMD_INIT_FUNC_TRACE();
 }
 
+static const uint32_t *
+dpaa2_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/*todo -= add more types */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_ICMP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == dpaa2_dev_rx)
+		return ptypes;
+	return NULL;
+}
+
 static int
 dpaa2_dev_start(struct rte_eth_dev *dev)
 {
@@ -518,6 +540,7 @@
 	.promiscuous_enable   = dpaa2_dev_promiscuous_enable,
 	.promiscuous_disable  = dpaa2_dev_promiscuous_disable,
 	.dev_infos_get	   = dpaa2_dev_info_get,
+	.dev_supported_ptypes_get = dpaa2_supported_ptypes_get,
 	.mtu_set           = dpaa2_dev_mtu_set,
 	.rx_queue_setup    = dpaa2_dev_rx_queue_setup,
 	.rx_queue_release  = dpaa2_dev_rx_queue_release,
diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
index 4b76be5..7d73bde 100644
--- a/drivers/net/dpaa2/dpaa2_rxtx.c
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -49,6 +49,88 @@
 #include <dpaa2_hw_mempool.h>
 
 #include "dpaa2_ethdev.h"
+#include "base/dpaa2_hw_dpni_annot.h"
+
+static inline uint32_t __attribute__((hot))
+dpaa2_dev_rx_parse(uint64_t hw_annot_addr)
+{
+	uint32_t pkt_type = RTE_PTYPE_UNKNOWN;
+	struct dpaa2_annot_hdr *annotation =
+			(struct dpaa2_annot_hdr *)hw_annot_addr;
+
+	PMD_RX_LOG(DEBUG, "annotation = 0x%lx   ", annotation->word4);
+
+	if (BIT_ISSET_AT_POS(annotation->word3, L2_ARP_PRESENT)) {
+		pkt_type = RTE_PTYPE_L2_ETHER_ARP;
+		goto parse_done;
+	} else if (BIT_ISSET_AT_POS(annotation->word3, L2_ETH_MAC_PRESENT)) {
+		pkt_type = RTE_PTYPE_L2_ETHER;
+	} else {
+		goto parse_done;
+	}
+
+	if (BIT_ISSET_AT_POS(annotation->word4, L3_IPV4_1_PRESENT |
+			     L3_IPV4_N_PRESENT)) {
+		pkt_type |= RTE_PTYPE_L3_IPV4;
+		if (BIT_ISSET_AT_POS(annotation->word4, L3_IP_1_OPT_PRESENT |
+			L3_IP_N_OPT_PRESENT))
+			pkt_type |= RTE_PTYPE_L3_IPV4_EXT;
+
+	} else if (BIT_ISSET_AT_POS(annotation->word4, L3_IPV6_1_PRESENT |
+		  L3_IPV6_N_PRESENT)) {
+		pkt_type |= RTE_PTYPE_L3_IPV6;
+		if (BIT_ISSET_AT_POS(annotation->word4, L3_IP_1_OPT_PRESENT |
+		    L3_IP_N_OPT_PRESENT))
+			pkt_type |= RTE_PTYPE_L3_IPV6_EXT;
+	} else {
+		goto parse_done;
+	}
+
+	if (BIT_ISSET_AT_POS(annotation->word4, L3_IP_1_FIRST_FRAGMENT |
+	    L3_IP_1_MORE_FRAGMENT |
+	    L3_IP_N_FIRST_FRAGMENT |
+	    L3_IP_N_MORE_FRAGMENT)) {
+		pkt_type |= RTE_PTYPE_L4_FRAG;
+		goto parse_done;
+	} else {
+		pkt_type |= RTE_PTYPE_L4_NONFRAG;
+	}
+
+	if (BIT_ISSET_AT_POS(annotation->word4, L3_PROTO_UDP_PRESENT))
+		pkt_type |= RTE_PTYPE_L4_UDP;
+
+	else if (BIT_ISSET_AT_POS(annotation->word4, L3_PROTO_TCP_PRESENT))
+		pkt_type |= RTE_PTYPE_L4_TCP;
+
+	else if (BIT_ISSET_AT_POS(annotation->word4, L3_PROTO_SCTP_PRESENT))
+		pkt_type |= RTE_PTYPE_L4_SCTP;
+
+	else if (BIT_ISSET_AT_POS(annotation->word4, L3_PROTO_ICMP_PRESENT))
+		pkt_type |= RTE_PTYPE_L4_ICMP;
+
+	else if (BIT_ISSET_AT_POS(annotation->word4, L3_IP_UNKNOWN_PROTOCOL))
+		pkt_type |= RTE_PTYPE_UNKNOWN;
+
+parse_done:
+	return pkt_type;
+}
+
+static inline void __attribute__((hot))
+dpaa2_dev_rx_offload(uint64_t hw_annot_addr, struct rte_mbuf *mbuf)
+{
+	struct dpaa2_annot_hdr *annotation =
+		(struct dpaa2_annot_hdr *)hw_annot_addr;
+
+	if (BIT_ISSET_AT_POS(annotation->word3,
+			     L2_VLAN_1_PRESENT | L2_VLAN_N_PRESENT))
+		mbuf->ol_flags |= PKT_RX_VLAN_PKT;
+
+	if (BIT_ISSET_AT_POS(annotation->word8, DPAA2_ETH_FAS_L3CE))
+		mbuf->ol_flags |= PKT_RX_IP_CKSUM_BAD;
+
+	if (BIT_ISSET_AT_POS(annotation->word8, DPAA2_ETH_FAS_L4CE))
+		mbuf->ol_flags |= PKT_RX_L4_CKSUM_BAD;
+}
 
 static inline struct rte_mbuf *__attribute__((hot))
 eth_fd_to_mbuf(const struct qbman_fd *fd)
@@ -66,7 +148,14 @@ static inline struct rte_mbuf *__attribute__((hot))
 	mbuf->data_len = DPAA2_GET_FD_LEN(fd);
 	mbuf->pkt_len = mbuf->data_len;
 
-	mbuf->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4;
+	/* Parse the packet */
+	/* parse results are after the private - sw annotation area */
+	mbuf->packet_type = dpaa2_dev_rx_parse(
+			(uint64_t)(DPAA2_GET_FD_ADDR(fd))
+			 + DPAA2_FD_PTA_SIZE);
+
+	dpaa2_dev_rx_offload((uint64_t)(DPAA2_GET_FD_ADDR(fd)) +
+			     DPAA2_FD_PTA_SIZE, mbuf);
 
 	mbuf->next = NULL;
 	rte_mbuf_refcnt_set(mbuf, 1);
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 26/34] net/dpaa2: add packet rx and tx support
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h |  54 +++++++
 drivers/net/dpaa2/Makefile               |   1 +
 drivers/net/dpaa2/dpaa2_ethdev.c         |   4 +
 drivers/net/dpaa2/dpaa2_ethdev.h         |   3 +
 drivers/net/dpaa2/dpaa2_rxtx.c           | 260 +++++++++++++++++++++++++++++++
 5 files changed, 322 insertions(+)
 create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c

diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
index 2dc0fd5..378d591 100644
--- a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
@@ -43,10 +43,16 @@
 #ifndef true
 #define true       1
 #endif
+#define lower_32_bits(x) ((uint32_t)(x))
+#define upper_32_bits(x) ((uint32_t)(((x) >> 16) >> 16))
 
 #ifndef ETH_VLAN_HLEN
 #define ETH_VLAN_HLEN   4 /** < Vlan Header Length */
 #endif
+
+#define MAX_TX_RING_SLOTS	8
+	/** <Maximum number of slots available in TX ring*/
+
 #define DPAA2_DQRR_RING_SIZE	16
 	/** <Maximum number of slots available in RX ring*/
 
@@ -112,4 +118,52 @@ struct dpaa2_queue {
 
 /*! Global MCP list */
 extern void *(*mcp_ptr_list);
+
+/* Refer to Table 7-3 in SEC BG */
+struct qbman_fle {
+	uint32_t addr_lo;
+	uint32_t addr_hi;
+	uint32_t length;
+	/* FMT must be 00, MSB is final bit  */
+	uint32_t fin_bpid_offset;
+	uint32_t frc;
+	uint32_t reserved[3]; /* Not used currently */
+};
+
+/*Macros to define operations on FD*/
+#define DPAA2_SET_FD_ADDR(fd, addr) do {			\
+	fd->simple.addr_lo = lower_32_bits((uint64_t)(addr));	\
+	fd->simple.addr_hi = upper_32_bits((uint64_t)(addr));	\
+} while (0)
+#define DPAA2_SET_FD_LEN(fd, length)	(fd)->simple.len = length
+#define DPAA2_SET_FD_BPID(fd, bpid)	((fd)->simple.bpid_offset |= bpid)
+#define DPAA2_SET_FD_OFFSET(fd, offset)	\
+	((fd->simple.bpid_offset |= (uint32_t)(offset) << 16))
+#define DPAA2_RESET_FD_CTRL(fd)	(fd)->simple.ctrl = 0
+
+#define	DPAA2_SET_FD_ASAL(fd, asal)	((fd)->simple.ctrl |= (asal << 16))
+#define DPAA2_SET_FD_FLC(fd, addr)	do { \
+	fd->simple.flc_lo = lower_32_bits((uint64_t)(addr));	\
+	fd->simple.flc_hi = upper_32_bits((uint64_t)(addr));	\
+} while (0)
+#define DPAA2_GET_FD_ADDR(fd)	\
+((uint64_t)((((uint64_t)((fd)->simple.addr_hi)) << 32) + (fd)->simple.addr_lo))
+
+#define DPAA2_GET_FD_LEN(fd)	((fd)->simple.len)
+#define DPAA2_GET_FD_BPID(fd)	(((fd)->simple.bpid_offset & 0x00003FFF))
+#define DPAA2_GET_FD_OFFSET(fd)	(((fd)->simple.bpid_offset & 0x0FFF0000) >> 16)
+#define DPAA2_INLINE_MBUF_FROM_BUF(buf, meta_data_size) \
+	((struct rte_mbuf *)((uint64_t)(buf) - (meta_data_size)))
+
+#define DPAA2_ASAL_VAL (DPAA2_MBUF_HW_ANNOTATION / 64)
+
+/* Only Enqueue Error responses will be
+ * pushed on FQID_ERR of Enqueue FQ
+ */
+#define DPAA2_EQ_RESP_ERR_FQ		0
+/* All Enqueue responses will be pushed on address
+ * set with qbman_eq_desc_set_response
+ */
+#define DPAA2_EQ_RESP_ALWAYS		1
+
 #endif
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 0e8095a..0d299d9 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -59,6 +59,7 @@ EXPORT_MAP := rte_pmd_dpaa2_version.map
 LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += base/dpaa2_hw_dpni.c
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_rxtx.c
 SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
 
 # library dependencies
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 3264bbe..3c4ca28 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -682,6 +682,8 @@
 	eth_dev->dev_ops = &dpaa2_ethdev_ops;
 	eth_dev->data->drv_name = drivername;
 
+	eth_dev->rx_pkt_burst = dpaa2_dev_rx;
+	eth_dev->tx_pkt_burst = dpaa2_dev_tx;
 	return 0;
 }
 
@@ -735,6 +737,8 @@
 	free(dpni);
 
 	eth_dev->dev_ops = NULL;
+	eth_dev->rx_pkt_burst = NULL;
+	eth_dev->tx_pkt_burst = NULL;
 
 	return 0;
 }
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h
index a56b525..7196398 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -77,4 +77,7 @@ int dpaa2_remove_flow_dist(struct rte_eth_dev *eth_dev,
 
 int dpaa2_attach_bp_list(struct dpaa2_dev_priv *priv, void *blist);
 
+uint16_t dpaa2_dev_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts);
+uint16_t dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts);
+
 #endif /* _DPAA2_ETHDEV_H */
diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
new file mode 100644
index 0000000..4b76be5
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -0,0 +1,260 @@
+/*-
+ *   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 <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_dev.h>
+#include <rte_ethdev.h>
+
+#include <fslmc_logs.h>
+#include <fslmc_vfio.h>
+#include <dpaa2_hw_pvt.h>
+#include <dpaa2_hw_dpio.h>
+#include <dpaa2_hw_mempool.h>
+
+#include "dpaa2_ethdev.h"
+
+static inline struct rte_mbuf *__attribute__((hot))
+eth_fd_to_mbuf(const struct qbman_fd *fd)
+{
+	struct rte_mbuf *mbuf = DPAA2_INLINE_MBUF_FROM_BUF(
+			DPAA2_GET_FD_ADDR(fd),
+			bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
+
+	/* need to repopulated some of the fields,
+	 * as they may have changed in last transmission
+	 */
+	mbuf->nb_segs = 1;
+	mbuf->ol_flags = 0;
+	mbuf->data_off = DPAA2_GET_FD_OFFSET(fd);
+	mbuf->data_len = DPAA2_GET_FD_LEN(fd);
+	mbuf->pkt_len = mbuf->data_len;
+
+	mbuf->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4;
+
+	mbuf->next = NULL;
+	rte_mbuf_refcnt_set(mbuf, 1);
+
+	PMD_RX_LOG(DEBUG, "to mbuf - mbuf =%p, mbuf->buf_addr =%p, off = %d,"
+		"fd_off=%d fd =%lx, meta = %d  bpid =%d, len=%d\n",
+		mbuf, mbuf->buf_addr, mbuf->data_off,
+		DPAA2_GET_FD_OFFSET(fd), DPAA2_GET_FD_ADDR(fd),
+		bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size,
+		DPAA2_GET_FD_BPID(fd), DPAA2_GET_FD_LEN(fd));
+
+	return mbuf;
+}
+
+static void __attribute__ ((noinline)) __attribute__((hot))
+eth_mbuf_to_fd(struct rte_mbuf *mbuf,
+	       struct qbman_fd *fd, uint16_t bpid)
+{
+	/*Resetting the buffer pool id and offset field*/
+	fd->simple.bpid_offset = 0;
+
+	DPAA2_SET_FD_ADDR(fd, (mbuf->buf_addr));
+	DPAA2_SET_FD_LEN(fd, mbuf->data_len);
+	DPAA2_SET_FD_BPID(fd, bpid);
+	DPAA2_SET_FD_OFFSET(fd, mbuf->data_off);
+	DPAA2_SET_FD_ASAL(fd, DPAA2_ASAL_VAL);
+
+	PMD_TX_LOG(DEBUG, "mbuf =%p, mbuf->buf_addr =%p, off = %d,"
+		"fd_off=%d fd =%lx, meta = %d  bpid =%d, len=%d\n",
+		mbuf, mbuf->buf_addr, mbuf->data_off,
+		DPAA2_GET_FD_OFFSET(fd), DPAA2_GET_FD_ADDR(fd),
+		bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size,
+		DPAA2_GET_FD_BPID(fd), DPAA2_GET_FD_LEN(fd));
+}
+
+uint16_t
+dpaa2_dev_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
+{
+	/* Function is responsible to receive frames for a given device and VQ*/
+	struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *)queue;
+	struct qbman_result *dq_storage;
+	uint32_t fqid = dpaa2_q->fqid;
+	int ret, num_rx = 0;
+	uint8_t is_last = 0, status;
+	struct qbman_swp *swp;
+	const struct qbman_fd *fd;
+	struct qbman_pull_desc pulldesc;
+	struct rte_eth_dev *dev = dpaa2_q->dev;
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			RTE_LOG(ERR, PMD, "Failure in affining portal\n");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+	dq_storage = dpaa2_q->q_storage->dq_storage[0];
+
+	qbman_pull_desc_clear(&pulldesc);
+	qbman_pull_desc_set_numframes(&pulldesc,
+				      (nb_pkts > DPAA2_DQRR_RING_SIZE) ?
+				       DPAA2_DQRR_RING_SIZE : nb_pkts);
+	qbman_pull_desc_set_fq(&pulldesc, fqid);
+	/* todo optimization - we can have dq_storage_phys available*/
+	qbman_pull_desc_set_storage(&pulldesc, dq_storage,
+			(dma_addr_t)(dq_storage), 1);
+
+	/*Issue a volatile dequeue command. */
+	while (1) {
+		if (qbman_swp_pull(swp, &pulldesc)) {
+			PMD_RX_LOG(ERR, "VDQ command is not issued."
+				   "QBMAN is busy\n");
+			/* Portal was busy, try again */
+			continue;
+		}
+		break;
+	};
+
+	/* Receive the packets till Last Dequeue entry is found with
+	 * respect to the above issues PULL command.
+	 */
+	while (!is_last) {
+		struct rte_mbuf *mbuf;
+		/*Check if the previous issued command is completed.
+		 * Also seems like the SWP is shared between the
+		 * Ethernet Driver and the SEC driver.
+		 */
+		while (!qbman_check_command_complete(swp, dq_storage))
+			;
+		/* Loop until the dq_storage is updated with
+		 * new token by QBMAN
+		 */
+		while (!qbman_result_has_new_result(swp, dq_storage))
+			;
+		/* Check whether Last Pull command is Expired and
+		 * setting Condition for Loop termination
+		 */
+		if (qbman_result_DQ_is_pull_complete(dq_storage)) {
+			is_last = 1;
+			/* Check for valid frame. */
+			status = (uint8_t)qbman_result_DQ_flags(dq_storage);
+			if (unlikely((status & QBMAN_DQ_STAT_VALIDFRAME) == 0))
+				continue;
+		}
+
+		fd = qbman_result_DQ_fd(dq_storage);
+		mbuf = (struct rte_mbuf *)(DPAA2_GET_FD_ADDR(fd)
+			 - bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
+		/* Prefeth mbuf */
+		rte_prefetch0(mbuf);
+		/* Prefetch Annotation address for the parse results */
+		rte_prefetch0((void *)((uint64_t)DPAA2_GET_FD_ADDR(fd)
+						+ DPAA2_FD_PTA_SIZE + 16));
+
+		bufs[num_rx] = eth_fd_to_mbuf(fd);
+		bufs[num_rx]->port = dev->data->port_id;
+
+		num_rx++;
+		dq_storage++;
+	} /* End of Packet Rx loop */
+
+	dpaa2_q->rx_pkts += num_rx;
+
+	/*Return the total number of packets received to DPAA2 app*/
+	return num_rx;
+}
+
+/*
+ * Callback to handle sending packets through WRIOP based interface
+ */
+uint16_t
+dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
+{
+	/* Function to transmit the frames to given device and VQ*/
+	uint32_t loop;
+	int32_t ret;
+	struct qbman_fd fd_arr[MAX_TX_RING_SLOTS];
+	uint32_t frames_to_send;
+	struct rte_mempool *mp;
+	struct qbman_eq_desc eqdesc;
+	struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *)queue;
+	struct qbman_swp *swp;
+	uint16_t num_tx = 0;
+	uint16_t bpid;
+	struct rte_eth_dev *dev = dpaa2_q->dev;
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			RTE_LOG(ERR, PMD, "Failure in affining portal\n");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	PMD_TX_LOG(DEBUG, "===> dev =%p, fqid =%d", dev, dpaa2_q->fqid);
+
+	/*Prepare enqueue descriptor*/
+	qbman_eq_desc_clear(&eqdesc);
+	qbman_eq_desc_set_no_orp(&eqdesc, DPAA2_EQ_RESP_ERR_FQ);
+	qbman_eq_desc_set_response(&eqdesc, 0, 0);
+	qbman_eq_desc_set_qd(&eqdesc, priv->qdid,
+			     dpaa2_q->flow_id, dpaa2_q->tc_index);
+
+	/*Clear the unused FD fields before sending*/
+	while (nb_pkts) {
+		frames_to_send = (nb_pkts >> 3) ? MAX_TX_RING_SLOTS : nb_pkts;
+
+		for (loop = 0; loop < frames_to_send; loop++) {
+			fd_arr[loop].simple.frc = 0;
+			DPAA2_RESET_FD_CTRL((&fd_arr[loop]));
+			DPAA2_SET_FD_FLC((&fd_arr[loop]), NULL);
+			mp = (*bufs)->pool;
+			bpid = mempool_to_bpid(mp);
+			eth_mbuf_to_fd(*bufs, &fd_arr[loop], bpid);
+			bufs++;
+		}
+		loop = 0;
+		while (loop < frames_to_send) {
+			loop += qbman_swp_send_multiple(swp, &eqdesc,
+					&fd_arr[loop], frames_to_send - loop);
+		}
+
+		num_tx += frames_to_send;
+		dpaa2_q->tx_pkts += frames_to_send;
+		nb_pkts -= frames_to_send;
+	}
+	return num_tx;
+}
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 25/34] net/dpaa2: add mtu config support
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/nics/features/dpaa2.ini       |  1 +
 drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h |  4 ++++
 drivers/net/dpaa2/dpaa2_ethdev.c         | 34 ++++++++++++++++++++++++++++++++
 3 files changed, 39 insertions(+)

diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
index b7c274a..a6b7964 100644
--- a/doc/guides/nics/features/dpaa2.ini
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -5,6 +5,7 @@
 ;
 [Features]
 Queue start/stop     = Y
+MTU update           = Y
 Promiscuous mode     = Y
 RSS hash             = Y
 L3 checksum offload  = Y
diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
index c5afaed..2dc0fd5 100644
--- a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
@@ -43,6 +43,10 @@
 #ifndef true
 #define true       1
 #endif
+
+#ifndef ETH_VLAN_HLEN
+#define ETH_VLAN_HLEN   4 /** < Vlan Header Length */
+#endif
 #define DPAA2_DQRR_RING_SIZE	16
 	/** <Maximum number of slots available in RX ring*/
 
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 7a5c4c6..3264bbe 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -477,6 +477,39 @@
 	if (ret < 0)
 		RTE_LOG(ERR, PMD, "Unable to disable promiscuous mode %d", ret);
 }
+
+static int
+dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
+{
+	int ret;
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+	uint32_t frame_size = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
+
+	PMD_INIT_FUNC_TRACE();
+
+	if (dpni == NULL) {
+		RTE_LOG(ERR, PMD, "dpni is NULL");
+		return -EINVAL;
+	}
+
+	/* check that mtu is within the allowed range */
+	if ((mtu < ETHER_MIN_MTU) || (frame_size > DPAA2_MAX_RX_PKT_LEN))
+		return -EINVAL;
+
+	/* Set the Max Rx frame length as 'mtu' +
+	 * Maximum Ethernet header length
+	 */
+	ret = dpni_set_max_frame_length(dpni, CMD_PRI_LOW, priv->token,
+					mtu + ETH_VLAN_HLEN);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "setting the max frame length failed");
+		return -1;
+	}
+	PMD_DRV_LOG(INFO, "MTU is configured %d for the device\n", mtu);
+	return 0;
+}
+
 static struct eth_dev_ops dpaa2_ethdev_ops = {
 	.dev_configure	  = dpaa2_eth_dev_configure,
 	.dev_start	      = dpaa2_dev_start,
@@ -485,6 +518,7 @@
 	.promiscuous_enable   = dpaa2_dev_promiscuous_enable,
 	.promiscuous_disable  = dpaa2_dev_promiscuous_disable,
 	.dev_infos_get	   = dpaa2_dev_info_get,
+	.mtu_set           = dpaa2_dev_mtu_set,
 	.rx_queue_setup    = dpaa2_dev_rx_queue_setup,
 	.rx_queue_release  = dpaa2_dev_rx_queue_release,
 	.tx_queue_setup    = dpaa2_dev_tx_queue_setup,
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 24/34] net/dpaa2: add support for promiscuous mode
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/nics/features/dpaa2.ini |  1 +
 drivers/net/dpaa2/dpaa2_ethdev.c   | 41 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
index d50c62e..b7c274a 100644
--- a/doc/guides/nics/features/dpaa2.ini
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -5,6 +5,7 @@
 ;
 [Features]
 Queue start/stop     = Y
+Promiscuous mode     = Y
 RSS hash             = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 5d7add5..7a5c4c6 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -438,11 +438,52 @@
 	}
 }
 
+static void
+dpaa2_dev_promiscuous_enable(
+		struct rte_eth_dev *dev)
+{
+	int ret;
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+
+	PMD_INIT_FUNC_TRACE();
+
+	if (dpni == NULL) {
+		RTE_LOG(ERR, PMD, "dpni is NULL");
+		return;
+	}
+
+	ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, true);
+	if (ret < 0)
+		RTE_LOG(ERR, PMD, "Unable to enable promiscuous mode %d", ret);
+}
+
+static void
+dpaa2_dev_promiscuous_disable(
+		struct rte_eth_dev *dev)
+{
+	int ret;
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+
+	PMD_INIT_FUNC_TRACE();
+
+	if (dpni == NULL) {
+		RTE_LOG(ERR, PMD, "dpni is NULL");
+		return;
+	}
+
+	ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, false);
+	if (ret < 0)
+		RTE_LOG(ERR, PMD, "Unable to disable promiscuous mode %d", ret);
+}
 static struct eth_dev_ops dpaa2_ethdev_ops = {
 	.dev_configure	  = dpaa2_eth_dev_configure,
 	.dev_start	      = dpaa2_dev_start,
 	.dev_stop	      = dpaa2_dev_stop,
 	.dev_close	      = dpaa2_dev_close,
+	.promiscuous_enable   = dpaa2_dev_promiscuous_enable,
+	.promiscuous_disable  = dpaa2_dev_promiscuous_disable,
 	.dev_infos_get	   = dpaa2_dev_info_get,
 	.rx_queue_setup    = dpaa2_dev_rx_queue_setup,
 	.rx_queue_release  = dpaa2_dev_rx_queue_release,
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 23/34] net/dpaa2: add support for l3 and l4 checksum offload
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/nics/features/dpaa2.ini       |  2 +
 drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h |  6 +++
 drivers/net/dpaa2/dpaa2_ethdev.c         | 72 ++++++++++++++++++++++++++++++--
 3 files changed, 76 insertions(+), 4 deletions(-)

diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
index 20152a0..d50c62e 100644
--- a/doc/guides/nics/features/dpaa2.ini
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -6,6 +6,8 @@
 [Features]
 Queue start/stop     = Y
 RSS hash             = Y
+L3 checksum offload  = Y
+L4 checksum offload  = Y
 Linux VFIO           = Y
 ARMv8                = Y
 Usage doc            = Y
diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
index 2c1ab7f..c5afaed 100644
--- a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
@@ -37,6 +37,12 @@
 #include <mc/fsl_mc_sys.h>
 #include <fsl_qbman_portal.h>
 
+#ifndef false
+#define false      0
+#endif
+#ifndef true
+#define true       1
+#endif
 #define DPAA2_DQRR_RING_SIZE	16
 	/** <Maximum number of slots available in RX ring*/
 
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index ae04cc3..5d7add5 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -69,7 +69,17 @@
 	dev_info->min_rx_bufsize = DPAA2_MIN_RX_BUF_SIZE;
 	dev_info->max_rx_queues = (uint16_t)priv->nb_rx_queues;
 	dev_info->max_tx_queues = (uint16_t)priv->nb_tx_queues;
-
+	dev_info->rx_offload_capa =
+		DEV_RX_OFFLOAD_IPV4_CKSUM |
+		DEV_RX_OFFLOAD_UDP_CKSUM |
+		DEV_RX_OFFLOAD_TCP_CKSUM |
+		DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
+	dev_info->tx_offload_capa =
+		DEV_TX_OFFLOAD_IPV4_CKSUM |
+		DEV_TX_OFFLOAD_UDP_CKSUM |
+		DEV_TX_OFFLOAD_TCP_CKSUM |
+		DEV_TX_OFFLOAD_SCTP_CKSUM |
+		DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
 	dev_info->speed_capa = ETH_LINK_SPEED_1G |
 			ETH_LINK_SPEED_2_5G |
 			ETH_LINK_SPEED_10G;
@@ -253,8 +263,13 @@
 	memset(&tx_conf_cfg, 0, sizeof(struct dpni_queue));
 	memset(&tx_flow_cfg, 0, sizeof(struct dpni_queue));
 
-	tc_id = 0;
-	flow_id = tx_queue_id;
+	if (priv->num_tc == 1) {
+		tc_id = 0;
+		flow_id = tx_queue_id % priv->num_dist_per_tc[tc_id];
+	} else {
+		tc_id = tx_queue_id;
+		flow_id = 0;
+	}
 
 	ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX,
 			     tc_id, flow_id, options, &tx_flow_cfg);
@@ -303,6 +318,7 @@
 	struct dpaa2_dev_priv *priv = data->dev_private;
 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
 	struct dpni_queue cfg;
+	struct dpni_error_cfg	err_cfg;
 	uint16_t qdid;
 	struct dpni_queue_id qid;
 	struct dpaa2_queue *dpaa2_q;
@@ -338,6 +354,48 @@
 		dpaa2_q->fqid = qid.fqid;
 	}
 
+	ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
+			       DPNI_OFF_RX_L3_CSUM, true);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Error to set RX l3 csum:Error = %d\n", ret);
+		return ret;
+	}
+
+	ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
+			       DPNI_OFF_RX_L4_CSUM, true);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Error to get RX l4 csum:Error = %d\n", ret);
+		return ret;
+	}
+
+	ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
+			       DPNI_OFF_TX_L3_CSUM, true);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Error to set TX l3 csum:Error = %d\n", ret);
+		return ret;
+	}
+
+	ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
+			       DPNI_OFF_TX_L4_CSUM, true);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Error to get TX l4 csum:Error = %d\n", ret);
+		return ret;
+	}
+
+	/*checksum errors, send them to normal path and set it in annotation */
+	err_cfg.errors = DPNI_ERROR_L3CE | DPNI_ERROR_L4CE;
+
+	err_cfg.error_action = DPNI_ERROR_ACTION_CONTINUE;
+	err_cfg.set_frame_annotation = true;
+
+	ret = dpni_set_errors_behavior(dpni, CMD_PRI_LOW,
+				       priv->token, &err_cfg);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Error to dpni_set_errors_behavior:"
+			     "code = %d\n", ret);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -454,7 +512,13 @@
 	 */
 	priv->nb_rx_queues = priv->num_dist_per_tc[DPAA2_DEF_TC];
 
-	priv->nb_tx_queues = attr.num_queues;
+	if (attr.num_tcs == 1)
+		priv->nb_tx_queues = attr.num_queues;
+	else
+		priv->nb_tx_queues = attr.num_tcs;
+
+	PMD_INIT_LOG(DEBUG, "num_tc %d", priv->num_tc);
+	PMD_INIT_LOG(DEBUG, "nb_rx_queues %d", priv->nb_rx_queues);
 
 	eth_dev->data->nb_rx_queues = priv->nb_rx_queues;
 	eth_dev->data->nb_tx_queues = priv->nb_tx_queues;
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 22/34] net/dpaa2: attach the buffer pool to dpni
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

This patch configures a MC-DPNI based DPAA2 PMD network
port with a DPBP based buffer pool.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h | 10 ++++++
 drivers/net/dpaa2/Makefile               |  2 ++
 drivers/net/dpaa2/base/dpaa2_hw_dpni.c   | 57 +++++++++++++++++++++++++++++
 drivers/net/dpaa2/dpaa2_ethdev.c         | 62 ++++++++++++++++++++++++++++++++
 drivers/net/dpaa2/dpaa2_ethdev.h         |  6 ++++
 5 files changed, 137 insertions(+)

diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
index 08be96c..2c1ab7f 100644
--- a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
@@ -50,6 +50,16 @@
 #define DPAA2_MBUF_MAX_ACQ_REL	7
 
 #define MAX_BPID 256
+#define DPAA2_MBUF_HW_ANNOTATION	64
+#define DPAA2_FD_PTA_SIZE		64
+
+#if (DPAA2_MBUF_HW_ANNOTATION + DPAA2_FD_PTA_SIZE) > RTE_PKTMBUF_HEADROOM
+#error "Annotation requirement is more than RTE_PKTMBUF_HEADROOM"
+#endif
+
+/* we will re-use the HEADROOM for annotation in RX */
+#define DPAA2_HW_BUF_RESERVE	0
+#define DPAA2_PACKET_LAYOUT_ALIGN	64 /*changing from 256 */
 
 struct dpaa2_dpio_dev {
 	TAILQ_ENTRY(dpaa2_dpio_dev) next;
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index c331270..0e8095a 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -49,6 +49,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
 CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
 CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
 CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/dpio
+CFLAGS += -I$(RTE_SDK)/drivers/pool/dpaa2
 CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
 
 # versioning export map
@@ -62,5 +63,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
 
 # library dependencies
 DEPDIRS-y += lib/librte_eal
+DEPDIRS-y += lib/librte_mempool
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpni.c b/drivers/net/dpaa2/base/dpaa2_hw_dpni.c
index c95c083..08f53b3 100644
--- a/drivers/net/dpaa2/base/dpaa2_hw_dpni.c
+++ b/drivers/net/dpaa2/base/dpaa2_hw_dpni.c
@@ -46,6 +46,7 @@
 
 #include <fslmc_logs.h>
 #include <dpaa2_hw_pvt.h>
+#include <dpaa2_hw_mempool.h>
 
 #include "../dpaa2_ethdev.h"
 
@@ -285,3 +286,59 @@ int dpaa2_remove_flow_dist(
 	}
 	kg_cfg->num_extracts = i;
 }
+
+int
+dpaa2_attach_bp_list(struct dpaa2_dev_priv *priv,
+		     void *blist)
+{
+	/* Function to attach a DPNI with a buffer pool list. Buffer pool list
+	 * handle is passed in blist.
+	 */
+	int32_t retcode;
+	struct fsl_mc_io *dpni = priv->hw;
+	struct dpni_pools_cfg bpool_cfg;
+	struct dpaa2_bp_list *bp_list = (struct dpaa2_bp_list *)blist;
+	struct dpni_buffer_layout layout;
+	int tot_size;
+
+	/* ... rx buffer layout .
+	 * Check alignment for buffer layouts first
+	 */
+
+	/* ... rx buffer layout ... */
+	tot_size = DPAA2_HW_BUF_RESERVE + RTE_PKTMBUF_HEADROOM;
+	tot_size = RTE_ALIGN_CEIL(tot_size,
+				  DPAA2_PACKET_LAYOUT_ALIGN);
+
+	memset(&layout, 0, sizeof(struct dpni_buffer_layout));
+	layout.options = DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM;
+
+	layout.data_head_room =
+		tot_size - DPAA2_FD_PTA_SIZE - DPAA2_MBUF_HW_ANNOTATION;
+	retcode = dpni_set_buffer_layout(dpni, CMD_PRI_LOW, priv->token,
+					 DPNI_QUEUE_RX, &layout);
+	if (retcode) {
+		PMD_INIT_LOG(ERR, "Err(%d) in setting rx buffer layout\n",
+			     retcode);
+		return retcode;
+	}
+
+	/*Attach buffer pool to the network interface as described by the user*/
+	bpool_cfg.num_dpbp = 1;
+	bpool_cfg.pools[0].dpbp_id = bp_list->buf_pool.dpbp_node->dpbp_id;
+	bpool_cfg.pools[0].backup_pool = 0;
+	bpool_cfg.pools[0].buffer_size =
+		RTE_ALIGN_CEIL(bp_list->buf_pool.size,
+			       256 /*DPAA2_PACKET_LAYOUT_ALIGN*/);
+
+	retcode = dpni_set_pools(dpni, CMD_PRI_LOW, priv->token, &bpool_cfg);
+	if (retcode != 0) {
+		PMD_INIT_LOG(ERR, "Error in attaching the buffer pool list"
+				" bpid = %d Error code = %d\n",
+				bpool_cfg.pools[0].dpbp_id, retcode);
+		return retcode;
+	}
+
+	priv->bp_list = bp_list;
+	return 0;
+}
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index ccd2c2a..ae04cc3 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -48,6 +48,7 @@
 #include <fslmc_logs.h>
 #include <fslmc_vfio.h>
 #include <dpaa2_hw_pvt.h>
+#include <dpaa2_hw_mempool.h>
 
 #include "dpaa2_ethdev.h"
 
@@ -64,6 +65,8 @@
 	dev_info->if_index = priv->hw_id;
 
 	dev_info->max_mac_addrs = priv->max_mac_filters;
+	dev_info->max_rx_pktlen = DPAA2_MAX_RX_PKT_LEN;
+	dev_info->min_rx_bufsize = DPAA2_MIN_RX_BUF_SIZE;
 	dev_info->max_rx_queues = (uint16_t)priv->nb_rx_queues;
 	dev_info->max_tx_queues = (uint16_t)priv->nb_tx_queues;
 
@@ -188,6 +191,7 @@
 	struct dpni_queue cfg;
 	uint8_t options = 0;
 	uint8_t flow_id;
+	uint32_t bpid;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -195,6 +199,13 @@
 	PMD_INIT_LOG(DEBUG, "dev =%p, queue =%d, pool = %p, conf =%p",
 		     dev, rx_queue_id, mb_pool, rx_conf);
 
+	if (!priv->bp_list || priv->bp_list->mp != mb_pool) {
+		bpid = mempool_to_bpid(mb_pool);
+		ret = dpaa2_attach_bp_list(priv,
+					   bpid_info[bpid].bp_list);
+		if (ret)
+			return ret;
+	}
 	dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[rx_queue_id];
 	dpaa2_q->mb_pool = mb_pool; /**< mbuf pool to populate RX ring. */
 
@@ -389,7 +400,9 @@
 	struct fsl_mc_io *dpni_dev;
 	struct dpni_attr attr;
 	struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
+	struct dpni_buffer_layout layout;
 	int i, ret, hw_id;
+	int tot_size;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -478,6 +491,55 @@
 		return -ret;
 	}
 
+	/* ... rx buffer layout ... */
+	tot_size = DPAA2_HW_BUF_RESERVE + RTE_PKTMBUF_HEADROOM;
+	tot_size = RTE_ALIGN_CEIL(tot_size,
+				  DPAA2_PACKET_LAYOUT_ALIGN);
+
+	memset(&layout, 0, sizeof(struct dpni_buffer_layout));
+	layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
+				DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
+				DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM |
+				DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
+
+	layout.pass_frame_status = 1;
+	layout.data_head_room = tot_size
+		- DPAA2_FD_PTA_SIZE - DPAA2_MBUF_HW_ANNOTATION;
+	layout.private_data_size = DPAA2_FD_PTA_SIZE;
+	layout.pass_parser_result = 1;
+	PMD_INIT_LOG(DEBUG, "Tot_size = %d, head room = %d, private = %d",
+		     tot_size, layout.data_head_room, layout.private_data_size);
+	ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token,
+				     DPNI_QUEUE_RX, &layout);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Err(%d) in setting rx buffer layout", ret);
+		return -1;
+	}
+
+	/* ... tx buffer layout ... */
+	memset(&layout, 0, sizeof(struct dpni_buffer_layout));
+	layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS;
+	layout.pass_frame_status = 1;
+	ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token,
+				     DPNI_QUEUE_TX, &layout);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Error (%d) in setting tx buffer"
+				  " layout", ret);
+		return -1;
+	}
+
+	/* ... tx-conf and error buffer layout ... */
+	memset(&layout, 0, sizeof(struct dpni_buffer_layout));
+	layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS;
+	layout.pass_frame_status = 1;
+	ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token,
+				     DPNI_QUEUE_TX_CONFIRM, &layout);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Error (%d) in setting tx-conf buffer"
+				  " layout", ret);
+		return -1;
+	}
+
 	eth_dev->dev_ops = &dpaa2_ethdev_ops;
 	eth_dev->data->drv_name = drivername;
 
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h
index 2d13137..a56b525 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -37,6 +37,9 @@
 #include <mc/fsl_dpni.h>
 #include <mc/fsl_mc_sys.h>
 
+#define DPAA2_MIN_RX_BUF_SIZE 512
+#define DPAA2_MAX_RX_PKT_LEN  10240 /*WRIOP support*/
+
 #define MAX_TCS			DPNI_MAX_TC
 #define MAX_RX_QUEUES		16
 #define MAX_TX_QUEUES		16
@@ -57,6 +60,7 @@ struct dpaa2_dev_priv {
 	void *rx_vq[MAX_RX_QUEUES];
 	void *tx_vq[MAX_TX_QUEUES];
 
+	struct dpaa2_bp_list *bp_list; /**<Attached buffer pool list */
 	uint32_t options;
 	uint16_t num_dist_per_tc[MAX_TCS];
 	uint8_t max_mac_filters;
@@ -71,4 +75,6 @@ int dpaa2_setup_flow_dist(struct rte_eth_dev *eth_dev,
 int dpaa2_remove_flow_dist(struct rte_eth_dev *eth_dev,
 			   uint8_t tc_index);
 
+int dpaa2_attach_bp_list(struct dpaa2_dev_priv *priv, void *blist);
+
 #endif /* _DPAA2_ETHDEV_H */
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 21/34] net/dpaa2: configure mac address at init
From: Hemant Agrawal @ 2016-12-19 20:54 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/net/dpaa2/dpaa2_ethdev.c | 28 ++++++++++++++++++++++++++++
 drivers/net/dpaa2/dpaa2_ethdev.h |  3 +++
 2 files changed, 31 insertions(+)

diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 9066aa5..ccd2c2a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -63,6 +63,7 @@
 
 	dev_info->if_index = priv->hw_id;
 
+	dev_info->max_mac_addrs = priv->max_mac_filters;
 	dev_info->max_rx_queues = (uint16_t)priv->nb_rx_queues;
 	dev_info->max_tx_queues = (uint16_t)priv->nb_tx_queues;
 
@@ -447,6 +448,9 @@
 
 	priv->hw = dpni_dev;
 	priv->hw_id = hw_id;
+	priv->options = attr.options;
+	priv->max_mac_filters = attr.mac_filter_entries;
+	priv->max_vlan_filters = attr.vlan_filter_entries;
 	priv->flags = 0;
 
 	ret = dpaa2_alloc_rx_tx_queues(eth_dev);
@@ -455,6 +459,25 @@
 		return -ret;
 	}
 
+	/* Allocate memory for storing MAC addresses */
+	eth_dev->data->mac_addrs = rte_zmalloc("dpni",
+		ETHER_ADDR_LEN * attr.mac_filter_entries, 0);
+	if (eth_dev->data->mac_addrs == NULL) {
+		PMD_INIT_LOG(ERR, "Failed to allocate %d bytes needed to "
+						"store MAC addresses",
+				ETHER_ADDR_LEN * attr.mac_filter_entries);
+		return -ENOMEM;
+	}
+
+	ret = dpni_get_primary_mac_addr(dpni_dev, CMD_PRI_LOW,
+					priv->token,
+			(uint8_t *)(eth_dev->data->mac_addrs[0].addr_bytes));
+	if (ret) {
+		PMD_INIT_LOG(ERR, "DPNI get mac address failed:"
+					" Error Code = %d\n", ret);
+		return -ret;
+	}
+
 	eth_dev->dev_ops = &dpaa2_ethdev_ops;
 	eth_dev->data->drv_name = drivername;
 
@@ -493,6 +516,11 @@
 		priv->rx_vq[0] = NULL;
 	}
 
+	/* Allocate memory for storing MAC addresses */
+	if (eth_dev->data->mac_addrs) {
+		rte_free(eth_dev->data->mac_addrs);
+		eth_dev->data->mac_addrs = NULL;
+	}
 
 	/*Close the device at underlying layer*/
 	ret = dpni_close(dpni, CMD_PRI_LOW, priv->token);
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h
index d24fcc6..2d13137 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -57,7 +57,10 @@ struct dpaa2_dev_priv {
 	void *rx_vq[MAX_RX_QUEUES];
 	void *tx_vq[MAX_TX_QUEUES];
 
+	uint32_t options;
 	uint16_t num_dist_per_tc[MAX_TCS];
+	uint8_t max_mac_filters;
+	uint8_t max_vlan_filters;
 	uint8_t num_tc;
 	uint8_t flags; /*dpaa2 config flags */
 };
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 20/34] net/dpaa2: add rss flow distribution
From: Hemant Agrawal @ 2016-12-19 20:53 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/nics/features/dpaa2.ini     |   1 +
 drivers/net/dpaa2/Makefile             |   1 +
 drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 287 +++++++++++++++++++++++++++++++++
 drivers/net/dpaa2/dpaa2_ethdev.c       |  31 +++-
 drivers/net/dpaa2/dpaa2_ethdev.h       |  12 ++
 5 files changed, 328 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni.c

diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
index 0b59725..20152a0 100644
--- a/doc/guides/nics/features/dpaa2.ini
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -5,6 +5,7 @@
 ;
 [Features]
 Queue start/stop     = Y
+RSS hash             = Y
 Linux VFIO           = Y
 ARMv8                = Y
 Usage doc            = Y
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 4425b76..c331270 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -57,6 +57,7 @@ EXPORT_MAP := rte_pmd_dpaa2_version.map
 # library version
 LIBABIVER := 1
 
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += base/dpaa2_hw_dpni.c
 SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
 
 # library dependencies
diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpni.c b/drivers/net/dpaa2/base/dpaa2_hw_dpni.c
new file mode 100644
index 0000000..c95c083
--- /dev/null
+++ b/drivers/net/dpaa2/base/dpaa2_hw_dpni.c
@@ -0,0 +1,287 @@
+/*-
+ *   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 <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 <fslmc_logs.h>
+#include <dpaa2_hw_pvt.h>
+
+#include "../dpaa2_ethdev.h"
+
+static void
+dpaa2_distset_to_dpkg_profile_cfg(
+		uint32_t req_dist_set,
+		struct dpkg_profile_cfg *kg_cfg);
+
+int
+dpaa2_setup_flow_dist(struct rte_eth_dev *eth_dev,
+		      uint32_t req_dist_set)
+{
+	struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
+	struct fsl_mc_io *dpni = priv->hw;
+	struct dpni_rx_tc_dist_cfg tc_cfg;
+	struct dpkg_profile_cfg kg_cfg;
+	void *p_params;
+	int ret, tc_index = 0;
+
+	p_params = rte_malloc(
+		NULL, DIST_PARAM_IOVA_SIZE, RTE_CACHE_LINE_SIZE);
+	if (!p_params) {
+		RTE_LOG(ERR, PMD, "Memory unavaialble\n");
+		return -ENOMEM;
+	}
+	memset(p_params, 0, DIST_PARAM_IOVA_SIZE);
+	memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
+
+	dpaa2_distset_to_dpkg_profile_cfg(req_dist_set, &kg_cfg);
+	tc_cfg.key_cfg_iova = (uint64_t)(p_params);
+	tc_cfg.dist_size = eth_dev->data->nb_rx_queues;
+	tc_cfg.dist_mode = DPNI_DIST_MODE_HASH;
+
+	ret = dpni_prepare_key_cfg(&kg_cfg, p_params);
+	if (ret) {
+		RTE_LOG(ERR, PMD, "Unable to prepare extract parameters\n");
+		rte_free(p_params);
+		return ret;
+	}
+
+	ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW, priv->token, tc_index,
+				  &tc_cfg);
+	rte_free(p_params);
+	if (ret) {
+		RTE_LOG(ERR, PMD, "Setting distribution for Rx failed with"
+			" err code: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+int dpaa2_remove_flow_dist(
+	struct rte_eth_dev *eth_dev,
+	uint8_t tc_index)
+{
+	struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
+	struct fsl_mc_io *dpni = priv->hw;
+	struct dpni_rx_tc_dist_cfg tc_cfg;
+	struct dpkg_profile_cfg kg_cfg;
+	void *p_params;
+	int ret;
+
+	p_params = rte_malloc(
+		NULL, DIST_PARAM_IOVA_SIZE, RTE_CACHE_LINE_SIZE);
+	if (!p_params) {
+		RTE_LOG(ERR, PMD, "Memory unavaialble\n");
+		return -ENOMEM;
+	}
+	memset(p_params, 0, DIST_PARAM_IOVA_SIZE);
+	memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
+
+	tc_cfg.key_cfg_iova = (uint64_t)(p_params);
+	tc_cfg.dist_size = 0;
+	tc_cfg.dist_mode = DPNI_DIST_MODE_NONE;
+
+	ret = dpni_prepare_key_cfg(&kg_cfg, p_params);
+	if (ret) {
+		RTE_LOG(ERR, PMD, "Unable to prepare extract parameters\n");
+		rte_free(p_params);
+		return ret;
+	}
+
+	ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW, priv->token, tc_index,
+				  &tc_cfg);
+	rte_free(p_params);
+	if (ret) {
+		RTE_LOG(ERR, PMD, "Setting distribution for Rx failed with"
+			" err code: %d\n", ret);
+		return ret;
+	}
+	return ret;
+}
+
+static void
+dpaa2_distset_to_dpkg_profile_cfg(
+		uint32_t req_dist_set,
+		struct dpkg_profile_cfg *kg_cfg)
+{
+	uint32_t loop = 0, i = 0, dist_field = 0;
+	int l2_configured = 0, l3_configured = 0;
+	int l4_configured = 0, sctp_configured = 0;
+
+	memset(kg_cfg, 0, sizeof(struct dpkg_profile_cfg));
+	while (req_dist_set) {
+		if (req_dist_set % 2 != 0) {
+			dist_field = 1U << loop;
+			switch (dist_field) {
+			case ETH_RSS_L2_PAYLOAD:
+
+				if (l2_configured)
+					break;
+				l2_configured = 1;
+
+				kg_cfg->extracts[i].extract.from_hdr.prot =
+					NET_PROT_ETH;
+				kg_cfg->extracts[i].extract.from_hdr.field =
+					NH_FLD_ETH_TYPE;
+				kg_cfg->extracts[i].type =
+					DPKG_EXTRACT_FROM_HDR;
+				kg_cfg->extracts[i].extract.from_hdr.type =
+					DPKG_FULL_FIELD;
+				i++;
+			break;
+
+			case ETH_RSS_IPV4:
+			case ETH_RSS_FRAG_IPV4:
+			case ETH_RSS_NONFRAG_IPV4_OTHER:
+			case ETH_RSS_IPV6:
+			case ETH_RSS_FRAG_IPV6:
+			case ETH_RSS_NONFRAG_IPV6_OTHER:
+			case ETH_RSS_IPV6_EX:
+
+				if (l3_configured)
+					break;
+				l3_configured = 1;
+
+				kg_cfg->extracts[i].extract.from_hdr.prot =
+					NET_PROT_IP;
+				kg_cfg->extracts[i].extract.from_hdr.field =
+					NH_FLD_IP_SRC;
+				kg_cfg->extracts[i].type =
+					DPKG_EXTRACT_FROM_HDR;
+				kg_cfg->extracts[i].extract.from_hdr.type =
+					DPKG_FULL_FIELD;
+				i++;
+
+				kg_cfg->extracts[i].extract.from_hdr.prot =
+					NET_PROT_IP;
+				kg_cfg->extracts[i].extract.from_hdr.field =
+					NH_FLD_IP_DST;
+				kg_cfg->extracts[i].type =
+					DPKG_EXTRACT_FROM_HDR;
+				kg_cfg->extracts[i].extract.from_hdr.type =
+					DPKG_FULL_FIELD;
+				i++;
+
+				kg_cfg->extracts[i].extract.from_hdr.prot =
+					NET_PROT_IP;
+				kg_cfg->extracts[i].extract.from_hdr.field =
+					NH_FLD_IP_PROTO;
+				kg_cfg->extracts[i].type =
+					DPKG_EXTRACT_FROM_HDR;
+				kg_cfg->extracts[i].extract.from_hdr.type =
+					DPKG_FULL_FIELD;
+				kg_cfg->num_extracts++;
+				i++;
+			break;
+
+			case ETH_RSS_NONFRAG_IPV4_TCP:
+			case ETH_RSS_NONFRAG_IPV6_TCP:
+			case ETH_RSS_NONFRAG_IPV4_UDP:
+			case ETH_RSS_NONFRAG_IPV6_UDP:
+			case ETH_RSS_IPV6_TCP_EX:
+			case ETH_RSS_IPV6_UDP_EX:
+
+				if (l4_configured)
+					break;
+				l4_configured = 1;
+
+				kg_cfg->extracts[i].extract.from_hdr.prot =
+					NET_PROT_TCP;
+				kg_cfg->extracts[i].extract.from_hdr.field =
+					NH_FLD_TCP_PORT_SRC;
+				kg_cfg->extracts[i].type =
+					DPKG_EXTRACT_FROM_HDR;
+				kg_cfg->extracts[i].extract.from_hdr.type =
+					DPKG_FULL_FIELD;
+				i++;
+
+				kg_cfg->extracts[i].extract.from_hdr.prot =
+					NET_PROT_TCP;
+				kg_cfg->extracts[i].extract.from_hdr.field =
+					NH_FLD_TCP_PORT_SRC;
+				kg_cfg->extracts[i].type =
+					DPKG_EXTRACT_FROM_HDR;
+				kg_cfg->extracts[i].extract.from_hdr.type =
+					DPKG_FULL_FIELD;
+				i++;
+				break;
+
+			case ETH_RSS_NONFRAG_IPV4_SCTP:
+			case ETH_RSS_NONFRAG_IPV6_SCTP:
+
+				if (sctp_configured)
+					break;
+				sctp_configured = 1;
+
+				kg_cfg->extracts[i].extract.from_hdr.prot =
+					NET_PROT_SCTP;
+				kg_cfg->extracts[i].extract.from_hdr.field =
+					NH_FLD_SCTP_PORT_SRC;
+				kg_cfg->extracts[i].type =
+					DPKG_EXTRACT_FROM_HDR;
+				kg_cfg->extracts[i].extract.from_hdr.type =
+					DPKG_FULL_FIELD;
+				i++;
+
+				kg_cfg->extracts[i].extract.from_hdr.prot =
+					NET_PROT_SCTP;
+				kg_cfg->extracts[i].extract.from_hdr.field =
+					NH_FLD_SCTP_PORT_DST;
+				kg_cfg->extracts[i].type =
+					DPKG_EXTRACT_FROM_HDR;
+				kg_cfg->extracts[i].extract.from_hdr.type =
+					DPKG_FULL_FIELD;
+				i++;
+				break;
+
+			default:
+				PMD_DRV_LOG(WARNING, "Bad flow distribution"
+					    " option %x\n", dist_field);
+			}
+		}
+		req_dist_set = req_dist_set >> 1;
+		loop++;
+	}
+	kg_cfg->num_extracts = i;
+}
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index d511d7b..9066aa5 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -116,7 +116,8 @@
 	}
 
 	vq_id = 0;
-	for (dist_idx = 0; dist_idx < priv->nb_rx_queues; dist_idx++) {
+	for (dist_idx = 0; dist_idx < priv->num_dist_per_tc[DPAA2_DEF_TC];
+	     dist_idx++) {
 		mcq = (struct dpaa2_queue *)priv->rx_vq[vq_id];
 		mcq->tc_index = DPAA2_DEF_TC;
 		mcq->flow_id = dist_idx;
@@ -142,6 +143,7 @@
 {
 	struct rte_eth_dev_data *data = dev->data;
 	struct rte_eth_conf *eth_conf = &data->dev_conf;
+	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -153,6 +155,18 @@
 		return -1;
 	}
 
+	if (eth_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) {
+		/* Return in case number of Rx queues is 1 */
+		if (data->nb_rx_queues == 1)
+			return 0;
+		ret = dpaa2_setup_flow_dist(dev,
+				eth_conf->rx_adv_conf.rss_conf.rss_hf);
+		if (ret) {
+			PMD_INIT_LOG(ERR, "unable to set flow distribution."
+				     "please check queue config\n");
+			return ret;
+		}
+	}
 	return 0;
 }
 
@@ -184,7 +198,7 @@
 	dpaa2_q->mb_pool = mb_pool; /**< mbuf pool to populate RX ring. */
 
 	/*Get the tc id and flow id from given VQ id*/
-	flow_id = rx_queue_id;
+	flow_id = rx_queue_id % priv->num_dist_per_tc[dpaa2_q->tc_index];
 	memset(&cfg, 0, sizeof(struct dpni_queue));
 
 	options = options | DPNI_QUEUE_OPT_USER_CTX;
@@ -374,7 +388,7 @@
 	struct fsl_mc_io *dpni_dev;
 	struct dpni_attr attr;
 	struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
-	int ret, hw_id;
+	int i, ret, hw_id;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -416,7 +430,16 @@
 	}
 
 	priv->num_tc = attr.num_tcs;
-	priv->nb_rx_queues = attr.num_queues;
+	for (i = 0; i < attr.num_tcs; i++) {
+		priv->num_dist_per_tc[i] = attr.num_queues;
+		break;
+	}
+
+	/* Distribution is per Tc only,
+	 * so choosing RX queues from default TC only
+	 */
+	priv->nb_rx_queues = priv->num_dist_per_tc[DPAA2_DEF_TC];
+
 	priv->nb_tx_queues = attr.num_queues;
 
 	eth_dev->data->nb_rx_queues = priv->nb_rx_queues;
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h
index 5f599a7..d24fcc6 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -37,12 +37,16 @@
 #include <mc/fsl_dpni.h>
 #include <mc/fsl_mc_sys.h>
 
+#define MAX_TCS			DPNI_MAX_TC
 #define MAX_RX_QUEUES		16
 #define MAX_TX_QUEUES		16
 
 /*default tc to be used for ,congestion, distribution etc configuration. */
 #define DPAA2_DEF_TC		0
 
+/* Size of the input SMMU mapped memory required by MC */
+#define DIST_PARAM_IOVA_SIZE 256
+
 struct dpaa2_dev_priv {
 	void *hw;
 	int32_t hw_id;
@@ -53,7 +57,15 @@ struct dpaa2_dev_priv {
 	void *rx_vq[MAX_RX_QUEUES];
 	void *tx_vq[MAX_TX_QUEUES];
 
+	uint16_t num_dist_per_tc[MAX_TCS];
 	uint8_t num_tc;
 	uint8_t flags; /*dpaa2 config flags */
 };
+
+int dpaa2_setup_flow_dist(struct rte_eth_dev *eth_dev,
+			  uint32_t req_dist_set);
+
+int dpaa2_remove_flow_dist(struct rte_eth_dev *eth_dev,
+			   uint8_t tc_index);
+
 #endif /* _DPAA2_ETHDEV_H */
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 19/34] net/dpaa2: add queue configuration support
From: Hemant Agrawal @ 2016-12-19 20:53 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

DPAA2 provide supports for HW queues. Each DPNI contains
a pre-configured number of RX and TX queues.

This patch reads the DPNI attributes, create the dpaa2_queue
to be used for RX and TX.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/nics/features/dpaa2.ini       |   1 +
 drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h |  20 +++
 drivers/net/dpaa2/dpaa2_ethdev.c         | 293 ++++++++++++++++++++++++++++++-
 drivers/net/dpaa2/dpaa2_ethdev.h         |  12 ++
 4 files changed, 324 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
index b176208..0b59725 100644
--- a/doc/guides/nics/features/dpaa2.ini
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -4,6 +4,7 @@
 ; Refer to default.ini for the full list of available PMD features.
 ;
 [Features]
+Queue start/stop     = Y
 Linux VFIO           = Y
 ARMv8                = Y
 Usage doc            = Y
diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
index dda6243..08be96c 100644
--- a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
@@ -37,9 +37,12 @@
 #include <mc/fsl_mc_sys.h>
 #include <fsl_qbman_portal.h>
 
+#define DPAA2_DQRR_RING_SIZE	16
+	/** <Maximum number of slots available in RX ring*/
 
 #define MC_PORTAL_INDEX		0
 #define NUM_DPIO_REGIONS	2
+#define NUM_DQS_PER_QUEUE       2
 
 #define MEMPOOL_F_HW_PKT_POOL 0x8000 /**< mpool flag to check offloaded pool */
 
@@ -70,6 +73,23 @@ struct dpaa2_dpio_dev {
 	int32_t hw_id; /**< An unique ID of this DPIO device instance */
 };
 
+struct queue_storage_info_t {
+	struct qbman_result *dq_storage[NUM_DQS_PER_QUEUE];
+};
+
+struct dpaa2_queue {
+	struct rte_mempool *mb_pool; /**< mbuf pool to populate RX ring. */
+	void *dev;
+	int32_t eventfd;	/*!< Event Fd of this queue */
+	uint32_t fqid;		/*!< Unique ID of this queue */
+	uint8_t tc_index;	/*!< traffic class identifier */
+	uint16_t flow_id;	/*!< To be used by DPAA2 frmework */
+	uint64_t rx_pkts;
+	uint64_t tx_pkts;
+	uint64_t err_pkts;
+	struct queue_storage_info_t *q_storage;
+};
+
 /*! Global MCP list */
 extern void *(*mcp_ptr_list);
 #endif
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index c0ace68..d511d7b 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -54,6 +54,89 @@
 /* Name of the DPAA2 Net PMD */
 static const char *drivername = "DPAA2 PMD";
 
+static void
+dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
+{
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+
+	PMD_INIT_FUNC_TRACE();
+
+	dev_info->if_index = priv->hw_id;
+
+	dev_info->max_rx_queues = (uint16_t)priv->nb_rx_queues;
+	dev_info->max_tx_queues = (uint16_t)priv->nb_tx_queues;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_2_5G |
+			ETH_LINK_SPEED_10G;
+}
+
+static int
+dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev)
+{
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+	uint16_t dist_idx;
+	uint32_t vq_id;
+	struct dpaa2_queue *mc_q, *mcq;
+	uint32_t tot_queues;
+	int i;
+	struct dpaa2_queue *dpaa2_q;
+
+	PMD_INIT_FUNC_TRACE();
+
+	tot_queues = priv->nb_rx_queues + priv->nb_tx_queues;
+	mc_q = rte_malloc(NULL, sizeof(struct dpaa2_queue) * tot_queues,
+			  RTE_CACHE_LINE_SIZE);
+	if (!mc_q) {
+		PMD_INIT_LOG(ERR, "malloc failed for rx/tx queues\n");
+		return -1;
+	}
+
+	for (i = 0; i < priv->nb_rx_queues; i++) {
+		mc_q->dev = dev;
+		priv->rx_vq[i] = mc_q++;
+		dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
+		dpaa2_q->q_storage = rte_malloc("dq_storage",
+					sizeof(struct queue_storage_info_t),
+					RTE_CACHE_LINE_SIZE);
+		if (!dpaa2_q->q_storage)
+			goto fail;
+
+		memset(dpaa2_q->q_storage, 0,
+		       sizeof(struct queue_storage_info_t));
+		dpaa2_q->q_storage->dq_storage[0] = rte_malloc(NULL,
+			DPAA2_DQRR_RING_SIZE * sizeof(struct qbman_result),
+			RTE_CACHE_LINE_SIZE);
+	}
+
+	for (i = 0; i < priv->nb_tx_queues; i++) {
+		mc_q->dev = dev;
+		mc_q->flow_id = DPNI_NEW_FLOW_ID;
+		priv->tx_vq[i] = mc_q++;
+	}
+
+	vq_id = 0;
+	for (dist_idx = 0; dist_idx < priv->nb_rx_queues; dist_idx++) {
+		mcq = (struct dpaa2_queue *)priv->rx_vq[vq_id];
+		mcq->tc_index = DPAA2_DEF_TC;
+		mcq->flow_id = dist_idx;
+		vq_id++;
+	}
+
+	return 0;
+fail:
+	i -= 1;
+	mc_q = priv->rx_vq[0];
+	while (i >= 0) {
+		dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
+		rte_free(dpaa2_q->q_storage->dq_storage[0]);
+		rte_free(dpaa2_q->q_storage);
+		priv->rx_vq[i--] = NULL;
+	}
+	rte_free(mc_q);
+	return -1;
+}
+
 static int
 dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 {
@@ -73,15 +156,134 @@
 	return 0;
 }
 
+/* Function to setup RX flow information. It contains traffic class ID,
+ * flow ID, destination configuration etc.
+ */
 static int
-dpaa2_dev_start(struct rte_eth_dev *dev)
+dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev,
+			 uint16_t rx_queue_id,
+			 uint16_t nb_rx_desc __rte_unused,
+			 unsigned int socket_id __rte_unused,
+			 const struct rte_eth_rxconf *rx_conf __rte_unused,
+			 struct rte_mempool *mb_pool)
 {
 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+	struct dpaa2_queue *dpaa2_q;
+	struct dpni_queue cfg;
+	uint8_t options = 0;
+	uint8_t flow_id;
+	int ret;
+
+	PMD_INIT_FUNC_TRACE();
+
+	PMD_INIT_LOG(DEBUG, "dev =%p, queue =%d, pool = %p, conf =%p",
+		     dev, rx_queue_id, mb_pool, rx_conf);
+
+	dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[rx_queue_id];
+	dpaa2_q->mb_pool = mb_pool; /**< mbuf pool to populate RX ring. */
+
+	/*Get the tc id and flow id from given VQ id*/
+	flow_id = rx_queue_id;
+	memset(&cfg, 0, sizeof(struct dpni_queue));
+
+	options = options | DPNI_QUEUE_OPT_USER_CTX;
+	cfg.user_context = (uint64_t)(dpaa2_q);
+
+	ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_RX,
+			     dpaa2_q->tc_index, flow_id, options, &cfg);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Error in setting the rx flow: = %d\n", ret);
+		return -1;
+	}
+
+	dev->data->rx_queues[rx_queue_id] = dpaa2_q;
+	return 0;
+}
+
+static int
+dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev,
+			 uint16_t tx_queue_id,
+			 uint16_t nb_tx_desc __rte_unused,
+			 unsigned int socket_id __rte_unused,
+			 const struct rte_eth_txconf *tx_conf __rte_unused)
+{
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+	struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *)
+		priv->tx_vq[tx_queue_id];
+	struct fsl_mc_io *dpni = priv->hw;
+	struct dpni_queue tx_conf_cfg;
+	struct dpni_queue tx_flow_cfg;
+	uint8_t options = 0, flow_id;
+	uint32_t tc_id;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
+	/* Return if queue already configured */
+	if (dpaa2_q->flow_id != DPNI_NEW_FLOW_ID)
+		return 0;
+
+	memset(&tx_conf_cfg, 0, sizeof(struct dpni_queue));
+	memset(&tx_flow_cfg, 0, sizeof(struct dpni_queue));
+
+	tc_id = 0;
+	flow_id = tx_queue_id;
+
+	ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX,
+			     tc_id, flow_id, options, &tx_flow_cfg);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Error in setting the tx flow: "
+			     "tc_id=%d, flow =%d ErrorCode = %x\n",
+			     tc_id, flow_id, -ret);
+			return -1;
+	}
+
+	dpaa2_q->flow_id = flow_id;
+
+	if (tx_queue_id == 0) {
+		/*Set tx-conf and error configuration*/
+		ret = dpni_set_tx_confirmation_mode(dpni, CMD_PRI_LOW,
+						    priv->token,
+						    DPNI_CONF_DISABLE);
+		if (ret) {
+			PMD_INIT_LOG(ERR, "Error in set tx conf mode settings"
+				     " ErrorCode = %x", ret);
+			return -1;
+		}
+	}
+	dpaa2_q->tc_index = tc_id;
+
+	dev->data->tx_queues[tx_queue_id] = dpaa2_q;
+	return 0;
+}
+
+static void
+dpaa2_dev_rx_queue_release(void *q __rte_unused)
+{
+	PMD_INIT_FUNC_TRACE();
+}
+
+static void
+dpaa2_dev_tx_queue_release(void *q __rte_unused)
+{
+	PMD_INIT_FUNC_TRACE();
+}
+
+static int
+dpaa2_dev_start(struct rte_eth_dev *dev)
+{
+	struct rte_eth_dev_data *data = dev->data;
+	struct dpaa2_dev_priv *priv = data->dev_private;
+	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+	struct dpni_queue cfg;
+	uint16_t qdid;
+	struct dpni_queue_id qid;
+	struct dpaa2_queue *dpaa2_q;
+	int ret, i;
+
+	PMD_INIT_FUNC_TRACE();
+
 	ret = dpni_enable(dpni, CMD_PRI_LOW, priv->token);
 	if (ret) {
 		PMD_INIT_LOG(ERR, "Failure %d in enabling dpni %d device\n",
@@ -89,6 +291,27 @@
 		return ret;
 	}
 
+	ret = dpni_get_qdid(dpni, CMD_PRI_LOW, priv->token,
+			    DPNI_QUEUE_TX, &qdid);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Error to get qdid:ErrorCode = %d\n", ret);
+		return ret;
+	}
+	priv->qdid = qdid;
+
+	for (i = 0; i < data->nb_rx_queues; i++) {
+		dpaa2_q = (struct dpaa2_queue *)data->rx_queues[i];
+		ret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token,
+				     DPNI_QUEUE_RX, dpaa2_q->tc_index,
+				       dpaa2_q->flow_id, &cfg, &qid);
+		if (ret) {
+			PMD_INIT_LOG(ERR, "Error to get flow "
+				     "information Error code = %d\n", ret);
+			return ret;
+		}
+		dpaa2_q->fqid = qid.fqid;
+	}
+
 	return 0;
 }
 
@@ -136,6 +359,11 @@
 	.dev_start	      = dpaa2_dev_start,
 	.dev_stop	      = dpaa2_dev_stop,
 	.dev_close	      = dpaa2_dev_close,
+	.dev_infos_get	   = dpaa2_dev_info_get,
+	.rx_queue_setup    = dpaa2_dev_rx_queue_setup,
+	.rx_queue_release  = dpaa2_dev_rx_queue_release,
+	.tx_queue_setup    = dpaa2_dev_tx_queue_setup,
+	.tx_queue_release  = dpaa2_dev_tx_queue_release,
 };
 
 static int
@@ -144,6 +372,7 @@
 	struct rte_device *dev = eth_dev->device;
 	struct rte_dpaa2_device *dpaa2_dev;
 	struct fsl_mc_io *dpni_dev;
+	struct dpni_attr attr;
 	struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
 	int ret, hw_id;
 
@@ -179,8 +408,30 @@
 		return -1;
 	}
 
+	ret = dpni_get_attributes(dpni_dev, CMD_PRI_LOW, priv->token, &attr);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Failure in getting dpni@%d attribute, "
+			" error code %d\n", hw_id, ret);
+		return -1;
+	}
+
+	priv->num_tc = attr.num_tcs;
+	priv->nb_rx_queues = attr.num_queues;
+	priv->nb_tx_queues = attr.num_queues;
+
+	eth_dev->data->nb_rx_queues = priv->nb_rx_queues;
+	eth_dev->data->nb_tx_queues = priv->nb_tx_queues;
+
 	priv->hw = dpni_dev;
 	priv->hw_id = hw_id;
+	priv->flags = 0;
+
+	ret = dpaa2_alloc_rx_tx_queues(eth_dev);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "dpaa2_alloc_rx_tx_queuesFailed\n");
+		return -ret;
+	}
+
 	eth_dev->dev_ops = &dpaa2_ethdev_ops;
 	eth_dev->data->drv_name = drivername;
 
@@ -188,13 +439,51 @@
 }
 
 static int
-dpaa2_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused)
+dpaa2_dev_uninit(struct rte_eth_dev *eth_dev)
 {
+	struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
+	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+	int i, ret;
+	struct dpaa2_queue *dpaa2_q;
+
 	PMD_INIT_FUNC_TRACE();
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return -EPERM;
 
+	if (!dpni) {
+		PMD_INIT_LOG(WARNING, "Already closed or not started");
+		return -1;
+	}
+
+	dpaa2_dev_close(eth_dev);
+
+	if (priv->rx_vq[0]) {
+		/* cleaning up queue storage */
+		for (i = 0; i < priv->nb_rx_queues; i++) {
+			dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
+			if (dpaa2_q->q_storage)
+				rte_free(dpaa2_q->q_storage);
+		}
+		/*free the all queue memory */
+		rte_free(priv->rx_vq[0]);
+		priv->rx_vq[0] = NULL;
+	}
+
+
+	/*Close the device at underlying layer*/
+	ret = dpni_close(dpni, CMD_PRI_LOW, priv->token);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Failure closing dpni device with"
+			" error code %d\n", ret);
+	}
+
+	/*Free the allocated memory for ethernet private data and dpni*/
+	priv->hw = NULL;
+	free(dpni);
+
+	eth_dev->dev_ops = NULL;
+
 	return 0;
 }
 
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h
index 840b688..5f599a7 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -37,11 +37,23 @@
 #include <mc/fsl_dpni.h>
 #include <mc/fsl_mc_sys.h>
 
+#define MAX_RX_QUEUES		16
+#define MAX_TX_QUEUES		16
+
+/*default tc to be used for ,congestion, distribution etc configuration. */
+#define DPAA2_DEF_TC		0
+
 struct dpaa2_dev_priv {
 	void *hw;
 	int32_t hw_id;
+	int32_t qdid;
 	uint16_t token;
+	uint8_t nb_tx_queues;
+	uint8_t nb_rx_queues;
+	void *rx_vq[MAX_RX_QUEUES];
+	void *tx_vq[MAX_TX_QUEUES];
 
+	uint8_t num_tc;
 	uint8_t flags; /*dpaa2 config flags */
 };
 #endif /* _DPAA2_ETHDEV_H */
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 18/34] net/dpaa2: adding eth ops to dpaa2
From: Hemant Agrawal @ 2016-12-19 20:53 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/net/dpaa2/Makefile       |   2 +
 drivers/net/dpaa2/dpaa2_ethdev.c | 121 +++++++++++++++++++++++++++++++++++++++
 drivers/net/dpaa2/dpaa2_ethdev.h |   3 +
 3 files changed, 126 insertions(+)

diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 5a1db74..4425b76 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -46,7 +46,9 @@ endif
 
 CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
 CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
 CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
+CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/dpio
 CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
 
 # versioning export map
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index a0e842c..c0ace68 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -47,20 +47,141 @@
 
 #include <fslmc_logs.h>
 #include <fslmc_vfio.h>
+#include <dpaa2_hw_pvt.h>
+
 #include "dpaa2_ethdev.h"
 
 /* Name of the DPAA2 Net PMD */
 static const char *drivername = "DPAA2 PMD";
 
 static int
+dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
+{
+	struct rte_eth_dev_data *data = dev->data;
+	struct rte_eth_conf *eth_conf = &data->dev_conf;
+
+	PMD_INIT_FUNC_TRACE();
+
+	/* Check for correct configuration */
+	if (eth_conf->rxmode.mq_mode != ETH_MQ_RX_RSS &&
+	    data->nb_rx_queues > 1) {
+		PMD_INIT_LOG(ERR, "Distribution is not enabled, "
+			    "but Rx queues more than 1\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+dpaa2_dev_start(struct rte_eth_dev *dev)
+{
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+	int ret;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ret = dpni_enable(dpni, CMD_PRI_LOW, priv->token);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Failure %d in enabling dpni %d device\n",
+			     ret, priv->hw_id);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ *  This routine disables all traffic on the adapter by issuing a
+ *  global reset on the MAC.
+ */
+static void
+dpaa2_dev_stop(struct rte_eth_dev *dev)
+{
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+	int ret;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ret = dpni_disable(dpni, CMD_PRI_LOW, priv->token);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Failure (ret %d) in disabling dpni %d dev\n",
+			     ret, priv->hw_id);
+		return;
+	}
+}
+
+static void
+dpaa2_dev_close(struct rte_eth_dev *dev)
+{
+	struct dpaa2_dev_priv *priv = dev->data->dev_private;
+	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+	int ret;
+
+	PMD_INIT_FUNC_TRACE();
+
+	/* Clean the device first */
+	ret = dpni_reset(dpni, CMD_PRI_LOW, priv->token);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Failure cleaning dpni device with"
+			     " error code %d\n", ret);
+		return;
+	}
+}
+
+static struct eth_dev_ops dpaa2_ethdev_ops = {
+	.dev_configure	  = dpaa2_eth_dev_configure,
+	.dev_start	      = dpaa2_dev_start,
+	.dev_stop	      = dpaa2_dev_stop,
+	.dev_close	      = dpaa2_dev_close,
+};
+
+static int
 dpaa2_dev_init(struct rte_eth_dev *eth_dev)
 {
+	struct rte_device *dev = eth_dev->device;
+	struct rte_dpaa2_device *dpaa2_dev;
+	struct fsl_mc_io *dpni_dev;
+	struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
+	int ret, hw_id;
+
 	PMD_INIT_FUNC_TRACE();
 
 	/* For secondary processes, the primary has done all the work */
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	dpaa2_dev = container_of(dev, struct rte_dpaa2_device, device);
+
+	hw_id = dpaa2_dev->object_id;
+
+	dpni_dev = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io));
+	if (!dpni_dev) {
+		PMD_INIT_LOG(ERR, "malloc failed for dpni device\n");
+		return -1;
+	}
+
+	dpni_dev->regs = mcp_ptr_list[0];
+	ret = dpni_open(dpni_dev, CMD_PRI_LOW, hw_id, &priv->token);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Failure in opening dpni@%d device with"
+			" error code %d\n", hw_id, ret);
+		return -1;
+	}
+
+	/* Clean the device first */
+	ret = dpni_reset(dpni_dev, CMD_PRI_LOW, priv->token);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Failure cleaning dpni@%d device with"
+			" error code %d\n", hw_id, ret);
+		return -1;
+	}
+
+	priv->hw = dpni_dev;
+	priv->hw_id = hw_id;
+	eth_dev->dev_ops = &dpaa2_ethdev_ops;
 	eth_dev->data->drv_name = drivername;
 
 	return 0;
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h
index 5778780..840b688 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -34,6 +34,9 @@
 #ifndef _DPAA2_ETHDEV_H
 #define _DPAA2_ETHDEV_H
 
+#include <mc/fsl_dpni.h>
+#include <mc/fsl_mc_sys.h>
+
 struct dpaa2_dev_priv {
 	void *hw;
 	int32_t hw_id;
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 17/34] drivers/common/dpaa2: dpio routine to affine to crypto threads
From: Hemant Agrawal @ 2016-12-19 20:53 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c          | 45 ++++++++++++++++++++++
 drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h          |  3 ++
 .../dpaa2/dpio/rte_pmd_dpaa2_dpio_version.map      |  1 +
 3 files changed, 49 insertions(+)

diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c b/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c
index 011bd9f..d7de0d5 100644
--- a/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c
@@ -276,6 +276,51 @@ static inline struct dpaa2_dpio_dev *dpaa2_get_qbman_swp(void)
 }
 
 int
+dpaa2_affine_qbman_swp_sec(void)
+{
+	unsigned int lcore_id = rte_lcore_id();
+	uint64_t tid = syscall(SYS_gettid);
+
+	if (lcore_id == LCORE_ID_ANY)
+		lcore_id = rte_get_master_lcore();
+	/* if the core id is not supported */
+	else if (lcore_id >= RTE_MAX_LCORE)
+		return -1;
+
+	if (dpaa2_io_portal[lcore_id].sec_dpio_dev) {
+		PMD_DRV_LOG(INFO, "DPAA Portal=0x%x (%d) is being shared"
+			    " between thread %lu and current  %lu",
+			    dpaa2_io_portal[lcore_id].sec_dpio_dev,
+			    dpaa2_io_portal[lcore_id].sec_dpio_dev->index,
+			    dpaa2_io_portal[lcore_id].sec_tid,
+			    tid);
+		RTE_PER_LCORE(_dpaa2_io).sec_dpio_dev
+			= dpaa2_io_portal[lcore_id].sec_dpio_dev;
+		rte_atomic16_inc(&dpaa2_io_portal
+				 [lcore_id].sec_dpio_dev->ref_count);
+		dpaa2_io_portal[lcore_id].sec_tid = tid;
+
+		PMD_DRV_LOG(DEBUG, "Old Portal=0x%x (%d) affined thread - %lu",
+			    dpaa2_io_portal[lcore_id].sec_dpio_dev,
+			    dpaa2_io_portal[lcore_id].sec_dpio_dev->index,
+			    tid);
+		return 0;
+	}
+
+	/* Populate the dpaa2_io_portal structure */
+	dpaa2_io_portal[lcore_id].sec_dpio_dev = dpaa2_get_qbman_swp();
+
+	if (dpaa2_io_portal[lcore_id].sec_dpio_dev) {
+		RTE_PER_LCORE(_dpaa2_io).sec_dpio_dev
+			= dpaa2_io_portal[lcore_id].sec_dpio_dev;
+		dpaa2_io_portal[lcore_id].sec_tid = tid;
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+int
 dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
 			 struct vfio_device_info *obj_info,
 		int object_id)
diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h b/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h
index 889c2c0..b160c0f 100644
--- a/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h
@@ -56,6 +56,9 @@ struct dpaa2_io_portal_t {
 /* Affine a DPIO portal to current processing thread */
 int dpaa2_affine_qbman_swp(void);
 
+/* Affine additional DPIO portal to current crypto processing thread */
+int dpaa2_affine_qbman_swp_sec(void);
+
 /* create dpio device */
 int dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
 			     struct vfio_device_info *obj_info,
diff --git a/drivers/common/dpaa2/dpio/rte_pmd_dpaa2_dpio_version.map b/drivers/common/dpaa2/dpio/rte_pmd_dpaa2_dpio_version.map
index 597cdbd..9ad8f11 100644
--- a/drivers/common/dpaa2/dpio/rte_pmd_dpaa2_dpio_version.map
+++ b/drivers/common/dpaa2/dpio/rte_pmd_dpaa2_dpio_version.map
@@ -2,6 +2,7 @@ DPDK_17.02 {
 	global:
 	per_lcore__dpaa2_io;
 	dpaa2_affine_qbman_swp;
+	dpaa2_affine_qbman_swp_sec;
 	dpaa2_create_dpio_device;
 
 	local: *;
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 16/34] drivers/pool/dpaa2: adding hw offloaded mempool
From: Hemant Agrawal @ 2016-12-19 20:53 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Adding NXP DPAA2 architecture specific mempool support
Each mempool instance is represented by a DPBP object
from the FSL-MC bus.

This patch also registers a dpaa2 type MEMPOOL OPS

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 config/common_base                                |   1 +
 config/defconfig_arm64-dpaa2-linuxapp-gcc         |   4 +
 drivers/Makefile                                  |   1 +
 drivers/bus/fslmc/Makefile                        |   1 +
 drivers/bus/fslmc/fslmc_vfio.c                    |  10 +-
 drivers/common/Makefile                           |   3 +
 drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h          |   7 +
 drivers/pool/Makefile                             |  38 +++
 drivers/pool/dpaa2/Makefile                       |  66 ++++
 drivers/pool/dpaa2/dpaa2_hw_mempool.c             | 362 ++++++++++++++++++++++
 drivers/pool/dpaa2/dpaa2_hw_mempool.h             | 104 +++++++
 drivers/pool/dpaa2/rte_pmd_dpaa2_pool_version.map |   8 +
 mk/rte.app.mk                                     |   1 +
 13 files changed, 605 insertions(+), 1 deletion(-)
 create mode 100644 drivers/pool/Makefile
 create mode 100644 drivers/pool/dpaa2/Makefile
 create mode 100644 drivers/pool/dpaa2/dpaa2_hw_mempool.c
 create mode 100644 drivers/pool/dpaa2/dpaa2_hw_mempool.h
 create mode 100644 drivers/pool/dpaa2/rte_pmd_dpaa2_pool_version.map

diff --git a/config/common_base b/config/common_base
index d605e85..493811f 100644
--- a/config/common_base
+++ b/config/common_base
@@ -276,6 +276,7 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
 # Compile Support Libraries for NXP DPAA2
 #
 CONFIG_RTE_LIBRTE_DPAA2_COMMON=n
+CONFIG_RTE_LIBRTE_DPAA2_POOL=n
 
 #
 # Compile NXP DPAA2 FSL-MC Bus
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index d3bc9d8..7665912 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -42,10 +42,14 @@ CONFIG_RTE_ARCH_ARM_TUNE="cortex-a57+fp+simd"
 CONFIG_RTE_MAX_LCORE=8
 CONFIG_RTE_MAX_NUMA_NODES=1
 
+CONFIG_RTE_PKTMBUF_HEADROOM=256
+
 #
 # Compile Support Libraries for DPAA2
 #
 CONFIG_RTE_LIBRTE_DPAA2_COMMON=y
+CONFIG_RTE_LIBRTE_DPAA2_POOL=n
+CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
 
 #
 # Compile NXP DPAA2 FSL-MC Bus
diff --git a/drivers/Makefile b/drivers/Makefile
index bdae63b..609523d 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -34,6 +34,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 DIRS-y += common
 DIRS-y += bus
 DIRS-y += net
+DIRS-y += pool
 DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index cc6d7c2..a830701 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -48,6 +48,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
 CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
 CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
 CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/dpio
+CFLAGS += -I$(RTE_SDK)/drivers/pool/dpaa2
 CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
 
 # versioning export map
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 1c80bf9..8d6a3eb 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -63,6 +63,7 @@
 
 #include "dpaa2_hw_pvt.h"
 #include "dpaa2_hw_dpio.h"
+#include "dpaa2_hw_mempool.h"
 
 #define VFIO_MAX_CONTAINERS	1
 
@@ -270,7 +271,7 @@ int fslmc_vfio_process_group(struct rte_bus *bus)
 	char path[PATH_MAX];
 	int64_t v_addr;
 	int ndev_count;
-	int dpio_count = 0;
+	int dpio_count = 0, dpbp_count = 0;
 	struct fslmc_vfio_group *group = &vfio_groups[0];
 	static int process_once;
 
@@ -420,6 +421,11 @@ int fslmc_vfio_process_group(struct rte_bus *bus)
 			if (!ret)
 				dpio_count++;
 		}
+		if (!strcmp(object_type, "dpbp")) {
+			ret = dpaa2_create_dpbp_device(object_id);
+			if (!ret)
+				dpbp_count++;
+		}
 	}
 	closedir(d);
 
@@ -427,6 +433,8 @@ int fslmc_vfio_process_group(struct rte_bus *bus)
 	if (ret)
 		FSLMC_VFIO_LOG(DEBUG, "Error in affining qbman swp %d", ret);
 
+	FSLMC_VFIO_LOG(DEBUG, "DPAA2: Added dpbp_count = %d dpio_count=%d\n",
+		      dpbp_count, dpio_count);
 	return 0;
 
 FAILURE:
diff --git a/drivers/common/Makefile b/drivers/common/Makefile
index 434280f..0a6d8db 100644
--- a/drivers/common/Makefile
+++ b/drivers/common/Makefile
@@ -34,6 +34,9 @@ include $(RTE_SDK)/mk/rte.vars.mk
 CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
 
 ifneq ($(CONFIG_RTE_LIBRTE_DPAA2_COMMON),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_POOL)
+endif
+ifneq ($(CONFIG_RTE_LIBRTE_DPAA2_COMMON),y)
 CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
 endif
 
diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
index ef3eb71..dda6243 100644
--- a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
@@ -41,6 +41,13 @@
 #define MC_PORTAL_INDEX		0
 #define NUM_DPIO_REGIONS	2
 
+#define MEMPOOL_F_HW_PKT_POOL 0x8000 /**< mpool flag to check offloaded pool */
+
+/* Maximum release/acquire from QBMAN */
+#define DPAA2_MBUF_MAX_ACQ_REL	7
+
+#define MAX_BPID 256
+
 struct dpaa2_dpio_dev {
 	TAILQ_ENTRY(dpaa2_dpio_dev) next;
 		/**< Pointer to Next device instance */
diff --git a/drivers/pool/Makefile b/drivers/pool/Makefile
new file mode 100644
index 0000000..4325edd
--- /dev/null
+++ b/drivers/pool/Makefile
@@ -0,0 +1,38 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2016 NXP. All rights reserved.
+#   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 NXP 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
+
+CONFIG_RTE_LIBRTE_DPAA2_POOL = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += dpaa2
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/pool/dpaa2/Makefile b/drivers/pool/dpaa2/Makefile
new file mode 100644
index 0000000..c33e631
--- /dev/null
+++ b/drivers/pool/dpaa2/Makefile
@@ -0,0 +1,66 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2016 NXP. All rights reserved.
+#   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 NXP 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_pool.a
+
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT),y)
+CFLAGS += -O0 -g
+CFLAGS += "-Wno-error"
+else
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+endif
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/dpio
+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_pool_version.map
+
+# Lbrary version
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += dpaa2_hw_mempool.c
+
+# library dependencies
+DEPDIRS-y += lib/librte_eal
+DEPDIRS-y += lib/librte_mempool
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/pool/dpaa2/dpaa2_hw_mempool.c b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
new file mode 100644
index 0000000..f609af7
--- /dev/null
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
@@ -0,0 +1,362 @@
+/*-
+ *   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 <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.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 <fslmc_logs.h>
+#include <fslmc_vfio.h>
+#include <mc/fsl_dpbp.h>
+#include <dpaa2_hw_pvt.h>
+#include <dpaa2_hw_dpio.h>
+#include "dpaa2_hw_mempool.h"
+
+static struct dpbp_node *g_dpbp_list;
+static struct dpbp_node *avail_dpbp;
+
+struct dpaa2_bp_info bpid_info[MAX_BPID];
+
+struct dpaa2_bp_list *h_bp_list;
+
+int
+dpaa2_create_dpbp_device(
+		int dpbp_id)
+{
+	struct dpbp_node *dpbp_node;
+	int ret;
+
+	/* Allocate DPAA2 dpbp handle */
+	dpbp_node = (struct dpbp_node *)malloc(sizeof(struct dpbp_node));
+	if (!dpbp_node) {
+		PMD_INIT_LOG(ERR, "Memory allocation failed for DPBP Device");
+		return -1;
+	}
+
+	/* Open the dpbp object */
+	dpbp_node->dpbp.regs = mcp_ptr_list[MC_PORTAL_INDEX];
+	ret = dpbp_open(&dpbp_node->dpbp,
+			CMD_PRI_LOW, dpbp_id, &dpbp_node->token);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Resource alloc failure with err code: %d",
+			     ret);
+		free(dpbp_node);
+		return -1;
+	}
+
+	/* Clean the device first */
+	ret = dpbp_reset(&dpbp_node->dpbp, CMD_PRI_LOW, dpbp_node->token);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "Failure cleaning dpbp device with"
+					" error code %d\n", ret);
+		return -1;
+	}
+
+	dpbp_node->dpbp_id = dpbp_id;
+	/* Add the dpbp handle into the global list */
+	dpbp_node->next = g_dpbp_list;
+	g_dpbp_list = dpbp_node;
+	avail_dpbp = g_dpbp_list;
+
+	PMD_INIT_LOG(DEBUG, "Buffer pool resource initialized %d", dpbp_id);
+
+	return 0;
+}
+
+static int
+hw_mbuf_create_pool(struct rte_mempool *mp)
+{
+	struct dpaa2_bp_list *bp_list;
+	struct dpbp_attr dpbp_attr;
+	uint32_t bpid;
+	int ret;
+
+	if (!avail_dpbp) {
+		PMD_DRV_LOG(ERR, "DPAA2 resources not available");
+		return -1;
+	}
+
+	ret = dpbp_enable(&avail_dpbp->dpbp, CMD_PRI_LOW, avail_dpbp->token);
+	if (ret != 0) {
+		PMD_INIT_LOG(ERR, "Resource enable failure with"
+			" err code: %d\n", ret);
+		return -1;
+	}
+
+	ret = dpbp_get_attributes(&avail_dpbp->dpbp, CMD_PRI_LOW,
+				  avail_dpbp->token, &dpbp_attr);
+	if (ret != 0) {
+		PMD_INIT_LOG(ERR, "Resource read failure with"
+			     " err code: %d\n", ret);
+		ret = dpbp_disable(&avail_dpbp->dpbp, CMD_PRI_LOW,
+				   avail_dpbp->token);
+		return -1;
+	}
+
+	/* Allocate the bp_list which will be added into global_bp_list */
+	bp_list = (struct dpaa2_bp_list *)malloc(sizeof(struct dpaa2_bp_list));
+	if (!bp_list) {
+		PMD_INIT_LOG(ERR, "No heap memory available");
+		return -1;
+	}
+
+	/* Set parameters of buffer pool list */
+	bp_list->buf_pool.num_bufs = mp->size;
+	bp_list->buf_pool.size = mp->elt_size
+			- sizeof(struct rte_mbuf) - rte_pktmbuf_priv_size(mp);
+	bp_list->buf_pool.bpid = dpbp_attr.bpid;
+	bp_list->buf_pool.h_bpool_mem = NULL;
+	bp_list->buf_pool.mp = mp;
+	bp_list->buf_pool.dpbp_node = avail_dpbp;
+	bp_list->next = h_bp_list;
+
+	bpid = dpbp_attr.bpid;
+
+	/* Increment the available DPBP */
+	avail_dpbp = avail_dpbp->next;
+
+	bpid_info[bpid].meta_data_size = sizeof(struct rte_mbuf)
+				+ rte_pktmbuf_priv_size(mp);
+	bpid_info[bpid].bp_list = bp_list;
+	bpid_info[bpid].bpid = bpid;
+
+	mp->pool_data = (void *)&bpid_info[bpid];
+
+	PMD_INIT_LOG(DEBUG, "BP List created for bpid =%d", dpbp_attr.bpid);
+
+	h_bp_list = bp_list;
+	/* Identification for our offloaded pool_data structure
+	 */
+	mp->flags |= MEMPOOL_F_HW_PKT_POOL;
+	return 0;
+}
+
+static void
+hw_mbuf_free_pool(struct rte_mempool *mp __rte_unused)
+{
+	/* TODO:
+	 * 1. Release bp_list memory allocation
+	 * 2. opposite of dpbp_enable()
+	 * <More>
+	 */
+	struct dpaa2_bp_list *bp;
+
+	/* Iterate over h_bp_list linked list and release each element */
+	while (h_bp_list) {
+		bp = h_bp_list;
+		h_bp_list = bp->next;
+
+		/* TODO: Should be changed to rte_free */
+		free(bp);
+	}
+}
+
+static
+void dpaa2_mbuf_release(struct rte_mempool *pool __rte_unused,
+			void * const *obj_table,
+			uint32_t bpid,
+			uint32_t meta_data_size,
+			int count)
+{
+	struct qbman_release_desc releasedesc;
+	struct qbman_swp *swp;
+	int ret;
+	int i, n;
+	uint64_t bufs[DPAA2_MBUF_MAX_ACQ_REL];
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret != 0) {
+			RTE_LOG(ERR, PMD, "Failed to allocate IO portal");
+			return;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	/* Create a release descriptor required for releasing
+	 * buffers into QBMAN
+	 */
+	qbman_release_desc_clear(&releasedesc);
+	qbman_release_desc_set_bpid(&releasedesc, bpid);
+
+	n = count % DPAA2_MBUF_MAX_ACQ_REL;
+
+	/* convert mbuf to buffers  for the remainder*/
+	for (i = 0; i < n ; i++)
+		bufs[i] = (uint64_t)obj_table[i] + meta_data_size;
+
+	/* feed them to bman*/
+	do {
+		ret = qbman_swp_release(swp, &releasedesc, bufs, n);
+	} while (ret == -EBUSY);
+
+	/* if there are more buffers to free */
+	while (n < count) {
+		/* convert mbuf to buffers */
+		for (i = 0; i < DPAA2_MBUF_MAX_ACQ_REL; i++)
+			bufs[i] = (uint64_t)obj_table[n + i] + meta_data_size;
+
+		do {
+			ret = qbman_swp_release(swp, &releasedesc, bufs,
+						DPAA2_MBUF_MAX_ACQ_REL);
+			} while (ret == -EBUSY);
+		n += DPAA2_MBUF_MAX_ACQ_REL;
+	}
+}
+
+int hw_mbuf_alloc_bulk(struct rte_mempool *pool,
+		       void **obj_table, unsigned int count)
+{
+#ifdef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
+	static int alloc;
+#endif
+	struct qbman_swp *swp;
+	uint32_t mbuf_size;
+	uint16_t bpid;
+	uint64_t bufs[DPAA2_MBUF_MAX_ACQ_REL];
+	int i, ret;
+	unsigned int n = 0;
+	struct dpaa2_bp_info *bp_info;
+
+	bp_info = mempool_to_bpinfo(pool);
+
+	if (!(bp_info->bp_list)) {
+		RTE_LOG(ERR, PMD, "DPAA2 buffer pool not configured\n");
+		return -2;
+	}
+
+	bpid = bp_info->bpid;
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret != 0) {
+			RTE_LOG(ERR, PMD, "Failed to allocate IO portal");
+			return -1;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	mbuf_size = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(pool);
+
+	while (n < count) {
+		/* Acquire is all-or-nothing, so we drain in 7s,
+		 * then the remainder.
+		 */
+		if ((count - n) > DPAA2_MBUF_MAX_ACQ_REL) {
+			ret = qbman_swp_acquire(swp, bpid, bufs,
+						DPAA2_MBUF_MAX_ACQ_REL);
+		} else {
+			ret = qbman_swp_acquire(swp, bpid, bufs,
+						count - n);
+		}
+		/* In case of less than requested number of buffers available
+		 * in pool, qbman_swp_acquire returns 0
+		 */
+		if (ret <= 0) {
+			PMD_TX_LOG(ERR, "Buffer acquire failed with"
+				   " err code: %d", ret);
+			/* The API expect the exact number of requested bufs */
+			/* Releasing all buffers allocated */
+			dpaa2_mbuf_release(pool, obj_table, bpid,
+					   bp_info->meta_data_size, n);
+			return -1;
+		}
+		/* assigning mbuf from the acquired objects */
+		for (i = 0; (i < ret) && bufs[i]; i++) {
+			/* TODO-errata - observed that bufs may be null
+			 * i.e. first buffer is valid,
+			 * remaining 6 buffers may be null
+			 */
+			obj_table[n] = (struct rte_mbuf *)(bufs[i] - mbuf_size);
+			rte_mbuf_refcnt_set((struct rte_mbuf *)obj_table[n], 0);
+			PMD_TX_LOG(DEBUG, "Acquired %p address %p from BMAN",
+				   (void *)bufs[i], (void *)obj_table[n]);
+			n++;
+		}
+	}
+
+#ifdef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
+	alloc += n;
+	PMD_TX_LOG(DEBUG, "Total = %d , req = %d done = %d",
+		   alloc, count, n);
+#endif
+	return 0;
+}
+
+static int
+hw_mbuf_free_bulk(struct rte_mempool *pool,
+		  void * const *obj_table, unsigned int n)
+{
+	struct dpaa2_bp_info *bp_info;
+
+	bp_info = mempool_to_bpinfo(pool);
+	if (!(bp_info->bp_list)) {
+		RTE_LOG(ERR, PMD, "DPAA2 buffer pool not configured");
+		return -1;
+	}
+	dpaa2_mbuf_release(pool, obj_table, bp_info->bpid,
+			   bp_info->meta_data_size, n);
+
+	return 0;
+}
+
+static unsigned
+hw_mbuf_get_count(const struct rte_mempool *mp __rte_unused)
+{
+	return 0;
+}
+
+struct rte_mempool_ops dpaa2_mpool_ops = {
+	.name = "dpaa2",
+	.alloc = hw_mbuf_create_pool,
+	.free = hw_mbuf_free_pool,
+	.enqueue = hw_mbuf_free_bulk,
+	.dequeue = hw_mbuf_alloc_bulk,
+	.get_count = hw_mbuf_get_count,
+};
+
+MEMPOOL_REGISTER_OPS(dpaa2_mpool_ops);
diff --git a/drivers/pool/dpaa2/dpaa2_hw_mempool.h b/drivers/pool/dpaa2/dpaa2_hw_mempool.h
new file mode 100644
index 0000000..4d6d645
--- /dev/null
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.h
@@ -0,0 +1,104 @@
+/*-
+ *   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.
+ */
+
+#ifndef _DPAA2_HW_DPBP_H_
+#define _DPAA2_HW_DPBP_H_
+
+#define DPAA2_MAX_BUF_POOLS	8
+
+struct dpbp_node {
+	struct dpbp_node *next;
+	struct fsl_mc_io dpbp;
+	uint16_t token;
+	int dpbp_id;
+};
+
+struct buf_pool_cfg {
+	void *addr; /*!< The address from where DPAA2 will carve out the
+		     * buffers. 'addr' should be 'NULL' if user wants
+		     * to create buffers from the memory which user
+		     * asked DPAA2 to reserve during 'nadk init'
+		     */
+	phys_addr_t    phys_addr;  /*!< corresponding physical address
+				    * of the memory provided in addr
+				    */
+	uint32_t num; /*!< number of buffers */
+	uint32_t size; /*!< size of each buffer. 'size' should include
+			* any headroom to be reserved and alignment
+			*/
+	uint16_t align; /*!< Buffer alignment (in bytes) */
+	uint16_t bpid; /*!< The buffer pool id. This will be filled
+			*in by DPAA2 for each buffer pool
+			*/
+};
+
+struct buf_pool {
+	uint32_t size;
+	uint32_t num_bufs;
+	uint16_t bpid;
+	uint8_t *h_bpool_mem;
+	struct rte_mempool *mp;
+	struct dpbp_node *dpbp_node;
+};
+
+/*!
+ * Buffer pool list configuration structure. User need to give DPAA2 the
+ * valid number of 'num_buf_pools'.
+ */
+struct dpaa2_bp_list_cfg {
+	struct buf_pool_cfg buf_pool; /* Configuration of each buffer pool*/
+};
+
+struct dpaa2_bp_list {
+	struct dpaa2_bp_list *next;
+	struct rte_mempool *mp;
+	struct buf_pool buf_pool;
+};
+
+struct dpaa2_bp_info {
+	uint32_t meta_data_size;
+	uint32_t bpid;
+	struct dpaa2_bp_list *bp_list;
+};
+
+#define mempool_to_bpinfo(mp) ((struct dpaa2_bp_info *)(mp)->pool_data)
+#define mempool_to_bpid(mp) ((mempool_to_bpinfo(mp))->bpid)
+
+extern struct dpaa2_bp_info bpid_info[MAX_BPID];
+
+int dpaa2_create_dpbp_device(int dpbp_id);
+
+int hw_mbuf_alloc_bulk(struct rte_mempool *pool,
+		       void **obj_table, unsigned int count);
+
+#endif /* _DPAA2_HW_DPBP_H_ */
diff --git a/drivers/pool/dpaa2/rte_pmd_dpaa2_pool_version.map b/drivers/pool/dpaa2/rte_pmd_dpaa2_pool_version.map
new file mode 100644
index 0000000..d18e076
--- /dev/null
+++ b/drivers/pool/dpaa2/rte_pmd_dpaa2_pool_version.map
@@ -0,0 +1,8 @@
+DPDK_17.02 {
+	global:
+	bpid_info;
+	dpaa2_create_dpbp_device;
+	hw_mbuf_alloc_bulk;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index f380c88..1f1157f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -113,6 +113,7 @@ 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_dpaa2_dpio
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_pmd_dpaa2_pool
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_pmd_fslmcbus
 endif
 _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 15/34] drivers/common/dpaa2: dpio object driver
From: Hemant Agrawal @ 2016-12-19 20:53 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

The DPIO driver is bound to DPIO objects discovered on the fsl-mc bus and
provides services that:
- allow other drivers, such as the Ethernet driver, to enqueue and dequeue
  frames for their respective objects

A system will typically allocate 1 DPIO object per CPU to allow queuing
operations to happen simultaneously across all CPUs.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/bus/fslmc/Makefile                         |   2 +
 drivers/bus/fslmc/fslmc_vfio.c                     |  21 +-
 drivers/common/Makefile                            |   4 +
 drivers/common/dpaa2/Makefile                      |   1 +
 drivers/common/dpaa2/dpio/Makefile                 |  64 ++++
 drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c          | 364 +++++++++++++++++++++
 drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h          |  64 ++++
 drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h           |  68 ++++
 .../dpaa2/dpio/rte_pmd_dpaa2_dpio_version.map      |   8 +
 mk/rte.app.mk                                      |   1 +
 10 files changed, 594 insertions(+), 3 deletions(-)
 create mode 100644 drivers/common/dpaa2/dpio/Makefile
 create mode 100644 drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c
 create mode 100644 drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h
 create mode 100644 drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
 create mode 100644 drivers/common/dpaa2/dpio/rte_pmd_dpaa2_dpio_version.map

diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index a8b1666..cc6d7c2 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -46,6 +46,8 @@ CFLAGS += "-Wno-strict-aliasing"
 
 CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
 CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
+CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
+CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/dpio
 CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
 
 # versioning export map
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 7739493..1c80bf9 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -61,6 +61,9 @@
 #include "rte_fslmc.h"
 #include "fslmc_vfio.h"
 
+#include "dpaa2_hw_pvt.h"
+#include "dpaa2_hw_dpio.h"
+
 #define VFIO_MAX_CONTAINERS	1
 
 #define FSLMC_VFIO_LOG(level, fmt, args...) \
@@ -224,7 +227,7 @@ static int64_t vfio_map_mcp_obj(struct fslmc_vfio_group *group, char *mcp_obj)
 }
 
 static void
-dpaa2_bus_add_device(struct rte_bus *bus, struct rte_dpaa2_device *dev)
+fslmc_bus_add_device(struct rte_bus *bus, struct rte_dpaa2_device *dev)
 {
 	/* device is valid, add in list (sorted) */
 	if (TAILQ_EMPTY(&bus->device_list)) {
@@ -261,12 +264,13 @@ int fslmc_vfio_process_group(struct rte_bus *bus)
 	struct fslmc_vfio_device *vdev;
 	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
 	char *temp_obj, *object_type, *mcp_obj, *dev_name;
-	int32_t object_id, i, dev_fd;
+	int32_t object_id, i, dev_fd, ret;
 	DIR *d;
 	struct dirent *dir;
 	char path[PATH_MAX];
 	int64_t v_addr;
 	int ndev_count;
+	int dpio_count = 0;
 	struct fslmc_vfio_group *group = &vfio_groups[0];
 	static int process_once;
 
@@ -407,11 +411,22 @@ int fslmc_vfio_process_group(struct rte_bus *bus)
 			FSLMC_VFIO_LOG(DEBUG, "DPAA2: Added [%s-%d]\n",
 				      object_type, object_id);
 
-			dpaa2_bus_add_device(bus, dev);
+			fslmc_bus_add_device(bus, dev);
+		}
+		if (!strcmp(object_type, "dpio")) {
+			ret = dpaa2_create_dpio_device(vdev,
+						       &device_info,
+						       object_id);
+			if (!ret)
+				dpio_count++;
 		}
 	}
 	closedir(d);
 
+	ret = dpaa2_affine_qbman_swp();
+	if (ret)
+		FSLMC_VFIO_LOG(DEBUG, "Error in affining qbman swp %d", ret);
+
 	return 0;
 
 FAILURE:
diff --git a/drivers/common/Makefile b/drivers/common/Makefile
index 76ec2d1..434280f 100644
--- a/drivers/common/Makefile
+++ b/drivers/common/Makefile
@@ -33,6 +33,10 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
 
+ifneq ($(CONFIG_RTE_LIBRTE_DPAA2_COMMON),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
+endif
+
 DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += dpaa2
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/common/dpaa2/Makefile b/drivers/common/dpaa2/Makefile
index 4960ebe..4ccaf26 100644
--- a/drivers/common/dpaa2/Makefile
+++ b/drivers/common/dpaa2/Makefile
@@ -32,5 +32,6 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += qbman
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += dpio
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/common/dpaa2/dpio/Makefile b/drivers/common/dpaa2/dpio/Makefile
new file mode 100644
index 0000000..762597f
--- /dev/null
+++ b/drivers/common/dpaa2/dpio/Makefile
@@ -0,0 +1,64 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2016 NXP. All rights reserved.
+#   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 NXP 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_dpio.a
+
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT),y)
+CFLAGS += -O0 -g
+CFLAGS += "-Wno-error"
+else
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+endif
+
+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_dpio_version.map
+
+# library version
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += dpaa2_hw_dpio.c
+
+# library dependencies
+DEPDIRS-y += lib/librte_eal
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c b/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c
new file mode 100644
index 0000000..011bd9f
--- /dev/null
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.c
@@ -0,0 +1,364 @@
+/*-
+ *   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 <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/syscall.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 <fslmc_logs.h>
+#include <fslmc_vfio.h>
+#include "dpaa2_hw_pvt.h"
+#include "dpaa2_hw_dpio.h"
+
+#define NUM_HOST_CPUS RTE_MAX_LCORE
+
+struct dpaa2_io_portal_t dpaa2_io_portal[RTE_MAX_LCORE];
+RTE_DEFINE_PER_LCORE(struct dpaa2_io_portal_t, _dpaa2_io);
+
+TAILQ_HEAD(dpio_device_list, dpaa2_dpio_dev);
+static struct dpio_device_list *dpio_dev_list; /*!< DPIO device list */
+static uint32_t io_space_count;
+
+/*Stashing Macros default for LS208x*/
+static int dpaa2_core_cluster_base = 0x04;
+static int dpaa2_cluster_sz = 2;
+
+/* For LS208X platform There are four clusters with following mapping:
+ * Cluster 1 (ID = x04) : CPU0, CPU1;
+ * Cluster 2 (ID = x05) : CPU2, CPU3;
+ * Cluster 3 (ID = x06) : CPU4, CPU5;
+ * Cluster 4 (ID = x07) : CPU6, CPU7;
+ */
+/* For LS108X platform There are two clusters with following mapping:
+ * Cluster 1 (ID = x02) : CPU0, CPU1, CPU2, CPU3;
+ * Cluster 2 (ID = x03) : CPU4, CPU5, CPU6, CPU7;
+ */
+
+/* Set the STASH Destination depending on Current CPU ID.
+ * e.g. Valid values of SDEST are 4,5,6,7. Where,
+ * CPU 0-1 will have SDEST 4
+ * CPU 2-3 will have SDEST 5.....and so on.
+ */
+static int
+dpaa2_core_cluster_sdest(int cpu_id)
+{
+	int x = cpu_id / dpaa2_cluster_sz;
+
+	if (x > 3)
+		x = 3;
+
+	return dpaa2_core_cluster_base + x;
+}
+
+static int
+configure_dpio_qbman_swp(struct dpaa2_dpio_dev *dpio_dev)
+{
+	struct qbman_swp_desc p_des;
+	struct dpio_attr attr;
+
+	dpio_dev->dpio = malloc(sizeof(struct fsl_mc_io));
+	if (!dpio_dev->dpio) {
+		PMD_INIT_LOG(ERR, "Memory allocation failure\n");
+		return -1;
+	}
+
+	PMD_DRV_LOG(DEBUG, "\t Allocated  DPIO Portal[%p]", dpio_dev->dpio);
+	dpio_dev->dpio->regs = dpio_dev->mc_portal;
+	if (dpio_open(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->hw_id,
+		      &dpio_dev->token)) {
+		PMD_INIT_LOG(ERR, "Failed to allocate IO space\n");
+		free(dpio_dev->dpio);
+		return -1;
+	}
+
+	if (dpio_reset(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token)) {
+		PMD_INIT_LOG(ERR, "Failed to reset dpio\n");
+		dpio_close(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token);
+		free(dpio_dev->dpio);
+		return -1;
+	}
+
+	if (dpio_enable(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token)) {
+		PMD_INIT_LOG(ERR, "Failed to Enable dpio\n");
+		dpio_close(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token);
+		free(dpio_dev->dpio);
+		return -1;
+	}
+
+	if (dpio_get_attributes(dpio_dev->dpio, CMD_PRI_LOW,
+				dpio_dev->token, &attr)) {
+		PMD_INIT_LOG(ERR, "DPIO Get attribute failed\n");
+		dpio_disable(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token);
+		dpio_close(dpio_dev->dpio, CMD_PRI_LOW,  dpio_dev->token);
+		free(dpio_dev->dpio);
+		return -1;
+	}
+
+	PMD_INIT_LOG(DEBUG, "Qbman Portal ID %d", attr.qbman_portal_id);
+	PMD_INIT_LOG(DEBUG, "Portal CE adr 0x%lX", attr.qbman_portal_ce_offset);
+	PMD_INIT_LOG(DEBUG, "Portal CI adr 0x%lX", attr.qbman_portal_ci_offset);
+
+	/* Configure & setup SW portal */
+	p_des.block = NULL;
+	p_des.idx = attr.qbman_portal_id;
+	p_des.cena_bar = (void *)(dpio_dev->qbman_portal_ce_paddr);
+	p_des.cinh_bar = (void *)(dpio_dev->qbman_portal_ci_paddr);
+	p_des.irq = -1;
+	p_des.qman_version = attr.qbman_version;
+
+	dpio_dev->sw_portal = qbman_swp_init(&p_des);
+	if (dpio_dev->sw_portal == NULL) {
+		PMD_DRV_LOG(ERR, " QBMan SW Portal Init failed\n");
+		dpio_close(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token);
+		free(dpio_dev->dpio);
+		return -1;
+	}
+
+	PMD_INIT_LOG(DEBUG, "QBMan SW Portal 0x%p\n", dpio_dev->sw_portal);
+
+	return 0;
+}
+
+static int
+dpaa2_configure_stashing(struct dpaa2_dpio_dev *dpio_dev)
+{
+	int sdest;
+	int cpu_id, ret;
+
+	/* Set the Stashing Destination */
+	cpu_id = rte_lcore_id();
+	if (cpu_id < 0) {
+		cpu_id = rte_get_master_lcore();
+		if (cpu_id < 0) {
+			RTE_LOG(ERR, PMD, "\tGetting CPU Index failed\n");
+			return -1;
+		}
+	}
+	/* Set the STASH Destination depending on Current CPU ID.
+	 * Valid values of SDEST are 4,5,6,7. Where,
+	 * CPU 0-1 will have SDEST 4
+	 * CPU 2-3 will have SDEST 5.....and so on.
+	 */
+
+	sdest = dpaa2_core_cluster_sdest(cpu_id);
+	PMD_DRV_LOG(DEBUG, "Portal= %d  CPU= %u SDEST= %d",
+		    dpio_dev->index, cpu_id, sdest);
+
+	ret = dpio_set_stashing_destination(dpio_dev->dpio, CMD_PRI_LOW,
+					    dpio_dev->token, sdest);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "%d ERROR in SDEST\n",  ret);
+		return -1;
+	}
+
+	return 0;
+}
+
+static inline struct dpaa2_dpio_dev *dpaa2_get_qbman_swp(void)
+{
+	struct dpaa2_dpio_dev *dpio_dev = NULL;
+	int ret;
+
+	/* Get DPIO dev handle from list using index */
+	TAILQ_FOREACH(dpio_dev, dpio_dev_list, next) {
+		if (dpio_dev && rte_atomic16_test_and_set(&dpio_dev->ref_count))
+			break;
+	}
+	if (!dpio_dev)
+		return NULL;
+
+	PMD_DRV_LOG(DEBUG, "New Portal=0x%x (%d) affined thread - %lu",
+		    dpio_dev, dpio_dev->index, syscall(SYS_gettid));
+
+	ret = dpaa2_configure_stashing(dpio_dev);
+	if (ret)
+		PMD_DRV_LOG(ERR, "dpaa2_configure_stashing failed");
+
+	return dpio_dev;
+}
+
+int
+dpaa2_affine_qbman_swp(void)
+{
+	unsigned int lcore_id = rte_lcore_id();
+	uint64_t tid = syscall(SYS_gettid);
+
+	if (lcore_id == LCORE_ID_ANY)
+		lcore_id = rte_get_master_lcore();
+	/* if the core id is not supported */
+	else if (lcore_id >= RTE_MAX_LCORE)
+		return -1;
+
+	if (dpaa2_io_portal[lcore_id].dpio_dev) {
+		PMD_DRV_LOG(INFO, "DPAA Portal=0x%x (%d) is being shared"
+			    " between thread %lu and current  %lu",
+			    dpaa2_io_portal[lcore_id].dpio_dev,
+			    dpaa2_io_portal[lcore_id].dpio_dev->index,
+			    dpaa2_io_portal[lcore_id].net_tid,
+			    tid);
+		RTE_PER_LCORE(_dpaa2_io).dpio_dev
+			= dpaa2_io_portal[lcore_id].dpio_dev;
+		rte_atomic16_inc(&dpaa2_io_portal
+				 [lcore_id].dpio_dev->ref_count);
+		dpaa2_io_portal[lcore_id].net_tid = tid;
+
+		PMD_DRV_LOG(DEBUG, "Old Portal=0x%x (%d) affined thread - %lu",
+			    dpaa2_io_portal[lcore_id].dpio_dev,
+			    dpaa2_io_portal[lcore_id].dpio_dev->index,
+			    tid);
+		return 0;
+	}
+
+	/* Populate the dpaa2_io_portal structure */
+	dpaa2_io_portal[lcore_id].dpio_dev = dpaa2_get_qbman_swp();
+
+	if (dpaa2_io_portal[lcore_id].dpio_dev) {
+		RTE_PER_LCORE(_dpaa2_io).dpio_dev
+			= dpaa2_io_portal[lcore_id].dpio_dev;
+		dpaa2_io_portal[lcore_id].net_tid = tid;
+
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+int
+dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
+			 struct vfio_device_info *obj_info,
+		int object_id)
+{
+	struct dpaa2_dpio_dev *dpio_dev;
+	struct vfio_region_info reg_info = { .argsz = sizeof(reg_info)};
+
+	if (obj_info->num_regions < NUM_DPIO_REGIONS) {
+		PMD_INIT_LOG(ERR, "ERROR, Not sufficient number "
+				"of DPIO regions.\n");
+		return -1;
+	}
+
+	if (!dpio_dev_list) {
+		dpio_dev_list = malloc(sizeof(struct dpio_device_list));
+		if (!dpio_dev_list) {
+			PMD_INIT_LOG(ERR, "Memory alloc failed in DPIO list\n");
+			return -1;
+		}
+
+		/* Initialize the DPIO List */
+		TAILQ_INIT(dpio_dev_list);
+	}
+
+	dpio_dev = malloc(sizeof(struct dpaa2_dpio_dev));
+	if (!dpio_dev) {
+		PMD_INIT_LOG(ERR, "Memory allocation failed for DPIO Device\n");
+		return -1;
+	}
+
+	PMD_DRV_LOG(INFO, "\t Aloocated DPIO [%p]", dpio_dev);
+	dpio_dev->dpio = NULL;
+	dpio_dev->hw_id = object_id;
+	dpio_dev->vfio_fd = vdev->fd;
+	rte_atomic16_init(&dpio_dev->ref_count);
+	/* Using single portal  for all devices */
+	dpio_dev->mc_portal = mcp_ptr_list[MC_PORTAL_INDEX];
+
+	reg_info.index = 0;
+	if (ioctl(dpio_dev->vfio_fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info)) {
+		PMD_INIT_LOG(ERR, "vfio: error getting region info\n");
+		return -1;
+	}
+
+	PMD_DRV_LOG(DEBUG, "\t  Region Offset = %llx", reg_info.offset);
+	PMD_DRV_LOG(DEBUG, "\t  Region Size = %llx", reg_info.size);
+	dpio_dev->ce_size = reg_info.size;
+	dpio_dev->qbman_portal_ce_paddr = (uint64_t)mmap(NULL, reg_info.size,
+				PROT_WRITE | PROT_READ, MAP_SHARED,
+				dpio_dev->vfio_fd, reg_info.offset);
+
+	/* Create Mapping for QBMan Cache Enabled area. This is a fix for
+	 * SMMU fault for DQRR statshing transaction.
+	 */
+	if (vfio_dmamap_mem_region(dpio_dev->qbman_portal_ce_paddr,
+				   reg_info.offset, reg_info.size)) {
+		PMD_INIT_LOG(ERR, "DMAMAP for Portal CE area failed.\n");
+		return -1;
+	}
+
+	reg_info.index = 1;
+	if (ioctl(dpio_dev->vfio_fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info)) {
+		PMD_INIT_LOG(ERR, "vfio: error getting region info\n");
+		return -1;
+	}
+
+	PMD_DRV_LOG(DEBUG, "\t  Region Offset = %llx", reg_info.offset);
+	PMD_DRV_LOG(DEBUG, "\t  Region Size = %llx", reg_info.size);
+	dpio_dev->ci_size = reg_info.size;
+	dpio_dev->qbman_portal_ci_paddr = (uint64_t)mmap(NULL, reg_info.size,
+				PROT_WRITE | PROT_READ, MAP_SHARED,
+				dpio_dev->vfio_fd, reg_info.offset);
+
+	if (configure_dpio_qbman_swp(dpio_dev)) {
+		PMD_INIT_LOG(ERR,
+			     "Fail to configure the dpio qbman portal for %d\n",
+			     dpio_dev->hw_id);
+		return -1;
+	}
+
+	io_space_count++;
+	dpio_dev->index = io_space_count;
+	TAILQ_INSERT_HEAD(dpio_dev_list, dpio_dev, next);
+
+	return 0;
+}
diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h b/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h
new file mode 100644
index 0000000..889c2c0
--- /dev/null
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_dpio.h
@@ -0,0 +1,64 @@
+/*-
+ *   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.
+ */
+
+#ifndef _FSLMC_DPIO_H_
+#define _FSLMC_DPIO_H_
+
+#include <mc/fsl_dpio.h>
+#include <mc/fsl_mc_sys.h>
+
+struct dpaa2_io_portal_t {
+	struct dpaa2_dpio_dev *dpio_dev;
+	struct dpaa2_dpio_dev *sec_dpio_dev;
+	uint64_t net_tid;
+	uint64_t sec_tid;
+};
+
+/*! Global per thread DPIO portal */
+RTE_DECLARE_PER_LCORE(struct dpaa2_io_portal_t, _dpaa2_io);
+
+#define DPAA2_PER_LCORE_DPIO RTE_PER_LCORE(_dpaa2_io).dpio_dev
+#define DPAA2_PER_LCORE_PORTAL DPAA2_PER_LCORE_DPIO->sw_portal
+
+#define DPAA2_PER_LCORE_SEC_DPIO RTE_PER_LCORE(_dpaa2_io).sec_dpio_dev
+#define DPAA2_PER_LCORE_SEC_PORTAL DPAA2_PER_LCORE_SEC_DPIO->sw_portal
+
+/* Affine a DPIO portal to current processing thread */
+int dpaa2_affine_qbman_swp(void);
+
+/* create dpio device */
+int dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
+			     struct vfio_device_info *obj_info,
+			     int object_id);
+
+#endif /* _FSLMC_DPIO_H_ */
diff --git a/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
new file mode 100644
index 0000000..ef3eb71
--- /dev/null
+++ b/drivers/common/dpaa2/dpio/dpaa2_hw_pvt.h
@@ -0,0 +1,68 @@
+/*-
+ *   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.
+ */
+
+#ifndef _DPAA2_HW_PVT_H_
+#define _DPAA2_HW_PVT_H_
+
+#include <mc/fsl_mc_sys.h>
+#include <fsl_qbman_portal.h>
+
+
+#define MC_PORTAL_INDEX		0
+#define NUM_DPIO_REGIONS	2
+
+struct dpaa2_dpio_dev {
+	TAILQ_ENTRY(dpaa2_dpio_dev) next;
+		/**< Pointer to Next device instance */
+	uint16_t index; /**< Index of a instance in the list */
+	rte_atomic16_t ref_count;
+		/**< How many thread contexts are sharing this.*/
+	struct fsl_mc_io *dpio; /** handle to DPIO portal object */
+	uint16_t token;
+	struct qbman_swp *sw_portal; /** SW portal object */
+	const struct qbman_result *dqrr[4];
+		/**< DQRR Entry for this SW portal */
+	void *mc_portal; /**< MC Portal for configuring this device */
+	uintptr_t qbman_portal_ce_paddr;
+		/**< Physical address of Cache Enabled Area */
+	uintptr_t ce_size; /**< Size of the CE region */
+	uintptr_t qbman_portal_ci_paddr;
+		/**< Physical address of Cache Inhibit Area */
+	uintptr_t ci_size; /**< Size of the CI region */
+	int32_t	vfio_fd; /**< File descriptor received via VFIO */
+	int32_t hw_id; /**< An unique ID of this DPIO device instance */
+};
+
+/*! Global MCP list */
+extern void *(*mcp_ptr_list);
+#endif
diff --git a/drivers/common/dpaa2/dpio/rte_pmd_dpaa2_dpio_version.map b/drivers/common/dpaa2/dpio/rte_pmd_dpaa2_dpio_version.map
new file mode 100644
index 0000000..597cdbd
--- /dev/null
+++ b/drivers/common/dpaa2/dpio/rte_pmd_dpaa2_dpio_version.map
@@ -0,0 +1,8 @@
+DPDK_17.02 {
+	global:
+	per_lcore__dpaa2_io;
+	dpaa2_affine_qbman_swp;
+	dpaa2_create_dpio_device;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 438fa2c..f380c88 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -112,6 +112,7 @@ _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_dpaa2_dpio
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_pmd_fslmcbus
 endif
 _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 14/34] bus/fslmc: add debug log message support
From: Hemant Agrawal @ 2016-12-19 20:53 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 config/common_base                        |  7 +++
 config/defconfig_arm64-dpaa2-linuxapp-gcc |  5 ++
 drivers/bus/fslmc/Makefile                |  5 ++
 drivers/bus/fslmc/fslmc_logs.h            | 76 +++++++++++++++++++++++++++++++
 drivers/common/dpaa2/qbman/Makefile       |  5 ++
 drivers/net/dpaa2/Makefile                |  5 ++
 drivers/net/dpaa2/dpaa2_ethdev.c          | 10 ++--
 7 files changed, 110 insertions(+), 3 deletions(-)
 create mode 100644 drivers/bus/fslmc/fslmc_logs.h

diff --git a/config/common_base b/config/common_base
index ea466c9..d605e85 100644
--- a/config/common_base
+++ b/config/common_base
@@ -286,6 +286,13 @@ CONFIG_RTE_LIBRTE_FSLMC_BUS=n
 # Compile burst-oriented NXP DPAA2 PMD driver
 #
 CONFIG_RTE_LIBRTE_DPAA2_PMD=n
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE=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 13c16c0..d3bc9d8 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -56,3 +56,8 @@ CONFIG_RTE_LIBRTE_FSLMC_BUS=y
 # Compile burst-oriented NXP DPAA2 PMD driver
 #
 CONFIG_RTE_LIBRTE_DPAA2_PMD=y
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE=n
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 54f757b..a8b1666 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -35,8 +35,13 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_fslmcbus.a
 
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT),y)
+CFLAGS += -O0 -g
+CFLAGS += "-Wno-error"
+else
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+endif
 CFLAGS += "-Wno-strict-aliasing"
 
 CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
diff --git a/drivers/bus/fslmc/fslmc_logs.h b/drivers/bus/fslmc/fslmc_logs.h
new file mode 100644
index 0000000..a890e6c
--- /dev/null
+++ b/drivers/bus/fslmc/fslmc_logs.h
@@ -0,0 +1,76 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   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 NXP 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 _FSLMC_LOGS_H_
+#define _FSLMC_LOGS_H_
+
+#define PMD_INIT_LOG(level, fmt, args...) \
+	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ##args)
+
+#ifdef RTE_LIBRTE_DPAA2_DEBUG_INIT
+#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
+#else
+#define PMD_INIT_FUNC_TRACE() do { } while (0)
+#endif
+
+#ifdef RTE_LIBRTE_DPAA2_DEBUG_RX
+#define PMD_RX_LOG(level, fmt, args...) \
+	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
+#else
+#define PMD_RX_LOG(level, fmt, args...) do { } while (0)
+#endif
+
+#ifdef RTE_LIBRTE_DPAA2_DEBUG_TX
+#define PMD_TX_LOG(level, fmt, args...) \
+	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
+#else
+#define PMD_TX_LOG(level, fmt, args...) do { } while (0)
+#endif
+
+#ifdef RTE_LIBRTE_DPAA2_DEBUG_TX_FREE
+#define PMD_TX_FREE_LOG(level, fmt, args...) \
+	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
+#else
+#define PMD_TX_FREE_LOG(level, fmt, args...) do { } while (0)
+#endif
+
+#ifdef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
+#define PMD_DRV_LOG_RAW(level, fmt, args...) \
+	RTE_LOG(level, PMD, "%s(): " fmt, __func__, ## args)
+#else
+#define PMD_DRV_LOG_RAW(level, fmt, args...) do { } while (0)
+#endif
+
+#define PMD_DRV_LOG(level, fmt, args...) \
+	PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
+
+#endif /* _FSLMC_LOGS_H_ */
diff --git a/drivers/common/dpaa2/qbman/Makefile b/drivers/common/dpaa2/qbman/Makefile
index a6f7ece..751e1e6 100644
--- a/drivers/common/dpaa2/qbman/Makefile
+++ b/drivers/common/dpaa2/qbman/Makefile
@@ -36,8 +36,13 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_dpaa2_qbman.a
 
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT),y)
+CFLAGS += -O0 -g
+CFLAGS += "-Wno-error"
+else
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+endif
 
 CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
 
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 316ceb7..5a1db74 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -36,8 +36,13 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_dpaa2.a
 
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT),y)
+CFLAGS += -O0 -g
+CFLAGS += "-Wno-error"
+else
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+endif
 
 CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
 CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 332088b..a0e842c 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -45,7 +45,7 @@
 #include <rte_ethdev.h>
 #include <rte_fslmc.h>
 
-
+#include <fslmc_logs.h>
 #include <fslmc_vfio.h>
 #include "dpaa2_ethdev.h"
 
@@ -55,6 +55,8 @@
 static int
 dpaa2_dev_init(struct rte_eth_dev *eth_dev)
 {
+	PMD_INIT_FUNC_TRACE();
+
 	/* For secondary processes, the primary has done all the work */
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
@@ -67,6 +69,8 @@
 static int
 dpaa2_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused)
 {
+	PMD_INIT_FUNC_TRACE();
+
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return -EPERM;
 
@@ -100,8 +104,8 @@ static int rte_dpaa2_probe(struct rte_driver *drv, struct rte_device *dev)
 						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");
+			PMD_INIT_LOG(CRIT, "Cannot allocate memzone for"
+				     " private port data\n");
 			return -ENOMEM;
 		}
 	}
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 13/34] net/dpaa2: introducing NXP dpaa2 pmd driver
From: Hemant Agrawal @ 2016-12-19 20:53 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

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                  |  58 ++++++++++
 drivers/net/dpaa2/dpaa2_ethdev.c            | 158 ++++++++++++++++++++++++++++
 drivers/net/dpaa2/dpaa2_ethdev.h            |  44 ++++++++
 drivers/net/dpaa2/rte_pmd_dpaa2_version.map |   4 +
 mk/rte.app.mk                               |   5 +
 10 files changed, 283 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

diff --git a/config/common_base b/config/common_base
index 45386cc..ea466c9 100644
--- a/config/common_base
+++ b/config/common_base
@@ -282,6 +282,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 bc93230..2bcf67b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -55,7 +55,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..316ceb7
--- /dev/null
+++ b/drivers/net/dpaa2/Makefile
@@ -0,0 +1,58 @@
+#   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-y += lib/librte_eal
+
+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..332088b
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -0,0 +1,158 @@
+/*-
+ *   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_driver *drv, struct rte_device *dev)
+{
+	struct eth_driver    *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	struct rte_dpaa2_driver *dpaa2_drv;
+	struct rte_dpaa2_device *dpaa2_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+	int diag;
+
+	dpaa2_drv = container_of(drv, struct rte_dpaa2_driver, driver);
+	dpaa2_dev = container_of(dev, struct rte_dpaa2_device, device);
+
+	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_device *dev)
+{
+	struct rte_dpaa2_device *dpaa2_dev;
+	struct rte_eth_dev *eth_dev;
+	dpaa2_dev = container_of(dev, struct rte_dpaa2_device, device);
+
+	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 f75f0e2..438fa2c 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -109,6 +109,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
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 12/34] bus/fslmc: scan for net and sec devices
From: Hemant Agrawal @ 2016-12-19 20:53 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

This patch will add support in fslmc vfio process to
scan and parse the dpni and dpseci object for net and crypto
devices. It will add the scanned devices to the fslmc bus.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/bus/fslmc/fslmc_bus.c  |  2 +-
 drivers/bus/fslmc/fslmc_vfio.c | 66 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index ef38b3b..bd0fc4f 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -58,7 +58,7 @@ int rte_fslmc_scan(struct rte_bus *bus_d)
 		FSLMC_BUS_LOG(ERR, "fslmc: Unable to setup devices");
 		return -1;
 	}
-	RTE_LOG(INFO, EAL, "fslmc: Bus scan completed");
+	RTE_LOG(INFO, EAL, "fslmc: Bus scan completed\n");
 	return 0;
 }
 
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index eae6495..7739493 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -209,15 +209,58 @@ static int64_t vfio_map_mcp_obj(struct fslmc_vfio_group *group, char *mcp_obj)
 	return v_addr;
 }
 
+static inline int
+dpaa2_compare_dpaa2_dev(const struct rte_dpaa2_device *dev,
+			 const struct rte_dpaa2_device *dev2)
+{
+	/*not the same family device */
+	if (dev->dev_type != dev2->dev_type)
+		return -1;
+
+	if (dev->object_id == dev2->object_id)
+		return 0;
+	else
+		return 1;
+}
+
+static void
+dpaa2_bus_add_device(struct rte_bus *bus, struct rte_dpaa2_device *dev)
+{
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&bus->device_list)) {
+		rte_eal_device_insert(&dev->device);
+		rte_eal_bus_add_device(bus, &dev->device);
+	} else {
+		struct rte_dpaa2_device *dev2;
+		struct rte_device *r_dev2;
+		int ret;
+
+		TAILQ_FOREACH(r_dev2, &bus->device_list, next) {
+			dev2 = container_of(r_dev2, struct rte_dpaa2_device,
+						device);
+			ret = dpaa2_compare_dpaa2_dev(dev, dev2);
+			if (ret <= 0)
+				continue;
+
+			rte_eal_bus_insert_device(bus, &dev2->device,
+						  &dev->device);
+			rte_eal_device_insert(&dev->device);
+			return;
+		}
+		rte_eal_device_insert(&dev->device);
+		rte_eal_bus_add_device(bus, &dev->device);
+	}
+}
+
 /* Following function shall fetch total available list of MC devices
  * from VFIO container & populate private list of devices and other
  * data structures
  */
-int fslmc_vfio_process_group(struct rte_bus *bus __rte_unused)
+int fslmc_vfio_process_group(struct rte_bus *bus)
 {
 	struct fslmc_vfio_device *vdev;
 	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-	char *temp_obj, *object_type __rte_unused, *mcp_obj, *dev_name;
+	char *temp_obj, *object_type, *mcp_obj, *dev_name;
 	int32_t object_id, i, dev_fd;
 	DIR *d;
 	struct dirent *dir;
@@ -347,6 +390,25 @@ int fslmc_vfio_process_group(struct rte_bus *bus __rte_unused)
 			FSLMC_VFIO_LOG(ERR, "DPAA2 VFIO_DEVICE_GET_INFO fail");
 			goto FAILURE;
 		}
+		if (!strcmp(object_type, "dpni") ||
+		    !strcmp(object_type, "dpseci")) {
+			struct rte_dpaa2_device *dev;
+
+			dev = malloc(sizeof(struct rte_dpaa2_device));
+			if (dev == NULL)
+				return -1;
+
+			memset(dev, 0, sizeof(*dev));
+			/* store hw_id of dpni/dpseci device */
+			dev->object_id = object_id;
+			dev->dev_type = (strcmp(object_type, "dpseci")) ?
+				DPAA2_MC_DPNI_DEVID : DPAA2_MC_DPSECI_DEVID;
+
+			FSLMC_VFIO_LOG(DEBUG, "DPAA2: Added [%s-%d]\n",
+				      object_type, object_id);
+
+			dpaa2_bus_add_device(bus, dev);
+		}
 	}
 	closedir(d);
 
-- 
1.9.1

^ permalink raw reply related

* [PATCHv2 11/34] bus/fslmc: add vfio support
From: Hemant Agrawal @ 2016-12-19 20:53 UTC (permalink / raw)
  To: dev
  Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
	ferruh.yigit, jerin.jacob, Hemant Agrawal
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>

Add support for using VFIO for dpaa2 based fsl-mc bus.

There are some differences in the way vfio used for fsl-mc bus
from the eal vfio.
 - The scanning of bus for individual objects on the basis of
   the DPRC container.
 - The use and mapping of MC portal for object access

With the evolution of bus model, they canbe further aligned with
eal vfio code.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/nics/features/dpaa2.ini |   1 +
 drivers/bus/fslmc/Makefile         |   2 +
 drivers/bus/fslmc/fslmc_bus.c      |  26 +-
 drivers/bus/fslmc/fslmc_vfio.c     | 471 +++++++++++++++++++++++++++++++++++++
 drivers/bus/fslmc/fslmc_vfio.h     |  74 ++++++
 5 files changed, 570 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/fslmc/fslmc_vfio.c
 create mode 100644 drivers/bus/fslmc/fslmc_vfio.h

diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
index b2ad6ec..b176208 100644
--- a/doc/guides/nics/features/dpaa2.ini
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -4,5 +4,6 @@
 ; Refer to default.ini for the full list of available PMD features.
 ;
 [Features]
+Linux VFIO           = Y
 ARMv8                = Y
 Usage doc            = Y
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index f5da4e0..54f757b 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -41,6 +41,7 @@ CFLAGS += "-Wno-strict-aliasing"
 
 CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
 CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
 
 # versioning export map
 EXPORT_MAP := rte_pmd_fslmcbus_version.map
@@ -55,6 +56,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
         mc/dpio.c \
         mc/mc_sys.c
 
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_vfio.c
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
 
 # library dependencies
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index cbf7600..ef38b3b 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -42,21 +42,39 @@
 #include <rte_ethdev.h>
 
 #include "rte_fslmc.h"
+#include "fslmc_vfio.h"
 
 #define FSLMC_BUS_LOG(level, fmt, args...) \
 	RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
 
 static
-int rte_fslmc_scan(struct rte_bus *bus_d __rte_unused)
+int rte_fslmc_scan(struct rte_bus *bus_d)
 {
+	if (fslmc_vfio_setup_group()) {
+		FSLMC_BUS_LOG(ERR, "fslmc: Unable to setup VFIO");
+		return -1;
+	}
+	if (fslmc_vfio_process_group(bus_d)) {
+		FSLMC_BUS_LOG(ERR, "fslmc: Unable to setup devices");
+		return -1;
+	}
+	RTE_LOG(INFO, EAL, "fslmc: Bus scan completed");
 	return 0;
 }
 
 static
-int rte_fslmc_match(struct rte_driver *drv __rte_unused,
-		    struct rte_device *dev __rte_unused)
+int rte_fslmc_match(struct rte_driver *drv, struct rte_device *dev)
 {
-	return 0;
+	struct rte_dpaa2_driver *dpaa2_drv;
+	struct rte_dpaa2_device *dpaa2_dev;
+
+	dpaa2_drv = container_of(drv, struct rte_dpaa2_driver, driver);
+	dpaa2_dev = container_of(dev, struct rte_dpaa2_device, device);
+
+	if (dpaa2_drv->drv_type == dpaa2_dev->dev_type)
+		return 0;
+
+	return 1;
 }
 
 struct rte_bus fslmc_bus = {
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
new file mode 100644
index 0000000..eae6495
--- /dev/null
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -0,0 +1,471 @@
+/*-
+ *   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 <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/vfs.h>
+#include <libgen.h>
+#include <dirent.h>
+#include <sys/eventfd.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_bus.h>
+
+#include "rte_fslmc.h"
+#include "fslmc_vfio.h"
+
+#define VFIO_MAX_CONTAINERS	1
+
+#define FSLMC_VFIO_LOG(level, fmt, args...) \
+	RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
+
+/** Pathname of FSL-MC devices directory. */
+#define SYSFS_DPAA2_MC_DEVICES "/sys/bus/fsl-mc/devices"
+
+/* Number of VFIO containers & groups with in */
+static struct fslmc_vfio_group vfio_groups[VFIO_MAX_GRP];
+static struct fslmc_vfio_container vfio_containers[VFIO_MAX_CONTAINERS];
+static int container_device_fd;
+void *(*mcp_ptr_list);
+static uint32_t mcp_id;
+
+static int vfio_connect_container(struct fslmc_vfio_group *vfio_group)
+{
+	struct fslmc_vfio_container *container;
+	int i, fd, ret;
+
+	/* Try connecting to vfio container if already created */
+	for (i = 0; i < VFIO_MAX_CONTAINERS; i++) {
+		container = &vfio_containers[i];
+		if (!ioctl(vfio_group->fd, VFIO_GROUP_SET_CONTAINER,
+			   &container->fd)) {
+			FSLMC_VFIO_LOG(INFO, "Container pre-exists with"
+				    " FD[0x%x] for this group",
+				    container->fd);
+			vfio_group->container = container;
+			return 0;
+		}
+	}
+
+	/* Opens main vfio file descriptor which represents the "container" */
+	fd = vfio_get_container_fd();
+	if (fd < 0) {
+		FSLMC_VFIO_LOG(ERR, "Failed to open VFIO container");
+		return -errno;
+	}
+
+	/* Check whether support for SMMU type IOMMU present or not */
+	if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU)) {
+		/* Connect group to container */
+		ret = ioctl(vfio_group->fd, VFIO_GROUP_SET_CONTAINER, &fd);
+		if (ret) {
+			FSLMC_VFIO_LOG(ERR, "Failed to setup group container");
+			close(fd);
+			return -errno;
+		}
+
+		ret = ioctl(fd, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
+		if (ret) {
+			FSLMC_VFIO_LOG(ERR, "Failed to setup VFIO iommu");
+			close(fd);
+			return -errno;
+		}
+	} else {
+		FSLMC_VFIO_LOG(ERR, "No supported IOMMU available");
+		close(fd);
+		return -EINVAL;
+	}
+
+	container = NULL;
+	for (i = 0; i < VFIO_MAX_CONTAINERS; i++) {
+		if (vfio_containers[i].used)
+			continue;
+		FSLMC_VFIO_LOG(DEBUG, "Unused container at index %d", i);
+		container = &vfio_containers[i];
+	}
+	if (!container) {
+		FSLMC_VFIO_LOG(ERR, "No free container found");
+		close(fd);
+		return -ENOMEM;
+	}
+
+	container->used = 1;
+	container->fd = fd;
+	container->group_list[container->index] = vfio_group;
+	vfio_group->container = container;
+	container->index++;
+	return 0;
+}
+
+int vfio_dmamap_mem_region(uint64_t vaddr,
+			   uint64_t iova,
+			   uint64_t size)
+{
+	struct fslmc_vfio_group *group;
+	struct vfio_iommu_type1_dma_map dma_map = {
+		.argsz = sizeof(dma_map),
+		.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
+	};
+
+	dma_map.vaddr = vaddr;
+	dma_map.size = size;
+	dma_map.iova = iova;
+
+	/* SET DMA MAP for IOMMU */
+	group = &vfio_groups[0];
+	if (ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA, &dma_map)) {
+		FSLMC_VFIO_LOG(ERR, "VFIO_IOMMU_MAP_DMA (errno = %d)", errno);
+		return -1;
+	}
+	return 0;
+}
+static int64_t vfio_map_mcp_obj(struct fslmc_vfio_group *group, char *mcp_obj)
+{
+	int64_t v_addr = (int64_t)MAP_FAILED;
+	int32_t ret, mc_fd;
+
+	struct vfio_device_info d_info = { .argsz = sizeof(d_info) };
+	struct vfio_region_info reg_info = { .argsz = sizeof(reg_info) };
+
+	/* getting the mcp object's fd*/
+	mc_fd = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, mcp_obj);
+	if (mc_fd < 0) {
+		FSLMC_VFIO_LOG(ERR, "error in VFIO get device %s fd from group"
+			    " %d", mcp_obj, group->fd);
+		return v_addr;
+	}
+
+	/* getting device info*/
+	ret = ioctl(mc_fd, VFIO_DEVICE_GET_INFO, &d_info);
+	if (ret < 0) {
+		FSLMC_VFIO_LOG(ERR, "error in VFIO getting DEVICE_INFO");
+		goto MC_FAILURE;
+	}
+
+	/* getting device region info*/
+	ret = ioctl(mc_fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info);
+	if (ret < 0) {
+		FSLMC_VFIO_LOG(ERR, "error in VFIO getting REGION_INFO");
+		goto MC_FAILURE;
+	}
+
+	FSLMC_VFIO_LOG(DEBUG, "region offset = %llx  , region size = %llx",
+		     reg_info.offset, reg_info.size);
+
+	v_addr = (uint64_t)mmap(NULL, reg_info.size,
+		PROT_WRITE | PROT_READ, MAP_SHARED,
+		mc_fd, reg_info.offset);
+
+MC_FAILURE:
+	close(mc_fd);
+
+	return v_addr;
+}
+
+/* Following function shall fetch total available list of MC devices
+ * from VFIO container & populate private list of devices and other
+ * data structures
+ */
+int fslmc_vfio_process_group(struct rte_bus *bus __rte_unused)
+{
+	struct fslmc_vfio_device *vdev;
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char *temp_obj, *object_type __rte_unused, *mcp_obj, *dev_name;
+	int32_t object_id, i, dev_fd;
+	DIR *d;
+	struct dirent *dir;
+	char path[PATH_MAX];
+	int64_t v_addr;
+	int ndev_count;
+	struct fslmc_vfio_group *group = &vfio_groups[0];
+	static int process_once;
+
+	/* if already done once */
+	if (process_once) {
+		FSLMC_VFIO_LOG(DEBUG, "Already scanned once - re-scan "
+			    "not supported");
+		return 0;
+	}
+	process_once = 0;
+
+	sprintf(path, "/sys/kernel/iommu_groups/%d/devices", group->groupid);
+
+	d = opendir(path);
+	if (!d) {
+		FSLMC_VFIO_LOG(ERR, "Unable to open directory %s", path);
+		return -1;
+	}
+
+	/*Counting the number of devices in a group and getting the mcp ID*/
+	ndev_count = 0;
+	mcp_obj = NULL;
+	while ((dir = readdir(d)) != NULL) {
+		if (dir->d_type == DT_LNK) {
+			ndev_count++;
+			if (!strncmp("dpmcp", dir->d_name, 5)) {
+				if (mcp_obj)
+					free(mcp_obj);
+				mcp_obj = malloc(sizeof(dir->d_name));
+				if (!mcp_obj) {
+					FSLMC_VFIO_LOG(ERR, "mcp obj:Unable to"
+						    " allocate memory");
+					return -ENOMEM;
+				}
+				strcpy(mcp_obj, dir->d_name);
+				temp_obj = strtok(dir->d_name, ".");
+				temp_obj = strtok(NULL, ".");
+				sscanf(temp_obj, "%d", &mcp_id);
+			}
+		}
+	}
+	closedir(d);
+
+	if (!mcp_obj) {
+		FSLMC_VFIO_LOG(ERR, "DPAA2 MCP Object not Found");
+		return -ENODEV;
+	}
+	RTE_LOG(INFO, EAL, "fslmc: DPRC contains = %d devices\n", ndev_count);
+
+	/* Allocate the memory depends upon number of objects in a group*/
+	group->vfio_device = (struct fslmc_vfio_device *)malloc(ndev_count *
+			     sizeof(struct fslmc_vfio_device));
+	if (!(group->vfio_device)) {
+		FSLMC_VFIO_LOG(ERR, "vfio device: Unable to allocate memory\n");
+		free(mcp_obj);
+		return -ENOMEM;
+	}
+
+	/* Allocate memory for MC Portal list */
+	mcp_ptr_list = malloc(sizeof(void *) * 1);
+	if (!mcp_ptr_list) {
+		FSLMC_VFIO_LOG(ERR, "portal list: Unable to allocate memory!");
+		free(mcp_obj);
+		goto FAILURE;
+	}
+
+	v_addr = vfio_map_mcp_obj(group, mcp_obj);
+	free(mcp_obj);
+	if (v_addr == (int64_t)MAP_FAILED) {
+		FSLMC_VFIO_LOG(ERR, "Error mapping region (errno = %d)", errno);
+		goto FAILURE;
+	}
+
+	FSLMC_VFIO_LOG(DEBUG, "DPAA2 MC has VIR_ADD = %ld", v_addr);
+
+	mcp_ptr_list[0] = (void *)v_addr;
+
+	d = opendir(path);
+	if (!d) {
+		FSLMC_VFIO_LOG(ERR, "Unable to open %s Directory", path);
+		goto FAILURE;
+	}
+
+	i = 0;
+	FSLMC_VFIO_LOG(DEBUG, "DPAA2 - Parsing devices:");
+	/* Parsing each object and initiating them*/
+	while ((dir = readdir(d)) != NULL) {
+		if (dir->d_type != DT_LNK)
+			continue;
+		if (!strncmp("dprc", dir->d_name, 4) ||
+		    !strncmp("dpmcp", dir->d_name, 5))
+			continue;
+		dev_name = malloc(sizeof(dir->d_name));
+		if (!dev_name) {
+			FSLMC_VFIO_LOG(ERR, "name: Unable to allocate memory");
+			goto FAILURE;
+		}
+		strcpy(dev_name, dir->d_name);
+		object_type = strtok(dir->d_name, ".");
+		temp_obj = strtok(NULL, ".");
+		sscanf(temp_obj, "%d", &object_id);
+		FSLMC_VFIO_LOG(DEBUG, " - %s ", dev_name);
+
+		/* getting the device fd*/
+		dev_fd = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, dev_name);
+		if (dev_fd < 0) {
+			FSLMC_VFIO_LOG(ERR, "VFIO_GROUP_GET_DEVICE_FD error"
+				    " Device fd: %s, Group: %d",
+				    dev_name, group->fd);
+			free(dev_name);
+			goto FAILURE;
+		}
+
+		free(dev_name);
+		vdev = &group->vfio_device[group->object_index++];
+		vdev->fd = dev_fd;
+		vdev->index = i;
+		i++;
+		/* Get Device inofrmation */
+		if (ioctl(vdev->fd, VFIO_DEVICE_GET_INFO, &device_info)) {
+			FSLMC_VFIO_LOG(ERR, "DPAA2 VFIO_DEVICE_GET_INFO fail");
+			goto FAILURE;
+		}
+	}
+	closedir(d);
+
+	return 0;
+
+FAILURE:
+	free(group->vfio_device);
+	group->vfio_device = NULL;
+	return -1;
+}
+
+
+int fslmc_vfio_setup_group(void)
+{
+	char path[PATH_MAX];
+	char iommu_group_path[PATH_MAX], *group_name;
+	struct fslmc_vfio_group *group = NULL;
+	struct stat st;
+	int groupid;
+	int ret, len, i;
+	char *container;
+	struct vfio_group_status status = { .argsz = sizeof(status) };
+
+	/* if already done once */
+	if (container_device_fd)
+		return 0;
+
+	container = getenv("DPRC");
+
+	if (container == NULL) {
+		FSLMC_VFIO_LOG(ERR, "VFIO container not set in env DPRC");
+		return -1;
+	}
+	RTE_LOG(INFO, PMD, "DPAA2: Processing Container = %s\n", container);
+	snprintf(path, sizeof(path), "%s/%s",
+		 SYSFS_DPAA2_MC_DEVICES, container);
+
+	/* Check whether fsl-mc container exists or not */
+	FSLMC_VFIO_LOG(DEBUG, "container device path = %s", path);
+	if (stat(path, &st) < 0) {
+		FSLMC_VFIO_LOG(ERR, "Error (%d) getting FSL-MC dev (%s)",
+			     errno,  path);
+		return -errno;
+	}
+
+	/* DPRC container exists. Now checkout the IOMMU Group */
+	strncat(path, "/iommu_group", sizeof(path) - strlen(path) - 1);
+
+	len = readlink(path, iommu_group_path, PATH_MAX);
+	if (len == -1) {
+		FSLMC_VFIO_LOG(ERR, "Error no iommu_group for device"
+			       "   %s: len = %d, (errno = %d)",
+			       path, len, errno);
+		return -errno;
+	}
+
+	iommu_group_path[len] = 0;
+	group_name = basename(iommu_group_path);
+	if (sscanf(group_name, "%d", &groupid) != 1) {
+		FSLMC_VFIO_LOG(ERR, "error in VFIO groupname reading %s", path);
+		return -errno;
+	}
+
+	FSLMC_VFIO_LOG(DEBUG, "VFIO iommu group id = %d", groupid);
+
+	/* Check if group already exists */
+	for (i = 0; i < VFIO_MAX_GRP; i++) {
+		group = &vfio_groups[i];
+		if (group->groupid == groupid) {
+			FSLMC_VFIO_LOG(ERR, "groupid already exists %d",
+				     groupid);
+			return 0;
+		}
+	}
+
+	/* Open the VFIO file corresponding to the IOMMU group */
+	snprintf(path, sizeof(path), "/dev/vfio/%d", groupid);
+
+	group->fd = open(path, O_RDWR);
+	if (group->fd < 0) {
+		FSLMC_VFIO_LOG(ERR, " VFIO error opening %s", path);
+		return -1;
+	}
+
+	/* Test & Verify that group is VIABLE & AVAILABLE */
+	if (ioctl(group->fd, VFIO_GROUP_GET_STATUS, &status)) {
+		FSLMC_VFIO_LOG(ERR, " VFIO error getting group status");
+		close(group->fd);
+		return -1;
+	}
+	if (!(status.flags & VFIO_GROUP_FLAGS_VIABLE)) {
+		FSLMC_VFIO_LOG(ERR, "VFIO group not viable");
+		close(group->fd);
+		return -1;
+	}
+	/* Since Group is VIABLE, Store the groupid */
+	group->groupid = groupid;
+
+	/* check if group does not have a container yet */
+	if (!(status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET)) {
+		/* Now connect this IOMMU group to given container */
+		if (vfio_connect_container(group)) {
+			FSLMC_VFIO_LOG(ERR, "VFIO error connecting container"
+				       " with groupid %d", groupid);
+			close(group->fd);
+			return -1;
+		}
+	}
+
+	/* Get Device information */
+	ret = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, container);
+	if (ret < 0) {
+		FSLMC_VFIO_LOG(ERR, "VFIO error getting device %s fd from"
+			       " group  %d", container, group->groupid);
+		return ret;
+	}
+	container_device_fd = ret;
+	FSLMC_VFIO_LOG(DEBUG, "VFIO Container FD is [0x%X]",
+		     container_device_fd);
+
+	return 0;
+}
diff --git a/drivers/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h
new file mode 100644
index 0000000..c5a42fe
--- /dev/null
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -0,0 +1,74 @@
+/*-
+ *   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 _FSLMC_VFIO_H_
+#define _FSLMC_VFIO_H_
+
+#include "eal_vfio.h"
+
+#define DPAA2_VENDOR_ID		0x1957
+#define DPAA2_MC_DPNI_DEVID	7
+#define DPAA2_MC_DPSECI_DEVID	3
+
+#define VFIO_MAX_GRP 1
+
+typedef struct fslmc_vfio_device {
+	int fd; /* fslmc root container device ?? */
+	int index; /*index of child object */
+	struct fslmc_vfio_device *child; /* Child object */
+} fslmc_vfio_device;
+
+typedef struct fslmc_vfio_group {
+	int fd; /* /dev/vfio/"groupid" */
+	int groupid;
+	struct fslmc_vfio_container *container;
+	int object_index;
+	struct fslmc_vfio_device *vfio_device;
+} fslmc_vfio_group;
+
+typedef struct fslmc_vfio_container {
+	int fd; /* /dev/vfio/vfio */
+	int used;
+	int index; /* index in group list */
+	struct fslmc_vfio_group *group_list[VFIO_MAX_GRP];
+} fslmc_vfio_container;
+
+int vfio_dmamap_mem_region(
+	uint64_t vaddr,
+	uint64_t iova,
+	uint64_t size);
+
+int fslmc_vfio_setup_group(void);
+int fslmc_vfio_process_group(struct rte_bus *bus);
+
+#endif /* _FSLMC_VFIO_H_ */
-- 
1.9.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox